Key takeaways
A production work order is an instruction to make a stated quantity of one item, to one revision, by one date. It carries its own copy of the routing and the bill of materials, so changes to the master data do not rewrite orders already on the floor.
Different systems use different names: manufacturing order, production order, shop order or job. The structure below applies to all of them.
A maintenance work order is a different object. It asks a technician to inspect or repair an asset, and it links to a machine, not to a part number or a customer order.
If you came here for corrective, preventive or inspection orders, read work order types explained. This page covers only the production side.
The header holds one row per order. It answers what, how many, by when and for whom.
| Field | What it holds |
|---|---|
| order_ | Unique order number, e.g. WO-24017 |
| item_ | Part number being made |
| item_ | Drawing or engineering revision, e.g. C |
| bom_ | Versions copied into the order at creation |
| qty_ | Quantity to make |
| qty_ | Good quantity reported at the last operation |
| qty_ | Sum of scrap booked on all operations |
| uom | Unit of measure: pcs, kg, m |
| due_ | Date the parts are needed |
| planned_ | Dates from scheduling |
| actual_ | First and last transaction time |
| priority | Sequence rank, e.g. 1 to 5 |
| status | Lifecycle state (see below) |
| sales_ | Customer demand link, empty for make to stock |
| lot_ | Lot or batch number of the output |
| site / plant | Where the order runs |
Keep qty_completed and qty_scrapped as derived totals of the transactions, not as numbers someone types. Typed totals drift away from the records within weeks.
A clean lifecycle has seven states. Each one should be triggered by a specific event, so the status always means the same thing.
| Status | Triggered by |
|---|---|
| Planned | Order created or converted from an MRP planned order, not yet on the floor |
| Released | Planner releases it after material and capacity checks |
| In progress | First operation start is booked |
| On hold | Quality block, missing material or customer change |
| Completed | Last operation reports its final quantity |
| Closed | Costs settled, no more bookings allowed |
| Cancelled | Order withdrawn before any booking; a started order is short-closed instead |
Two rules keep the lifecycle honest. No bookings before Released, and no bookings after Closed.
On hold should always carry a hold reason and a timestamp. Otherwise a late order and a blocked order look identical in every report.
The routing lists the steps and where they happen. When the order is created, the routing is copied into order operations, one row per step.
For the difference between the two master data structures, see BOM vs routing.
| Field | What it holds |
|---|---|
| op_ | Sequence: 10, 20, 30 (gaps allow inserts) |
| work_ | Machine or cell, e.g. WC-MILL-01 |
| setup_ | Minutes per order, not per part |
| ideal_ | Seconds per part at rated speed; store parts per cycle for multi-part fixtures |
| run_ | Standard time per unit, if different from ideal |
| queue_ | Expected wait before the operation |
| move_ | Transport to the next operation |
| labour | Crew size and skill for setup and run |
| instructions | Work instruction, drawing and program link |
| op_ | Not started, running, paused, done |
The distinction between ideal cycle time and standard run time matters. Many routings carry a standard padded with allowances, which is fine for costing but useless as a speed target.
Store both if you need both. Our guide to ideal cycle time explains how to set the fast one.
The bill of materials is copied into order components, one row per material. Each line can point to the operation that consumes it.
| Field | What it holds |
|---|---|
| component_ | Part number of the material |
| qty_ | Quantity per one parent unit |
| uom | Component unit: pcs, kg, m |
| qty_ | qty_ |
| qty_ | Quantity issued or backflushed so far, net of returns |
| consume_ | Operation where it is used, e.g. 10 |
| issue_ | Manual issue or backflush |
| lot_ | Yes or no; if yes, lot_ |
Manual issue means someone picks the material and books it to the order before or during the run. It is accurate but costs a transaction every time.
Backflush means the system deducts qty_per × reported quantity when an operation reports output. It is cheap, but scrapped parts still consumed material, so the stock goes wrong if scrap is not booked at the right operation.
For lot-tracked components, record which component lot went into which output lot. That link is your genealogy when a customer complaint arrives.
The header, operations and components are the plan. The transaction records are the truth, and every report should be built from them.
| Record | Key fields |
|---|---|
| Operation event | order_ |
| Quantity report | order_ |
| Scrap record | report_ |
| Downtime event | work_ |
| Labour booking | employee_ |
| Material issue | order_ |
Note that a downtime event belongs to the machine first and the order second. A machine can stop with no order on it, and that time still needs a reason.
Keep the reason lists short and specific. Our guide to downtime reason code design shows how to build one.
In words: one item has one or more routings and BOMs. One work order makes one item and copies one routing into many order operations and one BOM into many order components.
Each operation runs on one work center and collects many quantity reports, scrap records, labour bookings and events. Downtime events link to the work center and, when a job was running, to the order and operation.
| Table | Primary key | Foreign keys |
|---|---|---|
| work_ | order_ | item_ |
| order_ | order_ | order_ |
| order_ | order_ | order_ |
| quantity_ | report_ | order_ |
| scrap_ | scrap_ | order_ |
| downtime_ | event_ | work_ |
| labour_ | booking_ | employee_ |
| material_ | issue_ | order_ |
The composite key order_no + op_no is the spine of the model. Almost every question about a job ("where did we lose the time?") is answered by grouping on it.
Order WO-24017 asks for 1,200 pcs of bracket BRK-220 rev C. The routing has three operations.
| Operation | Setup + ideal cycle | Planned hours |
|---|---|---|
| 10 Turning (WC-TURN-02) | 45 min + 42 s | 14.75 h |
| 20 Milling (WC-MILL-01) | 60 min + 55 s | 19.33 h |
| 30 Deburr and wash | 15 min + 18 s | 6.25 h |
| Total | 40.33 h |
Operation 20 has the longest cycle, so it is the bottleneck. At 55 s per part it can deliver at most 3,600 ÷ 55 = 65.5 parts per hour, however fast turning runs.
If operations overlap, milling sets the finish date; if the whole lot moves at once, every operation adds its full time. See bottleneck analysis for the wider method.
The transaction records for the order show the following. Operation 10 scrapped 12 parts, so 1,188 reached milling.
| Operation 20 actuals | Value |
|---|---|
| Time the order held WC-MILL-01 (OEE planned production time) | 1,320 min (22.0 h) |
| Setup (planned 60) | 75 min |
| Unplanned downtime (spindle alarm, tool waits) | 95 min |
| Run time | 1,150 min |
| Parts processed | 1,188 |
| Scrap (reason: oversize bore) | 18 |
| Good parts | 1,170 |
Check it in one step: 1,170 good × 55 s = 64,350 s = 1,072.5 min, and 1,072.5 ÷ 1,320 = 81.25%, which rounds to 81.3%. The method is the same as in our OEE calculation guide, just scoped to one order and one operation.
Efficiency against the routing standard, here equal to the ideal cycle, tells a similar story. Standard minutes earned are 60 setup + 1,089 run = 1,149, and 1,149 ÷ 1,320 = 87.0% (see production efficiency for why the two numbers differ).
Operation 30 scrapped 2 more, so the order completes 1,168 good and 32 scrapped (12 + 18 + 2). Yield against the order is 1,168 ÷ 1,200 = 97.3%.
The order is 32 short. Because scrap was booked per operation with a reason, the planner knows 18 of the 32 came from oversize bores at milling, and can add a scrap factor or fix the process before the next order.
No single system owns the whole model in most plants. The split below is the common pattern, and it works when each field has exactly one owner.
| System | Owns |
|---|---|
| ERP | Item master, BOM, routing, order header, status up to Released, costs, Closed |
| MES | Dispatching, operation events, quantity and labour reports, material issue, genealogy |
| OEE / machine data | Machine states, cycle counts, downtime and short stops, OEE per run |
Our pages on the manufacturing execution system and MES vs ERP cover the boundary in more depth.
If actuals never flow back, nobody sees that the routing standard is wrong. In the example, milling was planned at 19.33 h and really took 22.0 h.
Without it, performance cannot be calculated and the bottleneck has to be guessed. A padded standard hides slow running inside "normal".
If scrap is booked as one number at order close, you know how many were lost but not where. Book it per operation with a reason, as in step 5 of the example.
Setup is per order and run time is per part. Mixing them breaks planned hours for every order size except the one the standard was built on.
Stops between orders then disappear. Store downtime against the work center and link the order when one was running.
If the order points to the live BOM or routing instead of a copy, an engineering change can rewrite a job that is half finished.
Typed totals disagree with the records and nobody knows which is right. Derive qty_completed and qty_scrapped from the scrap and quantity reports.
For the lot side of the order, with supplier lots, lot status and genealogy, see our lot traceability data model.
Fabrico does not create, plan or schedule production orders. Your ERP keeps that job.
Fabrico measures what happens on the machine while an order runs: OEE, downtime, short stops and cycle times, captured through PLC connections, IoT sensors and AI cameras.
Order data such as the product and its ideal cycle time can come in from your ERP, so each run is scored against the right target. The AI assistant answers questions about a machine's losses in plain language.
On the maintenance side, Fabrico is a full CMMS: your team creates maintenance work orders, runs preventive plans and tracks spare parts consumed per work order, from web or mobile apps.
Want to see how your orders really run on the bottleneck? Book a 30 minute demo with a Fabrico consultant, no commitment, or contact us with your questions.
At minimum: order number, part number and revision, quantity ordered, completed and scrapped, unit of measure, due date, planned start and finish, priority, status and lot number. Add operations from the routing and material lines from the BOM, each with its own fields.
A production work order makes a quantity of a part and links to an item, routing and BOM. A maintenance work order repairs or inspects an asset and links to a machine.
A typical lifecycle is Planned, Released, In progress, On hold, Completed and Closed, with Cancelled as an exit. Each status should change on a specific event, such as the first operation start for In progress.
On the routing operation, per part and per work center, and copied into the order operation. That lets you calculate planned hours, find the bottleneck and score performance for each run.
Per operation, with a reason code. The order total is then the sum, and you can see which step lost the parts.