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>
This commit is contained in:
2025-12-01 09:56:01 +08:00
parent 83ce1f7fc8
commit 642b879dd4
207 changed files with 19487 additions and 3048 deletions

View File

@@ -0,0 +1,561 @@
# 系統缺口分析與實作建議
**分析日期:** 2025-11-30
**分析目的:** 評估現有系統對於匯入 Excel 帳務資料的支援程度,並提出實作建議
---
## 一、現有系統能力盤點
### ✅ 已具備的功能
#### 1. 會計科目系統(完整)
- **Model**: `ChartOfAccount`
- **資料表**: `chart_of_accounts` (已建立 55 個專業科目)
- **支援**: 5 種科目類型 (資產/負債/淨資產/收入/支出)
- **狀態**: ✅ **可直接使用**
#### 2. 財務憑證系統(功能完整)
- **Model**: `FinanceDocument`
- **核心功能**:
- 多層級審批流程 (出納 → 會計 → 理事長 → 理監事會)
- 金額分級 (小額 < 5,000 / 中額 < 50,000 / 大額 ≥ 50,000)
- 付款指令 (`PaymentOrder`)
- 付款核銷 (`PaymentVerification`)
- **狀態**: ✅ **功能完整,可直接使用**
#### 3. 出納簿系統(完整)
- **Model**: `CashierLedgerEntry`
- **功能**:
- 記錄每筆現金異動
- 計算前後餘額
- 支援銀行對帳
- **狀態**: ✅ **可直接使用**
#### 4. 銀行對帳系統
- **Model**: `BankReconciliation`
- **功能**: 匹配銀行交易與系統記錄
- **狀態**: ✅ **可用於驗證匯入資料**
#### 5. 預算管理系統
- **Model**: `Budget`, `BudgetCategory`
- **功能**: 年度預算編列與控管
- **狀態**: ✅ **可直接匯入 2025 預算**
#### 6. 資料匯入基礎設施
- **套件**: Laravel Excel (maatwebsite/excel v3.1) ✅ 已安裝
- **現有範例**:
- `ImportMembers` (會員匯入指令)
- `ImportDocuments` (文件匯入指令)
- **基礎功能**:
- CSV/Excel 讀取
- 資料驗證 (多層次)
- 批次處理 (updateOrCreate)
- 稽核日誌
- Queue 非同步支援
- **狀態**: ✅ **基礎架構完整**
---
## 二、系統缺口分析
### ⚠️ 關鍵缺口:會計分錄系統
#### 問題:目前沒有完整的複式簿記系統
**現況調查發現:**
1. **`Transaction` Model 採用簡化單式記帳**
```php
// 現有欄位
$table->decimal('amount', 15, 2);
$table->enum('transaction_type', ['income', 'expense']);
```
- ❌ 沒有「借方/貸方」概念
- ❌ 無法記錄複式分錄
- ❌ 無法自動平衡檢查
2. **測試程式碼顯示曾規劃複式簿記**
```php
// tests/Unit/FinanceDocumentTest.php 中有使用
'debit_amount' => 10000,
'credit_amount' => 10000,
```
但實際 `Transaction` Model **並沒有這些欄位**
3. **缺少的核心功能**
- ❌ 傳票/分錄表 (Journal Entry)
- ❌ 試算表 (Trial Balance)
- ❌ 總分類帳 (General Ledger)
- ❌ 財務報表產生器
---
### 🔍 具體缺口清單
#### 缺口 1沒有「會計分錄」資料表
**影響:**
- 無法正確記錄一筆交易的借貸雙方
- 無法產生標準會計報表
- Excel 資料無法轉換為標準會計格式
**需要:**
```php
// 需建立 AccountingEntry (會計分錄) Model
Schema::create('accounting_entries', function (Blueprint $table) {
$table->id();
$table->foreignId('finance_document_id')->constrained();
$table->foreignId('chart_of_account_id')->constrained();
$table->enum('entry_type', ['debit', 'credit']); // 借方/貸方
$table->decimal('amount', 15, 2);
$table->text('description')->nullable();
$table->timestamps();
});
```
#### 缺口 2沒有「總分類帳」功能
**影響:**
- 無法查詢單一科目的所有交易明細
- 無法產生科目餘額表
**需要:**
- 建立 `GeneralLedgerController`
- 提供科目別查詢功能
- 計算每個科目的借貸總額與餘額
#### 缺口 3沒有「試算表」產生器
**影響:**
- 無法驗證借貸平衡
- 資料正確性難以檢查
**需要:**
- 建立 `TrialBalanceController`
- 彙總所有科目的借貸總額
- 自動檢查借=貸
#### 缺口 4財務憑證未自動產生會計分錄
**影響:**
- 憑證與分錄脫節
- 需手動建立對應關係
**需要:**
- 在 `FinanceDocument` 建立時自動產生分錄
- 支援多借多貸分錄
#### 缺口 5沒有 Excel 帳務資料匯入功能
**影響:**
- 2024 年歷史帳務無法匯入
- 需手動逐筆輸入
**需要:**
- 建立 `ImportAccountingData` Command
- Excel 科目對照表 (44 → 55 科目)
- 自動產生財務憑證 + 會計分錄
---
## 三、Excel 資料 vs 系統科目對照
### 對照表設計
| Excel 科目 | Excel 名稱 | 系統科目 | 系統名稱 | 轉換邏輯 |
|-----------|-----------|---------|---------|---------|
| 1000 | 現金及約當現金 | 1101 | 現金 | 直接對應 |
| 1101 | 銀行存款 | 1201 | 銀行存款 | 直接對應 |
| 4100 | 一般捐款收入 | 4201 | 捐贈收入 | 直接對應 |
| 4310 | 入會費 | 4102 | 入會費收入 | 直接對應 |
| 5100 | 業務費用 | 5201-5215 | (多個) | **需分析摘要** |
### 5100 業務費用細分規則
Excel 中所有支出都記為「5100 業務費用」,需根據「支出用途備註」欄位判斷:
```php
// 建議對照規則
$mappingRules = [
'交通|車費|計程車' => '5206', // 旅運費
'會場|場地|清潔' => '5209', // 會議費
'點心|餐|便當' => '5209', // 會議費
'郵寄|郵資|郵票' => '5203', // 郵電費
'影印|列印|印刷' => '5205', // 印刷費
'文具|用品' => '5204', // 文具用品
'電話|網路|通訊' => '5203', // 郵電費
];
```
---
## 四、建議實作方案
### 🎯 方案 A完整複式簿記系統推薦
#### 優點:
- ✅ 符合會計準則
- ✅ 可產生標準財務報表
- ✅ 自動借貸平衡檢查
- ✅ 未來擴展性強
#### 需建立:
1. **AccountingEntry Model** (會計分錄)
2. **GeneralLedger 功能** (總分類帳)
3. **TrialBalance 功能** (試算表)
4. **自動分錄產生器**
5. **Excel 匯入功能**
#### 工作量:中等(約 3-5 天)
---
### 🎯 方案 B簡化匯入快速方案
#### 做法:
- 使用現有 `FinanceDocument` + `CashierLedgerEntry`
- Excel 資料轉為憑證
- 不建立完整分錄系統
#### 優點:
- ⚡ 快速1-2 天)
- ✅ 使用現有功能
#### 缺點:
- ❌ 沒有複式簿記
- ❌ 無法產生標準報表
- ❌ 借貸不平衡無法自動檢測
---
## 五、推薦實作步驟(方案 A
### 階段一:建立會計分錄系統 (1-2 天)
#### 步驟 1.1:建立 AccountingEntry Model
```bash
php artisan make:model AccountingEntry -m
```
**Migration 內容:**
```php
Schema::create('accounting_entries', function (Blueprint $table) {
$table->id();
$table->foreignId('finance_document_id')->constrained()->onDelete('cascade');
$table->foreignId('chart_of_account_id')->constrained();
$table->enum('entry_type', ['debit', 'credit']);
$table->decimal('amount', 15, 2);
$table->date('entry_date');
$table->text('description')->nullable();
$table->timestamps();
$table->index(['finance_document_id', 'entry_type']);
$table->index(['chart_of_account_id', 'entry_date']);
});
```
#### 步驟 1.2:修改 FinanceDocument Model
新增關聯:
```php
public function accountingEntries()
{
return $this->hasMany(AccountingEntry::class);
}
public function debitEntries()
{
return $this->accountingEntries()->where('entry_type', 'debit');
}
public function creditEntries()
{
return $this->accountingEntries()->where('entry_type', 'credit');
}
```
新增分錄產生器:
```php
public function generateAccountingEntries()
{
// 根據憑證類型自動產生借貸分錄
// 例如:收入憑證 → 借:現金,貸:收入
}
```
#### 步驟 1.3:建立驗證規則
```php
// 檢查借貸平衡
public function validateBalance()
{
$debitTotal = $this->debitEntries()->sum('amount');
$creditTotal = $this->creditEntries()->sum('amount');
return $debitTotal === $creditTotal;
}
```
---
### 階段二:建立總分類帳功能 (0.5 天)
#### 步驟 2.1:建立 GeneralLedgerController
```bash
php artisan make:controller Admin/GeneralLedgerController
```
#### 步驟 2.2:功能需求
- 查詢指定科目的所有分錄
- 計算科目餘額
- 支援日期範圍篩選
---
### 階段三:建立試算表功能 (0.5 天)
#### 步驟 3.1:建立 TrialBalanceController
```bash
php artisan make:controller Admin/TrialBalanceController
```
#### 步驟 3.2:產生試算表
```php
// 彙總所有科目
$accounts = ChartOfAccount::all();
foreach ($accounts as $account) {
$debitTotal = AccountingEntry::where('chart_of_account_id', $account->id)
->where('entry_type', 'debit')
->sum('amount');
$creditTotal = AccountingEntry::where('chart_of_account_id', $account->id)
->where('entry_type', 'credit')
->sum('amount');
// ...
}
```
---
### 階段四:建立 Excel 匯入功能 (1-2 天)
#### 步驟 4.1:建立匯入指令
```bash
php artisan make:command ImportAccountingData
```
#### 步驟 4.2:科目對照表
```php
// config/accounting_mapping.php
return [
'excel_to_system' => [
'1000' => '1101', // 現金及約當現金 → 現金
'1101' => '1201', // 銀行存款 → 銀行存款
'4100' => '4201', // 一般捐款 → 捐贈收入
'4310' => '4102', // 入會費 → 入會費收入
],
'expense_keywords' => [
['keywords' => ['交通', '車費'], 'account' => '5206'],
['keywords' => ['郵寄', '郵資'], 'account' => '5203'],
['keywords' => ['影印', '印刷'], 'account' => '5205'],
// ...
],
];
```
#### 步驟 4.3:匯入邏輯
**讀取 Excel「收入」工作表**
```php
// 來源2025 收入支出總表 (含會計科目編號).xlsx → 收入
$rows = Excel::toArray(new IncomesImport, $file)[0];
foreach ($rows as $row) {
// 1. 轉換科目代碼
$systemAccountCode = $mapping[$row['科目編號']] ?? null;
// 2. 建立財務憑證
$document = FinanceDocument::create([
'document_number' => $this->generateDocumentNumber($row['日期']),
'document_date' => $this->parseExcelDate($row['日期']),
'document_type' => 'income',
'amount' => $row['收入金額'],
'description' => $row['收入來源備註'],
]);
// 3. 自動產生會計分錄
// 借:現金
AccountingEntry::create([
'finance_document_id' => $document->id,
'chart_of_account_id' => ChartOfAccount::where('account_code', '1101')->first()->id,
'entry_type' => 'debit',
'amount' => $row['收入金額'],
'description' => '現金收入',
]);
// 貸:收入科目
AccountingEntry::create([
'finance_document_id' => $document->id,
'chart_of_account_id' => ChartOfAccount::where('account_code', $systemAccountCode)->first()->id,
'entry_type' => 'credit',
'amount' => $row['收入金額'],
'description' => $row['收入來源備註'],
]);
}
```
**讀取 Excel「支出」工作表**
```php
// 來源2025 收入支出總表 (含會計科目編號).xlsx → 支出
foreach ($rows as $row) {
// 1. 判斷支出科目(根據用途備註)
$expenseAccount = $this->matchExpenseAccount($row['支出用途備註']);
// 2. 建立財務憑證
$document = FinanceDocument::create([...]);
// 3. 自動產生會計分錄
// 借:費用科目
// 貸:現金
}
```
#### 步驟 4.4:匯入驗證
```php
// 匯入後檢查
$this->info('驗證借貸平衡...');
$unbalanced = FinanceDocument::whereHas('accountingEntries')
->get()
->filter(function ($doc) {
return !$doc->validateBalance();
});
if ($unbalanced->count() > 0) {
$this->error("發現 {$unbalanced->count()} 筆不平衡憑證!");
}
```
---
### 階段五UI 界面建立 (1 天)
#### 5.1 總分類帳頁面
- 路徑:`/admin/general-ledger`
- 功能:科目選擇、日期範圍、分錄列表、餘額計算
#### 5.2 試算表頁面
- 路徑:`/admin/trial-balance`
- 功能:所有科目餘額、借貸總計、平衡檢查
#### 5.3 匯入頁面
- 路徑:`/admin/accounting/import`
- 功能:上傳 Excel、預覽對照、執行匯入、查看報告
---
## 六、資料匯入檢查清單
### 匯入前準備
- [ ] 確認會計科目表已建立 (55 個科目)
- [ ] 建立 AccountingEntry 資料表
- [ ] 建立科目對照設定檔
- [ ] 準備 Excel 檔案 (3 個)
- [ ] 備份現有資料庫
### 匯入執行
- [ ] 執行收入資料匯入
- [ ] 執行支出資料匯入
- [ ] 執行預算資料匯入
- [ ] 檢查借貸平衡
- [ ] 驗證金額總計
### 匯入後驗證
- [ ] 總分類帳查詢測試
- [ ] 試算表產生測試
- [ ] 與 Excel 原始資料核對
- [ ] 產生匯入報告
---
## 七、預期成果
### 完成後可實現:
1. **完整的複式簿記系統**
- 每筆交易都有借貸分錄
- 自動平衡檢查
- 符合會計準則
2. **Excel 資料完整匯入**
- 2024 年收入 79,000 元
- 2024 年支出明細
- 2025 年預算規劃
3. **標準會計報表**
- 總分類帳
- 試算表
- 為未來財務報表奠定基礎
4. **資料追溯性**
- 每筆分錄連結到財務憑證
- 稽核日誌記錄
- 可追蹤資料來源
---
## 八、時程估算
| 階段 | 工作項目 | 預估時間 |
|-----|---------|---------|
| 1 | 建立會計分錄系統 | 1-2 天 |
| 2 | 總分類帳功能 | 0.5 天 |
| 3 | 試算表功能 | 0.5 天 |
| 4 | Excel 匯入功能 | 1-2 天 |
| 5 | UI 界面建立 | 1 天 |
| **總計** | | **4-6 天** |
---
## 九、建議優先順序
### 🔥 高優先級(立即執行)
1. ✅ 會計科目表已建立(完成)
2. ⭐ 建立 AccountingEntry Model 和資料表
3. ⭐ 建立基本的分錄產生邏輯
### 📊 中優先級(本週完成)
4. 建立 Excel 匯入功能
5. 建立總分類帳查詢
6. 建立試算表產生器
### 📈 低優先級(未來擴展)
7. 財務報表產生器(資產負債表、收支表)
8. 圖表視覺化
9. 預算執行率分析
---
## 十、結論
### 現況總結:
- ✅ **基礎架構完整**:財務憑證、出納簿、銀行對帳系統都已建立
- ✅ **會計科目齊全**55 個專業科目已匯入
- ⚠️ **缺少複式簿記**:這是最關鍵的缺口
- ✅ **匯入基礎存在**Laravel Excel 已安裝,有參考範例
### 建議方向:
**採用方案 A完整複式簿記系統**,理由:
1. 一次做對,避免日後重構
2. 符合會計準則,產出專業報表
3. 工作量可控4-6 天)
4. 為未來功能打好基礎
### 下一步:
需要你確認是否採用此方案,我將開始:
1. 建立 `AccountingEntry` Model 和 Migration
2. 修改 `FinanceDocument` Model 加入分錄產生邏輯
3. 建立 Excel 匯入指令
**準備好開始實作了嗎?**