---
title: "Maintenance Work Orders"
description: "A maintenance work order authorises and records a single maintenance intervention on a single asset."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.beelocity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Maintenance Work Orders

A **maintenance work order** authorises and records a single maintenance intervention on a single asset. It's the document that tracks the labor, parts, and downtime for one intervention, and feeds your maintenance indicators.

## How a work order comes to exist

There are four ways a work order is created:

1. **Manual** — A planner clicks **New** on the Maintenance Work Orders page, picks an asset, sets the flavour, priority, optional details and due date. Beelocity infers the warehouse, currency, default expense account, and severity from the asset (and its team's default warehouse), and saves the order in DRAFT status with the next `MWO-MAN-…` number. From there the planner reviews, adds tasks and parts, and releases it like any other.
2. **Plan-generated** — The maintenance-plan scheduler materialises a PLANNED work order from a plan template the moment a time- or meter-based trigger fires.
3. **Work-request conversion** — An operator-filed work request is triaged and converted into a DRAFT work order; the asset, the details and the problem code carry over, and the team is set from the asset. One request can spawn several orders — see [Work Requests](work-requests.html#conversion-to-a-work-order).
4. **Production breakdown handoff** — A production work order in BREAKDOWN status spawns a maintenance work order automatically and pairs the two together for downtime accounting.

## Flavours

The flavour distinguishes what kind of work this is:

- **PREVENTIVE** — Scheduled work performed before failure. Generated by a maintenance plan.
- **INSPECTION** — A look-see; data-gathering. May or may not lead to follow-up work.
- **CORRECTIVE** — The asset is degraded but still operational. Planner-scheduled.
- **BREAKDOWN** — The asset is down. The fastest-track flavour; often skips approval.
- **CALIBRATION** — A controlled re-tuning; typically scheduled.
- **DISPOSAL** — Decommissioning work on an asset being retired.

The flavour drives the remedy-code list offered at close, the KPI bucket the WO contributes to, and whether downtime is mandatory.

## Status lifecycle

Work orders progress through:

1. **DRAFT** — Planner-authored, not yet ready.
2. **PLANNED** — Scheduler-generated from a plan; awaiting planner review.
3. **PENDING_APPROVAL** — Routed through the approvals engine (e.g., high-cost or capitalisable).
4. **APPROVED** — Sign-off received.
5. **SCHEDULED** — Released to the team; stock reserved; calendar exception emitted if the asset is a work center.
6. **IN_PROGRESS** — Work has started; downtime window opened if applicable; asset moves to `IN_MAINTENANCE`.
7. **ON_HOLD** — Paused (waiting on a part, waiting on the OEM); reason required.
8. **COMPLETED** — Work done; all tasks finished; downtime windows closed.
9. **CLOSED** — Costing finalised and KPI rollups recorded; immutable thereafter.
10. **CANCELLED** — Terminal cancellation; reverses any issued parts.

A privileged "reopen" transition can flip `CLOSED` back to `IN_PROGRESS` for corrections.

The road from Draft to Closed runs along the bottom of the work order's page. Each step shows
whether it has been reached, which one the order is on now, and what is still ahead; hover a step
you have already passed to see when it was reached and who moved it. The next step is a button —
click it and confirm. Putting the order on hold, closing it and reopening a closed one each ask
for what they need first: the hold for the reason and the date you expect to resume, the close for
the remedy that fixed the fault, the reopen for why. Cancelling asks for a reason too, and the
steps the order never took are greyed. Planned is written by the plan scheduler rather than by a
hand, so it is never offered as the next step — **Release** at the top of the page is the way on
from it.

The work-orders list is the module's worklist. Use the search box to find an order by number, and the **filter button** beside it to narrow by **Status**, **Flavour**, **Source**, **Severity**, **Asset**, **Team**, **Assignee**, **Overdue**, **Capitalised**, **Active**, a **Priority**, cost or variance range, or a **Due date** window — the Monday sweep is `Status = Scheduled`, `Due date` up to Friday ([Working with lists](../getting-started/working-with-lists.html#narrowing-the-list)).

## Releasing a work order

When a planner releases a work order from `SCHEDULED`, several things happen in a single transaction:

- The task list and parts list are **frozen** — subsequent plan edits don't affect this WO.
- A **cost snapshot** is captured — estimated labor (task durations × team rate) and estimated parts (`required_quantity × standard_cost`). This is the baseline for variance reporting at close.
- Stock is **reserved** for each part (non-optional parts only).
- If the asset is a work center, a **tentative calendar exception** is emitted so the production scheduler knows the line will go down.

## Logging the intervention

While the WO is in progress, the work order's page carries one tab per kind of line, so the planner and the technician work through them without leaving the order. Each tab has its own **New**, and each line opens on a page of its own under the order:

- **Tasks** tab — the technician marks each task complete, optionally records findings, picks a task-level remedy code. Closing the order requires every non-optional task to be marked Done; a task flagged **Lockout required** needs its confirmation recorded before it can be Done.
- **Parts** tab — the planned spare-part lines for the WO. Each row tracks the required quantity, what storeroom has reserved, how much has actually been issued, and what's been returned. The Issued / Returned totals auto-update from the Part issues tab.
- **Part issues** tab — actual stock movements drawn against the part lines. Each issue snapshots the unit cost and tags a reason (Consumed / Unused return / Warranty return / Scrap / Cancellation reversal) — the reason, not the sign of the quantity, decides whether the row is an issue or a return. The WO header's `actual_parts_cost` rolls up automatically. Each posted issue writes a `MAINTENANCE_ISSUE` stock movement (returns post a `MAINTENANCE_RETURN`). Parts can only be issued once the WO has been released (Scheduled or later). For serial-tracked spares (variant-keyed part lines), the issue form offers a **Serial number** picker: naming the exact physical unit marks its [serial number](../inventory/serial-numbers.html) **Consumed** in the same transaction (quantity must be 1 — a serial is one unit). An unused return puts the serial back **In stock** at the return warehouse; a warranty return marks it **Defective** while it awaits shipment to the supplier.
- **Labor entries** tab — start/end timestamps per technician with the hourly rate for the entry; the system computes the duration and accumulates `actual_labor_cost` on the WO header. Tag an entry to a task to auto-aggregate the task's actual duration.
- **Downtime** tab — the windows during which the WO took the asset offline. Opened when the WO starts (asset → `IN_MAINTENANCE`) and closed at completion (asset → `OPERATIONAL` if no other windows are open). Planned vs unplanned distinguishes scheduled outages from breakdowns and feeds the Availability KPI.

Each tab of the work order narrows on its own **filter button**: **Tasks** by **Task done**, **Lockout**, **Active** or a duration range — `Task done = No` is the technician's worklist; **Parts** by **Part**, **Unit**, **Issue method**, **Optional**, **Active** or any quantity / cost range; **Labor** by **Technician**, **Active**, a rate or cost range or a **Started** / **Ended** window; **Downtime** by **Planned**, **Asset**, **Active**, a duration range or a **Started** / **Ended** window; **Part issues** by **Part**, **Unit**, **Warehouse**, **Reason**, **Issued by**, **Repair pool**, **Repaired**, **Active** or an **Issued at** window — `Repair pool = Yes`, `Repaired = No` is the repair-pool sweep.

## Closing

Completing the WO stamps the actual end date, computes the variance against the cost snapshot, and recomputes the asset's lifetime maintenance cost and count. The WO is now `COMPLETED` but not yet finalised — the planner reviews and then closes.

Closing locks the WO and records the final figures: the asset's lifetime maintenance cost and count are updated, and any calendar exception is finalised. The total cost stays recorded on the WO header (labor + parts + other) and feeds the asset's lifetime maintenance cost.

After closing, the WO is immutable. The privileged reopen path is available for corrections.

## Variance reporting

`cost_variance = actual_total_cost − estimated_total` is computed and stamped when the WO is completed (and cleared if the WO is reopened). This is informational only. Persistent large variances on plan-generated WOs flag the plan as drifting and surface on the planner's "plans to review" list.

## Cancellation

A cancellation reverses any issued parts (`CANCELLATION_REVERSAL` movements that net the issues to zero), closes any open downtime windows, and cancels the calendar exception if one was emitted. Labor already logged stays on record — labor happened, and the cost stays.

## Holds

`ON_HOLD` pauses work without cancelling. Picking the status from the picker opens a dialog asking for:

- **Hold reason** — required, free-form text. Shown in the WO header while paused so the floor knows what's blocking the work.
- **Hold target date** — optional. The line's calendar exception is extended out to this date so the production planner knows the line stays out of capacity.
- **Pause downtime while on hold** — defaults to on. When enabled, the open downtime window closes at hold time and a fresh one opens on resume; the asset flips back to `OPERATIONAL` if no other windows are open. Useful when the asset comes back online while you wait for a part, so the availability KPI isn't punished by the wait.

## Reopening a closed work order

A privileged "Reopen" path flips a `CLOSED` WO back to `IN_PROGRESS`. Picking `IN_PROGRESS` on a closed WO opens a dialog asking for a reason. The reopen clears the cost variance and detaches the closer so the next complete-then-close rerolls the labour, parts, and variance numbers cleanly. Reservations that were released at close are not auto-restored — issue new parts against current stock if you need them. Use reopen for late labor entries, a missed part return, or a code correction that matters for KPI reporting.

## Releasing in one click

Once a WO is `PLANNED`, `APPROVED`, or back from `ON_HOLD`, a single primary **Release** button on the detail page moves it to `SCHEDULED` without dropping into the status picker. The release freezes the tasks and parts, captures the cost snapshot, reserves stock, and emits the tentative calendar exception in one transaction — same effect as `Status → SCHEDULED`, just one click. Audited as a dedicated release event so reporting can distinguish releases from generic status flips.

## Warning banners

The detail page surfaces two soft warnings the floor and planners need to see:

- **Meter reading was corrected.** When someone files a meter correction for the asset after this WO opens, an amber banner appears reminding the planner to re-verify counters before close. The fix-it window only matters until close; dismiss the banner once the counters are re-checked.
- **Warranty claim eligible.** When the WO closes while the asset is still inside its warranty window, an amber chip appears in the header (and in a dedicated column on the list grid) reminding the controller to file an OEM warranty claim before the WO is archived. This is informational only — no system action happens automatically; invoice the OEM out-of-band.

## Approvals

The work order is a registered subject type in the approvals engine. Typical conditions an org might wire:

- Estimated total cost above a threshold → controller sign-off.
- Flagged as capitalisable → finance director sign-off.
- A-critical asset → plant manager sign-off.

The approval engine itself is unchanged — see [Approvals](../approvals/index.html).

## Permissions — planner vs controller vs technician

Each work-order action is gated by a dedicated permission code so the role split between planners, controllers, and technicians is enforceable from the Roles page. Grant exactly the codes you need on each role; the umbrella _Maintenance work order_ permission only controls who can list and read them.

- **Read** — _Maintenance work order view_. Anyone touching maintenance needs this.
- **Create / draft** — _Maintenance work order create_. Planners and supervisors.
- **Release to the floor** — _Maintenance work order release_. The planner action that turns a `SCHEDULED` order into work the floor can pick up. Without this code the Release button is hidden.
- **Issue parts** — _Maintenance work order issue_. Storeman or technician issuing spares against a WO.
- **Report task progress** — _Maintenance work order report task_. Floor technicians marking tasks complete and logging labour.
- **Log labour batch** — _Maintenance work order labor_. End-of-shift bulk labour entry.
- **Manage downtime windows** — _Maintenance work order downtime_. Opening and closing the line-down windows that drive availability KPIs.
- **Mark Complete** — _Maintenance work order complete_. Supervisor sign-off that the work is physically done.
- **Close** — _Maintenance work order close_. Controller sign-off that finalises the WO and records the final cost rollup. Also required to **reopen** a closed WO (the reverse path).
- **Cancel** — _Maintenance work order cancel_. Reverses any issued parts and unwinds the schedule.
- **Place on hold / resume** — _Maintenance work order hold_. Pauses the WO and (optionally) the downtime window.
- **Decommission an asset** — _Maintenance asset decommission_. Controller-only — protects the asset register from a tech writing off equipment.

Grants are explicit: a `_MANAGE` grant on the umbrella does **not** imply any of the action-level codes above. A technician role typically holds `_VIEW`, `_REPORT_TASK`, and `_ISSUE`. A planner adds `_CREATE`, `_RELEASE`, `_HOLD`, `_CANCEL`. A controller adds `_COMPLETE`, `_CLOSE`, and `_ASSET_DECOMMISSION`.

Source: https://docs.beelocity.com/en/maintenance/work-orders/index.mdx
