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>
271 lines
18 KiB
PHP
271 lines
18 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-7xl sm:px-6 lg:px-8 space-y-6">
|
|
<!-- Filter Form -->
|
|
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<form method="GET" action="{{ route('admin.general-ledger.index') }}" class="space-y-4">
|
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-4">
|
|
<!-- Account Selection -->
|
|
<div class="sm:col-span-2">
|
|
<label for="account_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
科目
|
|
</label>
|
|
<select name="account_id" id="account_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-700 dark:text-gray-100">
|
|
<option value="">請選擇科目</option>
|
|
@foreach($accounts as $account)
|
|
<option value="{{ $account->id }}" @selected(request('account_id') == $account->id)>
|
|
{{ $account->account_code }} - {{ $account->account_name_zh }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Start Date -->
|
|
<div>
|
|
<label for="start_date" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
開始日期
|
|
</label>
|
|
<input type="date" name="start_date" id="start_date" value="{{ $startDate }}"
|
|
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-700 dark:text-gray-100">
|
|
</div>
|
|
|
|
<!-- End Date -->
|
|
<div>
|
|
<label for="end_date" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
結束日期
|
|
</label>
|
|
<input type="date" name="end_date" id="end_date" value="{{ $endDate }}"
|
|
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-700 dark:text-gray-100">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-4">
|
|
<button type="submit" class="inline-flex justify-center rounded-md bg-indigo-600 dark:bg-indigo-500 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-700 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
|
|
查詢
|
|
</button>
|
|
<a href="{{ route('admin.general-ledger.index') }}" class="inline-flex justify-center rounded-md bg-white dark:bg-gray-700 px-4 py-2 text-sm font-semibold text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-inset ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-600">
|
|
清除
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
@if($selectedAccount)
|
|
<!-- Account Info -->
|
|
<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 text-gray-900 dark:text-gray-100">
|
|
{{ $selectedAccount->account_code }} - {{ $selectedAccount->account_name_zh }}
|
|
<span class="text-sm text-gray-500 dark:text-gray-400">
|
|
({{ $selectedAccount->account_name_en }})
|
|
</span>
|
|
</h3>
|
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
類型:
|
|
@switch($selectedAccount->account_type)
|
|
@case('asset') 資產 @break
|
|
@case('liability') 負債 @break
|
|
@case('net_asset') 淨資產/基金 @break
|
|
@case('income') 收入 @break
|
|
@case('expense') 支出 @break
|
|
@default {{ $selectedAccount->account_type }}
|
|
@endswitch
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Summary Cards -->
|
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
<!-- Opening Balance -->
|
|
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg border-l-4 border-gray-400">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
期初餘額
|
|
</dt>
|
|
<dd class="mt-1 text-2xl font-semibold {{ $openingBalance >= 0 ? 'text-gray-900 dark:text-gray-100' : 'text-red-600 dark:text-red-400' }}">
|
|
NT$ {{ number_format($openingBalance, 2) }}
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Debit Total -->
|
|
<div class="bg-blue-50 dark:bg-blue-900/30 shadow sm:rounded-lg border-l-4 border-blue-400">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<dt class="text-sm font-medium text-blue-800 dark:text-blue-200">
|
|
借方總計
|
|
</dt>
|
|
<dd class="mt-1 text-2xl font-semibold text-blue-900 dark:text-blue-100">
|
|
NT$ {{ number_format($debitTotal, 2) }}
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Credit Total -->
|
|
<div class="bg-purple-50 dark:bg-purple-900/30 shadow sm:rounded-lg border-l-4 border-purple-400">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<dt class="text-sm font-medium text-purple-800 dark:text-purple-200">
|
|
貸方總計
|
|
</dt>
|
|
<dd class="mt-1 text-2xl font-semibold text-purple-900 dark:text-purple-100">
|
|
NT$ {{ number_format($creditTotal, 2) }}
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Closing Balance -->
|
|
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg border-l-4 {{ $closingBalance >= 0 ? 'border-green-400' : 'border-red-400' }}">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
期末餘額
|
|
</dt>
|
|
<dd class="mt-1 text-2xl font-semibold {{ $closingBalance >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' }}">
|
|
NT$ {{ number_format($closingBalance, 2) }}
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Entries Table -->
|
|
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100 mb-4">
|
|
分錄明細
|
|
</h4>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
<thead class="bg-gray-50 dark:bg-gray-700">
|
|
<tr>
|
|
<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>
|
|
<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-right text-xs font-medium uppercase tracking-wider text-blue-600 dark:text-blue-400">
|
|
借方
|
|
</th>
|
|
<th scope="col" class="px-4 py-3 text-right text-xs font-medium uppercase tracking-wider text-purple-600 dark:text-purple-400">
|
|
貸方
|
|
</th>
|
|
<th scope="col" class="px-4 py-3 text-right text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
|
|
餘額
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 dark:divide-gray-700 bg-white dark:bg-gray-800">
|
|
<!-- Opening Balance Row -->
|
|
<tr class="bg-gray-50 dark:bg-gray-700">
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
|
|
{{ \Carbon\Carbon::parse($startDate)->format('Y/m/d') }}
|
|
</td>
|
|
<td class="px-4 py-3 text-sm text-gray-500 dark:text-gray-400" colspan="2">
|
|
<em>期初餘額</em>
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-gray-500 dark:text-gray-400">
|
|
-
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-gray-500 dark:text-gray-400">
|
|
-
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right font-medium {{ $openingBalance >= 0 ? 'text-gray-900 dark:text-gray-100' : 'text-red-600 dark:text-red-400' }}">
|
|
{{ number_format($openingBalance, 2) }}
|
|
</td>
|
|
</tr>
|
|
|
|
@php $runningBalance = $openingBalance; @endphp
|
|
@forelse($entries as $entry)
|
|
@php
|
|
if (in_array($selectedAccount->account_type, ['asset', 'expense'])) {
|
|
$runningBalance += ($entry->entry_type === 'debit' ? $entry->amount : -$entry->amount);
|
|
} else {
|
|
$runningBalance += ($entry->entry_type === 'credit' ? $entry->amount : -$entry->amount);
|
|
}
|
|
@endphp
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
|
|
{{ $entry->entry_date->format('Y/m/d') }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm">
|
|
@if($entry->financeDocument)
|
|
<a href="{{ route('admin.finance.show', $entry->financeDocument) }}" class="text-indigo-600 dark:text-indigo-400 hover:underline">
|
|
#{{ $entry->finance_document_id }}
|
|
</a>
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100 max-w-xs truncate">
|
|
{{ $entry->description ?? '-' }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-blue-600 dark:text-blue-400">
|
|
{{ $entry->entry_type === 'debit' ? number_format($entry->amount, 2) : '' }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-purple-600 dark:text-purple-400">
|
|
{{ $entry->entry_type === 'credit' ? number_format($entry->amount, 2) : '' }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right font-medium {{ $runningBalance >= 0 ? 'text-gray-900 dark:text-gray-100' : 'text-red-600 dark:text-red-400' }}">
|
|
{{ number_format($runningBalance, 2) }}
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="6" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
|
|
此期間無分錄
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
|
|
<!-- Totals Row -->
|
|
@if($entries && $entries->count() > 0)
|
|
<tr class="bg-gray-100 dark:bg-gray-700 font-semibold">
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100" colspan="3">
|
|
本期合計
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-blue-700 dark:text-blue-300">
|
|
{{ number_format($debitTotal, 2) }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right text-purple-700 dark:text-purple-300">
|
|
{{ number_format($creditTotal, 2) }}
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-sm text-right {{ $closingBalance >= 0 ? 'text-green-700 dark:text-green-300' : 'text-red-700 dark:text-red-300' }}">
|
|
{{ number_format($closingBalance, 2) }}
|
|
</td>
|
|
</tr>
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<!-- No Account Selected -->
|
|
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
|
<div class="px-4 py-12 text-center">
|
|
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
請選擇科目
|
|
</h3>
|
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
從上方下拉選單選擇科目以查看分錄明細
|
|
</p>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</x-app-layout>
|