From a2b379e3490fe3dcb811c13c5d88d8f613722752 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Tue, 22 Nov 2022 00:37:34 +0100 Subject: [PATCH] Add member view --- app/Course/Models/Course.php | 9 + app/Course/Resources/CourseMemberResource.php | 33 ++++ app/Course/Resources/CourseResource.php | 12 +- app/Http/Views/MemberView.php | 2 +- app/Member/Actions/MemberShowAction.php | 2 + app/Member/Member.php | 2 +- app/Member/MemberResource.php | 23 ++- .../factories/Course/Models/CourseFactory.php | 5 + database/factories/Letter/BillKindFactory.php | 5 + .../factories/Payment/SubscriptionFactory.php | 5 + resources/js/views/member/Boolean.vue | 35 ++++ resources/js/views/member/Box.vue | 28 +++ resources/js/views/member/Heading.vue | 2 +- resources/js/views/member/ShowView.vue | 173 +++++++++++++++++- resources/js/views/member/VIndex.vue | 2 +- tests/Feature/Member/EditTest.php | 32 ++++ tests/Feature/Member/IndexTest.php | 4 + tests/Feature/Member/ShowTest.php | 55 ++++++ tests/Feature/Member/UpdateTest.php | 10 +- 19 files changed, 405 insertions(+), 34 deletions(-) create mode 100644 app/Course/Resources/CourseMemberResource.php create mode 100644 resources/js/views/member/Boolean.vue create mode 100644 resources/js/views/member/Box.vue diff --git a/app/Course/Models/Course.php b/app/Course/Models/Course.php index 6178b7cf..dc9f21af 100644 --- a/app/Course/Models/Course.php +++ b/app/Course/Models/Course.php @@ -11,4 +11,13 @@ class Course extends Model public $timestamps = false; public $fillable = ['name', 'nami_id']; + + public function getShortNameAttribute(): string + { + return str($this->name) + ->trim() + ->replaceFirst('Baustein', '') + ->trim() + ->replaceMatches('/ - .*/', ''); + } } diff --git a/app/Course/Resources/CourseMemberResource.php b/app/Course/Resources/CourseMemberResource.php new file mode 100644 index 00000000..462b06c0 --- /dev/null +++ b/app/Course/Resources/CourseMemberResource.php @@ -0,0 +1,33 @@ + + */ + public function toArray($request) + { + return [ + 'id' => $this->id, + 'organizer' => $this->organizer, + 'event_name' => $this->event_name, + 'completed_at_human' => Carbon::parse($this->completed_at)->format('d.m.Y'), + 'completed_at' => $this->completed_at, + 'course_name' => $this->course->name, + 'course_id' => $this->course->id, + 'course' => new CourseResource($this->whenLoaded('course')), + ]; + } +} diff --git a/app/Course/Resources/CourseResource.php b/app/Course/Resources/CourseResource.php index 9a42d8fb..9a2328dc 100644 --- a/app/Course/Resources/CourseResource.php +++ b/app/Course/Resources/CourseResource.php @@ -2,11 +2,10 @@ namespace App\Course\Resources; -use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; /** - * @mixin \App\Course\Models\CourseMember + * @mixin \App\Course\Models\Course */ class CourseResource extends JsonResource { @@ -20,13 +19,10 @@ class CourseResource extends JsonResource public function toArray($request) { return [ + 'name' => $this->name, + 'nami_id' => $this->nami_id, 'id' => $this->id, - 'organizer' => $this->organizer, - 'event_name' => $this->event_name, - 'completed_at_human' => Carbon::parse($this->completed_at)->format('d.m.Y'), - 'completed_at' => $this->completed_at, - 'course_name' => $this->course->name, - 'course_id' => $this->course->id, + 'short_name' => $this->short_name, ]; } } diff --git a/app/Http/Views/MemberView.php b/app/Http/Views/MemberView.php index 974dea88..d67b4a45 100644 --- a/app/Http/Views/MemberView.php +++ b/app/Http/Views/MemberView.php @@ -21,7 +21,7 @@ class MemberView return [ 'data' => MemberResource::collection(Member::select('*') ->filter($filter)->search($request->query('search', null)) - ->with('billKind')->with('payments.subscription')->with('memberships')->with('courses')->with('leaderMemberships')->with('ageGroupMemberships') + ->with('billKind')->with('payments.subscription')->with('memberships')->with('courses')->with('subscription')->with('leaderMemberships')->with('ageGroupMemberships') ->withIsConfirmed()->withPendingPayment() ->orderByRaw('lastname, firstname') ->paginate(15) diff --git a/app/Member/Actions/MemberShowAction.php b/app/Member/Actions/MemberShowAction.php index 29b97f4f..fa920ecf 100644 --- a/app/Member/Actions/MemberShowAction.php +++ b/app/Member/Actions/MemberShowAction.php @@ -23,6 +23,8 @@ class MemberShowAction ->load('payments.subscription') ->load('nationality') ->load('region') + ->load('subscription') + ->load('courses.course') ), 'toolbar' => [['href' => route('member.index'), 'label' => 'Zurück', 'color' => 'primary', 'icon' => 'undo']], ]; diff --git a/app/Member/Member.php b/app/Member/Member.php index 1841d909..4219b953 100644 --- a/app/Member/Member.php +++ b/app/Member/Member.php @@ -48,7 +48,7 @@ class Member extends Model /** * @var array */ - public $dates = ['try_created_at', 'joined_at', 'birthday']; + public $dates = ['try_created_at', 'joined_at', 'birthday', 'efz', 'ps_at', 'more_ps_at', 'without_education_at', 'without_efz_at']; /** * @var array diff --git a/app/Member/MemberResource.php b/app/Member/MemberResource.php index 14c0318f..545b4489 100644 --- a/app/Member/MemberResource.php +++ b/app/Member/MemberResource.php @@ -2,11 +2,12 @@ namespace App\Member; -use App\Course\Resources\CourseResource; +use App\Course\Resources\CourseMemberResource; use App\Member\Resources\NationalityResource; use App\Member\Resources\RegionResource; use App\Membership\MembershipResource; use App\Payment\PaymentResource; +use App\Payment\SubscriptionResource; use Illuminate\Http\Resources\Json\JsonResource; /** @@ -36,7 +37,7 @@ class MemberResource extends JsonResource 'joined_at_human' => $this->joined_at->format('d.m.Y'), 'id' => $this->id, 'subscription_id' => $this->subscription_id, - 'subscription_name' => $this->subscription_name, + 'subscription' => new SubscriptionResource($this->whenLoaded('subscription')), 'gender_id' => $this->gender_id, 'gender_name' => $this->gender?->name ?: 'keine Angabe', 'fullname' => ($this->gender ? $this->gender?->salutation.' ' : '').$this->fullname, @@ -62,18 +63,24 @@ class MemberResource extends JsonResource 'memberships' => MembershipResource::collection($this->whenLoaded('memberships')), 'pending_payment' => $this->pending_payment ? number_format($this->pending_payment / 100, 2, ',', '.').' €' : null, 'age_group_icon' => $this->ageGroupMemberships->first()?->subactivity->slug, - 'courses' => CourseResource::collection($this->whenLoaded('courses')), + 'courses' => CourseMemberResource::collection($this->whenLoaded('courses')), 'nationality' => new NationalityResource($this->whenLoaded('nationality')), 'region' => new RegionResource($this->whenLoaded('region')), 'full_address' => $this->fullAddress, - 'efz' => $this->efz, + 'efz' => $this->efz?->format('Y-m-d'), + 'efz_human' => $this->efz?->format('d.m.Y') ?: null, + 'ps_at_human' => $this->ps_at?->format('d.m.Y') ?: null, + 'more_ps_at_human' => $this->more_ps_at?->format('d.m.Y') ?: null, + 'without_education_at_human' => $this->without_education_at?->format('d.m.Y') ?: null, + 'without_efz_at_human' => $this->without_efz_at?->format('d.m.Y') ?: null, 'efz_link' => $this->getEfzLink(), - 'ps_at' => $this->ps_at, - 'more_ps_at' => $this->more_ps_at, + 'ps_at' => $this->ps_at?->format('Y-m-d'), + 'more_ps_at' => $this->more_ps_at?->format('Y-m-d'), 'has_svk' => $this->has_svk, + 'nami_id' => $this->nami_id, 'has_vk' => $this->has_vk, - 'without_education_at' => $this->without_education_at, - 'without_efz_at' => $this->without_efz_at, + 'without_education_at' => $this->without_education_at?->format('Y-m-d'), + 'without_efz_at' => $this->without_efz_at?->format('Y-m-d'), 'multiply_pv' => $this->multiply_pv, 'multiply_more_pv' => $this->multiply_more_pv, 'age' => $this->getModel()->getAge(), diff --git a/database/factories/Course/Models/CourseFactory.php b/database/factories/Course/Models/CourseFactory.php index af2b9aa5..e0e737af 100644 --- a/database/factories/Course/Models/CourseFactory.php +++ b/database/factories/Course/Models/CourseFactory.php @@ -25,6 +25,11 @@ class CourseFactory extends Factory ]; } + public function name(string $name): self + { + return $this->state(['name' => $name]); + } + public function inNami(int $namiId): self { return $this->state(['nami_id' => $namiId]); diff --git a/database/factories/Letter/BillKindFactory.php b/database/factories/Letter/BillKindFactory.php index 853bc478..47cc7e65 100644 --- a/database/factories/Letter/BillKindFactory.php +++ b/database/factories/Letter/BillKindFactory.php @@ -23,4 +23,9 @@ class BillKindFactory extends Factory 'name' => $this->faker->words(3, true), ]; } + + public function name(string $name): self + { + return $this->state(['name' => $name]); + } } diff --git a/database/factories/Payment/SubscriptionFactory.php b/database/factories/Payment/SubscriptionFactory.php index 24c26bee..aacd7c72 100644 --- a/database/factories/Payment/SubscriptionFactory.php +++ b/database/factories/Payment/SubscriptionFactory.php @@ -18,4 +18,9 @@ class SubscriptionFactory extends Factory 'fee_id' => Fee::factory()->createOne()->id, ]; } + + public function name(string $name): self + { + return $this->state(['name' => $name]); + } } diff --git a/resources/js/views/member/Boolean.vue b/resources/js/views/member/Boolean.vue new file mode 100644 index 00000000..19176b8f --- /dev/null +++ b/resources/js/views/member/Boolean.vue @@ -0,0 +1,35 @@ + + + diff --git a/resources/js/views/member/Box.vue b/resources/js/views/member/Box.vue new file mode 100644 index 00000000..4f91bbae --- /dev/null +++ b/resources/js/views/member/Box.vue @@ -0,0 +1,28 @@ + + + diff --git a/resources/js/views/member/Heading.vue b/resources/js/views/member/Heading.vue index 2b2b4fc7..906d37a1 100644 --- a/resources/js/views/member/Heading.vue +++ b/resources/js/views/member/Heading.vue @@ -1,5 +1,5 @@ diff --git a/resources/js/views/member/ShowView.vue b/resources/js/views/member/ShowView.vue index 45f2955b..c8e49fd5 100644 --- a/resources/js/views/member/ShowView.vue +++ b/resources/js/views/member/ShowView.vue @@ -1,8 +1,7 @@ @@ -71,7 +197,8 @@ export default { components: { 'key-value': () => import('./KeyValue'), - 'heading': () => import('./Heading'), + 'boolean': () => import('./Boolean'), + 'box': () => import('./Box'), }, created() { @@ -82,6 +209,34 @@ export default { diff --git a/resources/js/views/member/VIndex.vue b/resources/js/views/member/VIndex.vue index b19dfdee..233508ca 100644 --- a/resources/js/views/member/VIndex.vue +++ b/resources/js/views/member/VIndex.vue @@ -66,7 +66,7 @@ > - +
diff --git a/tests/Feature/Member/EditTest.php b/tests/Feature/Member/EditTest.php index a0e302e5..da80894c 100644 --- a/tests/Feature/Member/EditTest.php +++ b/tests/Feature/Member/EditTest.php @@ -28,4 +28,36 @@ class EditTest extends TestCase $this->assertInertiaHas('edit', $response, 'mode'); $this->assertInertiaHas(false, $response, 'conflict'); } + + public function testItDisplaysEducation(): void + { + $this->withoutExceptionHandling()->login()->loginNami(); + $member = Member::factory() + ->defaults() + ->create([ + 'efz' => '2022-09-20', + 'ps_at' => '2022-04-20', + 'more_ps_at' => '2022-06-02', + 'without_education_at' => '2022-06-03', + 'without_efz_at' => '2022-06-04', + 'has_vk' => true, + 'has_svk' => true, + 'multiply_pv' => true, + 'multiply_more_pv' => true, + ]); + + $response = $this->get(route('member.edit', ['member' => $member])); + + $this->assertInertiaHas([ + 'efz' => '2022-09-20', + 'ps_at' => '2022-04-20', + 'more_ps_at' => '2022-06-02', + 'without_education_at' => '2022-06-03', + 'without_efz_at' => '2022-06-04', + 'has_vk' => true, + 'has_svk' => true, + 'multiply_pv' => true, + 'multiply_more_pv' => true, + ], $response, 'data'); + } } diff --git a/tests/Feature/Member/IndexTest.php b/tests/Feature/Member/IndexTest.php index bfb752af..6a2a62de 100644 --- a/tests/Feature/Member/IndexTest.php +++ b/tests/Feature/Member/IndexTest.php @@ -139,5 +139,9 @@ class IndexTest extends TestCase 'status_name' => 'Nicht bezahlt', 'nr' => '2019', ], $response, 'data.data.0.payments.0'); + $this->assertInertiaHas([ + 'id' => $member->subscription->id, + 'name' => $member->subscription->name, + ], $response, 'data.data.0.subscription'); } } diff --git a/tests/Feature/Member/ShowTest.php b/tests/Feature/Member/ShowTest.php index cf799c64..4177c58d 100644 --- a/tests/Feature/Member/ShowTest.php +++ b/tests/Feature/Member/ShowTest.php @@ -2,9 +2,12 @@ namespace Tests\Feature\Member; +use App\Course\Models\Course; +use App\Course\Models\CourseMember; use App\Fee; use App\Gender; use App\Group; +use App\Letter\BillKind; use App\Member\Member; use App\Member\Membership; use App\Nationality; @@ -35,6 +38,10 @@ class ShowTest extends TestCase ->has(Payment::factory()->notPaid()->nr('2019')->subscription('Free', 1050)) ->for(Gender::factory()->name('Männlich')) ->for(Region::factory()->name('NRW')) + ->for(BillKind::factory()->name('Post')) + ->inNami(123) + ->for(Subscription::factory()->name('Sub')->for(Fee::factory())) + ->has(CourseMember::factory()->for(Course::factory()->name(' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention '))->state(['organizer' => 'DPSG', 'event_name' => 'Wochenende', 'completed_at' => '2022-03-03']), 'courses') ->create([ 'birthday' => '1991-04-20', 'address' => 'Itterstr 3', @@ -50,6 +57,17 @@ class ShowTest extends TestCase 'email' => 'a@b.de', 'email_parents' => 'b@c.de', 'fax' => '+49 212 1255674', + 'efz' => '2022-09-20', + 'ps_at' => '2022-04-20', + 'more_ps_at' => '2022-06-02', + 'without_education_at' => '2022-06-03', + 'without_efz_at' => '2022-06-04', + 'has_vk' => true, + 'has_svk' => true, + 'multiply_pv' => true, + 'multiply_more_pv' => true, + 'send_newspaper' => true, + 'joined_at' => '2022-06-11', ]); $response = $this->get("/member/{$member->id}"); @@ -68,17 +86,45 @@ class ShowTest extends TestCase 'email_parents' => 'b@c.de', 'fax' => '+49 212 1255674', 'fullname' => 'Herr Max Muster', + 'efz_human' => '20.09.2022', + 'ps_at_human' => '20.04.2022', + 'more_ps_at_human' => '02.06.2022', + 'without_education_at_human' => '03.06.2022', + 'without_efz_at_human' => '04.06.2022', + 'has_vk' => true, + 'has_svk' => true, + 'multiply_pv' => true, + 'multiply_more_pv' => true, + 'has_nami' => true, + 'nami_id' => 123, + 'send_newspaper' => true, + 'joined_at_human' => '11.06.2022', + 'bill_kind_name' => 'Post', + 'subscription' => [ + 'name' => 'Sub', + ], ], $response, 'data'); $this->assertInertiaHas([ 'activity_name' => '€ LeiterIn', + 'subactivity_name' => 'Jungpfadfinder', 'id' => $member->memberships->first()->id, 'human_date' => '19.11.2022', ], $response, 'data.memberships.0'); + $this->assertInertiaHas([ + 'organizer' => 'DPSG', + 'event_name' => 'Wochenende', + 'completed_at_human' => '03.03.2022', + 'course' => [ + 'name' => ' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention ', + 'short_name' => '2e', + ], + ], $response, 'data.courses.0'); $this->assertInertiaHas([ 'subscription' => [ 'name' => 'Free', 'id' => $member->payments->first()->subscription->id, 'amount' => 1050, + 'amount_human' => '10,50 €', ], 'status_name' => 'Nicht bezahlt', 'nr' => '2019', @@ -103,6 +149,15 @@ class ShowTest extends TestCase 'nationality' => [ 'name' => 'deutsch', ], + 'efz_human' => null, + 'ps_at_human' => null, + 'more_ps_at_human' => null, + 'without_education_at_human' => null, + 'without_efz_at_human' => null, + 'has_vk' => false, + 'has_svk' => false, + 'multiply_pv' => false, + 'multiply_more_pv' => false, ], $response, 'data'); } } diff --git a/tests/Feature/Member/UpdateTest.php b/tests/Feature/Member/UpdateTest.php index 8f534e47..52cc0cc3 100644 --- a/tests/Feature/Member/UpdateTest.php +++ b/tests/Feature/Member/UpdateTest.php @@ -89,15 +89,15 @@ class UpdateTest extends TestCase 'multiply_more_pv' => true, ])); - $this->assertEquals('2021-02-01', $member->fresh()->ps_at); - $this->assertEquals('2021-02-02', $member->fresh()->more_ps_at); + $this->assertEquals('2021-02-01', $member->fresh()->ps_at->format('Y-m-d')); + $this->assertEquals('2021-02-02', $member->fresh()->more_ps_at->format('Y-m-d')); $this->assertTrue($member->fresh()->has_svk); $this->assertTrue($member->fresh()->has_vk); $this->assertTrue($member->fresh()->multiply_pv); $this->assertTrue($member->fresh()->multiply_more_pv); - $this->assertEquals('2021-02-03', $member->fresh()->efz); - $this->assertEquals('2021-02-04', $member->fresh()->without_education_at); - $this->assertEquals('2021-02-05', $member->fresh()->without_efz_at); + $this->assertEquals('2021-02-03', $member->fresh()->efz->format('Y-m-d')); + $this->assertEquals('2021-02-04', $member->fresh()->without_education_at->format('Y-m-d')); + $this->assertEquals('2021-02-05', $member->fresh()->without_efz_at->format('Y-m-d')); } /**