Add receipt numbers to membership payments
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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": "全名",
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
搜尋
|
搜尋
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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">
|
||||||
儲存付款
|
儲存付款
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user