ข้ามไปที่เนื้อหา

Workflow

หน้านี้อธิบาย state machine ของ Annual Inspection อย่างละเอียด รวมถึง การจัดการ edge case ที่อาจเจอในการใช้งานจริง

State Diagram

stateDiagram-v2
    [*] --> Draft

    state Draft {
        [*] --> EmptyDraft
        EmptyDraft --> HasLines: Add Equipment (wizard)
        HasLines --> EmptyDraft: ลบ line ทุกบรรทัด
    }

    Draft --> InProgress: Start Inspection
    note left of InProgress
        ต้องมี ≥1 line ก่อน
    end note

    state InProgress {
        [*] --> SettingConditions
        SettingConditions --> AllMarked: บันทึก condition ครบ
        AllMarked --> SettingConditions: แก้ condition ใหม่
    }

    InProgress --> Submitted: Submit
    note right of Submitted
        ต้องไม่มี unmarked line
        + ทำ condition propagation
    end note

    Submitted --> Draft: Reset to Draft
    note left of Submitted
        Manager group เท่านั้น
    end note

    Submitted --> [*]

Transition: Draft → In Progress

Trigger

คลิกปุ่ม Start Inspection ที่ header

Precondition

  • มี อย่างน้อย 1 line ใน line_ids
  • ผู้ใช้มีสิทธิ์เขียน (Asset Officer หรือ ผู้ใช้ในหน่วยงานเดียวกัน)

Effect

ฟิลด์ เปลี่ยนเป็น
state in_progress
start_date fields.Datetime.now()

ผลข้างเคียง

  • รายการครุภัณฑ์ในตาราง ล็อกequipment_id กลายเป็น readonly
  • ปุ่ม Add Equipment และ Start Inspection จะ hidden
  • ปุ่ม Submit ปรากฏขึ้น

Error case

สาเหตุ Error วิธีแก้
ไม่มี line "Cannot start an inspection with no equipment lines." กลับไป Add Equipment ก่อน

Transition: In Progress → Submitted

Trigger

คลิกปุ่ม Submit ที่ header

Precondition

  • ทุก line ต้องมี condition ที่ไม่ใช่ False
  • ถ้า condition เป็น broken หรือ deteriorated → ต้องมี damage_description

Effect

ฟิลด์ เปลี่ยนเป็น
state submitted
submitted_date fields.Datetime.now()

ผลข้างเคียง (สำคัญ!)

ระบบจะทำ condition propagation อัตโนมัติ:

# Pseudo-code
for condition, lines in inspection.line_ids.grouped("condition").items():
    lines.equipment_id.sudo().write({"current_condition": condition})

maintenance.equipment.current_condition ของครุภัณฑ์ทุกชิ้นใน inspection จะถูกอัพเดทให้ตรงกับสถานะที่เพิ่งตรวจพบ

ทำไมต้อง sudo()

Asset Officer อาจไม่มีสิทธิ์เขียน maintenance.equipment (ทะเบียนหลัก) sudo() bypass ACL ในขั้นตอนนี้ — โดยมี state guard ป้องกัน: _propagate_condition_to_master จะทำงานเฉพาะเมื่อ state == 'submitted'

Error case

สาเหตุ Error วิธีแก้
มี line ยังไม่ตรวจ "All equipment must have a condition set before submitting. Missing: …" กลับไประบุ condition
broken/deteriorated ไม่มีคำอธิบาย "Please describe how X is damaged" กรอก damage_description

Transition: Submitted → Draft (Reset)

Trigger

คลิกปุ่ม Reset to Draft ที่ header

Precondition

  • ผู้ใช้ต้องอยู่ในกลุ่ม maintenance.group_equipment_manager
  • (กลุ่ม Asset Officer ไม่มีสิทธิ์ — ต้องส่งคำขอ Manager)

Effect

ฟิลด์ เปลี่ยนเป็น
state draft
start_date / submitted_date คงเดิม (ยังเก็บไว้เพื่อ audit)

ผลข้างเคียง

  • ครุภัณฑ์ใน maintenance.equipment.current_condition ไม่ rollback — สถานะที่ propagate ไปแล้วจะยังอยู่
  • ถ้า resubmit ครั้งใหม่ → submitted_date จะถูกเขียนทับ
  • รายการครุภัณฑ์กลับมาแก้/เพิ่ม/ลบได้เหมือนเดิม

Audit trail

ทุก transition จะถูกบันทึกใน mail.thread chatter ของ inspection:

  • เปลี่ยน state ใคร เมื่อไหร่
  • ค่า start_date, submitted_date ที่เปลี่ยน

Sub-workflow: เพิ่มครุภัณฑ์ผ่าน Wizard

Domain ของ wizard

[
    ("active", "=", True),
    ("id", "not in", already_added_ids),
    ("department_id", "in", [department_id, False]),
]

→ wizard แสดง:

  • ครุภัณฑ์ที่ active เท่านั้น
  • ที่ ยังไม่ถูกเพิ่ม ใน inspection นี้
  • หน่วยงานตรงกับ inspection หรือไม่มีหน่วยงาน (เพื่อให้ครุภัณฑ์กลางถูกตรวจได้)

Snapshot ที่ถูก copy

ตอน action_add_selected ของ wizard จะ copy ฟิลด์เหล่านี้จาก equipment master:

Equipment field Inspection line field
name equipment_name
ref ref_no
category_id.complete_name category_name
brand_id.name brand_name
equipment_model_id.name model_name
effective_date effective_date
cost cost
employee_id.name employee_name
roots_criticality_color criticality_color
current_condition condition (pre-fill)

ทำไมต้อง snapshot

หลังจาก inspection ถูก submit ไปแล้ว ถ้ามีการแก้ทะเบียนหลัก (เช่น เปลี่ยนผู้ใช้งาน) รายงานที่พิมพ์ไปแล้วจะยังคงตรงกับข้อมูล ณ เวลาตรวจ

Edge cases และวิธีแก้

Case 1: ครุภัณฑ์ใหม่เพิ่งซื้อหลังจากเริ่มตรวจ

Scenario: เริ่มตรวจวันที่ 1 ต.ค. → ซื้อครุภัณฑ์ใหม่ 5 ต.ค. → ตอนนี้ state = In Progress

Resolution: ครุภัณฑ์ใหม่จะ ไม่ถูกเพิ่ม อัตโนมัติ เพราะ inspection ล็อกที่ Draft แล้ว ทางเลือก:

  1. Manager Reset to Draft → เพิ่มครุภัณฑ์ใหม่ → Submit ใหม่
  2. ปล่อยไว้ — ครุภัณฑ์ใหม่จะถูกตรวจในปีถัดไป

Case 2: ครุภัณฑ์โอนข้ามหน่วยงานระหว่างที่ตรวจ

Scenario: Inspection ของหน่วยงาน A กำลังตรวจ → ครุภัณฑ์ชิ้นหนึ่งถูกโอนไป หน่วยงาน B → ปัจจุบัน department_id ของ equipment = B

Resolution: - ใน inspection ของ A: snapshot ที่บันทึกไว้ตอน Add ยังเป็น A → ยังตรวจได้ปกติ - ใน inspection ของ B (ถ้ามี): จะเห็นครุภัณฑ์ชิ้นนี้ใน wizard ของ B ได้ด้วย - ทั้ง 2 inspection สามารถมี line ของครุภัณฑ์เดียวกัน เพราะ _sql_constraints จำกัดที่ระดับ (inspection_id, equipment_id) ไม่ใช่ระดับ equipment เดียวกันข้าม inspection

Case 3: ลืม Submit ก่อนสิ้นปีงบประมาณ

ระบบ ไม่บังคับ ส่งภายในกำหนด — เป็นความรับผิดชอบของหน่วยงาน แต่ field submitted_date จะแสดงวันที่ส่งจริง — ถ้าส่งช้าจะปรากฏใน audit log

Case 4: เปลี่ยนหน่วยงานหลังเพิ่ม Line แล้ว

department_id ที่ header จะกลายเป็น readonly เมื่อ state = draft และมี line แล้ว (เพราะ snapshot ครุภัณฑ์ผูกกับหน่วยงานเดิม)

ถ้าเลือกผิดตอนสร้าง:

  1. ลบ inspection (Asset Officer มีสิทธิ์ลบใน Draft)
  2. สร้างใหม่ ด้วยหน่วยงานที่ถูกต้อง