Files
rmutr/docs/superpowers/specs/2026-07-22-in-plan-report-submit-review-fix-design.md
T
2026-07-22 07:56:59 +07:00

12 KiB

รายงานผล(ในแผน) — แก้บั๊กปุ่ม "ส่งให้กองแผนตรวจสอบ" + ล็อกฟอร์ม

บริบท

หน้า "หน่วยงานทำรายงานผล" (agency-report-form/list-all, typeUrl 20, component MakeYearPlanFormComponent ที่ make-year-plant-form.component.ts) ให้หน่วยงานติ๊กเลือกแถวที่กรอกรายงานผลแล้ว (item.value.agency_report) แล้วกดปุ่ม "ส่งให้กองแผนตรวจสอบ" (html:1036-1040, แสดงเมื่อ typeUrl == 20 && isListAllMode())

บั๊กปัจจุบัน: เมธอด save() (ts:2377) เช็ค if(this.isListAllMode()) เป็นเงื่อนไขแรกสุดและ return ทันที (ts:2380-2409) isListAllMode() (ts:159-161) คืนค่า true เมื่อ state === 'add' && typeUrl ∈ {12,14,20} — เนื่องจาก route list-all ไม่มี :id พารามิเตอร์ state จึงเป็น 'add' เสมอ ทำให้ผู้ใช้ที่กด "ส่งให้กองแผนตรวจสอบ" (typeUrl 20) ตกเข้า branch isListAllMode() ซึ่งเป็น logic คนละเรื่อง (group ตาม change_project_uid แล้ว ChangeProjectSV.put()) — ไม่อ่าน this.selection.selected เลย และไม่เรียก AgencyReportSV.updateStatusAgency() จึงไม่มีการส่งสถานะ agency_report.status_id ไปกองแผนจริงๆ

Branch else if(this.typeUrl == 20) (ts:2439-2508) ที่ทำงานถูกต้องสมบูรณ์อยู่แล้ว (อ่าน selection.selected → กรองแถวที่มี agency_report.agency_report_uid → ตั้ง status_id=1AgencyReportSV.updateStatusAgency()) จึงเป็น dead code ที่ไม่มีทางถูกเรียกถึงจากปุ่มนี้

ฝั่งกองแผน (check-project-report, typeUrl 16) ทำงานสมบูรณ์อยู่แล้ว — 3 แท็บ (รอตรวจสอบ/ส่งแก้ไข/ตรวจสอบแล้ว ตาม status_id 1/2/3), ปุ่ม save_send()/save_pass() ใน agency-report-form.component.ts เรียก backend จริง (PUT) — ไม่ต้องแก้ฝั่งนี้

สิ่งที่ขาดเพิ่มเติมเมื่อเทียบกับ flow "รายงานนอกแผน" ที่เพิ่งทำ (2026-07-21-out-of-plan-report-review-design.md): list-all ไม่มี badge สถานะ/ไม่มีการกันติ๊กซ้ำ และฟอร์มรายงานฝั่งหน่วยงาน (typeUrl 202) ไม่ถูกล็อกเมื่อสถานะเป็นรอตรวจสอบ/ตรวจสอบแล้ว (ทั้งที่ flow นอกแผน (typeUrl 282) มี pattern นี้อยู่แล้ว)

ขอบเขต

  • แก้จุดเดียวใน save() ของ make-year-plant-form.component.ts ให้ typeUrl 20 ไม่ถูก isListAllMode() ดักก่อน — ไม่แก้ definition ของ isListAllMode() เอง (กระทบจุดอื่นในเทมเพลตน้อยที่สุด)
  • เพิ่ม [disabled] บน checkbox ของ list-all (เฉพาะ typeUrl 20) + เพิ่ม badge สถานะข้างปุ่ม "เพิ่ม/แก้ไขรายงาน"
  • เพิ่ม form-lock (isLocked + form.disable()) ให้ branch typeUrl == 202 ใน agency-report-form.component.ts มิเรอร์ pattern เดียวกับ branch นอกแผน (typeUrl == 282) ที่มีอยู่แล้ว
  • ไม่แตะ check-project-report (typeUrl 16), ไม่แตะ backend, ไม่แตะ flow ของรายงานนอกแผน (typeUrl 28x/29x) ที่ทำไปแล้วเมื่อวาน
  • ไม่แก้ isListAllMode() สำหรับ typeUrl 12/14 — พฤติกรรมเดิมของสองตัวนี้ต้องเหมือนเดิมทุกประการ

การเปลี่ยนแปลงที่ต้องทำ

1. แก้ save() dispatch bug (make-year-plant-form.component.ts:2380)

if(this.isListAllMode() && this.typeUrl !== 20){

(เดิม: if(this.isListAllMode()){)

ผล: typeUrl 20 ตกไปที่ else if(this.typeUrl == 20) (ts:2439) ซึ่งมี switch(this.state) — เนื่องจาก state เป็น 'add' เสมอบน route นี้ จะเข้า case 'add': (ts:2457-2478) ที่ทำงานถูกต้องอยู่แล้วโดยไม่ต้องแก้เพิ่ม (validate updateForm.length, confirmSave(), updateStatusAgency(), saveSuccess(), loadAllDetails())

typeUrl 12/14 ยังคง isListAllMode() === true และเงื่อนไข && this.typeUrl !== 20 ไม่กระทบ จึงยังตกเข้า branch เดิม (ChangeProjectSV.put) เหมือนเดิมทุกประการ

2. Checkbox disable + status badge (make-year-plan-form.component.html รอบบรรทัด 474-493)

Checkbox (html:474-479) เพิ่ม:

[disabled]="typeUrl == 20 && (item.value.agency_report?.agency_report_uid == null || item.value.agency_report?.status_id === 1 || item.value.agency_report?.status_id === 3)"

ข้าง report-btn (หลังบรรทัด 492) เพิ่ม badge อ่านจาก item.value.agency_report?.status_id (แสดงเฉพาะเมื่อ agency_report_uid != null):

status_id ป้าย สี
0 / null ร่าง เทา
1 รอตรวจสอบ เหลือง (ใช้โทนเดียวกับ badge "นอกแผน" ที่มีอยู่แล้ว: #fef3c7/#92400e)
2 ส่งแก้ไข แดง/ส้ม
3 ตรวจสอบแล้ว เขียว
<span *ngIf="typeUrl == 20 && item.value.agency_report?.agency_report_uid != null"
      [style.background]="reportStatusBadge(item.value.agency_report?.status_id).bg"
      [style.color]="reportStatusBadge(item.value.agency_report?.status_id).color"
      style="display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:600;margin-top:3px;white-space:nowrap;">
  {{reportStatusBadge(item.value.agency_report?.status_id).label}}
</span>

เพิ่มเมธอด helper reportStatusBadge(status_id) ใน make-year-plant-form.component.ts คืนค่า {label, bg, color} ตามตารางด้านบน (ค่า default เมื่อ status_id เป็น 0/null/undefined คือ "ร่าง")

3. ล็อกฟอร์มรายงานฝั่งหน่วยงาน (agency-report-form.component.ts, branch typeUrl == 202)

หา branch typeUrl == 202 (ใน case 'edit':, cf. ts:469-508 ตามผลสำรวจ) เพิ่มก่อน Swal.close() เหมือนที่ branch 282 มี (ts:555-558):

if (x.status_id === 1 || x.status_id === 3) {
  this.isLocked = true
  this.form.disable()
}

(ไม่ต้องเช็ค out_of_plan_report_detail_uid ในเงื่อนไขนี้ เพราะ branch 202 ใช้กับรายงานในแผนเท่านั้นอยู่แล้ว)

ปุ่ม "บันทึก"/badge locked banner ที่มีอยู่แล้วในเทมเพลต (gate ด้วย isLocked, ไม่ผูกกับ typeUrl เฉพาะ) ทำงานอัตโนมัติกับ branch นี้โดยไม่ต้องแก้เทมเพลตเพิ่ม — ปุ่ม save_send()/save_pass() (typeUrl 202161) ไม่ถูกกระทบเพราะไม่ได้ gate ด้วย !isLocked และใช้ getRawValue() ที่อ่านค่าจาก disabled control ได้ปกติ

Error handling

  • กดส่งโดยไม่ติ๊กแถวที่มีรายงาน: error text เดิม "กรุณาเลือกรายการที่ต้องการส่ง" (มีอยู่แล้ว ts:2459)
  • API update_status ล้มเหลว: errText(err.error?.description ?? 'เกิดข้อผิดพลาด') เดิม (ts:2467-2470) ไม่ rollback selection
  • guard การเลือกแถวซ้ำเป็น client-side เท่านั้น (checkbox disabled) ไม่มี guard เพิ่มฝั่ง backend — สอดคล้องกับ pattern เดิมของโปรเจกต์ (เหมือน flow นอกแผน)

Testing (manual/browser)

  1. เข้า agency-report-form/list-all (typeUrl 20) → เห็น badge "ร่าง" บนแถวที่กรอกรายงานแล้วแต่ยังไม่ส่ง, ไม่มี badge บนแถวที่ยังไม่มีรายงาน
  2. ติ๊กแถวที่มีรายงานสถานะ "ร่าง" 1-2 แถว → กด "ส่งให้กองแผนตรวจสอบ" → ยืนยัน error ไม่ขึ้นถ้ามีเลือกอยู่ → หลังส่งสำเร็จ badge เปลี่ยนเป็น "รอตรวจสอบ" และ checkbox แถวนั้น disabled ไปโดยอัตโนมัติ (reload)
  3. กด "ส่ง" โดยไม่ติ๊กอะไร (หรือติ๊กเฉพาะแถวที่ยังไม่มีรายงาน) → ยืนยัน error "กรุณาเลือกรายการที่ต้องการส่ง" ขึ้น
  4. เปิดฟอร์มรายงานของแถวที่ส่งไปแล้ว (status 1) จาก list-all → ยืนยันฟอร์ม disable ทั้งหมด ปุ่มบันทึกหาย
  5. เข้า check-project-report ในฐานะกองแผน → เห็นรายการที่ส่งมาในแท็บ "รอตรวจสอบ" (regression check — ต้องยังทำงานเหมือนเดิมทุกประการ เพราะไม่ได้แก้โค้ดฝั่งนี้)
  6. กด "ส่งกลับแก้ไข" → กลับไปหน่วยงาน → badge เปลี่ยนเป็น "ส่งแก้ไข" → checkbox กลับมาติ๊กได้ → ฟอร์มแก้ไขได้อีกครั้ง (ไม่ล็อก เพราะ status_id=2)
  7. แก้ไข+ส่งใหม่ (ทำซ้ำข้อ 2) → กองแผนกด "ตรวจสอบผ่าน" → badge เปลี่ยนเป็น "ตรวจสอบแล้ว" → เปิดฟอร์มยืนยัน disable ถาวร
  8. เข้า agency-report-form/list-all ด้วย typeUrl 12 หรือ 14 (ถ้ามีสิทธิ์ทดสอบ) → ยืนยันปุ่ม/พฤติกรรม save เดิมไม่เปลี่ยน (regression check สำหรับ Change 1)