Skip to content

Repair Workflow

The Repair Workflow module (roots_hemms_workflow) replaces Odoo's default three-stage maintenance flow (New / In Progress / Repaired) with the five-stage hospital repair workflow used by Thai BME departments — the exact set of states a surveyor will ask you to walk through during an HA accreditation visit.

Every transition is timed against a per-stage SLA, every transition is written to an immutable audit log, and every kanban card carries a criticality badge so the BME manager can triage at a glance.

The five stages

The module seeds these stages on install (bilingual labels — the Thai name is the canonical one for ward staff, the English label is for surveyors and admins):

# Stage Thai SLA Default responsible
10 Submitted ส่งซ่อม 4 h Ward staff
20 Pending Review รอตรวจสอบ 8 h BME Manager
30 In Repair กำลังซ่อม 24 h BME Technician
40 Awaiting Pickup ซ่อมเสร็จ - รอรับ 8 h BME Manager (sign-off)
50 Received รับงานแล้ว Ward staff

Sequence numbers are spaced by 10 so an admin can interleave custom stages later without renumbering. The Received stage is the only one with fold=True and done=True — Odoo treats it as the terminal column, collapsed in the kanban by default.

PM Scheduled is a sixth stage — added by roots_hemms_pm

The Preventive Maintenance module ships an additional stage, PM Scheduled (ตามแผนบำรุงรักษา), at sequence 5 with a 72-hour SLA. PM-generated requests enter the workflow there instead of Submitted. The corrective-flow stages above are untouched.

State machine

stateDiagram-v2
    direction LR
    [*] --> Submitted: Ward staff opens ticket
    [*] --> PM_Scheduled: roots_hemms_pm cron
    PM_Scheduled --> Pending_Review: BME tech acknowledges
    Submitted --> Pending_Review: BME manager picks up
    Pending_Review --> In_Repair: assignment + diagnosis
    In_Repair --> Awaiting_Pickup: repair complete
    Awaiting_Pickup --> Received: ward staff collects
    Received --> [*]

    Submitted: ส่งซ่อม\n(Submitted)\nSLA 4h
    Pending_Review: รอตรวจสอบ\n(Pending Review)\nSLA 8h
    In_Repair: กำลังซ่อม\n(In Repair)\nSLA 24h
    Awaiting_Pickup: ซ่อมเสร็จ - รอรับ\n(Awaiting Pickup)\nSLA 8h
    Received: รับงานแล้ว\n(Received)\nDone
    PM_Scheduled: PM Scheduled\n(roots_hemms_pm)\nSLA 72h

The flow is not rigidly state-enforced — maintenance.stage uses Odoo's standard sequence-ordered kanban, so any user with edit rights can drag a card backwards or skip a column. The audit log captures every move regardless of direction, so backwards transitions are visible to the manager and to surveyors.

Why it matters

Clinical workflow visibility

The default Odoo flow doesn't distinguish "the technician is fixing it" from "the technician is done but nobody from the ward has come to pick it up". In a hospital, those two states sit in totally different queues — one is a BME problem, the other is a ward problem. Splitting them out unblocks the BME team's KPIs.

Surveyor evidence

HA and ISO 15189 surveyors ask: "Show me the last 10 broken ventilators. When was each one reported, how long did each step take, who signed off?" The audit log (hemms.stage.transition.log) answers that question in one query.

SLA accountability

Each stage carries its own expected duration. When a request sits in Pending Review for more than 8 hours, the kanban card flips to a red SLA badge and the form shows a banner. The flag is computed SQL-side (see _search_roots_is_sla_breached in models/maintenance_request.py) so the SLA Breached search filter scales to tens of thousands of historical requests without timeout.

Key features

  • 5 seeded stages with bilingual TH+EN names, per-stage SLA hours, and a "Default Responsible Role" hint (ward_staff, bme_manager, bme_technician, bme_manager_signoff).
  • Live "Time in Stage" widget on form + list + kanban (float_time formatted).
  • SLA-breach banner on the form, red row decoration on the list, red SLA badge on the kanban card — same data, three presentations.
  • Equipment criticality badge on every card (green / yellow / red) — pulled related from the equipment, indexed for fast filtering.
  • Audit Trail tab on the request form — read-only list of every stage transition with timestamp, actor, from-stage, to-stage, and the hours spent in the previous stage.
  • Stage Transition Audit Log under Maintenance → Configuration — manager-only screen that searches across all requests, useful for surveyor evidence.
  • Three workflow search filters: My Responsibility (current responsible = me), SLA Breached (active timer overdue), Critical Equipment (red criticality). Plus three "Group By" options: by Stage, by Current Responsible, by Equipment Criticality.
  • Auto-message on stage change — every transition posts a note to the request's chatter (Stage changed: A → B) using mail.mt_note, so the audit trail survives even if the log model is filtered.
  • Initial-stage audit entry — the first stage a request lands in (Submitted, PM Scheduled, or whatever an admin custom-sets) is itself logged with from_stage_id empty, so the trail is complete from creation.

Module dependencies

Layer Module Why
Q1 roots_hemms_criticality Equipment color (related field on request)
Layer 1 maintenance (Odoo base) The maintenance.stage + maintenance.request models
Layer 1 hr res.users linkage on the audit log
Layer 1 mail Chatter messages on stage change

Downstream consumers of this module:

  • roots_hemms_pm — adds the PM Scheduled initial stage + plan engine
  • roots_hemms_spare_parts — links picking requests to the maintenance request stage
  • roots_hemms_service_contracts — coverage banner reads on the same request, sets roots_is_billable_to_hospital

License: LGPL-3. Maturity: Alpha (shipped in Q1, hardened in Q7 CI run).

Where to next

  • Get Started — open and walk a ticket through all five stages in 5 minutes
  • Configuration — adjust SLA hours, add custom stages, ACL for the audit log
  • Workflows — corrective, PM-generated, stuck-review, cancelled, vendor-handled scenarios
  • Reporting — kanban, list, calendar, pivot, audit log for surveyor evidence