docs: add disbursement plan research design spec

This commit is contained in:
Nut.ไปเรื่อย
2026-06-17 12:04:26 +07:00
parent 4e51959fa6
commit 5a94f2481f
@@ -0,0 +1,132 @@
# Design: แผนการเบิกจ่ายเป็นงวด (Research Disbursement Plan)
**Date:** 2026-06-17
**Page:** `http://localhost:4200/app/agency-report-research` (typeUrl=27)
**Approved by:** User
---
## 1. Summary
เพิ่มฟีเจอร์ "แผนการเบิกจ่ายเป็นงวด" ให้กับหน้า `agency-report-research` โดยมีปุ่มไอคอนต่อแต่ละโครงการในตาราง list20-research เมื่อกดจะเปิด MatDialog popup สำหรับกรอก/แก้ไขแผนการเบิกจ่าย 3 งวด พร้อมบันทึกลง DB ผ่าน API เดิม
---
## 2. Data Model
### 2.1 Backend — เพิ่ม 6 field ใน `change_project_research_detail`
| Field | Type | Description |
|-------|------|-------------|
| `disbursement_1_amount` | `decimal?` | จำนวนเงิน งวดที่ 1 |
| `disbursement_1_date` | `DateTime?` | ว/ด/ป งวดที่ 1 |
| `disbursement_2_amount` | `decimal?` | จำนวนเงิน งวดที่ 2 |
| `disbursement_2_date` | `DateTime?` | ว/ด/ป งวดที่ 2 |
| `disbursement_last_amount` | `decimal?` | จำนวนเงิน งวดสุดท้าย |
| `disbursement_last_date` | `DateTime?` | ว/ด/ป งวดสุดท้าย |
**ทำไม:** เก็บข้อมูลบน record เดิม ไม่ต้องสร้างตารางใหม่ ข้อมูลต่อโครงการมีเพียง 1 ชุด (3 งวด)
**หมายเหตุ:** `รวมเบิกจ่ายทั้งสิ้น` คำนวณใน frontend (sum ของ 3 amount) ไม่เก็บใน DB
### 2.2 Migration
ไฟล์: `Migrations/YYYYMMDDHHMMSS_disbursement_plan_research.cs`
- `AddColumn` ทั้ง 6 field ใน table `change_project_research_detail` schema `BUDGET`
---
## 3. Architecture
### 3.1 Backend (ASP.NET Core)
- **ไม่ต้องสร้าง controller ใหม่** — `t_change_project_research_detail` มี `[GeneratedUidController]` อยู่แล้ว
- เพิ่ม field ในโมเดล → migration → deploy
- PUT endpoint เดิม `/api/request_budget/change_project_research_detail/{uid}` รองรับ field ใหม่โดยอัตโนมัติ
### 3.2 Frontend (Angular)
```
list20-research component
└─ เพิ่ม Output: onDisbursementPlan (EventEmitter)
└─ เพิ่มคอลัมน์ "แผนเบิกจ่าย" + ปุ่มไอคอน
request-budget-statistics.container
└─ handle onDisbursementPlan → เปิด MatDialog
DisbursementPlanResearchDialogComponent (ใหม่)
├─ Input: data (change_project_research_detail row)
├─ Form: disbursement_1_amount, disbursement_1_date, disbursement_2_amount, disbursement_2_date, disbursement_last_amount, disbursement_last_date
├─ Computed: total = sum(amounts)
└─ Save: PUT via ChangeProjectResearchDetailService
```
---
## 4. UI Design
### 4.1 ตาราง list20-research — คอลัมน์เพิ่มใหม่
| คอลัมน์ | เนื้อหา |
|---------|---------|
| แผนเบิกจ่าย | badge "✓ กรอกแล้ว" (สีเขียว) ถ้า disbursement_1_amount ไม่ null, badge "ยังไม่กรอก" (สีเทา) ถ้ายังไม่มีข้อมูล |
| เครื่องมือ | เพิ่มปุ่มไอคอนเงิน (💰) ก่อนปุ่ม edit — สีเขียวเข้มถ้ากรอกแล้ว, สีเขียวอ่อนถ้ายังไม่กรอก |
### 4.2 Dialog — ตาราง
```
┌─────────────────────────────────────────────┬──────────────────┐
│ แผนการเบิกจ่ายเงิน │ รวมเบิกจ่าย │
├──────────────┬──────────────┬───────────────┤ ทั้งสิ้น (บาท) │
│ งวดที่ 1 │ งวดที่ 2 │ งวดสุดท้าย │ │
├──────┬───────┼──────┬───────┼──────┬────────┤ │
│ จำนวน│ ว/ด/ป │ จำนวน│ ว/ด/ป │ จำนวน│ ว/ด/ป │ [คำนวณอัตโนมัติ] │
│ เงิน │ │ เงิน │ │ เงิน │ │ │
├──────┼───────┼──────┼───────┼──────┼────────┼──────────────────┤
│ input│ date │ input│ date │ input│ date │ readonly computed │
└──────┴───────┴──────┴───────┴──────┴────────┴──────────────────┘
```
- Input จำนวนเงิน: ใช้ `appCurrencyInputMask` (pattern เดิมในโปรเจกต์)
- Input วันที่: `mat-datepicker`
- รวม: คำนวณ real-time ด้วย getter
### 4.3 Actions
- **บันทึก**: confirmSave → PUT detail → updateSuccess → close dialog → reload list
- **ยกเลิก**: ปิด dialog ไม่บันทึก
---
## 5. Files to Create/Modify
### Backend
| File | Action |
|------|--------|
| `Modules/RequestBudgets/Databases/Models/change_project_research_detail.cs` | เพิ่ม 6 field |
| `Migrations/YYYYMMDDHHMMSS_disbursement_plan_research.cs` | สร้างใหม่ |
### Frontend
| File | Action |
|------|--------|
| `presenter/popup/disbursement-plan-research-dialog/disbursement-plan-research-dialog.component.ts` | สร้างใหม่ |
| `presenter/popup/disbursement-plan-research-dialog/disbursement-plan-research-dialog.component.html` | สร้างใหม่ |
| `presenter/popup/disbursement-plan-research-dialog/disbursement-plan-research-dialog.component.scss` | สร้างใหม่ |
| `presenter/list/.../list20-research/list20-research.component.html` | เพิ่มคอลัมน์ + ปุ่ม |
| `presenter/list/.../list20-research/list20-research.component.ts` | เพิ่ม Output onDisbursementPlan |
| `container/.../request-budget-statistics.container.ts` | handle event + เปิด dialog |
| `request-budget-statistics.module.ts` | ลงทะเบียน component ใหม่ |
---
## 6. Error Handling
- ถ้า save ล้มเหลว: แสดง `swSV.errText(err?.error?.description)`
- Dialog ใช้ `ChangeDetectionStrategy.OnPush` + `cdRef.detectChanges()` ตาม pattern เดิม
---
## 7. Out of Scope
- ไม่สร้างหน้าแยก (ใช้ dialog แทน)
- ไม่รองรับหลายชุดแผนต่อโครงการ (1 โครงการ = 1 แผน)
- ไม่เพิ่ม column ใน list view (แสดงเฉพาะใน dialog)