7.5 KiB
7.5 KiB
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 ใน tablechange_project_research_detailschemaBUDGET
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)