From 90bdc28e234463616430194327ba16d3dcaedcbe Mon Sep 17 00:00:00 2001 From: philipp lang Date: Sat, 19 Nov 2022 00:09:53 +0100 Subject: [PATCH] Wip: Member view next: Schulungen darstellen --- app/Actions/MemberPullAction.php | 3 +- app/Member/Actions/MemberShowAction.php | 9 +- app/Member/GenderResource.php | 19 ++++ app/Member/Member.php | 5 +- app/Member/MemberRequest.php | 1 + app/Member/MemberResource.php | 6 ++ app/Member/Resources/NationalityResource.php | 28 ++++++ app/Member/Resources/RegionResource.php | 28 ++++++ database/factories/GenderFactory.php | 10 +++ database/factories/NationalityFactory.php | 5 ++ database/factories/RegionFactory.php | 10 +++ resources/js/views/member/Heading.vue | 9 ++ resources/js/views/member/KeyValue.vue | 38 ++++++++ resources/js/views/member/Show.vue | 23 ----- resources/js/views/member/ShowView.vue | 89 +++++++++++++++++++ tests/Feature/Member/MemberPullActionTest.php | 46 ++++++++++ tests/Feature/Member/ShowTest.php | 71 ++++++++++++++- tests/Feature/Member/UpdateTest.php | 15 ++++ 18 files changed, 386 insertions(+), 29 deletions(-) create mode 100644 app/Member/GenderResource.php create mode 100644 app/Member/Resources/NationalityResource.php create mode 100644 app/Member/Resources/RegionResource.php create mode 100644 resources/js/views/member/Heading.vue create mode 100644 resources/js/views/member/KeyValue.vue delete mode 100644 resources/js/views/member/Show.vue create mode 100644 resources/js/views/member/ShowView.vue diff --git a/app/Actions/MemberPullAction.php b/app/Actions/MemberPullAction.php index ec56c651..29249b31 100644 --- a/app/Actions/MemberPullAction.php +++ b/app/Actions/MemberPullAction.php @@ -48,6 +48,7 @@ class MemberPullAction } try { + $region = Region::firstWhere('nami_id', $this->member->region_id ?: -1); $m = Member::updateOrCreate(['nami_id' => $this->member->id], [ 'firstname' => $this->member->firstname, 'lastname' => $this->member->lastname, @@ -70,7 +71,7 @@ class MemberPullAction 'group_id' => Group::firstOrCreate(['nami_id' => $this->member->group_id], ['nami_id' => $this->member->group_id, 'name' => $this->member->group_name])->id, 'gender_id' => optional(Gender::firstWhere('nami_id', $this->member->gender_id ?: -1))->id, 'confession_id' => optional(Confession::firstWhere('nami_id', $this->member->confession_id ?: -1))->id, - 'region_id' => optional(Region::firstWhere('nami_id', $this->member->region_id ?: -1))->id, + 'region_id' => $region && !$region->is_null ? $region->id : null, 'country_id' => optional(Country::where('nami_id', $this->member->country_id)->first())->id, 'subscription_id' => $this->getSubscriptionId($this->member), 'nationality_id' => Nationality::where('nami_id', $this->member->nationality_id)->firstOrFail()->id, diff --git a/app/Member/Actions/MemberShowAction.php b/app/Member/Actions/MemberShowAction.php index 8d0d32b0..29b97f4f 100644 --- a/app/Member/Actions/MemberShowAction.php +++ b/app/Member/Actions/MemberShowAction.php @@ -18,7 +18,12 @@ class MemberShowAction public function handle(Member $member): array { return [ - 'data' => new MemberResource($member->load('memberships')->load('payments.subscription')), + 'data' => new MemberResource($member + ->load('memberships') + ->load('payments.subscription') + ->load('nationality') + ->load('region') + ), 'toolbar' => [['href' => route('member.index'), 'label' => 'Zurück', 'color' => 'primary', 'icon' => 'undo']], ]; } @@ -28,6 +33,6 @@ class MemberShowAction session()->put('menu', 'member'); session()->put('title', 'Mitglied '.$member->fullname); - return Inertia::render('member/Show', $this->handle($member)); + return Inertia::render('member/ShowView', $this->handle($member)); } } diff --git a/app/Member/GenderResource.php b/app/Member/GenderResource.php new file mode 100644 index 00000000..9ed9944b --- /dev/null +++ b/app/Member/GenderResource.php @@ -0,0 +1,19 @@ +belongsTo(Region::class); + return $this->belongsTo(Region::class)->withDefault([ + 'name' => '-- kein --', + 'nami_id' => null, + ]); } public function confession(): BelongsTo diff --git a/app/Member/MemberRequest.php b/app/Member/MemberRequest.php index f3dca5be..9f921cd0 100644 --- a/app/Member/MemberRequest.php +++ b/app/Member/MemberRequest.php @@ -78,6 +78,7 @@ class MemberRequest extends FormRequest 'nationality_id' => 'nullable|exists:nationalities,id', 'children_phone' => '', 'fax' => '', + 'other_country' => '', ]; } diff --git a/app/Member/MemberResource.php b/app/Member/MemberResource.php index 29639afd..26bc3fac 100644 --- a/app/Member/MemberResource.php +++ b/app/Member/MemberResource.php @@ -3,6 +3,8 @@ namespace App\Member; use App\Course\Resources\CourseResource; +use App\Member\Resources\NationalityResource; +use App\Member\Resources\RegionResource; use App\Membership\MembershipResource; use App\Payment\PaymentResource; use Illuminate\Http\Resources\Json\JsonResource; @@ -36,6 +38,7 @@ class MemberResource extends JsonResource 'subscription_id' => $this->subscription_id, 'subscription_name' => $this->subscription_name, 'gender_id' => $this->gender_id, + 'gender_name' => $this->gender?->name ?: 'keine Angabe', 'further_address' => $this->further_address, 'work_phone' => $this->work_phone, 'mobile_phone' => $this->mobile_phone, @@ -59,6 +62,9 @@ class MemberResource extends JsonResource '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')), + 'nationality' => new NationalityResource($this->whenLoaded('nationality')), + 'region' => new RegionResource($this->whenLoaded('region')), + 'full_address' => $this->fullAddress, 'efz' => $this->efz, 'efz_link' => $this->getEfzLink(), 'ps_at' => $this->ps_at, diff --git a/app/Member/Resources/NationalityResource.php b/app/Member/Resources/NationalityResource.php new file mode 100644 index 00000000..31d45330 --- /dev/null +++ b/app/Member/Resources/NationalityResource.php @@ -0,0 +1,28 @@ + $this->name, + 'nami_id' => $this->nami_id, + 'id' => $this->id, + ]; + } +} diff --git a/app/Member/Resources/RegionResource.php b/app/Member/Resources/RegionResource.php new file mode 100644 index 00000000..ea3eeae6 --- /dev/null +++ b/app/Member/Resources/RegionResource.php @@ -0,0 +1,28 @@ + $this->name, + 'nami_id' => $this->nami_id, + 'id' => $this->id, + ]; + } +} diff --git a/database/factories/GenderFactory.php b/database/factories/GenderFactory.php index 29823b5e..2d0fb74d 100644 --- a/database/factories/GenderFactory.php +++ b/database/factories/GenderFactory.php @@ -21,4 +21,14 @@ class GenderFactory extends Factory 'nami_id' => $this->faker->numberBetween(100, 200), ]; } + + 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/NationalityFactory.php b/database/factories/NationalityFactory.php index 5ec3e64c..82a062a2 100644 --- a/database/factories/NationalityFactory.php +++ b/database/factories/NationalityFactory.php @@ -25,6 +25,11 @@ class NationalityFactory 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/RegionFactory.php b/database/factories/RegionFactory.php index a50feea8..7ad0a2f9 100644 --- a/database/factories/RegionFactory.php +++ b/database/factories/RegionFactory.php @@ -22,4 +22,14 @@ class RegionFactory extends Factory 'is_null' => false, ]; } + + 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/resources/js/views/member/Heading.vue b/resources/js/views/member/Heading.vue new file mode 100644 index 00000000..2b2b4fc7 --- /dev/null +++ b/resources/js/views/member/Heading.vue @@ -0,0 +1,9 @@ + + + diff --git a/resources/js/views/member/KeyValue.vue b/resources/js/views/member/KeyValue.vue new file mode 100644 index 00000000..6b1ad99e --- /dev/null +++ b/resources/js/views/member/KeyValue.vue @@ -0,0 +1,38 @@ + + + diff --git a/resources/js/views/member/Show.vue b/resources/js/views/member/Show.vue deleted file mode 100644 index ceb5816e..00000000 --- a/resources/js/views/member/Show.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/resources/js/views/member/ShowView.vue b/resources/js/views/member/ShowView.vue new file mode 100644 index 00000000..67adf142 --- /dev/null +++ b/resources/js/views/member/ShowView.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/tests/Feature/Member/MemberPullActionTest.php b/tests/Feature/Member/MemberPullActionTest.php index 506e74d5..8c8d231a 100644 --- a/tests/Feature/Member/MemberPullActionTest.php +++ b/tests/Feature/Member/MemberPullActionTest.php @@ -5,6 +5,8 @@ namespace Tests\Feature\Member; use App\Actions\MemberPullAction; use App\Member\Member; use App\Member\Membership; +use App\Nationality; +use App\Region; use App\Setting\NamiSettings; use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; @@ -63,4 +65,48 @@ class MemberPullActionTest extends TestCase 'member_id' => $member->id, ]); } + + public function testRegionIdIsSetToNull(): void + { + Nationality::factory()->inNami(1054)->create(); + Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => true]); + app(MemberFake::class)->shows(55, 123, [ + 'gruppierungId' => 55, + 'id' => 123, + 'regionId' => 999, + ]); + app(MembershipFake::class)->fetches(123, []); + app(CourseFake::class)->fetches(123, []); + $this->withoutExceptionHandling()->login()->loginNami(); + + app(MemberPullAction::class) + ->api(app(NamiSettings::class)->login()) + ->member(55, 123) + ->execute(); + + $this->assertDatabaseHas('members', [ + 'region_id' => null, + ]); + } + + public function testItSetsNormalAttributes(): void + { + Nationality::factory()->inNami(1054)->create(); + $region = Region::factory()->inNami(999)->name('nicht-de')->create(['is_null' => false]); + app(MemberFake::class)->shows(55, 123, [ + 'regionId' => 999, + ]); + app(MembershipFake::class)->fetches(123, []); + app(CourseFake::class)->fetches(123, []); + $this->withoutExceptionHandling()->login()->loginNami(); + + app(MemberPullAction::class) + ->api(app(NamiSettings::class)->login()) + ->member(55, 123) + ->execute(); + + $this->assertDatabaseHas('members', [ + 'region_id' => $region->id, + ]); + } } diff --git a/tests/Feature/Member/ShowTest.php b/tests/Feature/Member/ShowTest.php index c8c7d565..5111ebd4 100644 --- a/tests/Feature/Member/ShowTest.php +++ b/tests/Feature/Member/ShowTest.php @@ -2,9 +2,16 @@ namespace Tests\Feature\Member; +use App\Fee; +use App\Gender; +use App\Group; use App\Member\Member; use App\Member\Membership; +use App\Nationality; use App\Payment\Payment; +use App\Payment\Subscription; +use App\Region; +use Carbon\Carbon; use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; @@ -12,17 +19,56 @@ class ShowTest extends TestCase { use DatabaseTransactions; + public function setUp(): void + { + parent::setUp(); + + Carbon::setTestNow(Carbon::parse('2006-01-01 15:00:00')); + } + public function testItShowsSingleMember(): void { $this->withoutExceptionHandling()->login()->loginNami(); $member = Member::factory() + ->defaults() ->has(Membership::factory()->in('€ LeiterIn', 5, 'Jungpfadfinder', 88)->state(['created_at' => '2022-11-19 05:00:00'])) ->has(Payment::factory()->notPaid()->nr('2019')->subscription('Free', 1050)) - ->defaults()->create(['firstname' => 'Max']); + ->for(Gender::factory()->name('Herr')) + ->for(Region::factory()->name('NRW')) + ->create([ + 'birthday' => '1991-04-20', + 'address' => 'Itterstr 3', + 'zip' => '42719', + 'location' => 'Solingen', + 'firstname' => 'Max', + 'other_country' => 'other', + 'main_phone' => '+49 212 1266775', + 'mobile_phone' => '+49 212 1266776', + 'work_phone' => '+49 212 1266777', + 'children_phone' => '+49 212 1266778', + 'email' => 'a@b.de', + 'email_parents' => 'b@c.de', + 'fax' => '+49 212 1255674', + ]); $response = $this->get("/member/{$member->id}"); - $this->assertInertiaHas('Max', $response, 'data.firstname'); + $this->assertInertiaHas([ + 'birthday_human' => '20.04.1991', + 'age' => 14, + 'firstname' => 'Max', + 'gender_name' => 'Herr', + 'full_address' => 'Itterstr 3, 42719 Solingen', + 'region' => ['name' => 'NRW'], + 'other_country' => 'other', + 'main_phone' => '+49 212 1266775', + 'mobile_phone' => '+49 212 1266776', + 'work_phone' => '+49 212 1266777', + 'children_phone' => '+49 212 1266778', + 'email' => 'a@b.de', + 'email_parents' => 'b@c.de', + 'fax' => '+49 212 1255674', + ], $response, 'data'); $this->assertInertiaHas([ 'activity_name' => '€ LeiterIn', 'id' => $member->memberships->first()->id, @@ -38,4 +84,25 @@ class ShowTest extends TestCase 'nr' => '2019', ], $response, 'data.payments.0'); } + + public function testItShowsMinimalSingleMember(): void + { + $this->withoutExceptionHandling()->login()->loginNami(); + $member = Member::factory() + ->for(Group::factory()) + ->for(Nationality::factory()->name('deutsch')) + ->for(Subscription::factory()->for(Fee::factory())) + ->create(['firstname' => 'Max']); + + $response = $this->get("/member/{$member->id}"); + + $this->assertInertiaHas([ + 'region' => ['name' => '-- kein --'], + 'nationality' => ['name' => '-- kein --'], + 'gender_name' => 'keine Angabe', + 'nationality' => [ + 'name' => 'deutsch', + ], + ], $response, 'data'); + } } diff --git a/tests/Feature/Member/UpdateTest.php b/tests/Feature/Member/UpdateTest.php index e84e637e..8f534e47 100644 --- a/tests/Feature/Member/UpdateTest.php +++ b/tests/Feature/Member/UpdateTest.php @@ -53,6 +53,21 @@ class UpdateTest extends TestCase $response->assertRedirect("/member/{$member->id}/edit?conflict=1"); } + public function testItUpdatesContact(): void + { + $this->withoutExceptionHandling()->login()->loginNami(); + $member = $this->member(['nami_id' => null]); + $this->fakeRequest(); + + $response = $this + ->from("/member/{$member->id}") + ->patch("/member/{$member->id}", array_merge($member->getAttributes(), [ + 'other_country' => 'englisch', + ])); + + $this->assertEquals('englisch', $member->fresh()->other_country); + } + public function testItUpdatesCriminalRecord(): void { $this->withoutExceptionHandling()->login()->loginNami();