Skip to content

Preventive Maintenance: Workflows

The PM request lifecycle

A PM request flows through 5 stages — the standard repair workflow, prefixed by "PM Scheduled":

┌─────────────────────────────────────────────────────────────────┐
│  PM-only stage   │            Standard repair workflow          │
├──────────────────┼───────────────────────────────────────────────┤
│ PM Scheduled  →  │  Pending Review  →  In Repair  →  Awaiting   │
│  (72hr SLA)      │  (8hr SLA)         (24hr SLA)    Pickup      │
│                  │                                  (8hr SLA)   │
│                  │                                       │      │
│                  │                                       ▼      │
│                  │                              Received (done) │
└─────────────────────────────────────────────────────────────────┘

Each transition is logged to hemms.stage.transition.log for audit.

Stage-by-stage walkthrough

Stage 1 — PM Scheduled

Who handles this: BME Technician (the configured roots_responsible_role)

What it means: The cron has created a request based on the plan's schedule. The technician hasn't acknowledged it yet.

SLA: 72 hours from creation. If the technician doesn't move the request forward within 3 days, the SLA flag fires and the request appears in the SLA Breached filter.

Typical actions:

  • Review the equipment + maintenance kind + instructions
  • Schedule the actual visit
  • Move to Pending Review when acknowledged

Stage 2 — Pending Review

Who handles this: BME Manager

What it means: The manager reviews the technician's plan-of-work, checks parts availability, and assigns the technician.

SLA: 8 hours.

Typical actions:

  • Assign user_id to the technician
  • Order parts if needed
  • Move to In Repair

Stage 3 — In Repair

Who handles this: BME Technician

What it means: Active PM work is happening on the equipment.

SLA: 24 hours.

Typical actions:

  • Perform the PM tasks per the plan's instructions
  • Record any issues found (broken parts, recommended replacements)
  • Update the request notes
  • Move to Awaiting Pickup when work is complete

Stage 4 — Awaiting Pickup

Who handles this: BME Manager (sign-off)

What it means: PM work is complete; awaiting the ward's confirmation of receipt.

SLA: 8 hours.

Typical actions:

  • Notify the ward
  • Manager signs off on the work
  • Move to Received when the ward acknowledges

Stage 5 — Received

Who handles this: Ward Staff (confirms receipt)

What it means: The PM cycle is complete. The request is closed.

SLA: None (terminal stage).

The audit log now shows all 5 transitions with timestamps and elapsed hours per stage.

What happens if a PM request breaches SLA

The compute field roots_is_sla_breached evaluates to True when:

NOW() - roots_stage_entered_at  >  current_stage.roots_sla_hours

There's no automatic escalation — but you can:

  • Filter the kanban / list view by SLA Breached = True
  • Build a report that groups breaches by responsible role
  • Set up a server action (Settings → Technical → Server Actions) to send an email or post a chatter note when the flag fires

The kanban card shows a red flag icon with the text "SLA" next to the criticality dot when a request is in breach.

Corrective vs PM — the routing logic

The module's key design decision is keeping corrective and PM work visually separate while sharing the same underlying workflow:

Request type Entry stage How it's identified
Corrective (ad-hoc repair) "Submitted" (sequence 10) maintenance_plan_id IS NULL
PM (scheduled) "PM Scheduled" (sequence 5) maintenance_plan_id is set

This is enforced by:

  1. stage_id default overrideroots_hemms_pm redefines the field's default to exclude PM-initial stages, so corrective requests get "Submitted" not "PM Scheduled"
  2. create() override — When maintenance_plan_id is in the create vals, route to the PM-initial stage explicitly

After Stage 1, both types share the same 4-stage flow (Pending Review → In Repair → Awaiting Pickup → Received).

Auditing a PM request

Every PM request has full audit context:

Stage transition log

Open the request → Audit Trail tab → see all transitions:

Transitioned At From Stage To Stage By Time in Previous (hr)
2026-05-18 09:15 (initial) PM Scheduled system 0.0
2026-05-19 14:32 PM Scheduled Pending Review tech_a 29.3
2026-05-19 16:45 Pending Review In Repair manager 2.2
... ... ... ... ...

Chatter (mail.thread)

Every stage transition also posts a chatter message:

Stage changed: PM Scheduled → Pending Review

Followers (assigned user, equipment owner) are notified by email by default (controlled by skip_notify_follower_on_requests on the plan).

Equipment-level history

Open the equipment record → Maintenance tab → see:

  • All historic PM requests for this equipment
  • Last completed PM date per kind
  • Currently-open PM requests (if any)

Edge cases

What if the plan is deleted while a PM request is open?

OCA's maintenance_plan.unlink() blocks deletion if there's an open PM request for the equipment and kind. You'll see an error:

The maintenance plan Calibration of equipment Vital Monitor #5 has generated a request which is not done yet. You should either set the request as done, remove its maintenance kind or delete it first.

To delete the plan: first close (Received stage) or unlink the open PM request, then retry.

What if the equipment is archived?

The cron skips archived equipment — no new PM requests are generated. Open PM requests for the archived equipment remain visible until completed.

What if 2 different plans hit the same date for the same equipment?

The cron creates 2 separate requests — one per plan. The kanban shows both side-by-side.

What if start_maintenance_date is in the past?

The cron catches up — it walks forward from start_maintenance_date, creating requests for each missed interval up to the planning horizon. Useful when adding a plan to legacy equipment.

Next steps