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>
273 lines
20 KiB
PHP
273 lines
20 KiB
PHP
<x-app-layout>
|
||
<x-slot name="header">
|
||
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
|
||
新增收入記錄
|
||
</h2>
|
||
</x-slot>
|
||
|
||
<div class="py-12">
|
||
<div class="mx-auto max-w-3xl sm:px-6 lg:px-8">
|
||
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
||
<div class="px-4 py-5 sm:p-6">
|
||
<form method="POST" action="{{ route('admin.incomes.store') }}" enctype="multipart/form-data">
|
||
@csrf
|
||
|
||
<div class="space-y-6">
|
||
{{-- 基本資訊 --}}
|
||
<div>
|
||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">基本資訊</h3>
|
||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">輸入收入的基本資料。</p>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||
{{-- 標題 --}}
|
||
<div class="sm:col-span-2">
|
||
<label for="title" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
標題 <span class="text-red-500">*</span>
|
||
</label>
|
||
<input type="text" name="title" id="title" value="{{ old('title') }}" required
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="例如:2024年度會費收入">
|
||
@error('title')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 收入日期 --}}
|
||
<div>
|
||
<label for="income_date" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
收入日期 <span class="text-red-500">*</span>
|
||
</label>
|
||
<input type="date" name="income_date" id="income_date" value="{{ old('income_date', date('Y-m-d')) }}" required
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300">
|
||
@error('income_date')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 金額 --}}
|
||
<div>
|
||
<label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
金額 (NT$) <span class="text-red-500">*</span>
|
||
</label>
|
||
<input type="number" name="amount" id="amount" value="{{ old('amount') }}" required
|
||
step="0.01" min="0.01"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="0.00">
|
||
@error('amount')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 收入類型 --}}
|
||
<div>
|
||
<label for="income_type" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
收入類型 <span class="text-red-500">*</span>
|
||
</label>
|
||
<select name="income_type" id="income_type" required
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300">
|
||
<option value="">請選擇收入類型</option>
|
||
<option value="membership_fee" @selected(old('income_type') == 'membership_fee')>會費</option>
|
||
<option value="entrance_fee" @selected(old('income_type') == 'entrance_fee')>入會費</option>
|
||
<option value="donation" @selected(old('income_type') == 'donation')>捐款</option>
|
||
<option value="activity" @selected(old('income_type') == 'activity')>活動收入</option>
|
||
<option value="grant" @selected(old('income_type') == 'grant')>補助款</option>
|
||
<option value="interest" @selected(old('income_type') == 'interest')>利息收入</option>
|
||
<option value="other" @selected(old('income_type') == 'other')>其他</option>
|
||
</select>
|
||
@error('income_type')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 會計科目 --}}
|
||
<div>
|
||
<label for="chart_of_account_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
會計科目 <span class="text-red-500">*</span>
|
||
</label>
|
||
<select name="chart_of_account_id" id="chart_of_account_id" required
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300">
|
||
<option value="">請選擇會計科目</option>
|
||
@foreach ($chartOfAccounts as $account)
|
||
<option value="{{ $account->id }}" @selected(old('chart_of_account_id') == $account->id)>
|
||
{{ $account->account_code }} - {{ $account->account_name_zh }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
@error('chart_of_account_id')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="border-gray-200 dark:border-gray-700">
|
||
|
||
{{-- 付款資訊 --}}
|
||
<div>
|
||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">付款資訊</h3>
|
||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">記錄付款方式與相關資訊。</p>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||
{{-- 付款方式 --}}
|
||
<div>
|
||
<label for="payment_method" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
付款方式 <span class="text-red-500">*</span>
|
||
</label>
|
||
<select name="payment_method" id="payment_method" required
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300">
|
||
<option value="">請選擇付款方式</option>
|
||
<option value="cash" @selected(old('payment_method') == 'cash')>現金</option>
|
||
<option value="bank_transfer" @selected(old('payment_method') == 'bank_transfer')>銀行轉帳</option>
|
||
<option value="check" @selected(old('payment_method') == 'check')>支票</option>
|
||
</select>
|
||
@error('payment_method')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 銀行帳號 --}}
|
||
<div>
|
||
<label for="bank_account" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
銀行帳號
|
||
</label>
|
||
<input type="text" name="bank_account" id="bank_account" value="{{ old('bank_account') }}"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="例如:012-12345678">
|
||
@error('bank_account')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 付款人姓名 --}}
|
||
<div>
|
||
<label for="payer_name" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
付款人姓名
|
||
</label>
|
||
<input type="text" name="payer_name" id="payer_name" value="{{ old('payer_name') }}"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="付款人姓名">
|
||
@error('payer_name')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 關聯會員 --}}
|
||
<div>
|
||
<label for="member_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
關聯會員
|
||
</label>
|
||
<select name="member_id" id="member_id"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300">
|
||
<option value="">不關聯會員</option>
|
||
@foreach ($members as $member)
|
||
<option value="{{ $member->id }}" @selected(old('member_id', $selectedMember?->id) == $member->id)>
|
||
{{ $member->full_name }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
@error('member_id')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</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 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="收據編號">
|
||
@error('receipt_number')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 交易參考號 --}}
|
||
<div>
|
||
<label for="transaction_reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
交易參考號
|
||
</label>
|
||
<input type="text" name="transaction_reference" id="transaction_reference" value="{{ old('transaction_reference') }}"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="銀行交易參考號">
|
||
@error('transaction_reference')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="border-gray-200 dark:border-gray-700">
|
||
|
||
{{-- 說明與備註 --}}
|
||
<div>
|
||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">說明與備註</h3>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 gap-6">
|
||
{{-- 說明 --}}
|
||
<div>
|
||
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
說明
|
||
</label>
|
||
<textarea name="description" id="description" rows="3"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="收入來源說明">{{ old('description') }}</textarea>
|
||
@error('description')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 備註 --}}
|
||
<div>
|
||
<label for="notes" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
內部備註
|
||
</label>
|
||
<textarea name="notes" id="notes" rows="2"
|
||
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-900 dark:text-gray-300"
|
||
placeholder="內部備註(僅管理員可見)">{{ old('notes') }}</textarea>
|
||
@error('notes')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
|
||
{{-- 附件 --}}
|
||
<div>
|
||
<label for="attachment" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||
附件
|
||
</label>
|
||
<input type="file" name="attachment" id="attachment"
|
||
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 file:text-indigo-700
|
||
dark:file:bg-indigo-900 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">支援 PDF、圖片等格式,最大 10MB</p>
|
||
@error('attachment')
|
||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||
@enderror
|
||
</div>
|
||
</div>
|
||
|
||
{{-- 提交按鈕 --}}
|
||
<div class="flex justify-end space-x-3 pt-6">
|
||
<a href="{{ route('admin.incomes.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">
|
||
取消
|
||
</a>
|
||
<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 focus:ring-offset-2">
|
||
建立收入記錄
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</x-app-layout>
|