Files
rmutr/docs/superpowers/specs/2026-06-17-disbursement-plan-research-design.md
T
2026-06-17 12:04:26 +07:00

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 ใน 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)