Add form to create memberships

This commit is contained in:
philipp lang 2021-08-22 22:23:17 +02:00
parent 55fd4315ce
commit b39f7a8726
8 changed files with 163 additions and 2 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Views;
use App\Activity;
use App\Member\Member;
use App\Member\MemberResource;
use App\Payment\ActionFactory;
@ -12,10 +13,12 @@ use Illuminate\Http\Request;
class MemberView {
public function index(Request $request, array $filter) {
$activities = Activity::with('subactivities')->get();
return [
'data' => MemberResource::collection(Member::select('*')
->filter($filter)->search($request->query('search', null))
->with('billKind')->with('payments')
->with('billKind')->with('payments')->with('memberships')
->withSubscriptionName()->withIsConfirmed()->withPendingPayment()->withAgeGroup()
->orderByRaw('lastname, firstname')
->paginate(15)
@ -24,6 +27,10 @@ class MemberView {
'paymentDefaults' => ['nr' => date('Y')],
'subscriptions' => Subscription::get()->pluck('name', 'id'),
'statuses' => Status::get()->pluck('name', 'id'),
'activities' => $activities->pluck('name', 'id'),
'subactivities' => $activities->map(function(Activity $activity) {
return ['subactivities' => $activity->subactivities->pluck('name', 'id'), 'id' => $activity->id];
})->pluck('subactivities', 'id'),
];
}

View File

@ -2,6 +2,7 @@
namespace App\Member;
use App\Membership\MembershipResource;
use App\Payment\PaymentResource;
use Illuminate\Http\Resources\Json\JsonResource;
@ -49,6 +50,7 @@ class MemberResource extends JsonResource
'is_confirmed' => $this->is_confirmed,
'children_phone' => $this->children_phone,
'payments' => PaymentResource::collection($this->whenLoaded('payments')),
'memberships' => MembershipResource::collection($this->whenLoaded('memberships')),
'pending_payment' => $this->pending_payment ? number_format($this->pending_payment / 100, 2, ',', '.').' €' : null,
'first_activity_id' => $this->first_activity_id,
'first_subactivity_id' => $this->first_subactivity_id,

View File

@ -2,12 +2,26 @@
namespace App\Member;
use App\Activity;
use App\Subactivity;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Membership extends Model
{
use HasFactory;
public $fillable = ['subactivity_id', 'activity_id', 'group_id', 'member_id', 'nami_id', 'created_at'];
public function activity(): BelongsTo
{
return $this->belongsTo(Activity::class);
}
public function subactivity(): BelongsTo
{
return $this->belongsTo(Subactivity::class);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Membership;
use App\Http\Controllers\Controller;
use App\Member\Member;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class MembershipController extends Controller
{
public function store(Member $member, Request $request): RedirectResponse
{
$member->memberships()->create($request->input());
return redirect()->back();
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Membership;
use Illuminate\Http\Resources\Json\JsonResource;
class MembershipResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'activity_id' => $this->activity_id,
'activity_name' => $this->activity->name,
'subactivity_id' => $this->subactivity_id,
'subactivity_name' => optional($this->subactivity)->name,
'human_date' => $this->created_at->format('d.m.Y'),
];
}
}

View File

@ -53,6 +53,7 @@
<td class="flex">
<inertia-link :href="`/member/${member.id}/edit`" class="inline-flex btn btn-warning btn-sm"><sprite src="pencil"></sprite></inertia-link>
<a href="#" @click.prevent="openSidebar(index, 'payment.index')" class="inline-flex btn btn-info btn-sm"><sprite src="money"></sprite></a>
<a href="#" @click.prevent="openSidebar(index, 'membership.index')" class="inline-flex btn btn-info btn-sm"><sprite src="user"></sprite></a>
<inertia-link href="#" @click.prevent="remove(member)" class="inline-flex btn btn-danger btn-sm"><sprite src="trash"></sprite></inertia-link>
</td>
</tr>
@ -65,6 +66,7 @@
<transition name="sidebar">
<payments v-if="single !== null && sidebar === 'payment.index'" @close="closeSidebar" :subscriptions="subscriptions" :statuses="statuses" v-model="data.data[single]"></payments>
<memberships v-if="single !== null && sidebar === 'membership.index'" @close="closeSidebar" :activities="activities" :subactivities="subactivities" v-model="data.data[single]"></memberships>
</transition>
</div>
</template>
@ -72,6 +74,7 @@
<script>
import App from '../../layouts/App';
import Payments from './Payments.vue';
import Memberships from './Memberships.vue';
import Filt from './Filt.vue';
import mergesQueryString from '../../mixins/mergesQueryString.js';
@ -88,7 +91,7 @@ export default {
mixins: [mergesQueryString],
components: { Payments, Filt },
components: { Memberships, Payments, Filt },
methods: {
remove(member) {
@ -113,6 +116,8 @@ export default {
paymentDefaults: {},
query: {},
billKinds: {},
activities: {},
subactivities: {},
}
}
</script>

View File

@ -0,0 +1,87 @@
<template>
<div class="sidebar flex flex-col">
<sidebar-header :links="links" @create="mode = 'create'; single = {}" @close="$emit('close')" title="Mitgliedschaften"></sidebar-header>
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<f-select id="activity_id" :options="activities" v-model="single.activity_id" label="Tätigkeit" required></f-select>
<f-select v-if="single.activity_id" :options="subactivities[single.activity_id]" id="subactivity_id" v-model="single.subactivity_id" label="Untertätigkeit"></f-select>
<button type="submit" class="btn btn-primary">Absenden</button>
</form>
<table v-else class="custom-table custom-table-light custom-table-sm text-sm flex-grow">
<thead>
<th>Tätigkeit</th>
<th>Untertätigkeit</th>
<th>Datum</th>
<th></th>
</thead>
<tr v-for="membership, index in value.memberships">
<td v-text="membership.activity_name"></td>
<td v-text="membership.subactivity_name"></td>
<td v-text="membership.human_date"></td>
<td class="flex">
<a href="#" @click.prevent="single = membership; mode = 'edit'" class="inline-flex btn btn-warning btn-sm"><sprite src="pencil"></sprite></a>
<inertia-link href="#" @click.prevent="remove(membership)" class="inline-flex btn btn-danger btn-sm"><sprite src="trash"></sprite></inertia-link>
</td>
</tr>
</table>
</div>
</template>
<script>
import SidebarHeader from '../../components/SidebarHeader.vue';
export default {
data: function() {
return {
mode: null,
single: null,
links: [
{ event: 'create', label: 'Neu' }
]
};
},
components: { SidebarHeader },
methods: {
remove(payment) {
this.$inertia.delete(`/member/${this.value.id}/payment/${payment.id}`);
},
accept(payment) {
this.$inertia.patch(`/member/${this.value.id}/payment/${payment.id}`, { ...payment, status_id: 3 });
},
openLink(link) {
if (link.disabled) {
return;
}
window.open(link.href);
},
submit() {
var _self = this;
var options = {
onFinish() {
_self.single = null;
_self.mode = null;
}
};
this.mode === 'create'
? this.$inertia.post(`/member/${this.value.id}/membership`, this.single, options)
: this.$inertia.patch(`/member/${this.value.id}/membership/${this.single.id}`, this.single, options);
}
},
props: {
value: {},
activities: {},
subactivities: {},
}
};
</script>

View File

@ -4,6 +4,7 @@ use App\Http\Controllers\HomeController;
use App\Initialize\InitializeController;
use App\Member\MemberConfirmController;
use App\Member\MemberController;
use App\Membership\MembershipController;
use App\Payment\AllpaymentController;
use App\Payment\PaymentController;
use App\Payment\SendpaymentController;
@ -26,4 +27,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
->name('member.singlepdf');
Route::get('/sendpayment', [SendpaymentController::class, 'create'])->name('sendpayment.create');
Route::get('/sendpayment/pdf', [SendpaymentController::class, 'send'])->name('sendpayment.pdf');
Route::apiResource('member.membership', MembershipController::class);
});