Files
Gbanyan 642b879dd4 Add membership fee system with disability discount and fix document permissions
Features:
- Implement two fee types: entrance fee and annual fee (both NT$1,000)
- Add 50% discount for disability certificate holders
- Add disability certificate upload in member profile
- Integrate disability verification into cashier approval workflow
- Add membership fee settings in system admin

Document permissions:
- Fix hard-coded role logic in Document model
- Use permission-based authorization instead of role checks

Additional features:
- Add announcements, general ledger, and trial balance modules
- Add income management and accounting entries
- Add comprehensive test suite with factories
- Update UI translations to Traditional Chinese

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 09:56:01 +08:00

299 lines
21 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
付款單詳情: {{ $paymentOrder->payment_order_number }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-5xl sm:px-6 lg:px-8 space-y-4">
@if (session('status'))
<div class="rounded-md bg-green-50 dark:bg-green-900/30 p-4">
<p class="text-sm font-medium text-green-800 dark:text-green-200">{{ session('status') }}</p>
</div>
@endif
@if (session('error'))
<div class="rounded-md bg-red-50 dark:bg-red-900/30 p-4">
<p class="text-sm font-medium text-red-800 dark:text-red-200">{{ session('error') }}</p>
</div>
@endif
<!-- Payment Order Info -->
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">付款單資訊</h3>
<span class="inline-flex rounded-full px-3 py-1 text-sm font-semibold
@if($paymentOrder->status === 'executed') bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200
@elseif($paymentOrder->status === 'verified') bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200
@elseif($paymentOrder->status === 'pending_verification') bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200
@elseif($paymentOrder->status === 'cancelled') bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200
@else bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-300
@endif">
{{ $paymentOrder->getStatusText() }}
</span>
</div>
<dl class="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2">
<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 font-mono">{{ $paymentOrder->payment_order_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">{{ $paymentOrder->payee_name }}</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 font-semibold">NT$ {{ number_format($paymentOrder->payment_amount, 2) }}</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">{{ $paymentOrder->getPaymentMethodText() }}</dd>
</div>
@if($paymentOrder->payment_method === 'bank_transfer')
<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">{{ $paymentOrder->payee_bank_name ?? 'N/A' }}</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">{{ $paymentOrder->payee_bank_code ?? 'N/A' }}</dd>
</div>
<div class="sm:col-span-2">
<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 font-mono">{{ $paymentOrder->payee_account_number ?? 'N/A' }}</dd>
</div>
@endif
<div class="sm:col-span-2">
<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">
{{ $paymentOrder->createdByAccountant->name }} - {{ $paymentOrder->created_at->format('Y-m-d H:i') }}
</dd>
</div>
@if($paymentOrder->notes)
<div class="sm:col-span-2">
<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">{{ $paymentOrder->notes }}</dd>
</div>
@endif
</dl>
</div>
</div>
<!-- Verification Section -->
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100 mb-4">出納覆核</h3>
@if($paymentOrder->verified_at)
<dl class="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2">
<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">{{ $paymentOrder->verifiedByCashier->name }}</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">{{ $paymentOrder->verified_at->format('Y-m-d H:i') }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">覆核狀態</dt>
<dd class="mt-1 text-sm">
<span class="inline-flex rounded-full px-2 text-xs font-semibold
@if($paymentOrder->verification_status === 'approved') bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200
@elseif($paymentOrder->verification_status === 'rejected') bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200
@else bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200
@endif">
@if($paymentOrder->verification_status === 'approved') 通過
@elseif($paymentOrder->verification_status === 'rejected') 駁回
@else 待覆核
@endif
</span>
</dd>
</div>
@if($paymentOrder->verification_notes)
<div class="sm:col-span-2">
<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">{{ $paymentOrder->verification_notes }}</dd>
</div>
@endif
</dl>
@else
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">此付款單待出納覆核</p>
@can('verify_payment_order')
@if($paymentOrder->canBeVerifiedByCashier())
<form method="POST" action="{{ route('admin.payment-orders.verify', $paymentOrder) }}" class="space-y-4">
@csrf
<div>
<label for="verification_notes" class="block text-sm font-medium text-gray-700 dark:text-gray-300">覆核備註</label>
<textarea name="verification_notes" id="verification_notes" rows="3"
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-700 dark:border-gray-600 dark:text-gray-100"></textarea>
</div>
<div class="flex space-x-3">
<button type="submit" name="action" value="approve"
class="inline-flex items-center rounded-md border border-transparent bg-green-600 dark:bg-green-500 px-4 py-2 text-sm font-medium text-white hover:bg-green-700 dark:hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 dark:focus:ring-green-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
通過覆核
</button>
<button type="submit" name="action" value="reject"
class="inline-flex items-center rounded-md border border-transparent bg-red-600 dark:bg-red-500 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 dark:hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 dark:focus:ring-red-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
駁回
</button>
</div>
</form>
@endif
@endcan
@endif
</div>
</div>
<!-- Execution Section -->
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100 mb-4">付款執行</h3>
@if($paymentOrder->executed_at)
<dl class="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2">
<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">{{ $paymentOrder->executedByCashier->name }}</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">{{ $paymentOrder->executed_at->format('Y-m-d H:i') }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">執行狀態</dt>
<dd class="mt-1 text-sm">
<span class="inline-flex rounded-full px-2 text-xs font-semibold
@if($paymentOrder->execution_status === 'completed') bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200
@elseif($paymentOrder->execution_status === 'failed') bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200
@else bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200
@endif">
@if($paymentOrder->execution_status === 'completed') 已完成
@elseif($paymentOrder->execution_status === 'failed') 失敗
@else 待執行
@endif
</span>
</dd>
</div>
@if($paymentOrder->transaction_reference)
<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 font-mono">{{ $paymentOrder->transaction_reference }}</dd>
</div>
@endif
@if($paymentOrder->payment_receipt_path)
<div class="sm:col-span-2">
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">付款憑證</dt>
<dd class="mt-1">
<a href="{{ route('admin.payment-orders.download-receipt', $paymentOrder) }}" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-300">
下載憑證
</a>
</dd>
</div>
@endif
</dl>
@else
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">此付款單待執行付款</p>
@can('execute_payment')
@if($paymentOrder->canBeExecuted())
<form method="POST" action="{{ route('admin.payment-orders.execute', $paymentOrder) }}" enctype="multipart/form-data" class="space-y-4">
@csrf
<div>
<label for="transaction_reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
交易參考號 <span class="text-red-500 dark:text-red-400">*</span>
</label>
<input type="text" name="transaction_reference" id="transaction_reference" required
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-700 dark:border-gray-600 dark:text-gray-100">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">銀行交易編號或支票號碼</p>
</div>
<div>
<label for="payment_receipt" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
付款憑證
</label>
<input type="file" name="payment_receipt" id="payment_receipt"
class="mt-1 block w-full text-sm text-gray-500 dark:text-gray-400
file:mr-4 file:py-2 file:px-4
file:rounded-md file:border-0
file:text-sm file:font-semibold
file:bg-indigo-50 dark:file:bg-indigo-900/50 file:text-indigo-700 dark:file:text-indigo-300
hover:file:bg-indigo-100 dark:hover:file:bg-indigo-800">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">上傳轉帳收據或付款證明(最大 10MB</p>
</div>
<div>
<label for="execution_notes" class="block text-sm font-medium text-gray-700 dark:text-gray-300">執行備註</label>
<textarea name="execution_notes" id="execution_notes" rows="3"
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-700 dark:border-gray-600 dark:text-gray-100"></textarea>
</div>
<div>
<button type="submit"
class="inline-flex items-center rounded-md border border-transparent bg-green-600 dark:bg-green-500 px-4 py-2 text-sm font-medium text-white hover:bg-green-700 dark:hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 dark:focus:ring-green-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
確認執行付款
</button>
</div>
</form>
@endif
@endcan
@endif
</div>
</div>
<!-- Related Finance Document -->
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100 mb-4">關聯報銷申請單</h3>
<dl class="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2">
<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">{{ $paymentOrder->financeDocument->title }}</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">{{ $paymentOrder->financeDocument->getRequestTypeText() }}</dd>
</div>
@if($paymentOrder->financeDocument->member)
<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">{{ $paymentOrder->financeDocument->member->full_name }}</dd>
</div>
@endif
<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">{{ $paymentOrder->financeDocument->submittedBy->name }}</dd>
</div>
</dl>
<div class="mt-4">
<a href="{{ route('admin.finance.show', $paymentOrder->financeDocument) }}" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-300">
查看完整申請單
</a>
</div>
</div>
</div>
<!-- Actions -->
<div class="flex justify-between">
<a href="{{ route('admin.payment-orders.index') }}" class="inline-flex items-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-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">
返回列表
</a>
@can('create_payment_order')
@if(!$paymentOrder->isExecuted() && $paymentOrder->status !== 'cancelled')
<form method="POST" action="{{ route('admin.payment-orders.cancel', $paymentOrder) }}" onsubmit="return confirm('確定要取消此付款單嗎?');">
@csrf
<button type="submit" class="inline-flex items-center rounded-md border border-transparent bg-red-600 dark:bg-red-500 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 dark:hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 dark:focus:ring-red-600 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
取消付款單
</button>
</form>
@endif
@endcan
</div>
</div>
</div>
</x-app-layout>