Wip: Member view
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
next: Schulungen darstellen
This commit is contained in:
parent
30592a1dc9
commit
90bdc28e23
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Member;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class GenderResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
|
@ -202,7 +202,10 @@ class Member extends Model
|
|||
|
||||
public function region(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Region::class);
|
||||
return $this->belongsTo(Region::class)->withDefault([
|
||||
'name' => '-- kein --',
|
||||
'nami_id' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function confession(): BelongsTo
|
||||
|
|
|
@ -78,6 +78,7 @@ class MemberRequest extends FormRequest
|
|||
'nationality_id' => 'nullable|exists:nationalities,id',
|
||||
'children_phone' => '',
|
||||
'fax' => '',
|
||||
'other_country' => '',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Member\Resources;
|
||||
|
||||
use App\Nationality;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* @mixin Nationality
|
||||
*/
|
||||
class NationalityResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'nami_id' => $this->nami_id,
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Member\Resources;
|
||||
|
||||
use App\Region;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* @mixin Region
|
||||
*/
|
||||
class RegionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'nami_id' => $this->nami_id,
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<div class="text-gray-300">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="text-gray-400 text-xs" v-text="label"></div>
|
||||
<div class="text-gray-200 text-sm">
|
||||
<span v-if="!type" v-text="value"></span>
|
||||
<a
|
||||
:href="`mailto:${value}`"
|
||||
class="text-teal-500 hover:text-teal-300 transition-all"
|
||||
v-text="value"
|
||||
v-if="type === 'email'"
|
||||
></a>
|
||||
<a
|
||||
:href="`tel:${value}`"
|
||||
class="text-teal-500 hover:text-teal-300 transition-all"
|
||||
v-text="value"
|
||||
v-if="type === 'tel'"
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
type: {
|
||||
default: function () {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
value: {
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,23 +0,0 @@
|
|||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
inner: {},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {},
|
||||
|
||||
props: {
|
||||
data: {},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.inner = this.data;
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div class="p-6 grid gap-6 this-grid">
|
||||
<!-- ****************************** Stammdaten ******************************* -->
|
||||
<div class="bg-gray-800 p-3 grid grid-cols-2 justify-start gap-3 rounded-lg">
|
||||
<heading class="col-span-full">Stammdaten</heading>
|
||||
<key-value label="Geschlecht" :value="inner.gender_name"></key-value>
|
||||
<key-value label="Vorname" :value="inner.firstname"></key-value>
|
||||
<key-value label="Nachname" :value="inner.lastname"></key-value>
|
||||
<key-value label="Adresse" :value="inner.full_address"></key-value>
|
||||
<key-value label="Geburtsdatum" :value="inner.birthday_human"></key-value>
|
||||
<key-value label="Alter" :value="inner.age"></key-value>
|
||||
<key-value label="Bundesland" :value="inner.region.name"></key-value>
|
||||
<key-value label="Nationalität" :value="inner.nationality.name"></key-value>
|
||||
<key-value
|
||||
v-show="inner.other_country"
|
||||
label="Andere Staatsangehörigkeit"
|
||||
:value="inner.other_country"
|
||||
></key-value>
|
||||
</div>
|
||||
|
||||
<!-- ******************************** Kontakt ******************************** -->
|
||||
<div class="bg-gray-800 p-3 grid justify-start gap-3 rounded-lg">
|
||||
<heading class="col-span-full">Kontakt</heading>
|
||||
<key-value
|
||||
v-show="inner.main_phone"
|
||||
label="Telefon Eltern"
|
||||
:value="inner.main_phone"
|
||||
type="tel"
|
||||
></key-value>
|
||||
<key-value
|
||||
v-show="inner.mobile_phone"
|
||||
label="Handy Eltern"
|
||||
:value="inner.mobile_phone"
|
||||
type="tel"
|
||||
></key-value>
|
||||
<key-value
|
||||
v-show="inner.work_phone"
|
||||
label="Telefon Eltern geschäftlich"
|
||||
:value="inner.work_phone"
|
||||
type="tel"
|
||||
></key-value>
|
||||
<key-value
|
||||
v-show="inner.children_phone"
|
||||
label="Telefon Kind"
|
||||
:value="inner.children_phone"
|
||||
type="tel"
|
||||
></key-value>
|
||||
<key-value v-show="inner.email" label="E-Mail-Adresse Kind" :value="inner.email" type="email"></key-value>
|
||||
<key-value
|
||||
v-show="inner.email_parents"
|
||||
label="E-Mail-Adresse Eltern"
|
||||
:value="inner.email_parents"
|
||||
type="email"
|
||||
></key-value>
|
||||
<key-value v-show="inner.fax" label="Fax" :value="inner.fax" type="tel"></key-value>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
inner: {},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {},
|
||||
|
||||
props: {
|
||||
data: {},
|
||||
},
|
||||
|
||||
components: {
|
||||
'key-value': () => import('./KeyValue'),
|
||||
'heading': () => import('./Heading'),
|
||||
},
|
||||
|
||||
created() {
|
||||
this.inner = this.data;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.this-grid {
|
||||
grid-template-columns: max-content max-content 1fr;
|
||||
}
|
||||
</style>
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue