Add receipt numbers to membership payments

This commit is contained in:
2026-02-05 16:41:04 +08:00
parent 8fc4adb6ad
commit 329877b5bf
12 changed files with 100 additions and 10 deletions

View File

@@ -25,6 +25,7 @@ class AdminPaymentController extends Controller
'amount' => ['required', 'numeric', 'min:0'], 'amount' => ['required', 'numeric', 'min:0'],
'method' => ['nullable', 'string', 'max:255'], 'method' => ['nullable', 'string', 'max:255'],
'reference' => ['nullable', 'string', 'max:255'], 'reference' => ['nullable', 'string', 'max:255'],
'receipt_number' => ['nullable', 'string', 'max:255'],
]); ]);
$payment = $member->payments()->create($validated); $payment = $member->payments()->create($validated);
@@ -52,6 +53,7 @@ class AdminPaymentController extends Controller
'amount' => ['required', 'numeric', 'min:0'], 'amount' => ['required', 'numeric', 'min:0'],
'method' => ['nullable', 'string', 'max:255'], 'method' => ['nullable', 'string', 'max:255'],
'reference' => ['nullable', 'string', 'max:255'], 'reference' => ['nullable', 'string', 'max:255'],
'receipt_number' => ['nullable', 'string', 'max:255'],
]); ]);
$payment->update($validated); $payment->update($validated);

View File

@@ -46,7 +46,8 @@ class PaymentVerificationController extends Controller
$query->whereHas('member', function ($q) use ($search) { $query->whereHas('member', function ($q) use ($search) {
$q->where('full_name', 'like', "%{$search}%") $q->where('full_name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%"); ->orWhere('email', 'like', "%{$search}%");
})->orWhere('reference', 'like', "%{$search}%"); })->orWhere('reference', 'like', "%{$search}%")
->orWhere('receipt_number', 'like', "%{$search}%");
} }
$payments = $query->paginate(20)->withQueryString(); $payments = $query->paginate(20)->withQueryString();

View File

@@ -39,6 +39,7 @@ class MembershipPayment extends Model
'disability_discount', 'disability_discount',
'method', 'method',
'reference', 'reference',
'receipt_number',
'status', 'status',
'payment_method', 'payment_method',
'receipt_path', 'receipt_path',

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('membership_payments', function (Blueprint $table) {
$table->string('receipt_number')->nullable()->after('reference');
});
DB::table('membership_payments')
->whereNull('receipt_number')
->whereNotNull('reference')
->where('reference', '<>', '')
->where('notes', 'like', '2026-02-03 會員名冊與會員費與捐款統計資料.xlsx%')
->update(['receipt_number' => DB::raw('reference')]);
}
public function down(): void
{
Schema::table('membership_payments', function (Blueprint $table) {
$table->dropColumn('receipt_number');
});
}
};

View File

@@ -296,6 +296,7 @@
"Submitted By": "提交者", "Submitted By": "提交者",
"Verify": "審核", "Verify": "審核",
"Receipt": "收據", "Receipt": "收據",
"Receipt Number": "收據編號",
"Download Receipt": "下載收據", "Download Receipt": "下載收據",
"Edit member": "編輯會員", "Edit member": "編輯會員",
"Full name": "全名", "Full name": "全名",

View File

@@ -366,6 +366,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>
@@ -394,6 +397,9 @@
<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">
{{ $payment->payment_method_label ?? ($payment->method ?? __('N/A')) }} {{ $payment->payment_method_label ?? ($payment->method ?? __('N/A')) }}
</td> </td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ $payment->receipt_number ?? '—' }}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm"> <td class="whitespace-nowrap px-4 py-3 text-sm">
{!! $payment->status_label ?? '<span class="inline-flex items-center rounded-md bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-medium text-gray-600 dark:text-gray-300">' . __('Legacy') . '</span>' !!} {!! $payment->status_label ?? '<span class="inline-flex items-center rounded-md bg-gray-100 dark:bg-gray-700 px-2 py-1 text-xs font-medium text-gray-600 dark:text-gray-300">' . __('Legacy') . '</span>' !!}
</td> </td>
@@ -435,7 +441,7 @@
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="7" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400"> <td colspan="8" 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>

View File

@@ -79,7 +79,7 @@
<div class="mb-4"> <div class="mb-4">
<form method="GET" action="{{ route('admin.payment-verifications.index') }}" class="flex gap-2"> <form method="GET" action="{{ route('admin.payment-verifications.index') }}" class="flex gap-2">
<input type="hidden" name="tab" value="{{ $tab }}"> <input type="hidden" name="tab" value="{{ $tab }}">
<input type="text" name="search" value="{{ request('search') }}" placeholder="依會員姓名、電子郵件或參考編號搜尋..." <input type="text" name="search" value="{{ request('search') }}" placeholder="依會員姓名、電子郵件、收據編號或參考編號搜尋..."
class="flex-1 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100"> class="flex-1 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100">
<button type="submit" class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400"> <button type="submit" class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400">
搜尋 搜尋

View File

@@ -89,7 +89,12 @@
</div> </div>
<div> <div>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">參考編號</dt> <dt class="text-sm font-medium text-gray-500 dark:text-gray-400">收據編號</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $payment->receipt_number ?? '—' }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">付款參考</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $payment->reference ?? '—' }}</dd> <dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $payment->reference ?? '—' }}</dd>
</div> </div>
@@ -326,4 +331,4 @@
}); });
</script> </script>
@endpush @endpush
</x-app-layout> </x-app-layout>

View File

@@ -83,7 +83,7 @@
<div> <div>
<label for="reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> <label for="reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
參考 付款參考
</label> </label>
<input <input
type="text" type="text"
@@ -97,6 +97,22 @@
@enderror @enderror
</div> </div>
<div>
<label for="receipt_number" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
收據編號
</label>
<input
type="text"
name="receipt_number"
id="receipt_number"
value="{{ old('receipt_number') }}"
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"
>
@error('receipt_number')
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
</div>
<div class="flex justify-end"> <div class="flex justify-end">
<button type="submit" class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 dark:bg-indigo-500 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800"> <button type="submit" class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 dark:bg-indigo-500 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
儲存付款 儲存付款

View File

@@ -84,7 +84,7 @@
<div> <div>
<label for="reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> <label for="reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
參考 付款參考
</label> </label>
<input <input
type="text" type="text"
@@ -98,6 +98,22 @@
@enderror @enderror
</div> </div>
<div>
<label for="receipt_number" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
收據編號
</label>
<input
type="text"
name="receipt_number"
id="receipt_number"
value="{{ old('receipt_number', $payment->receipt_number) }}"
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"
>
@error('receipt_number')
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
</div>
<div class="flex justify-between"> <div class="flex justify-between">
<form method="POST" action="{{ route('admin.members.payments.destroy', [$member, $payment]) }}"> <form method="POST" action="{{ route('admin.members.payments.destroy', [$member, $payment]) }}">
@csrf @csrf

View File

@@ -84,7 +84,7 @@
<div class="header"> <div class="header">
<h1>PAYMENT RECEIPT</h1> <h1>PAYMENT RECEIPT</h1>
<p>Membership Payment Confirmation</p> <p>Membership Payment Confirmation</p>
<p>Receipt #{{ $payment->id }}</p> <p>Receipt #{{ $payment->receipt_number ?? $payment->id }}</p>
</div> </div>
<div class="amount-box"> <div class="amount-box">
@@ -106,9 +106,15 @@
<td>Payment Method:</td> <td>Payment Method:</td>
<td>{{ $payment->method ?? 'N/A' }}</td> <td>{{ $payment->method ?? 'N/A' }}</td>
</tr> </tr>
@if($payment->receipt_number)
<tr>
<td>Receipt Number:</td>
<td>{{ $payment->receipt_number }}</td>
</tr>
@endif
@if($payment->reference) @if($payment->reference)
<tr> <tr>
<td>Reference Number:</td> <td>Payment Reference:</td>
<td>{{ $payment->reference }}</td> <td>{{ $payment->reference }}</td>
</tr> </tr>
@endif @endif

View File

@@ -230,6 +230,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">
{{ __('Method') }} {{ __('Method') }}
</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">
{{ __('Receipt Number') }}
</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">
{{ __('Status') }} {{ __('Status') }}
</th> </th>
@@ -255,6 +258,9 @@
<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">
{{ $payment->payment_method_label ?? __('N/A') }} {{ $payment->payment_method_label ?? __('N/A') }}
</td> </td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ $payment->receipt_number ?? __('N/A') }}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm"> <td class="whitespace-nowrap px-4 py-3 text-sm">
{!! $payment->status_label !!} {!! $payment->status_label !!}
</td> </td>
@@ -286,7 +292,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>