Add payment show pdf
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Philipp Lang 2023-12-01 01:25:02 +01:00
parent 566ed704a6
commit ad8511874d
7 changed files with 108 additions and 2 deletions

View File

@ -116,7 +116,7 @@ abstract class Invoice extends Document
}
/**
* @param Collection<int|string, Member> $members
* @param Collection<(int|string), Member> $members
*
* @return array<string, string>
*/

View File

@ -0,0 +1,26 @@
<?php
namespace App\Payment\Actions;
use App\Invoice\BillDocument;
use App\Payment\Payment;
use Illuminate\Http\Response;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\Tex\BaseCompiler;
use Zoomyboy\Tex\Tex;
class DisplayPdfAction
{
use AsAction;
public function handle(Payment $payment): BaseCompiler|Response
{
if (null === $payment->invoice_data) {
return response()->noContent();
}
$invoice = BillDocument::from($payment->invoice_data);
return Tex::compile($invoice);
}
}

View File

@ -28,6 +28,9 @@ class PaymentResource extends JsonResource
'id' => $this->id,
'is_accepted' => $this->status->isAccepted(),
'links' => [
'show' => $this->invoice_data
? route('payment.pdf', ['payment' => $this->getModel()])
: null,
'update' => route('payment.update', ['payment' => $this->getModel()]),
'destroy' => route('payment.destroy', ['payment' => $this->getModel()]),
]

View File

@ -31,9 +31,11 @@
<td v-text="payment.status_name"></td>
<td v-text="payment.subscription.name"></td>
<td class="flex">
<a v-show="payment.links.show" :href="payment.links.show"
class="inline-flex btn btn-success btn-sm"><ui-sprite src="eye"></ui-sprite></a>
<a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(payment)"><ui-sprite
src="pencil"></ui-sprite></a>
<button v-show="!payment.is_accepted" href="#" class="inline-flex btn btn-success btn-sm"
<button v-show="!payment.is_accepted" class="inline-flex btn btn-success btn-sm"
@click.prevent="accept(payment)"><ui-sprite src="check"></ui-sprite></button>
<button class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(payment)"><ui-sprite
src="trash"></ui-sprite></button>

View File

@ -46,6 +46,7 @@ use App\Membership\Actions\MembershipUpdateAction;
use App\Membership\Actions\StoreForGroupAction;
use App\Payment\Actions\AllpaymentPageAction;
use App\Payment\Actions\AllpaymentStoreAction;
use App\Payment\Actions\DisplayPdfAction;
use App\Payment\Actions\IndexAction as PaymentIndexAction;
use App\Payment\Actions\PaymentDestroyAction;
use App\Payment\Actions\PaymentStoreAction;
@ -106,6 +107,7 @@ Route::group(['middleware' => 'auth:web'], function (): void {
// ---------------------------------- payment ----------------------------------
Route::get('/member/{member}/payment', PaymentIndexAction::class)->name('member.payment.index');
Route::get('/payment/{payment}/pdf', DisplayPdfAction::class)->name('payment.pdf');
Route::post('/member/{member}/payment', PaymentStoreAction::class)->name('member.payment.store');
Route::patch('/payment/{payment}', PaymentUpdateAction::class)->name('payment.update');
Route::delete('/payment/{payment}', PaymentDestroyAction::class)->name('payment.destroy');

View File

@ -2,6 +2,8 @@
namespace Tests\Feature\Payment;
use App\Invoice\BillDocument;
use App\Invoice\DocumentFactory;
use App\Member\Member;
use App\Payment\Payment;
use App\Payment\Subscription;
@ -32,6 +34,7 @@ class IndexTest extends TestCase
->assertJsonPath('data.0.subscription_id', $payment->subscription->id)
->assertJsonPath('data.0.status_name', 'Nicht bezahlt')
->assertJsonPath('data.0.nr', '2019')
->assertJsonPath('data.0.links.show', null)
->assertJsonPath('data.0.links.update', url("/payment/{$payment->id}"))
->assertJsonPath('data.0.links.destroy', url("/payment/{$payment->id}"))
->assertJsonPath('meta.statuses.0.name', 'Nicht bezahlt')
@ -40,4 +43,21 @@ class IndexTest extends TestCase
->assertJsonPath('meta.subscriptions.0.name', Subscription::first()->name)
->assertJsonPath('meta.links.store', url("/member/{$member->id}/payment"));
}
public function testItShowsPaymentLink(): void
{
$this->withoutExceptionHandling()->login()->loginNami();
$member = Member::factory()
->has(Payment::factory()->notPaid()->nr('2019')->subscription('Free', [
new Child('a', 1000),
new Child('b', 50),
]))
->defaults()->create();
$members = collect([$member]);
app(DocumentFactory::class)->afterSingle(BillDocument::fromMembers($members), $members);
$this->get("/member/{$member->id}/payment")
->assertJsonPath('data.0.links.show', route('payment.pdf', ['payment' => $member->payments->first()]));
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace Tests\Feature\Payment;
use App\Invoice\BillDocument;
use App\Invoice\DocumentFactory;
use App\Member\Member;
use App\Payment\Payment;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Collection;
use Tests\RequestFactories\Child;
use Tests\TestCase;
class PaymentPdfTest extends TestCase
{
use DatabaseTransactions;
public function testItShowsAnInvoiceAsPdf(): void
{
$this->login()->loginNami();
$member = Member::factory()
->defaults()
->has(Payment::factory()->notPaid()->nr('1997')->subscription('tollerbeitrag', [
new Child('a', 5400),
]))
->emailBillKind()
->create(['firstname' => 'Lah', 'lastname' => 'Mom', 'email' => 'peter@example.com']);
/** @var Collection<(int|string), Member> */
$members = collect([$member]);
app(DocumentFactory::class)->afterSingle(BillDocument::fromMembers($members), $members);
$response = $this->get(route('payment.pdf', ['payment' => $member->payments->first()]));
$response->assertOk();
$this->assertPdfPageCount(1, $response->getFile());
}
public function testItReturnsNoPdfWhenPaymentDoesntHaveInvoiceData(): void
{
$this->login()->loginNami();
$member = Member::factory()
->defaults()
->has(Payment::factory()->notPaid()->nr('1997')->subscription('tollerbeitrag', [
new Child('a', 5400),
]))
->emailBillKind()
->create(['firstname' => 'Lah', 'lastname' => 'Mom', 'email' => 'peter@example.com']);
/** @var Collection<(int|string), Member> */
$response = $this->get(route('payment.pdf', ['payment' => $member->payments->first()]));
$response->assertStatus(204);
}
}