From 0b3765baa357fdc3952c3c041dfec7225d051357 Mon Sep 17 00:00:00 2001 From: philipp lang <philipp@aweos.de> Date: Thu, 17 Nov 2022 20:43:51 +0100 Subject: [PATCH] Add Ps Block --- app/Home/DashboardFactory.php | 2 + app/Member/PsPendingBlock.php | 49 +++++++++++++++++ resources/js/views/home/PsPending.vue | 31 +++++++++++ resources/js/views/home/VIndex.vue | 1 + tests/Feature/Member/PsPendingBlockTest.php | 61 +++++++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 app/Member/PsPendingBlock.php create mode 100644 resources/js/views/home/PsPending.vue create mode 100644 tests/Feature/Member/PsPendingBlockTest.php diff --git a/app/Home/DashboardFactory.php b/app/Home/DashboardFactory.php index fb344630..87302320 100644 --- a/app/Home/DashboardFactory.php +++ b/app/Home/DashboardFactory.php @@ -4,6 +4,7 @@ namespace App\Home; use App\Efz\EfzPendingBlock; use App\Home\Blocks\Block; +use App\Member\PsPendingBlock; use App\Membership\AgeGroupCountBlock; use App\Membership\TestersBlock; use App\Payment\MemberPaymentBlock; @@ -18,6 +19,7 @@ class DashboardFactory MemberPaymentBlock::class, TestersBlock::class, EfzPendingBlock::class, + PsPendingBlock::class, ]; /** diff --git a/app/Member/PsPendingBlock.php b/app/Member/PsPendingBlock.php new file mode 100644 index 00000000..b73ca9b8 --- /dev/null +++ b/app/Member/PsPendingBlock.php @@ -0,0 +1,49 @@ +<?php + +namespace App\Member; + +use App\Home\Blocks\Block; +use Illuminate\Database\Eloquent\Builder; + +class PsPendingBlock extends Block +{ + /** + * @return Builder<Member> + */ + public function query(): Builder + { + return Member::where(function ($query) { + $time = now()->subYears(5)->endOfYear(); + + return $query + ->orWhere(fn ($query) => $query->whereNull('ps_at')->whereNull('more_ps_at')) + ->orWhere(fn ($query) => $query->whereNull('ps_at')->where('more_ps_at', '<=', $time)) + ->orWhere(fn ($query) => $query->where('ps_at', '<=', $time)->whereNull('more_ps_at')) + ->orWhere(fn ($query) => $query->where('ps_at', '>=', $time)->where('more_ps_at', '<=', $time)); + }) + ->orderByRaw('lastname, firstname') + ->whereHas('memberships', fn ($builder) => $builder->isLeader()); + } + + /** + * @return array{members: array{fullname: string}} + */ + public function data(): array + { + return [ + 'members' => $this->query()->get()->map(fn ($member) => [ + 'fullname' => $member->fullname, + ])->toArray(), + ]; + } + + public function component(): string + { + return 'ps-pending'; + } + + public function title(): string + { + return 'Ausstehende Präventionsschulungen'; + } +} diff --git a/resources/js/views/home/PsPending.vue b/resources/js/views/home/PsPending.vue new file mode 100644 index 00000000..c2832b48 --- /dev/null +++ b/resources/js/views/home/PsPending.vue @@ -0,0 +1,31 @@ +<template> + <div> + <div + v-for="(member, index) in inner.members" + :key="index" + class="flex mt-2 items-center leading-none text-gray-100" + > + <span class="grow" v-text="`${member.fullname}`"></span> + </div> + </div> +</template> + +<script> +export default { + data: function () { + return { + inner: { + members: [], + }, + }; + }, + + props: { + data: {}, + }, + + created() { + this.inner = this.data; + }, +}; +</script> diff --git a/resources/js/views/home/VIndex.vue b/resources/js/views/home/VIndex.vue index 1682659e..1f10b20c 100644 --- a/resources/js/views/home/VIndex.vue +++ b/resources/js/views/home/VIndex.vue @@ -25,6 +25,7 @@ export default { 'VBlock': () => import('./VBlock'), 'age-group-count': () => import('./AgeGroupCount.vue'), 'efz-pending': () => import('./EfzPending.vue'), + 'ps-pending': () => import('./PsPending.vue'), 'testers': () => import('./Testers.vue'), 'member-payment': () => import('./MemberPayment.vue'), }, diff --git a/tests/Feature/Member/PsPendingBlockTest.php b/tests/Feature/Member/PsPendingBlockTest.php new file mode 100644 index 00000000..df9c126c --- /dev/null +++ b/tests/Feature/Member/PsPendingBlockTest.php @@ -0,0 +1,61 @@ +<?php + +namespace Tests\Feature\Member; + +use App\Member\Member; +use App\Member\Membership; +use App\Member\PsPendingBlock; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\TestCase; + +class PsPendingBlockTest extends TestCase +{ + use DatabaseTransactions; + + public function testItRendersContent(): void + { + $noPsAtAll = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Jane', 'lastname' => 'Doe']); + $validPs = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Max', 'lastname' => 'Doe', 'ps_at' => now()->subYears(4)]); + $validMorePs = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Joe', 'lastname' => 'Doe', 'more_ps_at' => now()->subYears(4)]); + $invalidPs = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Mike', 'lastname' => 'Doe', 'ps_at' => now()->subYears(5)]); + $invalidMorePs = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Nora', 'lastname' => 'Doe', 'more_ps_at' => now()->subYears(5)]); + $invalidPsButValidMorePs = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->has(Membership::factory()->in('€ LeiterIn', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Hey', 'lastname' => 'Doe', 'ps_at' => now()->subYears(10), 'more_ps_at' => now()->subYears(3)]); + $notALeader = Member::factory() + ->defaults() + ->has(Membership::factory()->in('€ Mitglied', 5, 'Wölfling', 8)) + ->create(['firstname' => 'Mae', 'lastname' => 'Doe']); + + $data = app(PsPendingBlock::class)->render()['data']; + + $this->assertEquals([ + 'members' => [ + ['fullname' => 'Jane Doe'], + ['fullname' => 'Mike Doe'], + ['fullname' => 'Nora Doe'], + ], + ], $data); + } +}