01 — Quick Reference

Statuses

Record Status flow
Work order draft → planned → (awaiting_access / awaiting_isolation / awaiting_parts) → assigned → in_progress → (suspended) → ready_for_test → returned_to_service → ready_for_verification → closed (or cancelled)
Material requirement identified → requested → reserved / unavailable → purchasing → issued → fulfilled (or cancelled)
Work task not_started → in_progress → complete / failed / not_applicable / deferred
Isolation requested → approved → applied → verified → released_for_work → restored

Statuses show as coloured badges in the lists: green done, red failed or unavailable, amber in progress, blue new or planned.

Numbers

Record Number How
Work order WO-1003, WO-1004, … Assigned on save when left blank; continues the existing series and skips numbers already used. Read-only once issued.
Material requirement MR-0001, … Same rule (the seeded MR-1001-01 style is a different series).
Evidence EV-… Entered by the user.

Tasks already done

A template task can be flagged skip if recent (the Skip If Recent tick on the template task). When an order is created from the template, a flagged task that was completed on the same asset within recent_task_skip_days (14 by default, schema/work_settings.yaml) is copied as Not applicable with the reason Already done on WO-xxxx (date), and its tools are not asked for. This is what stops a 1,000 hour service repeating the oil change of a 250 hour service done a week earlier. Isolation and test tasks are not flagged, so they are always done. The planner can still change a skipped task back on the draft order. Parts are not part of a template, so nothing is added or removed for them.

What a work order cost

Each order has cost lines (the Work Cost Line tab): parts issued from stock (Inventory's average cost), material bought for the job and contractor work (Purchasing, at the order price when received), and labour. Labour is worked out when the order closes: each time entry costs its hours times the Labour Rate in force on the day the entry was made (the most specific row: class and type, class, type, then any; until the rates move to Finance (W2) the class is the entry's trade code in lower case, e.g. electrician, and an entry with no trade uses the "any class" rows); contractor time is contractor cost; an order with no time entries costs its actual hours at the "any class and type" rate on the finish date, and hours that were never recorded cost nothing. A saved rate is never changed: set its Effective to date and add a new row from the new date, so earlier periods keep their rate (the application refuses an edit, and an overlap for one class and type). On closing - by work.verify_and_close or by setting the status on screen - the lines are totalled into actual cost and its four parts (labour, parts, purchased, contractor), and work.work_closed carries them to Finance. A cost that arrives after the order closed (a late delivery, an invoice item, a late timesheet entry) is added to the order's cost, marked late, and announced (work.late_cost_recorded); Finance posts it as a supplement.

Reopening. work.reopen_work_order takes a closed order back to in progress (finish date cleared, the reason kept in the status history). When it closes again its cost is worked out afresh and Finance posts the difference as an amendment; the first posting is not reversed, and an amendment can be negative. Corrections. A saved time entry of a closed order is not edited, because its cost has been posted: add a new entry, with negative hours to take hours off (it is costed as a late line at the rate in force that day), or reopen the order.

work.verify_and_close closes an order that is in progress, in test, returned to service or ready for verification, with no task in progress or failed; a verification that is not accepted is recorded and the order stays open.

People, contractors and trades (Workforce)

People are kept in Workforce (port 5102). Work's Person list is a read-only copy of Workforce's employees: each row has the employee's network id (cid), number, name, position, trade and status, and is created and updated by Workforce's events (workforce.employee_registered / employee_changed; employee_left makes the copy inactive). Person and Organisation cannot be created or edited on Work's screens; register or change people in Workforce.

A contractor's person is linked to an Organisation of type contractor whose code is the supplier number of the contractor company (for the demo, Priya Kaur C2044 → SUP-0042 Example Heavy Components), with supplier_cid / supplier_ref set. The organisation is found by the supplier number, or created the first time one of its people arrives.

The trade (trade_cid / trade_ref, a Workforce trade picked with workforce.search_trades) is recorded on each assignment and stamped on each time entry. A time entry with no trade takes the person's trade when Work's copy knows it; a blank trade means "not stated". A later change of the person's trade does not change entries already made, so past costs stay as they were. work.record_time takes trade_cid or the trade's code (trade_code). The free-text labour_class is gone from assignments and time entries.

References to other applications

A field that points at a record in another application has two parts:

Field Shows Example
…_ref the readable reference — this is what the lists show Inventory Reservation RES-1002 ↗
…_cid the network id (UUID) — in the detail panel's Identifiers & integration section 0192f020-…-1002

The ↗ link opens the record read-only in the application that owns it (a separate login may be asked for) — reservations open in Inventory, catalogue items in Catalogue, purchase requirements in Purchasing. References to applications not built yet (assets, warranty) show the reference without a link. When Inventory answers a material requirement, the reservation's reference is filled in automatically; when Purchasing raises a purchase requirement for it, the PR-… number is filled in and the requirement moves to purchasing, and each supplier date change updates Expected Available (a delay is noted with its reason). When the goods arrive and are accepted, Inventory reserves them and the requirement becomes reserved; once no critical material is still missing, a work order held awaiting_parts returns to the status it had before the hold (Status History reason MATERIAL_AVAILABLE).

Choosing a catalogue item: on a form, type part of the item code, description or a manufacturer number in the Catalogue Item box and pick from the list — the network id below it is filled in for you (the search asks the Catalogue application).

Everyday tasks

To… Do this
Raise a work order Work Orders → Work Order → New. Leave the number blank.
Ask for a part On the work order: Material Requirements → New (catalogue item, quantity, required by). Saving it tells Inventory, which reserves stock or reports it unavailable.
See why an order is held The order's Status History (reason, and the network message that caused it) and Dependencies.
Record a component taken off On the work order: Removed Components → New (pick the component in Component Asset). Saving it tells the Asset Register, which closes that installation (R11).
See if a failure is under warranty The work order's Warranty Candidate (WC-…, set by Warranty when a removed part is a candidate) links ↗ to Warranty.
See governance conditions on a job The work order's Dependencies: an obligation from Assurance (OBL-…) appears as an engineering / external-constraint dependency.
Close work properly Evidence → Test Result → Return to Service → Verification → Closeout.
See identifiers or every column Column-set switcher on a list → All fields.

Running it

python server/run.py work_management                       # alone, http://localhost:5087
python networks/work_supply/network.py start            # with the orchestrator, Inventory, Purchasing and Catalogue