diff --git a/construction-installment-calculator/index.html b/construction-installment-calculator/index.html index 84cc542..2ca1e18 100644 --- a/construction-installment-calculator/index.html +++ b/construction-installment-calculator/index.html @@ -4,7 +4,7 @@ คำนวณงวดงานสิ่งก่อสร้าง - + + + + +

🔍 Preview: แผนการเบิกจ่ายเป็นงวด

+

ตัวอย่างการแสดงผลใน Angular — ไอคอน 💰 ในตารางรายโครงการ และ dialog form

+ + +
📋 ตารางรายโครงการ (list20-research) — มีไอคอน 💰 ต่อโครงการ
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ลำดับปีงบชื่อโครงการหน่วยงานแหล่งเงินงบประมาณแผนเบิกจ่ายเครื่องมือ
12567โครงการพัฒนาคุณภาพการศึกษาด้านวิทยาศาสตร์คณะวิศวกรรมศาสตร์กองทุนพัฒนา95,000 + ✓ กรอกแล้ว + + + +
22567โครงการวิจัยนวัตกรรมดิจิทัลคณะเทคโนโลยีสารสนเทศงบประมาณแผ่นดิน150,000 + ยังไม่กรอก + + + +
+
+ + + + + +
✅ หลังบันทึก — ข้อมูลที่กรอกจะแสดงใน tooltip หรือ badge
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ชื่อโครงการงวด 1ว/ด/ปงวด 2ว/ด/ปงวดสุดท้ายว/ด/ปรวมเบิกจ่าย
โครงการพัฒนาคุณภาพการศึกษาฯ66,50015/11/256719,00020/01/25689,50030/03/256895,000
+
+ + + + diff --git a/docs/superpowers/plans/2026-06-04-budget-type-select-menu.md b/docs/superpowers/plans/2026-06-04-budget-type-select-menu.md new file mode 100644 index 0000000..01a869b --- /dev/null +++ b/docs/superpowers/plans/2026-06-04-budget-type-select-menu.md @@ -0,0 +1,456 @@ +# Budget Type Select Menu Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** แยก 3 ปุ่ม dropdown (งบลงทุน / งบเงินอุดหนุน / งบรายจ่ายอื่น) ออกจาก search component ไปเป็นหน้าเลือกประเภทงบประมาณใหม่ที่ route `app/request-budget/select` ออกแบบตาม design ที่กำหนด + +**Architecture:** สร้าง `BudgetTypeSelectComponent` ใหม่เป็น child route ใน `RequestBudgetModule` ที่ path `select` — component นี้เป็น presenter ล้วนๆ ไม่มี API call, ทำหน้าที่แสดง 3 card พร้อม sub-item แล้ว navigate ไปยัง route เดิมที่ 3 ปุ่มเดิมชี้อยู่ จากนั้นแทนที่ 3 ปุ่มใน search component ด้วยปุ่มเดียว + +**Tech Stack:** Angular 13+, Angular Material (mat-button, mat-icon), Tailwind CSS, TypeScript + +--- + +## File Structure + +| Action | Path | +|--------|------| +| **Create** | `rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/budget-type-select.component.ts` | +| **Create** | `rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/budget-type-select.component.html` | +| **Create** | `rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/budget-type-select.component.scss` | +| **Modify** | `rmutr-web/src/app/feature/budget-request/request-budget/request-budget.module.ts` | +| **Modify** | `rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.html` (lines 86–118) | +| **Modify** | `rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.ts` | + +--- + +### Task 1: Create BudgetTypeSelectComponent (TypeScript) + +**Files:** +- Create: `rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/budget-type-select.component.ts` + +- [ ] **Step 1: สร้างไฟล์ component TypeScript** + +```typescript +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { Router } from '@angular/router'; +import { RequestPlanUidService } from 'src/app/core/service/request-budget/request-plan-uid.service'; + +@Component({ + selector: 'app-budget-type-select', + templateUrl: './budget-type-select.component.html', + styleUrls: ['./budget-type-select.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class BudgetTypeSelectComponent { + + constructor( + private router: Router, + private requestPlanUidSV: RequestPlanUidService, + ) {} + + goBack() { + this.router.navigate(['app/request-budget']); + } + + // งบลงทุน + add_invest_asset() { + this.router.navigate(['app/durable-articles-manage']); + } + + add_invest() { + this.router.navigate(['app/invest-construct-manage']); + } + + // งบเงินอุดหนุน + add_request_actualize() { + this.router.navigate(['app/request-actualize']); + } + + add() { + this.router.navigate(['app/menu-icon']); + } + + addrequest7() { + this.requestPlanUidSV.request_budget_type$.next('944e7cec-d666-447f-8809-bb13d21f2ca4'); + this.router.navigate(['app/request-budget-list']); + } + + // งบรายจ่ายอื่น + add_request_other_expenses() { + this.router.navigate(['app/request-other-expenses/add']); + } + + add2() { + this.router.navigate(['app/menu-icon-2']); + } +} +``` + +- [ ] **Step 2: สร้างไฟล์ SCSS (ว่างไว้ก่อน)** + +สร้างไฟล์ `budget-type-select.component.scss` เนื้อหาว่างเปล่า (ใช้ Tailwind ทั้งหมด) + +```scss +``` + +--- + +### Task 2: Create BudgetTypeSelectComponent (HTML Template) + +**Files:** +- Create: `rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/budget-type-select.component.html` + +Design จากรูปภาพ: +- พื้นหลังสีครีม `bg-gray-50` +- Header มีปุ่ม back + title + subtitle +- Section title + คำอธิบาย + hint ขวา +- 3 card แบบ flex row: งบลงทุน(แดง), งบเงินอุดหนุน(น้ำเงิน), งบรายจ่ายอื่น(ม่วง) +- แต่ละ card: icon + ชื่อ + คำอธิบาย + sub-item list + +- [ ] **Step 3: สร้าง HTML template** + +```html +
+ + +
+ +
+

จัดทำคำของบประมาณแผ่นดิน

+

คำของบประมาณแผ่นดิน

+
+
+ + +
+
+

เลือกประเภทคำของบประมาณ

+

เลือกหมวดงบและประเภทย่อยเพื่อเริ่มจัดทำรายการคำของบประมาณ

+
+
+ auto_awesome + เลือกได้ในที่เดียว ไม่ต้องเปิดเมนูซ้อน +
+
+ + +
+ + +
+ +
+
+ domain +
+
+

งบลงทุน

+

ครุภัณฑ์ · ที่ดินและสิ่งก่อสร้าง

+
+
+ + +

เลือกประเภทย่อย

+ + + + + + +
+ + +
+ +
+
+ pool +
+
+

งบเงินอุดหนุน

+

ดำเนินงาน · โครงการ · อื่น ๆ

+
+
+ + +

เลือกประเภทย่อย

+ + + + + + + + + +
+ + +
+ +
+
+ card_giftcard +
+
+

งบรายจ่ายอื่น

+

ดำเนินงาน · โครงการ

+
+
+ + +

เลือกประเภทย่อย

+ + + + + + +
+ +
+
+``` + +--- + +### Task 3: Register Component in Module + Add Child Route + +**Files:** +- Modify: `rmutr-web/src/app/feature/budget-request/request-budget/request-budget.module.ts` + +- [ ] **Step 4: เพิ่ม import + declaration + route** + +เปิดไฟล์ `request-budget.module.ts` แล้วแก้ไขดังนี้: + +```typescript +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RequestBudgetContainer } from './container/request-budget/request-budget.container'; +import { RequestBudgetListComponent } from './presenter/list/request-budget-list/request-budget-list.component'; +import { RequestBudgetRouterComponent } from './router/request-budget-router/request-budget-router.component'; +import { Routes, RouterModule } from '@angular/router'; +import { SharedModule } from 'src/app/shared/shared.module'; +import { RequestBudgetSearchComponent } from './presenter/search/request-budget-search/request-budget-search.component'; +import { BudgetTypeSelectComponent } from './presenter/budget-type-select/budget-type-select.component'; // NEW +import { TotalFootShowPipe } from './presenter/pipe/total-foot-table-show.pipe'; +import { TotalInvestShowPipe } from './presenter/pipe/total-invest-show.pipe copy'; +import { TotalRequestTopicShowPipe } from './presenter/pipe/total-request-topic-show.pipe2'; +import { TotalPlanInvestShowPipe } from './presenter/pipe/total-plan-invest-table-show.pipe'; +import { TotalPlanRequestShowPipe } from './presenter/pipe/total-plan-request-table-show.pipe'; +import { TotalPlanShowPipe } from './presenter/pipe/total-plan-table-show.pipe'; +import { TotalBudgetShowPipe } from './presenter/pipe/total-budget-show.pipe'; +import { TotalProgressPipe } from './presenter/pipe/total-progress.pipe copy'; +import { TotalHeadInvestShowPipe } from './presenter/pipe/total-head-invest-table-show.pipe'; + +const routes: Routes = [ + { + path: '', + component: RequestBudgetRouterComponent, + children: [ + { + path: '', + component: RequestBudgetContainer + }, + { + path: 'select', // NEW — หน้าเลือกประเภทงบ + component: BudgetTypeSelectComponent + }, + ] + } +] + +@NgModule({ + declarations: [ + RequestBudgetContainer, + RequestBudgetRouterComponent, + RequestBudgetListComponent, + RequestBudgetSearchComponent, + BudgetTypeSelectComponent, // NEW + TotalFootShowPipe, + TotalInvestShowPipe, + TotalRequestTopicShowPipe, + TotalPlanRequestShowPipe, + TotalPlanInvestShowPipe, + TotalPlanShowPipe, + TotalBudgetShowPipe, + TotalProgressPipe, + TotalHeadInvestShowPipe + ], + imports: [ + CommonModule, + SharedModule, + RouterModule.forChild(routes), + ] +}) +export class RequestBudgetModule { } +``` + +--- + +### Task 4: Replace 3 Buttons in Search Component + +**Files:** +- Modify: `rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.html` (lines 86–118) +- Modify: `rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.ts` + +- [ ] **Step 5: แทนที่ 3 ปุ่มใน search component HTML** + +แทนที่บรรทัด 86–118 ใน `request-budget-search.component.html`: + +**เดิม (ลบออก):** +```html +
+ + + + + +    + + + + + + +    + + + + + + +
+``` + +**ใหม่ (ใส่แทน):** +```html +
+ +
+``` + +- [ ] **Step 6: เพิ่ม method ใน search component TS** + +เปิดไฟล์ `request-budget-search.component.ts` แล้วเพิ่ม method `openBudgetTypeSelect()` ต่อท้าย method `add_request_other_expenses()` (ก่อนปิด class): + +```typescript + openBudgetTypeSelect() { + this.router.navigate(['app/request-budget/select']); + } +``` + +> **หมายเหตุ:** methods เดิม (add, add2, add_invest_asset, add_invest, addrequest7, add_request_actualize, add_request_other_expenses) ไม่ต้องลบออก เผื่อยังมีที่อื่นเรียกใช้ + +- [ ] **Step 7: ตรวจสอบ Angular dev server compile ไม่มี error** + +เปิด terminal แล้วดู log ที่ `/tmp/rmutr-web.log` — ต้องไม่มีบรรทัดที่ขึ้นต้นด้วย `ERROR` + +- [ ] **Step 8: เปิด browser ที่ `http://localhost:4200/app/request-budget`** + +ตรวจสอบ: +1. ปุ่ม "จัดทำคำของบประมาณ" ปรากฏแทนที่ 3 ปุ่มเดิม +2. กดปุ่มแล้ว navigate ไปที่ `/app/request-budget/select` +3. หน้า select แสดง 3 card ครบถ้วน (งบลงทุน, งบเงินอุดหนุน, งบรายจ่ายอื่น) +4. กด back arrow กลับมาหน้า list ได้ +5. กด sub-item ใดก็ navigate ไปยัง route ที่ถูกต้อง + +- [ ] **Step 9: Commit** + +```bash +git add rmutr-web/src/app/feature/budget-request/request-budget/presenter/budget-type-select/ +git add rmutr-web/src/app/feature/budget-request/request-budget/request-budget.module.ts +git add rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.html +git add rmutr-web/src/app/feature/budget-request/request-budget/presenter/search/request-budget-search/request-budget-search.component.ts +git commit -m "feat: add budget-type-select menu page, replace 3 dropdown buttons" +``` + +--- + +## Self-Review Checklist + +- [x] **Spec coverage:** 3 ปุ่มถูกแยกออก ✓ | หน้าใหม่ออกแบบตาม design image ✓ | back button ✓ | sub-item navigation ครบ 7 รายการ ✓ +- [x] **No placeholders:** ทุก step มี code จริง ✓ +- [x] **Type consistency:** `BudgetTypeSelectComponent` ใช้ชื่อเดียวกันในทุก task ✓ | route path `select` ตรงกัน ✓ | method names ตรงกับ `RequestPlanUidService` ✓ +- [x] **`addrequest7` ใช้ `RequestPlanUidService`** — inject ใน Task 1 และใช้ใน method ✓ +- [x] **`RequestBudgetRouterComponent` มี ``** — child route `select` จะทำงานได้ ✓ diff --git a/schedule-table-prototype.html b/schedule-table-prototype.html new file mode 100644 index 0000000..7473e69 --- /dev/null +++ b/schedule-table-prototype.html @@ -0,0 +1,458 @@ + + + + + +25. ตารางกำหนดการดำเนินโครงการ — Prototype + + + + +
+ +
+ 25. ตารางกำหนดการดำเนินโครงการ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + diff --git a/sync_budget_come_from.sql b/sync_budget_come_from.sql new file mode 100644 index 0000000..acb1e98 --- /dev/null +++ b/sync_budget_come_from.sql @@ -0,0 +1,53 @@ +-- Sync budget_come_from = result for all affected tables +-- Run this script when DB connection is restored + +-- 1. analysis_5 status_id=1,2,3 (non-research, แผ่นดิน) +UPDATE "BUDGET"."request_budget_analysis_5" a5 +SET budget_come_from = rbs3.result +FROM "BUDGET"."request_budget" rb3 +JOIN "BUDGET"."request_budget_summarize" rbs3 ON rbs3.request_budget_uid = rb3.request_budget_uid +WHERE rb3.status_id = 3 + AND rb3.project_name_th = a5.project_name_th + AND a5.api = 'request_budget' + AND a5.status_id IN (1,2,3) + AND COALESCE(a5.budget_come_from,'') != COALESCE(rbs3.result,''); + +-- 2. analysis_5 status_id=1,2,3 (non-research, รายได้) +UPDATE "BUDGET"."request_budget_analysis_5" a5 +SET budget_come_from = rbs3.result +FROM "BUDGET"."request_budget_income" rb3 +JOIN "BUDGET"."request_budget_income_summarize" rbs3 ON rbs3.request_budget_income_uid = rb3.request_budget_income_uid +WHERE rb3.status_id = 3 + AND rb3.project_name_th = a5.project_name_th + AND a5.api = 'request_budget_income' + AND a5.status_id IN (1,2,3) + AND COALESCE(a5.budget_come_from,'') != COALESCE(rbs3.result,''); + +-- 3. analysis_5_research (via project_name_th join) +UPDATE "BUDGET"."request_budget_analysis_5_research" a5r +SET budget_come_from = rbs3.result +FROM "BUDGET"."request_budget" rb3 +JOIN "BUDGET"."request_budget_summarize" rbs3 ON rbs3.request_budget_uid = rb3.request_budget_uid +WHERE rb3.status_id = 3 + AND rb3.project_name_th = a5r.project_name_th + AND COALESCE(a5r.budget_come_from,'') != COALESCE(rbs3.result,''); + +-- 4. change_project_detail (แผ่นดิน) +UPDATE "BUDGET"."change_project_detail" cpd +SET budget_come_from = rbs3.result +FROM "BUDGET"."request_budget" rb3 +JOIN "BUDGET"."request_budget_summarize" rbs3 ON rbs3.request_budget_uid = rb3.request_budget_uid +WHERE rb3.status_id = 3 + AND rb3.project_name_th = cpd.project_name_th + AND (cpd.api = 'request_budget' OR cpd.api IS NULL) + AND COALESCE(cpd.budget_come_from,'') != COALESCE(rbs3.result,''); + +-- 5. change_project_detail (รายได้) +UPDATE "BUDGET"."change_project_detail" cpd +SET budget_come_from = rbs3.result +FROM "BUDGET"."request_budget_income" rb3 +JOIN "BUDGET"."request_budget_income_summarize" rbs3 ON rbs3.request_budget_income_uid = rb3.request_budget_income_uid +WHERE rb3.status_id = 3 + AND rb3.project_name_th = cpd.project_name_th + AND cpd.api = 'request_budget_income' + AND COALESCE(cpd.budget_come_from,'') != COALESCE(rbs3.result,'');