Production Reference Public

Manufacturing Orders

Base Production Manufacturing Orders A Manufacturing Order (MO) is a single production run — it turns component materials into a finished good, moves through a controlled…

Guide version: r1 Module version: 1.0.0 Updated: 2026-07-22 Estimated time: 19 min
Base Production

Manufacturing Orders

A Manufacturing Order (MO) is a single production run — it turns component materials into a finished good, moves through a controlled lifecycle, and, on completion, automatically posts the resulting stock movements to your Inventory.

ℹ️
Where this fits. You set up Work Centers once and build a Bill of Materials for each product. A Manufacturing Order is a run of that recipe: it plans the materials, then consumes them and produces the finished good in Inventory. For the underlying stock flow (flow '-' consume, flow '+' produce), see Core Concepts & Data Flow.

What a Manufacturing Order does

An MO lets a planner declare “I want to produce X quantity of finished good Y (optionally following bill-of-materials Z)”, then tracks the run from planning to completion. Along the way ERPat:

  • Auto-generates a human-readable reference (MO-00001, MO-00002, …).
  • On Confirm, snapshots the BOM's component list — scaled to the planned quantity — onto the order, so later BOM edits never rewrite production history.
  • On Complete, posts stock movements to core Inventory: it deducts each consumed component and adds the produced finished good.

The feature reads finished goods, components, units, and variants from the core Inventory tables, so it works even if the Inventory UI is off — but a finished good must have a default inventory variant before its output can be stocked.

5
Lifecycle states
4
Lifecycle actions
3
Priorities
2
Detail tabs

The lifecycle

Every order flows left to right through Draft → Confirmed → In Progress → Done. A separate Cancelled state can be reached from any non-Done state. Done and Cancelled are terminal.

Draft
editable; nothing committed
Confirmed
components planned from BOM
In Progress
production started
Done
stock posted (terminal)
Cancelled
abandoned (terminal)

Status legend

DraftNew, not yet confirmed; editable, components not yet snapshotted.
ConfirmedCommitted; BOM components have been snapshotted (planned) onto the order.
In ProgressProduction has physically started (actual_start_date set).
DoneCompleted; inventory posted, quantity produced and actual end recorded. Terminal.
CancelledOrder abandoned; no stock is reversed. Terminal.

Priority legend

Priority is a planning aid only — there is no scheduling or capacity logic behind it in this module. It defaults to Normal and is plain dropdown text, not a coloured badge.

LowLeast urgent.
NormalDefault priority for a new order.
HighMost urgent.

State-by-state — what you can do

StateMeaningAllowed transitions
Draft Newly created, not yet committed. Editable; components not yet snapshotted. Confirm → Confirmed · Cancel → Cancelled · Delete (soft) · Edit allowed
Confirmed Committed; BOM components snapshotted onto the order. Header + components editable. Start Production → In Progress · Mark as Done → Done · Cancel → Cancelled · Edit allowed
In Progress Production physically started. Header Edit is not offered, but component lines stay editable. Mark as Done → Done · Cancel → Cancelled
Done Completed; stock posted (stock_posted = 1), quantity produced and actual end recorded. Terminal. None — cannot be edited, cancelled, or completed again.
Cancelled Abandoned. Terminal. No stock is reversed by cancellation. None — cannot be confirmed, started, or completed; only viewable / deletable.

Lifecycle actions in detail

Each action appears on the order's view page only when its guard passes, and all four require the production_update permission. Confirm, Complete, and Cancel each show a JavaScript confirm() dialog first; the page reloads on success.

Confirm Order Draft → Confirmed

Advances a Draft order to Confirmed and plans its materials. The order must exist, be in status draft, and must have a BOM. If the order has no component lines yet, the system snapshots each BOM component onto the order:

Required Quantity
bom_component.quantity × (quantity_planned ÷ bom.quantity)
Consumed Quantity
starts at 0
Unit & Notes
copied from the BOM component
Result
status becomes confirmed
⚠️
Confirm dialog: “Confirm this order? Components will be planned from the bill of materials.” On success you see “Manufacturing order confirmed. Components have been planned from the bill of materials.”
Snapshot happens only once, and only if the order has zero component lines. If you manually add any component line before confirming, the BOM will not be snapshotted at all — you keep exactly the lines you entered. Confirm also never re-snapshots an order that already has lines.

Start Production Confirmed → In Progress

Advances a Confirmed order to In Progress. The guard requires status confirmed. It sets status to in_progress and stamps actual_start_date = now if it was not already set. No inventory is posted.

ℹ️
Start Production runs immediately — there is no confirmation dialog. On success: “Production started for this manufacturing order.” This step is optional; completion can also record the start time if the order was never started.

Mark as Done (Complete) Confirmed / In Progress → Done

Completes the order and posts the stock movements. This is the moment inventory actually changes. In order:

  1. Consume each stocked component

    For every component line whose item has a default variant, ERPat writes an item_inventories row with flow '-' and qty = quantity_required, then sets that line's quantity_consumed = quantity_required. Components whose item has no default variant (e.g. services) are silently skipped — no stock is deducted and their Consumed stays 0.

  2. Produce the finished good

    Writes one item_inventories row with flow '+' against the finished good's default variant, with qty = the posted quantity produced or, if none supplied, the planned quantity.

  3. Close the order

    Sets status = 'done', records quantity_produced, actual_end_date = now, and stock_posted = 1 (also actual_start_date = now if the order was never started).

Completion confirmation dialog:
“Complete this order? Components will be consumed and the finished good produced in inventory. This cannot be undone.”
On success: “Manufacturing order completed. Stock movements have been posted to inventory.” Completion is irreversiblestock_posted is set to 1 and Done is terminal.
⚠️
No stock-availability check. There is no negative-stock guard — completing an order can drive inventory negative if components are short. The standard Mark as Done button posts only the order id, so it always uses Quantity to Produce as the produced amount; an overridden produced quantity is only possible via a posted quantity_produced parameter.

Cancel Order Any state except Done → Cancelled

Cancels an order that will not be produced. The guard refuses if status is done. It simply sets status = 'cancelled' and does not reverse any already-posted stock.

⚠️
Cancel dialog: “Cancel this manufacturing order?” On success: “Manufacturing order cancelled.” Because Done orders can't be cancelled, cancellation never has posted stock to reverse in practice — but note that cancellation on its own performs no inventory reversal.

Guards & validation messages

The lifecycle is protected by guards on the server. When a guard fails you get a specific message — know these so you can diagnose a blocked action quickly.

Message keyTextWhen it fires
bom_required_to_confirm “Select a bill of materials before confirming the order.” You click Confirm Order but the order has no BOM. A BOM is optional at creation but mandatory to confirm.
mo_no_components_to_post “Add at least one component before completing the order.” You click Mark as Done but the order has no component lines to consume.
mo_finished_good_no_variant “The finished good has no inventory variant, so stock cannot be posted.” On completion, when the finished good item has no default_variant_id. Set up the item's variant in Inventory first.
mo_already_completed “This manufacturing order is already completed.” You attempt to complete an order that is already Done / has stock_posted = 1. Guards against double-posting.
mo_invalid_status_transition “This action is not allowed for the current order status.” Any disallowed transition (wrong current status). Also returned by Save Component when the parent order isn't in an editable status.
finished_good_required Missing required — the Finished Good field is required. Saving an order without a Finished Good. The field is client-required (data-rule-required) and server-validated (item_id required|numeric).

Save validation

OnServer validatesSuccess / failure
Save order id numeric, item_id required|numeric, quantity_planned required. (Finished Good & Quantity to Produce are client-required too.) Success: “Record saved.” Failure: “An error occurred.”
Save component id numeric, manufacturing_order_id required|numeric, item_id required|numeric, quantity_required required. Success: “Record saved.” Failure: “An error occurred.”
Delete order Standard delete confirmation dialog. Success: “Record deleted.” Failure: “Record cannot be deleted.”
Delete component Standard delete confirmation dialog. Success: “Record deleted.” Failure: “Record cannot be deleted.”

Order fields

These are the fields on the Add / Edit Manufacturing Order modal and the header of the view page. Editing the header is offered only while the order is Draft or Confirmed.

FieldMeaningRequiredNotes
reference — Reference Human-readable order number, e.g. MO-00001. Auto-generated from MAX(id)+1 as MO- + 5-digit zero-padded number. System Static text in the create modal (pre-computes the next number); never user-editable; not shown when editing. Falls back to #id if empty.
bom_id — Bill of Materials Optional link to an active BOM. Its components are snapshotted onto the order at Confirm; its operations show on the Operations tab. Optional (but required to Confirm) Select2 of active BOMs; label “BOM title (finished good title)”. Selecting a BOM auto-fills Finished Good and Unit. Stored NULL if blank.
item_id — Finished Good The product this order produces; receives the flow '+' inventory movement on completion. Required Select2 of active items with item_type='product'. Must have a default_variant_id to complete the order.
quantity_planned — Quantity to Produce How many units of the finished good are planned. Drives the BOM-component scaling factor at Confirm and the default produced quantity at completion. Required Number input, step any, defaults to 1. Stored DECIMAL(15,2); passed through convert_number_to_decimal().
quantity_produced — Quantity Produced Actual output produced; set at completion (defaults to Quantity to Produce). 0 until Done. System (set on Complete) DECIMAL(15,2). Read-only in the UI; only the complete action can set it (via optional posted quantity_produced).
unit_id — Unit Unit of measure for the finished good output. Optional Select2 from Units; label “title - value child_title” for child units. Falls back to the item's unit_id when posting stock. Stored NULL if blank.
work_center_id — Work Center The production work center / resource assigned to the run. Optional Select2 of active work centers; label “code - title” (or just title). Display / reference only — no scheduling logic. Stored NULL if blank.
priority — Priority Planning priority: Low, Normal, or High. Optional Select2; defaults to normal. VARCHAR(20). Display / planning aid only.
status — Status Lifecycle state: draft, confirmed, in_progress, done, cancelled. System Defaults to draft on create. Changed only by lifecycle actions, never editable in the form. VARCHAR(20).
planned_start_date — Planned Start Intended production start date. Optional HTML date input (DATE). 0000-00-00 treated as empty and shown as “-”. Used by list filters and status-summary date ranges.
planned_end_date — Planned End Intended production end date. Optional HTML date input (DATE). 0000-00-00 treated as empty.
actual_start_date — Actual Start Timestamp the order actually started production. System DATETIME. Set to now on Start Production (if empty); also set on Complete if never started.
actual_end_date — Actual End Timestamp the order was completed. System DATETIME. Set to now on Complete. Drives output / consumption reports' date ranges.
stock_posted — (internal) Stock Posted flag 1 once completion has posted inventory movements; guards against double-posting. System TINYINT(1), default 0. Not shown in UI. Complete refuses if already 1.
notes — Notes Free-text remarks about the order. Optional TEXT. Rendered with nl2br on the view page.
created_by — Created By User who created the order (shown as legal name in the list). System Set to the logged-in user's id on create.
created_at — (created timestamp) UTC creation time. System Set via get_current_utc_time() on create.
????
Pick a BOM first. In the modal, choosing a Bill of Materials auto-fills the Finished Good and Unit for you (via the bom_meta map). The help text under the BOM field reads “Components are copied from the bill of materials when the order is confirmed.”

Components & Operations tabs

The order's view page has two AJAX tabs. The Components tab auto-opens shortly after the page loads.

The per-order snapshot of required materials — the component lines. When the order is editable you can add, edit, and delete lines here. The Add Component button appears only when you have production_update and the order status is draft, confirmed, or in_progress.

ColumnMeaningRequiredNotes
item_id — Component The material / item consumed by the order. Required Select2 of active product items (“- Select item -”). Its default_variant_id receives the flow '-' movement on completion.
quantity_required — Required Quantity How much of the component this order needs; snapshotted from BOM (scaled) or entered manually. Required Number input, step any, DECIMAL(15,2). This exact amount is what is consumed on completion.
quantity_consumed — Consumed Quantity Amount actually issued to production. 0 until completion. System On Complete it is set equal to Required Quantity for each stocked component. DECIMAL(15,2).
unit_id — Unit Unit of measure for the component line. Optional Select2 from Units; falls back to the component item's unit_id when posting stock.
notes — Notes Free-text remark on the component line. Optional VARCHAR(500). Copied from the BOM component note on snapshot.
ℹ️
Add / Edit Component modal. Pick a Component (required, placeholder “- Select item -”), enter the Required Quantity (required) with its Unit beside it, and optional Notes. Saving re-checks on the server that the parent order is still in an editable status (draft / confirmed / in_progress); if not you get “This action is not allowed for the current order status.”

A read-only view of the routing operations inherited from the order's BOM. There is no add / edit here — operations are managed on the Bill of Materials.

ColumnMeaningRequiredNotes
sequence — Sequence Order / step number of the routing operation (from BOM). Read-only Displayed as an integer, centered.
title — Operation Name of the routing step (from BOM operations). Read-only Read-only display.
work_center_title — Work Center Work center for that operation step. Read-only Shows “-” if none.
duration_mins — Duration (minutes) Standard duration of the step in minutes. Read-only Right-aligned decimal.
notes — Notes Remarks for the operation step. Read-only Empty / absent values render as “-”.
ℹ️
If the order has no BOM (or the BOM has no operations), the tab shows “No components defined yet.” across all columns — a slightly misleading label for the operations table, but that is the shared empty-state text.

The Manufacturing Orders list

The list is a DataTable (manufacturing-orders-table) with a refresh button and a status filter dropdown. The Add Manufacturing Order button (top-right) is shown only with the production_create permission.

ColumnShows
ReferenceThe MO-##### number, linked to the order's view page.
Finished GoodThe product being produced.
Bill of MaterialsThe linked BOM (if any).
Quantity to ProduceRight-aligned, shown with its unit.
Quantity ProducedRight-aligned; 0 until Done.
StatusCentered coloured label (Draft / Confirmed / In Progress / Done / Cancelled).
Planned StartThe planned start date.
Created ByCreator's legal name.
OptionsView / Edit / Delete (each shown per its guard).

The default sort is Reference descending (newest first). The Status filter (a Select2 with a leading “- Status -” blank option) reloads the table server-side, showing only orders in the chosen state.


SOP — run a make-to-stock production order

The end-to-end standard operating procedure for a full production run, from planning to posted stock.

  1. Check the preconditions

    The finished good item must exist and have a default inventory variant. If you'll use a BOM, an active BOM for that finished good (with components, and optionally operations) must exist. Component items to be stocked must also have default variants. See Getting Started → Prerequisites.

  2. Create the order (Planner)

    Go to Production → Manufacturing Orders and click Add Manufacturing Order. Select the BOM (auto-fills Finished Good + Unit), set Quantity to Produce, and set priority / dates / work center as needed. Click Save. The order is created as Draft with an auto reference like MO-00007.

  3. Confirm to plan materials (Supervisor)

    Open the Draft order and click Confirm Order — a BOM is mandatory to confirm. Accept the dialog “Confirm this order? Components will be planned from the bill of materials.” The BOM components are snapshotted onto the order, scaled to the planned quantity. The order becomes Confirmed.

  4. Review & adjust the plan

    Review the Components tab; adjust Required Quantities or add / remove component lines while the order is Draft / Confirmed / In Progress. Review the Operations tab (read-only routing from the BOM).

  5. Start production (Operator)

    When work begins, click Start Production (Confirmed only) to record the actual start time. The order becomes In Progress. This is optional — completion can also record the start time.

  6. Complete & post stock (Operator / Supervisor)

    When output is finished, click Mark as Done and accept “Complete this order? Components will be consumed and the finished good produced in inventory. This cannot be undone.” ERPat deducts each stocked component (flow '-', qty = Required Quantity) and adds the finished good (flow '+', qty = Quantity Produced, defaulting to Quantity to Produce). The order becomes Done; Quantity Produced and Actual End are recorded, and each component's Consumed Quantity is set.

  7. (Or) Cancel if abandoned

    If the run is abandoned before Done, click Cancel Order (any non-Done state) and accept “Cancel this manufacturing order?” Cancellation does not post or reverse stock.

How component quantities are computed at Confirm

  1. Compute the factor

    Factor = Quantity to Produce (MO) ÷ BOM output quantity (bom.quantity, treated as 1 if 0 or missing).

  2. Scale each component

    For each BOM component: snapshot Required Quantity = BOM component quantity × Factor.

  3. Only if empty

    The snapshot happens only if the order currently has zero component lines; if you already added lines manually, Confirm will not overwrite them.

  4. Consumed starts at 0

    Consumed Quantity starts at 0 and is filled in at completion.

⚠️
A BOM output quantity of 0 (or missing) is treated as 1, which can inflate scaled quantities — set the BOM's output quantity correctly. See Bill of Materials.

Common use cases

Role: Production Planner. Manufacturing Orders → Add Manufacturing Order. In Bill of Materials, pick an active BOM — Finished Good and Unit auto-fill. Enter Quantity to Produce (e.g. 100). Optionally set Work Center, Priority, Planned Start / End, Notes. Save. The order appears as Draft with an auto reference like MO-00007.
Role: Production Supervisor. Open the Draft order (click its reference). Click Confirm Order and accept “Confirm this order? Components will be planned from the bill of materials.” The system copies the BOM components, scaling each by (Quantity to Produce ÷ BOM output quantity), into the Components tab with 0 consumed. Status becomes Confirmed; review the Components tab and add / edit lines if needed.
Role: Supervisor / Operator. Open a Confirmed order. Optionally click Start Production to mark it In Progress (records actual start time). When output is finished, click Mark as Done and accept “Complete this order? Components will be consumed and the finished good produced in inventory. This cannot be undone.” The system deducts each stocked component (flow '-', qty = Required Quantity) and adds the finished good (flow '+', qty = Quantity Produced, defaulting to Quantity to Produce). Status becomes Done; Quantity Produced and Actual End are recorded, each component's Consumed Quantity is set.
Role: Production Supervisor. Open a Draft / Confirmed / In Progress order, go to the Components tab, click Add Component, pick the item, enter Required Quantity and Unit, add optional Notes, and Save. The extra material will be consumed from inventory when the order is completed.
Role: Production Planner. Open any order that is not yet Done. Click Cancel Order and accept “Cancel this manufacturing order?” Status becomes Cancelled. Note: if stock was somehow already posted, cancellation does not reverse it (Done orders can't be cancelled anyway).
Role: Manager. Go to Manufacturing Orders. Use the Status filter dropdown to pick Draft / Confirmed / In Progress / Done / Cancelled. The table reloads showing only matching orders; click a reference to drill in.

Permissions

Reaching any Manufacturing Orders page requires that the Production module is enabled and you hold the base production access.

PermissionGrants
production (module + access)Reach any Manufacturing Orders page and View an order (no separate view permission key).
production_createCreate a new manufacturing order (the Add button and save() on a new record).
production_updateEdit orders, add / edit / delete component lines, and run all lifecycle actions (Confirm, Start, Complete, Cancel).
production_deleteSoft-delete a manufacturing order (and cascade-delete its component lines).
ℹ️
Gated actions you lack permission for return the standard no permission response; page-level access failures redirect. See the full Permissions & Roles matrix.

Gotchas & things to watch

Confirm requires a BOM. Even though the BOM field is optional at creation, Confirm fails with “Select a bill of materials before confirming the order.” if the order has no BOM.
⚠️
  • Snapshot is once-only. BOM components are copied at Confirm only if the order has zero component lines. Add any line manually first and the BOM will not be snapshotted at all.
  • Silent skips. Completion consumes each line's Required quantity and sets Consumed = Required — but a component whose item has no default variant is silently skipped (no stock deducted, Consumed stays 0).
  • Finished good needs a variant. Completion is blocked with “The finished good has no inventory variant, so stock cannot be posted.” if the item has no default variant. Set it up in Inventory first.
  • No negative-stock guard. Completing can drive inventory negative if components are short — there is no availability check.
  • Irreversible completion. stock_posted is set to 1 and Done is terminal; re-completing is refused (“This manufacturing order is already completed.”). Cancelling a Done order is refused, and cancelling other states does not reverse posted stock.
  • Editing scope quirk. The header Edit button appears only in Draft / Confirmed, but component lines stay editable through In Progress. Delete Component does not re-check order status, so a line could be deletable even when Save is blocked.
  • Delete cascades. Deleting an order soft-deletes it and deletes all its component lines — there is no undo in the UI.
  • Reference gaps. References derive from MAX(id)+1, so gaps appear if orders are deleted; the reference is fixed at creation and never renumbered.
  • Informational only. Work Center and Priority carry no scheduling / capacity logic in this module.

Related pages

Was this guide helpful?

Report a content problem