Get Started¶
This page takes you through opening a repair ticket and moving it through every one of the five stages, with the SLA badge, the audit trail, and the chatter message all behaving correctly along the way.
Time required
About 5 minutes for a single ticket walked manually all the way to Received.
Prerequisites¶
You need:
- The
roots_hemms_workflowmodule installed (it's part of every HEMMS install — verify under Apps if unsure) - At least one
maintenance.equipmentrecord visible to you (see Equipment Master if your database is empty) - Your user in the Maintenance / User group at minimum; stage administration also needs Maintenance / Administrator
- An assigned
roots_criticality_coloron the equipment if you want to see the criticality badge — defaults to grey otherwise
Step 1 — Open a request¶
There are two paths.
From the equipment record¶
- Go to Maintenance → Equipment
- Open any record (for example, a ventilator)
- Click the Maintenance smart button → :guilabel:
New - The equipment is pre-filled; type a title and a short description
From the maintenance kanban¶
- Go to Maintenance → Maintenance
- The kanban opens grouped by Stage
- Click :guilabel:
Newin the ส่งซ่อม (Submitted) column - Pick the equipment from the dropdown
Either way: hit Save. The new request lands in ส่งซ่อม (Submitted) with roots_stage_entered_at = now(), the Time in Stage widget at 0:00, and the Current Responsible inheriting whichever user was assigned (user_id).
First audit entry — created at create time
The very first stage a request enters is also logged. Open the Audit Trail tab on the form: you should already see one row with From Stage empty and To Stage = Submitted. This is what surveyors look for when they ask "when was the ticket first raised?".
Step 2 — Walk it through the five stages¶
You can move stages two ways:
- Form view: click the stage name on the status bar at the top of the form
- Kanban view: drag the card from one column to the next
Each move triggers four things in the same transaction:
_writecapturesfrom → to, computes time in previous stage (now −roots_stage_entered_at), and writes one row tohemms.stage.transition.logroots_stage_entered_atresets tonow()so the next stage's SLA timer starts fresh- A chatter message is posted to the request: "Stage changed: ส่งซ่อม (Submitted) → รอตรวจสอบ (Pending Review)" with subtype
mail.mt_note - Current Responsible stays on whoever
user_idpoints to — the workflow does not auto-rotate users, it only signals the expected role via the stage'sroots_responsible_rolefield
Walk the ticket through:
| From | To | What you're saying |
|---|---|---|
| Submitted | Pending Review | "Manager: please triage" |
| Pending Review | In Repair | "Tech assigned, work starting" |
| In Repair | Awaiting Pickup | "Repair done, ready to be collected" |
| Awaiting Pickup | Received | "Ward staff has picked it up" |
When you land on Received, the kanban folds that column away (Odoo treats done=True, fold=True stages as terminal), the request's stage_id.done flag flips on, and downstream modules (PM, contracts) treat the ticket as closed.
What changes on Received?
Odoo's base maintenance.request sets close_date when the request lands on a stage with done=True. The workflow module does not override that — it only adds the audit log entry and the chatter message. The standard close_date and duration fields keep working.
Step 3 — Trigger an SLA breach (optional)¶
To see the breach banner in action without waiting 4 hours, open the form view of a request currently in Submitted and either:
- Use developer mode → Settings → Maintenance Stages → Submitted → drop SLA Hours from
4.0to0.01, save, refresh the request; or - Wait 4 hours
Either way, when time_in_current_stage_hours > stage.roots_sla_hours and the stage's SLA is positive, you'll see:
- Form: a red banner above the sheet — "SLA Breached — This request has exceeded the expected time for the current stage."
- List: the row turns red (
decoration-danger) - Kanban: a red
SLAbadge appears on the card
The breach state is computed live, not stored — there's no overnight job to wait for. The SLA Breached search filter is backed by a single SQL query so filtering across thousands of requests is instant.
Step 4 — Read the audit trail¶
There are two places to inspect transition history.
On the request — Audit Trail tab¶
Open any request → click the Audit Trail notebook tab. You see a read-only list (create="0" edit="0" delete="0") of every transition for this request, newest first:
| Column | Source |
|---|---|
| Transitioned At | transitioned_at (auto now()) |
| From Stage | empty for the create-time entry |
| To Stage | the destination stage |
| Transitioned By | the res.users who triggered the write |
| Time in Prev Stage (h) | now − previous roots_stage_entered_at |
| Note | free-form, blank by default |
Cross-request — Stage Transition Audit Log¶
Go to Maintenance → Configuration → Stage Transition Audit Log (visible only to users in maintenance.group_equipment_manager). This is the manager-level screen — every transition by every user on every request, with search by request, from-stage, to-stage, or actor, plus three "Group By" presets.
Surveyor question this answers
"Show me every move out of 'Pending Review' in the last 30 days that took longer than the 8-hour SLA, grouped by technician." — Group By To Stage, filter on a date range, sort the Time in Prev Stage column descending.
Step 5 — See the chatter audit too¶
Open the request's chatter (bottom of the form). For every stage transition you'll see a system note:
OdooBot — Stage changed: รอตรวจสอบ (Pending Review) → กำลังซ่อม (In Repair)
The chatter copy is in addition to the audit log — it's there so the trail survives even if the audit log model is hidden from a given user (e.g., a ward nurse).
Tips and gotchas¶
- Backward moves are allowed and logged. Drag a card from In Repair back to Submitted: the log captures the move, the chatter notes it, and
roots_stage_entered_atresets. The flow is not state-enforced. - No-op writes do not log. If a form save happens without
stage_idactually changing (e.g., editing the description), no audit row is created. - Current Responsible follows
user_id. It will not silently fall back to the acting user (which would otherwise stamp every request to the admin on a recompute). To assign a request, set Responsible Technician — the smart field mirrors it. many2one_avatar_userwidget — both the form and list show the responsible as a clickable avatar.- Bilingual stage names are stage names, not translations. The TH half lives in the same
namefield as the EN half — they're not separate per-locale strings. Both surveyor and ward nurse see identical labels.
Where to next¶
- Workflows — concrete scenarios (corrective, PM-generated, stuck, cancelled, vendor)
- Configuration — adjust SLA, add custom stages, manage the audit log ACL
- Reporting — kanban, list, calendar, pivot, audit log