Add payment links
This commit is contained in:
parent
ef973f1286
commit
b200b31bc7
app
Http/Views
Member
Payment
Pdf
database/factories/Payment
resources/js/views/member
tests/Feature/Payments
|
@ -4,6 +4,7 @@ namespace App\Http\Views;
|
||||||
|
|
||||||
use App\Member\Member;
|
use App\Member\Member;
|
||||||
use App\Member\MemberResource;
|
use App\Member\MemberResource;
|
||||||
|
use App\Payment\ActionFactory;
|
||||||
use App\Payment\PaymentResource;
|
use App\Payment\PaymentResource;
|
||||||
use App\Payment\Status;
|
use App\Payment\Status;
|
||||||
use App\Payment\Subscription;
|
use App\Payment\Subscription;
|
||||||
|
@ -43,6 +44,7 @@ class MemberView {
|
||||||
'links' => [
|
'links' => [
|
||||||
['icon' => 'plus', 'href' => route('member.payment.create', ['member' => $member]) ],
|
['icon' => 'plus', 'href' => route('member.payment.create', ['member' => $member]) ],
|
||||||
],
|
],
|
||||||
|
'payment_links' => app(ActionFactory::class)->forMember($member),
|
||||||
'mode' => 'index',
|
'mode' => 'index',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace App\Member;
|
namespace App\Member;
|
||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
use App\Payment\PaymentResource;
|
use App\Payment\PaymentResource;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
class MemberResource extends JsonResource
|
class MemberResource extends JsonResource
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Payment;
|
||||||
|
|
||||||
|
use App\Member\Member;
|
||||||
|
use App\Pdf\PdfRepositoryFactory;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class ActionFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
public function forMember(Member $member): Collection
|
||||||
|
{
|
||||||
|
return app(PdfRepositoryFactory::class)->getTypes()->map(function(string $repo) use ($member) {
|
||||||
|
$repo = app($repo);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'href' => route('member.singlepdf', ['member' => $member, 'type' => get_class($repo)]),
|
||||||
|
'label' => $repo->linkLabel(),
|
||||||
|
'disabled' => !$repo->createable($member),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Pdf;
|
namespace App\Pdf;
|
||||||
|
|
||||||
|
use App\Member\Member;
|
||||||
use App\Payment\Payment;
|
use App\Payment\Payment;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
@ -16,6 +17,16 @@ class BillType extends Repository implements PdfRepository
|
||||||
$this->pages = $pages;
|
$this->pages = $pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function createable(Member $member): bool
|
||||||
|
{
|
||||||
|
return $member->payments()->whereNeedsBill()->count() !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function linkLabel(): string
|
||||||
|
{
|
||||||
|
return 'Rechnung erstellen';
|
||||||
|
}
|
||||||
|
|
||||||
public function getSubject(): string
|
public function getSubject(): string
|
||||||
{
|
{
|
||||||
return 'Rechnung';
|
return 'Rechnung';
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Pdf;
|
namespace App\Pdf;
|
||||||
|
|
||||||
|
use App\Member\Member;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
interface PdfRepository
|
interface PdfRepository
|
||||||
|
@ -27,4 +28,8 @@ interface PdfRepository
|
||||||
|
|
||||||
public function getLocation(Collection $page): string;
|
public function getLocation(Collection $page): string;
|
||||||
|
|
||||||
|
public function createable(Member $member): bool;
|
||||||
|
|
||||||
|
public function linkLabel(): string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,15 @@ use Illuminate\Support\Str;
|
||||||
class PdfRepositoryFactory
|
class PdfRepositoryFactory
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private array $types = [
|
||||||
|
BillType::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getTypes(): Collection
|
||||||
|
{
|
||||||
|
return collect($this->types);
|
||||||
|
}
|
||||||
|
|
||||||
public function fromSingleRequest(string $type, Member $member): ?PdfRepository
|
public function fromSingleRequest(string $type, Member $member): ?PdfRepository
|
||||||
{
|
{
|
||||||
$members = $this->singleMemberCollection($member);
|
$members = $this->singleMemberCollection($member);
|
||||||
|
|
|
@ -25,6 +25,11 @@ class PaymentFactory extends Factory
|
||||||
return $this->for(Status::whereName('Nicht bezahlt')->first());
|
return $this->for(Status::whereName('Nicht bezahlt')->first());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function paid(): self
|
||||||
|
{
|
||||||
|
return $this->for(Status::whereName('Rechnung beglichen')->first());
|
||||||
|
}
|
||||||
|
|
||||||
public function nr(string $nr): self
|
public function nr(string $nr): self
|
||||||
{
|
{
|
||||||
return $this->state(['nr' => $nr]);
|
return $this->state(['nr' => $nr]);
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col pb-6 px-6">
|
<div class="flex flex-col pb-6 px-6">
|
||||||
<a href="#" class="text-center btn btn-primary">Rechnung erstellen</a>
|
<a href="#" @click.prevent="openLink(link)" :class="{'disabled': link.disabled}" target="_BLANK" v-for="link in value.payment_links" class="mt-1 text-center btn btn-primary" v-text="link.label"></a>
|
||||||
<a href="#" class="text-center mt-1 btn btn-primary">Erinnerung erstellen</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -41,6 +40,14 @@ export default {
|
||||||
|
|
||||||
accept(payment) {
|
accept(payment) {
|
||||||
this.$inertia.patch(`/member/${this.value.data.id}/payment/${payment.id}`, { ...payment, status_id: 3 });
|
this.$inertia.patch(`/member/${this.value.data.id}/payment/${payment.id}`, { ...payment, status_id: 3 });
|
||||||
|
},
|
||||||
|
|
||||||
|
openLink(link) {
|
||||||
|
if (link.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(link.href);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Payments;
|
||||||
|
|
||||||
|
use App\Member\Member;
|
||||||
|
use App\Pdf\BillType;
|
||||||
|
use Database\Factories\Payment\PaymentFactory;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class IndexTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function testItGetsLinkWhenMemberHasPayableBills(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
$this->login();
|
||||||
|
|
||||||
|
$member = Member::factory()
|
||||||
|
->defaults()
|
||||||
|
->withPayments([
|
||||||
|
fn (PaymentFactory $payment) => $payment->notPaid()->nr('1995')->subscription('::subName::', 1500),
|
||||||
|
])
|
||||||
|
->create(['firstname' => '::firstname']);
|
||||||
|
|
||||||
|
$this->get("/member/{$member->id}/payment")->assertInertia('member/Index', [
|
||||||
|
'href' => route('member.singlepdf', ['member' => $member, 'type' => BillType::class]),
|
||||||
|
'label' => 'Rechnung erstellen',
|
||||||
|
'disabled' => false,
|
||||||
|
], 'single.payment_links.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLinkIsFalseWhenMemberHasnoPayments(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
$this->login();
|
||||||
|
|
||||||
|
$member = Member::factory()
|
||||||
|
->defaults()
|
||||||
|
->create(['firstname' => '::firstname']);
|
||||||
|
|
||||||
|
$this->get("/member/{$member->id}/payment")->assertInertia('member/Index', [
|
||||||
|
'href' => route('member.singlepdf', ['member' => $member, 'type' => BillType::class]),
|
||||||
|
'label' => 'Rechnung erstellen',
|
||||||
|
'disabled' => true,
|
||||||
|
], 'single.payment_links.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItReturnsDisabledWhenPaymentsArePaid(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
$this->login();
|
||||||
|
|
||||||
|
$member = Member::factory()
|
||||||
|
->defaults()
|
||||||
|
->withPayments([
|
||||||
|
fn (PaymentFactory $payment) => $payment->paid()->nr('1995')->subscription('::subName::', 1500),
|
||||||
|
])
|
||||||
|
->create(['firstname' => '::firstname']);
|
||||||
|
|
||||||
|
$this->get("/member/{$member->id}/payment")->assertInertia('member/Index', [
|
||||||
|
'href' => route('member.singlepdf', ['member' => $member, 'type' => BillType::class]),
|
||||||
|
'label' => 'Rechnung erstellen',
|
||||||
|
'disabled' => true,
|
||||||
|
], 'single.payment_links.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue