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

สถาปัตยกรรม

HEMMS ไม่ใช่ addon ของ Odoo แบบ monolithic ก้อนเดียว — แต่เป็นสแต็กของสาม ชั้นที่ประกอบล้อมรอบโมดูลการบำรุงรักษาที่มาในตัวของ Odoo แต่ละชั้น ตอบคำถามที่ต่างกันและสามารถพัฒนาแยกจากกันได้

โมเดลสามชั้น

┌─────────────────────────────────────────────────────────────────┐
│ Layer 3 — roots_hemms_* (Hospital lens)                          │
│ ───────────────────────────────────────                          │
│ Governance, compliance, Thai-specific workflow, HA Thailand audit │
│   • roots_hemms_workflow        request lifecycle + SLA + audit  │
│   • roots_hemms_criticality     value × risk matrix              │
│   • roots_hemms_asset_master    brand/model + Ref. No.           │
│   • roots_hemms_asset_inspection annual stock-check (ปจป.)        │
│   • roots_hemms_pm              hospital PM kinds + stage         │
└─────────────────────────────────────────────────────────────────┘
                              │ extends
┌─────────────────────────────────────────────────────────────────┐
│ Layer 2 — OCA building blocks                                     │
│ ──────────────────────────────                                    │
│ Generic, configurable, community-maintained                       │
│   • maintenance_plan           PM scheduling engine               │
│   • maintenance_stock          spare parts ↔ stock                │
│   • maintenance_partner        external service providers         │
│   • sign_oca                   e-signature engine (OCA/sign)      │
│   • ...vendored modules in addons/oca/ (see addons/oca/README.md) │
└─────────────────────────────────────────────────────────────────┘
                              │ extends
┌─────────────────────────────────────────────────────────────────┐
│ Layer 1 — Odoo Base                                               │
│ ──────────────────                                                │
│ maintenance.request, maintenance.equipment, maintenance.stage,    │
│ res.partner, res.users, hr.employee, hr.department                │
└─────────────────────────────────────────────────────────────────┘

Layer 1 — สิ่งที่ Odoo Base มอบให้เรา

แอป maintenance ของ Odoo Community Edition:

  • maintenance.request — รายการงาน
  • maintenance.equipment — สินทรัพย์
  • maintenance.stage — ขั้นตอนของขั้นตอนการทำงาน (มี 4 ค่าเริ่มต้น: New / In Progress / Repaired / Scrap)
  • มุมมอง Kanban / list / form
  • การมอบหมายทีมพื้นฐานผ่าน maintenance.team

สิ่งที่ขาดไปสำหรับโรงพยาบาล:

  • ไม่มีป้ายสองภาษา
  • ไม่มีการติดตาม SLA ต่อขั้นตอน
  • ไม่มีบันทึกการตรวจสอบที่มีโครงสร้าง (มีเพียง mail.message ปะปนกับ chatter)
  • ไม่มีโมเดลระดับความวิกฤต/ความเสี่ยง
  • ไม่มีขั้นตอนการตรวจสอบสินทรัพย์ประจำปี
  • ไม่มีรหัสครุภัณฑ์ของราชการ (รหัสครุภัณฑ์)
  • ไม่มีการจัดตาราง PM

Layer 2 — สิ่งที่ OCA building blocks เพิ่มเข้ามา

รีโพ maintenance ของ OCA (vendor ไว้ใต้ addons/oca/) มอบส่วนขยายเชิงโดเมน แต่ละส่วนเป็น โมดูลแยกที่เลือกเปิดใช้ได้ ลองนึกถึงพวกมันเหมือนตัวต่อ Lego — เลือกเฉพาะสิ่งที่คุณต้องการ

โมดูล เพิ่ม ทำไมโรงพยาบาลจึงสนใจ
maintenance_plan maintenance.plan + maintenance.kind + cron สร้าง PM request อัตโนมัติตามช่วงเวลาในปฏิทิน
maintenance_stock เชื่อม maintenance.request กับ stock.picking ติดตามการใช้อะไหล่ต่อการซ่อมแต่ละครั้ง
maintenance_partner เชื่อมกับ res.partner ติดตามผู้ให้บริการภายนอกต่อเครื่องมือแพทย์
sign_oca (OCA/sign) sign.oca.template / request / role + audit log กลไก e-Signature สำหรับการตรวจ ปจป. + สัญญาบริการ (Q4)
maintenance_equipment_ref เพิ่มฟิลด์ ref รหัสครุภัณฑ์คงคลังของราชการ (รหัสครุภัณฑ์)
maintenance_equipment_category_hierarchy หมวดหมู่แม่/ลูก การจัดกลุ่มเครื่องมือแพทย์แบบลำดับชั้น
... ดู addons/oca/README.md สำหรับรายการที่ vendor ไว้ทั้งหมด ... ...

โมดูล OCA นั้น ทั่วไปและกำหนดค่าได้ — ไม่ได้บังคับขั้นตอนการทำงาน ของโรงพยาบาล มันให้ building block แก่เรา เราเป็นผู้ประกอบมันเข้าด้วยกัน

Layer 3 — สิ่งที่ชั้น roots_hemms_* เพิ่มเข้ามา

โมดูล roots_hemms_* ห่อหุ้ม building block ของ OCA ด้วย การกำกับดูแล เฉพาะโรงพยาบาลและการปฏิบัติตามข้อกำหนดของไทย พวกมันคือ "Hospital Lens" ที่อยู่บน การบำรุงรักษาแบบทั่วไป

โมดูล เพิ่ม ประเด็นการกำกับดูแล
roots_hemms_workflow ขั้นตอนการทำงาน BME ไทย 5 ขั้น + SLA + audit log เชิงปฏิบัติการ: ใครทำอะไร เมื่อไหร่ เป็นไปตาม SLA หรือไม่
roots_hemms_criticality เมทริกซ์ Value × Risk → สีระดับความวิกฤต การจัดลำดับความสำคัญ: เครื่องมือแพทย์ใดสำคัญที่สุด
roots_hemms_asset_master ข้อมูลหลัก Brand / Model + current_condition ข้อมูลหลัก: เราเป็นเจ้าของเครื่องมือแพทย์อะไรบ้าง
roots_hemms_asset_inspection ขั้นตอนการตรวจนับสินทรัพย์ประจำปี (ปจป.) การกำกับดูแล: การตรวจสอบประจำปีของ HA Thailand
roots_hemms_pm ชนิด PM ของโรงพยาบาล + ขั้นตอน PM Scheduled การกำกับดูแล: การบำรุงรักษาเชิงป้องกันตามตาราง

ชั้นต่าง ๆ ประกอบกันอย่างไร: ตัวอย่าง PM request

ตัวอย่างที่ทำเสร็จแล้วแสดงทั้งสามชั้นทำงานจริง

ขั้นที่ 1 — การตั้งค่า (ผู้ดูแลระบบ ทำครั้งเดียว)

  1. Layer 1 — มีระเบียนเครื่องมือแพทย์สำหรับ "Vital Signs Monitor #5"
  2. Layer 3roots_hemms_criticality คำนวณ criticality_color = red (มูลค่าสูง × ความเสี่ยงสูง เพราะเป็นเครื่องมือใน ICU)
  3. Layer 2 — ผู้ดูแล maintenance_plan แนบแผน: kind = Calibration, interval = 6 เดือน, start_date = วันนี้
  4. Layer 3roots_hemms_pm มอบ kind "Calibration" เป็นข้อมูลตั้งต้น (ผู้ดูแลไม่ต้องพิมพ์เองตั้งแต่ต้น)

ขั้นที่ 2 — การจัดตาราง (cron รายวัน)

  1. Layer 2maintenance_plan._cron_generate_requests() รันเวลา 06:00
  2. สำหรับแต่ละแผน cron จะเดินไปข้างหน้าทีละ interval จนกระทั่งถึง หน้าต่าง planning_horizon
  3. สำหรับแต่ละวันในหน้าต่างนั้น มันจะสร้าง maintenance.request พร้อม maintenance_type = "preventive" และตั้ง maintenance_plan_id
  4. Layer 3roots_hemms_pm.maintenance.request.create() เขียนทับ การกำหนดขั้นตอน: ถ้าตั้ง maintenance_plan_id ไว้ จะกำหนดเส้นทางไปยัง ขั้น "PM Scheduled" แทนค่าเริ่มต้น "Submitted"

ขั้นที่ 3 — การดำเนินงาน (ช่างเทคนิค งานประจำวัน)

  1. Layer 1 — Request ปรากฏใน kanban ใต้คอลัมน์ "PM Scheduled"
  2. Layer 3roots_hemms_workflow ส่งต่อระดับความวิกฤตของเครื่องมือแพทย์ไปยัง request ดังนั้นการ์ดจะแสดงจุดสีแดง
  3. Layer 3 — ช่างเทคนิคย้ายขั้นตอน: PM Scheduled → Pending Review → In Repair → Awaiting Pickup → Received
  4. Layer 3 — ทุกการเปลี่ยนขั้นตอนสร้างแถวใน hemms.stage.transition.log (ร่องรอยการตรวจสอบ)
  5. Layer 3 — ถ้าขั้นตอนใดเกิน roots_sla_hours request นั้นจะปรากฏ ในการค้นหา [("roots_is_sla_breached", "=", True)]

ขั้นที่ 4 — การรายงาน (ผู้จัดการ สิ้นรอบ)

  1. Layer 3roots_hemms_workflow มอบแดชบอร์ด SLA (เมตริกเชิงปฏิบัติการ)
  2. Layer 3roots_hemms_asset_inspection มอบรายงาน PDF การตรวจนับ สินทรัพย์ประจำปี (เมตริกการกำกับดูแล)
  3. Layer 3roots_hemms_criticality มอบการจำแนกแดง/เหลือง/เขียว เพื่อการจัดลำดับความสำคัญ

ทำไมการแบ่งชั้นนี้จึงสำคัญ

1. เราไม่ฝืน Odoo หรือ OCA

ด้วยการขยายแทนการแทนที่ เราได้:

  • การแก้บั๊กจาก Odoo SA ไหลเข้าโค้ดของเราโดยอัตโนมัติ
  • ฟีเจอร์ใหม่จาก OCA เป็นแบบเลือกเปิดใช้ (เราเพิ่มอีกโมดูลได้โดยไม่ต้องรื้อทำใหม่)
  • การฝึกอบรม Odoo มาตรฐานใช้ได้กับผู้ใช้ของเรา (kanban, list, search ฯลฯ)

2. ประเด็นของโรงพยาบาลอยู่ในชั้นเดียว

หากเราจำเป็นต้องรองรับการติดตั้งที่ไม่ใช่โรงพยาบาล (เช่น การผลิต) เราสามารถสลับ roots_hemms_* เป็น roots_manufacturing_* ได้ — Layer 1+2 ยังคง เหมือนเดิม ตรรกะของโรงพยาบาลไม่พันกับโมเดล maintenance request

3. การกำกับดูแลตรวจสอบได้

ทุกโมดูล Layer 3 มีขนาดเล็ก โฟกัส และง่ายต่อการจับคู่กับข้อกำหนด การกำกับดูแล:

  • "แสดงร่องรอยการตรวจสอบของ request นี้ให้ฉันดู" → hemms.stage.transition.log
  • "แสดง PM ที่เกินกำหนดทั้งหมดบนเครื่องมือแพทย์ที่วิกฤต" → join criticality_color + roots_is_sla_breached + maintenance_type=preventive
  • "แสดงรายงานการตรวจสอบประจำปีของปีที่แล้ว" → hemms.asset.inspection ที่มี state = submitted

4. แต่ละโมดูลกำหนดเวอร์ชันแยกกันได้

การเปลี่ยนแปลงในชนิด PM ไม่บังคับให้ต้องปล่อยเวอร์ชันของโมดูล workflow การ migration schema ใน roots_hemms_workflow ไม่ลามไปยังโมดูล inspection เว้นแต่จะระบุการพึ่งพาไว้อย่างชัดเจน

หลักการตั้งชื่อฟิลด์

ฟิลด์เฉพาะของโรงพยาบาลใช้คำนำหน้า roots_ เพื่อเลี่ยงการชนกับฟิลด์ของ Odoo หรือ OCA และเพื่อให้สังเกตได้ง่ายในผลลัพธ์ของ fields_get()

# ✅ Hospital-specific
roots_value_tier = fields.Selection(...)
roots_criticality_color = fields.Selection(...)
roots_sla_hours = fields.Float(...)
roots_stage_entered_at = fields.Datetime(...)

# ✅ Inherited / standard (no prefix)
name = fields.Char(...)
state = fields.Selection(...)
maintenance_kind_id = fields.Many2one(...)   # comes from OCA

# ❌ Avoid
hospital_priority = ...   # too vague; not prefix-discoverable
priority_v2 = ...         # version in a field name is a smell

เมื่อสืบทอดโมเดล Odoo / OCA base และเพิ่มฟิลด์ ให้ใส่คำนำหน้า roots_ เสมอ เมื่อนิยามโมเดลใหม่ที่ HEMMS เป็นเจ้าของ ตัว _name เป็น คำนำหน้าที่เพียงพออยู่แล้ว ฟิลด์แต่ละตัวไม่จำเป็นต้องมีคำนำหน้าซ้ำซ้อน

เมทริกซ์การตัดสินใจ OCA กับ roots_hemms_*

เมื่อจะเพิ่มฟีเจอร์ใหม่ ให้ถามว่า:

คำถาม ชั้น
นี่เป็นฟังก์ชันการบำรุงรักษาทั่วไปหรือไม่ (เช่น เชื่อมกับคลังสินค้า, การจับเวลา) มองหาโมดูล OCA ที่มีอยู่แล้วก่อน
นี่เป็นการกำกับดูแลเฉพาะโรงพยาบาลหรือไม่ (เช่น การตรวจสอบ HA Thailand, ขั้นตอน BME ไทย) สร้างใน roots_hemms_*
นี่เป็นการปรับเฉพาะ UI เท่านั้นหรือไม่ สืบทอด view อย่าเขียนโมเดลใหม่
นี่กำหนดค่าได้ต่อการติดตั้งหรือไม่ ใช้ ir.config_parameter หรือ setting ไม่ใช่ค่าคงที่ฮาร์ดโค้ด

หลักทั่วไป

ตั้งค่าเริ่มต้นเป็น OCA สร้างใหม่ใน roots_hemms_* เฉพาะเมื่อ OCA ไม่มี และข้อกำหนดเป็นเฉพาะโรงพยาบาล/ไทย และมันคุ้มกับภาระการดูแล เท่านั้น

ตัวอย่างการตัดสินใจในอดีต:

  • "เราต้องการการจัดตาราง PM" → ✅ OCA maintenance_plan (ไม่ต้องสร้าง)
  • "เราต้องการการติดตามอะไหล่" → ✅ OCA maintenance_stock (ไม่ต้องสร้าง)
  • "เราต้องการขั้นตอน BME ไทย 5 ขั้นพร้อมการตรวจจับการละเมิด SLA" → ✅ สร้าง roots_hemms_workflow (OCA มีเพียง 4 ขั้นทั่วไปโดยไม่มี SLA)
  • "เราต้องการรายงาน PDF ปจป. ประจำปีในรูปแบบไทย" → ✅ สร้าง roots_hemms_asset_inspection (ไม่มีสิ่งเทียบเท่าใน OCA)
  • "เราต้องการชนิดการบำรุงรักษาสองภาษา" → ✅ สร้าง roots_hemms_pm เพื่อขยาย maintenance.kind ของ OCA ด้วย roots_name_th (wrapper น้ำหนักเบา)

กราฟ dependency ของโมดูล

                    maintenance (Odoo base)
                     base_maintenance (OCA)
                    maintenance_plan (OCA)
                              │   ┌──────────────────────────┐
                              ├───┤ roots_hemms_asset_master │
                              │   └──────────────────────────┘
                              │                  ▲
                              │                  │
                              │   ┌──────────────────────────┐
                              ├───┤ roots_hemms_criticality  │
                              │   └──────────────────────────┘
                              │                  ▲
                              │                  │
                              │   ┌──────────────────────────┐
                              ├───┤ roots_hemms_workflow     │
                              │   └──────────────────────────┘
                              │                  ▲
                              │                  │
                              │   ┌──────────────────────────────┐
                              ├───┤ roots_hemms_asset_inspection │
                              │   └──────────────────────────────┘
                              │                  ▲
                              │                  │
                              │   ┌──────────────────────────┐
                              └───┤ roots_hemms_pm           │  (Q1)
                                  └──────────────────────────┘

อภิธานศัพท์

ศัพท์ ความหมาย
Layer 1 โมดูลการบำรุงรักษา base ของ Odoo CE
Layer 2 building block ที่ OCA vendor ไว้ (addons/oca/)
Layer 3 ส่วนขยายเฉพาะโรงพยาบาลของ HEMMS (addons/roots/)
BME Biomedical Engineering — แผนกของโรงพยาบาลที่ดูแลเครื่องมือแพทย์
HA Thailand สถาบันรับรองคุณภาพสถานพยาบาล (ประเทศไทย) — กำหนดมาตรฐานการรับรองโรงพยาบาล
ปจป. รายงานการตรวจสอบสินทรัพย์ประจำปี (ตรวจสอบพัสดุประจำปี)
SLA Service Level Agreement — จำนวนชั่วโมงสูงสุดที่ request ควรอยู่ในขั้นหนึ่ง
Criticality ความสำคัญของเครื่องมือแพทย์ — value × risk → แดง/เหลือง/เขียว