270 lines
7.2 KiB
Markdown
270 lines
7.2 KiB
Markdown
# DAC_領據.SelectSummary 彙整邏輯 - 完成報告
|
|
|
|
## 概述
|
|
|
|
已成功完成 `DAC_領據.SelectSummary` 方法中的**彙整邏輯**。該方法負責將領據、勞務費、差旅費和付款設定資料進行分組彙總,生成個人費用彙整表。
|
|
|
|
## 完成的工作
|
|
|
|
### 1. 資料模型定義 ✅
|
|
|
|
在 `DAC\領據系統\DAC_領據2.cs` 中定義了完整的資料模型:
|
|
|
|
**`個人費用彙整表List` 類別**
|
|
- 繼承自 `List<個人費用彙整表Item>`
|
|
- 實現 `IDataList` 介面
|
|
- 支援 ORM 資料填充
|
|
|
|
**`個人費用彙整表Item` 類別**
|
|
```csharp
|
|
public partial class 個人費用彙整表Item
|
|
{
|
|
// 內部欄位 (查詢用)
|
|
public string 講師_非講師編號 { get; set; }
|
|
public DateTime? 活動日期 { get; set; }
|
|
|
|
// 顯示欄位
|
|
public string 領款人姓名 { get; set; }
|
|
public string 身分證字號 { get; set; }
|
|
public decimal 堂數 { get; set; } // 已彙總
|
|
public decimal 付款金額 { get; set; } // 已彙總
|
|
public string 扣繳類別 { get; set; }
|
|
public string 扣繳類別名稱 { get; set; }
|
|
public string 帳戶名 { get; set; }
|
|
public string 匯款帳號 { get; set; }
|
|
public string 銀行分行代碼 { get; set; }
|
|
public string 銀行分行 { get; set; }
|
|
}
|
|
```
|
|
|
|
### 2. SelectSummary 方法完成 ✅
|
|
|
|
**方法簽名**
|
|
```csharp
|
|
public 個人費用彙整表List SelectSummary(
|
|
bool noInputReturnAll,
|
|
int startRowIndex,
|
|
int maximumRows,
|
|
DateTime? 起日,
|
|
DateTime? 迄日,
|
|
string 身分別,
|
|
string 付款方式)
|
|
```
|
|
|
|
**實現流程**
|
|
|
|
#### 步驟 1: 基本資料查詢
|
|
- 從 `領據` 表查詢基本資訊
|
|
- 左 JOIN `勞務費` 表(取得堂數和金額)
|
|
- 左 JOIN `差旅費` 表(取得差旅費用)
|
|
- 支援日期和身分別、付款方式篩選
|
|
|
|
#### 步驟 2: 加入付款設定資料
|
|
```csharp
|
|
var dao付款設定 = new DAC_付款設定(conn);
|
|
foreach (var r in tempData)
|
|
{
|
|
var paymentSetting = dao付款設定.SelectRecentlyActivated(r.講師_非講師編號, r.活動日期);
|
|
if (paymentSetting != null)
|
|
{
|
|
r.扣繳類別 = 扣繳類別.GetActuralValue(paymentSetting.扣繳類別);
|
|
r.扣繳類別名稱 = 扣繳類別.GetName(paymentSetting.扣繳類別);
|
|
r.帳戶名 = paymentSetting.匯款戶名;
|
|
r.匯款帳號 = paymentSetting.匯款帳號;
|
|
r.銀行分行代碼 = paymentSetting.銀行分行代碼;
|
|
r.銀行分行 = paymentSetting.銀行分行;
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 步驟 3: 彙整聚合 ✨
|
|
```csharp
|
|
// 按照 (領款人姓名、身分證字號、扣繳類別、帳戶名、匯款帳號、銀行分行代碼) 分組
|
|
var groupedData = tempData.GroupBy(x => new
|
|
{
|
|
x.領款人姓名,
|
|
x.身分證字號,
|
|
x.扣繳類別,
|
|
x.帳戶名,
|
|
x.匯款帳號,
|
|
x.銀行分行代碼,
|
|
x.銀行分行
|
|
});
|
|
|
|
// 彙總堂數和付款金額
|
|
foreach (var group in groupedData)
|
|
{
|
|
var summaryItem = new 個人費用彙整表Item
|
|
{
|
|
領款人姓名 = group.Key.領款人姓名,
|
|
身分證字號 = group.Key.身分證字號,
|
|
扣繳類別 = group.Key.扣繳類別,
|
|
帳戶名 = group.Key.帳戶名,
|
|
匯款帳號 = group.Key.匯款帳號,
|
|
銀行分行代碼 = group.Key.銀行分行代碼,
|
|
銀行分行 = group.Key.銀行分行,
|
|
// 核心彙總邏輯
|
|
堂數 = group.Sum(x => x.堂數),
|
|
付款金額 = group.Sum(x => x.付款金額)
|
|
};
|
|
result.Add(summaryItem);
|
|
}
|
|
```
|
|
|
|
### 3. WebService 整合 ✅
|
|
|
|
在 `Services\領據處理.asmx.cs` 的 `SearchSummaryTable` 方法中呼叫 DAC 層:
|
|
|
|
```csharp
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
var dao領據 = new DAC_領據(conn);
|
|
var summaryData = dao領據.SelectSummary(
|
|
true, // noInputReturnAll
|
|
0, // startRowIndex
|
|
int.MaxValue, // maximumRows
|
|
startDate, // 起日
|
|
endDate, // 迄日
|
|
身分別,
|
|
付款方式
|
|
);
|
|
|
|
if (輸出方式 == "DATA")
|
|
{
|
|
if (summaryData.Count > 0)
|
|
return ServiceResponse.CreateSuccess("查詢成功", summaryData);
|
|
else
|
|
return ServiceResponse.CreateError("查不到相關資料");
|
|
}
|
|
else // EXPORT
|
|
{
|
|
// TODO: Excel 匯出邏輯
|
|
var excelResult = new
|
|
{
|
|
excelData = "",
|
|
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
|
};
|
|
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📊 資料流程圖
|
|
|
|
```
|
|
領據表
|
|
↓ (LEFT JOIN 勞務費)
|
|
↓ (LEFT JOIN 差旅費)
|
|
↓ 過濾條件 (日期、身分別、付款方式)
|
|
↓
|
|
臨時資料集合 tempData
|
|
↓ 迴圈逐筆加入付款設定資料
|
|
↓
|
|
加入扣繳類別、帳戶名、匯款帳號、銀行資訊
|
|
↓
|
|
按照彙整鍵值分組
|
|
↓
|
|
彙總:
|
|
- 堂數加總 (SUM)
|
|
- 付款金額加總 (SUM)
|
|
↓
|
|
個人費用彙整表 (彙整後結果)
|
|
```
|
|
|
|
## 🔑 彙整鍵值
|
|
|
|
以下欄位組合作為彙整的唯一鍵值:
|
|
1. `領款人姓名`
|
|
2. `身分證字號`
|
|
3. `扣繳類別`
|
|
4. `帳戶名`
|
|
5. `匯款帳號`
|
|
6. `銀行分行代碼`
|
|
7. `銀行分行`
|
|
|
|
**邏輯說明**:同一個講師或非講師,如果有多筆領據且:
|
|
- 相同的身分證字號
|
|
- 相同的扣繳類別
|
|
- 相同的付款帳戶資訊
|
|
|
|
則會被合併為一筆記錄,堂數和付款金額會累加。
|
|
|
|
## 💾 程式碼統計
|
|
|
|
| 項目 | 數量 |
|
|
|------|------|
|
|
| 新增類別 | 2 個 (List + Item) |
|
|
| 實現方法 | 1 個 (SelectSummary) |
|
|
| 程式碼行數 | ~60 行 |
|
|
| 編譯狀態 | ✅ 成功 |
|
|
|
|
## 🧪 測試檢查清單
|
|
|
|
### 單元測試
|
|
- [ ] 無條件查詢 (返回所有資料)
|
|
- [ ] 日期範圍查詢 (起日、迄日)
|
|
- [ ] 身分別篩選 (講師/非講師)
|
|
- [ ] 付款方式篩選
|
|
- [ ] 多條件組合查詢
|
|
- [ ] 無符合資料情況
|
|
|
|
### 功能測試
|
|
- [ ] 驗證彙整結果正確性
|
|
- [ ] 檢查堂數加總是否正確
|
|
- [ ] 檢查付款金額加總是否正確
|
|
- [ ] 驗證付款設定資料正確加入
|
|
- [ ] 確認無重複資料
|
|
|
|
### 效能測試
|
|
- [ ] 大量資料查詢性能
|
|
- [ ] 分組彙整效率
|
|
- [ ] 記憶體使用情況
|
|
|
|
## 🚀 後續步驟
|
|
|
|
### 1. Excel 匯出實現 ⏳
|
|
在 `SearchSummaryTable` 方法的 EXPORT 部分實現:
|
|
- 生成 Excel 檔案
|
|
- 設置欄位格式和寬度
|
|
- Base64 編碼
|
|
- 返回可下載的檔案
|
|
|
|
### 2. 前端整合驗證 ⏳
|
|
- 測試查詢功能
|
|
- 驗證表格顯示
|
|
- 測試匯出功能
|
|
- 檢查效能
|
|
|
|
### 3. 資料庫優化 (可選)
|
|
- 為常查詢欄位添加索引
|
|
- 考慮物化視圖加速查詢
|
|
- 分析查詢執行計劃
|
|
|
|
## 📝 注意事項
|
|
|
|
1. **付款設定查詢**
|
|
- 使用 `SelectRecentlyActivated` 方法
|
|
- 根據活動日期選取生效的設定
|
|
|
|
2. **分組邏輯**
|
|
- 使用 LINQ GroupBy 進行彙整
|
|
- 堂數和付款金額使用 SUM 聚合
|
|
|
|
3. **空值處理**
|
|
- 左 JOIN 可能導致 NULL 值
|
|
- 已在 SQL 中使用 ISNULL 處理
|
|
|
|
4. **效能考量**
|
|
- 當前採用記憶體彙整(GroupBy)
|
|
- 大量資料時可考慮移到 SQL 實現
|
|
|
|
## ✅ 建置狀態
|
|
|
|
✅ **項目成功構建,無編譯錯誤**
|
|
|
|
---
|
|
|
|
**完成日期:** 2024年
|
|
**實施狀態:** 彙整邏輯完成,待 Excel 匯出實現
|
|
**下一里程碑:** Excel 匯出功能
|