Add fee type to membership payments display

This commit is contained in:
2026-01-25 05:10:01 +08:00
parent b528a63387
commit 36a4e87f3f
7 changed files with 67 additions and 8 deletions

View File

@@ -20,6 +20,7 @@ class AdminPaymentController extends Controller
public function store(Request $request, Member $member) public function store(Request $request, Member $member)
{ {
$validated = $request->validate([ $validated = $request->validate([
'fee_type' => ['required', 'in:' . MembershipPayment::FEE_TYPE_ENTRANCE . ',' . MembershipPayment::FEE_TYPE_ANNUAL],
'paid_at' => ['required', 'date'], 'paid_at' => ['required', 'date'],
'amount' => ['required', 'numeric', 'min:0'], 'amount' => ['required', 'numeric', 'min:0'],
'method' => ['nullable', 'string', 'max:255'], 'method' => ['nullable', 'string', 'max:255'],
@@ -46,6 +47,7 @@ class AdminPaymentController extends Controller
public function update(Request $request, Member $member, MembershipPayment $payment) public function update(Request $request, Member $member, MembershipPayment $payment)
{ {
$validated = $request->validate([ $validated = $request->validate([
'fee_type' => ['required', 'in:' . MembershipPayment::FEE_TYPE_ENTRANCE . ',' . MembershipPayment::FEE_TYPE_ANNUAL],
'paid_at' => ['required', 'date'], 'paid_at' => ['required', 'date'],
'amount' => ['required', 'numeric', 'min:0'], 'amount' => ['required', 'numeric', 'min:0'],
'method' => ['nullable', 'string', 'max:255'], 'method' => ['nullable', 'string', 'max:255'],

View File

@@ -78,6 +78,7 @@
"Membership Expiry Date": "會籍到期日期", "Membership Expiry Date": "會籍到期日期",
"Payment History": "繳費紀錄", "Payment History": "繳費紀錄",
"Paid At": "繳費時間", "Paid At": "繳費時間",
"Fee Type": "會費類型",
"Amount": "金額", "Amount": "金額",
"Method": "方式", "Method": "方式",
"Status": "狀態", "Status": "狀態",
@@ -515,4 +516,4 @@
"Activate your membership account": "啟用您的會員帳號", "Activate your membership account": "啟用您的會員帳號",
"Default: One year from start date": "預設:從開始日期起一年", "Default: One year from start date": "預設:從開始日期起一年",
"After activation, the member will receive a confirmation email and gain access to member-only resources.": "啟用後,會員將收到確認信並可存取會員專屬資源。" "After activation, the member will receive a confirmation email and gain access to member-only resources.": "啟用後,會員將收到確認信並可存取會員專屬資源。"
} }

View File

@@ -271,6 +271,9 @@
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"> <th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
付款時間 付款時間
</th> </th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
會費類型
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"> <th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
金額 金額
</th> </th>
@@ -294,6 +297,11 @@
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100"> <td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ optional($payment->paid_at)->toDateString() }} {{ optional($payment->paid_at)->toDateString() }}
</td> </td>
<td class="whitespace-nowrap px-4 py-3 text-sm">
<span class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium {{ $payment->fee_type === 'annual_fee' ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200' : 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' }}">
{{ $payment->fee_type_label ?? '未指定' }}
</span>
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100"> <td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
TWD {{ number_format($payment->amount, 0) }} TWD {{ number_format($payment->amount, 0) }}
</td> </td>
@@ -341,7 +349,7 @@
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="6" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400"> <td colspan="7" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
</svg> </svg>
@@ -356,4 +364,4 @@
</section> </section>
</div> </div>
</div> </div>
</x-app-layout> </x-app-layout>

View File

@@ -94,6 +94,7 @@
<thead class="bg-gray-50 dark:bg-gray-900"> <thead class="bg-gray-50 dark:bg-gray-900">
<tr> <tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">會員</th> <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">會員</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">會費類型</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">金額</th> <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">金額</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">付款日期</th> <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">付款日期</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">方式</th> <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">方式</th>
@@ -109,6 +110,11 @@
<div class="font-medium text-gray-900 dark:text-gray-100">{{ $payment->member->full_name }}</div> <div class="font-medium text-gray-900 dark:text-gray-100">{{ $payment->member->full_name }}</div>
<div class="text-gray-500 dark:text-gray-400">{{ $payment->member->email }}</div> <div class="text-gray-500 dark:text-gray-400">{{ $payment->member->email }}</div>
</td> </td>
<td class="whitespace-nowrap px-3 py-4 text-sm">
<span class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium {{ $payment->fee_type === 'annual_fee' ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200' : 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' }}">
{{ $payment->fee_type_label ?? '未指定' }}
</span>
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-900 dark:text-gray-100"> <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-900 dark:text-gray-100">
TWD {{ number_format($payment->amount, 0) }} TWD {{ number_format($payment->amount, 0) }}
</td> </td>
@@ -139,7 +145,7 @@
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="7" class="px-3 py-8 text-center text-sm text-gray-500 dark:text-gray-400"> <td colspan="8" class="px-3 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
找不到付款記錄 找不到付款記錄
</td> </td>
</tr> </tr>
@@ -154,4 +160,4 @@
</div> </div>
</div> </div>
</div> </div>
</x-app-layout> </x-app-layout>

View File

@@ -29,6 +29,24 @@
@enderror @enderror
</div> </div>
<div>
<label for="fee_type" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
會費類型
</label>
<select
name="fee_type"
id="fee_type"
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
required
>
<option value="entrance_fee" @selected(old('fee_type', $member->getNextFeeType()) === 'entrance_fee')>入會會費</option>
<option value="annual_fee" @selected(old('fee_type', $member->getNextFeeType()) === 'annual_fee')>常年會費</option>
</select>
@error('fee_type')
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
</div>
<div> <div>
<label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> <label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
金額 金額
@@ -90,4 +108,3 @@
</div> </div>
</div> </div>
</x-app-layout> </x-app-layout>

View File

@@ -30,6 +30,24 @@
@enderror @enderror
</div> </div>
<div>
<label for="fee_type" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
會費類型
</label>
<select
name="fee_type"
id="fee_type"
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
required
>
<option value="entrance_fee" @selected(old('fee_type', $payment->fee_type) === 'entrance_fee')>入會會費</option>
<option value="annual_fee" @selected(old('fee_type', $payment->fee_type) === 'annual_fee')>常年會費</option>
</select>
@error('fee_type')
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
</div>
<div> <div>
<label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> <label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
金額 金額
@@ -99,4 +117,3 @@
</div> </div>
</div> </div>
</x-app-layout> </x-app-layout>

View File

@@ -221,6 +221,9 @@
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"> <th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Paid At') }} {{ __('Paid At') }}
</th> </th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Fee Type') }}
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"> <th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Amount') }} {{ __('Amount') }}
</th> </th>
@@ -241,6 +244,11 @@
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100"> <td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ optional($payment->paid_at)->format('Y-m-d') }} {{ optional($payment->paid_at)->format('Y-m-d') }}
</td> </td>
<td class="whitespace-nowrap px-4 py-3 text-sm">
<span class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium {{ $payment->fee_type === 'annual_fee' ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200' : 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' }}">
{{ $payment->fee_type_label ?? __('N/A') }}
</span>
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100"> <td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
TWD {{ number_format($payment->amount, 0) }} TWD {{ number_format($payment->amount, 0) }}
</td> </td>
@@ -278,7 +286,7 @@
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="5" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400"> <td colspan="6" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
</svg> </svg>