docs: add disbursement plan research design spec
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user