How it fits together

Make to stock

Components go in, a finished product comes out, and the cost of one becomes the cost of the other. Here's the whole loop — recipe, work order, consumption, completion, and the sale that finally relieves it.

User guide › Make to stock

Manufacturing sits on top of stock

It owns no inventory model of its own. Installing Manufacturing installs Point of Sale with it, because components and finished goods are the same product catalog, held in the same warehouses, moved through the same stock ledger you read about in Stock lifecycle. Read that page first if you haven't — this one assumes it.

The shape of the loop

Three quantities move, and they move in a strict order. Nothing skips a stage:

StageWhere the value lives
Components on the shelfInventory. Bought and received like anything else.
Work in progressValue that has left the component shelf but isn't a finished product yet.
Finished goods on the shelfInventory again — at the cost the build actually consumed.

Value is conserved the whole way round. What you take off the component shelf is exactly what lands on the finished-goods shelf, which is exactly what the sale later relieves. Do the loop and come back to zero.

The journey

  1. Write the bill of materials — /mfg-boms

    A BOM is a recipe: pick the finished product, then add a component line per material with the quantity needed for one output unit. Quantities carry each product's unit, so a recipe reads as 0.25 kg, 2 pc, 0.1 L rather than bare numbers.

    BOMs are versioned and carry a status of draft, active or archived. Only one version per product can be active at a time — activating a new one automatically archives the previous, so switching a recipe is a one-field edit and there's never an ambiguity about which recipe a new work order will use.

    Recipes can nest: a component that has its own active BOM is a sub-assembly, and the editor flags it. A cycle — A needs B, B needs A — is refused outright.

    Stock: unchanged. Ledger: nothing. A recipe is reference data.

  2. Raise a work order — /mfg-production

    Choose the product and how many you're building. The active BOM is exploded against that quantity into work-order lines — one per component, with the planned quantity, resolved name and SKU. The order is numbered WO-YYYYMMDD-NNNN and starts at status planned.

    Alongside the explosion you get a live shortage preview: each component's planned quantity against what's on hand, so you can see before you commit whether the build is possible. It's a preview, not a block — creating the work order is always allowed.

    Stock: unchanged. Creating a work order reserves nothing. Components stay sellable and available to other builds until you actually issue them. Ledger: nothing.

  3. Issue the components

    This is the step that consumes stock. For each line, in one transaction:

    • A consume stock movement (negative) is written, referencing the work-order number.
    • The component's on-hand balance is decremented under a row lock.
    • The cost relieved is snapshotted onto the work-order line, and the total is added to the order's WIP value.

    Availability is checked twice — once up front and again under the lock — and the whole issue is refused if any line is short. There is no overselling on a shop floor: you cannot consume material that isn't there. Fix the shortage and issue again.

    Issuing is repeatable. The first issue flips the order to in progress; later issues top it up, which is how you record spoilage or a component you underestimated. Each issue adds to WIP.

    Lot-tracked components are drawn down soonest-expiry-first; serial-tracked units are marked consumed against the work order.

    Ledger under perpetual: Dr Work in progress (1320) / Cr Inventory (1340) at the value issued. Value moves from the shelf to the floor; nothing has been spent.

  4. Add labour and overhead (optional)

    Extra cost lines — labour, overhead, other — can be added to an open work order with a description and an amount. They capitalise into WIP alongside the materials, so the finished unit cost reflects what the build really cost, not just its parts. They stay editable until the order completes or is cancelled.

    Ledger under perpetual: Dr WIP (1320) / Cr Production costs absorbed (7250). The credit offsets the expense you already booked when you paid for the labour, so the cost ends up in inventory and only hits your P&L when the finished product sells. Removing a cost line reverses the entry.

  5. Complete the build

    Record how many good units you got. That quantity goes into finished-goods stock at the destination warehouse: a produce movement (positive) plus a balance increase, valued out of the open WIP.

    Two cases decide the valuation:

    • A partial receipt — you're receiving fewer units than remain planned — takes the current WIP average per remaining planned unit, and the order stays in progress.
    • The final receipt — reaching the planned quantity, or exceeding it — sweeps the entire remaining WIP into the units received, so rounding can never strand a few tetri in work in progress.

    Finishing short is explicit: complete with the close option and the good units are valued normally while the leftover WIP is written off as scrap. The order goes to completed and its unit cost is recorded.

    Ledger under perpetual: one balanced journal — Dr Inventory (1340) for the value received, Dr Inventory write-off (7110) for any scrap variance, and Cr WIP (1320) for the total.

  6. The finished good's cost updates

    Completion blends the built cost into the finished product's own running average, using the same weighted-average formula a purchase receipt uses. This is the roll-up: the price of the components, plus any labour and overhead you capitalised, divided by the good units produced, folded into the product's cost.

    A lot-tracked finished good gets a production lot named after the work order. Serial-tracked finished goods register the serials you supply as in stock.

  7. Sell it — /pos or the online store

    From here the finished good is an ordinary product. It sells at the register, in the store, on an invoice line — with no idea it was ever manufactured. Checkout decrements its stock, relieves its cost, and (under perpetual) posts Dr COGS (7100) / Cr Inventory (1340).

    Because the build capitalised into the same inventory account the sale relieves, the loop closes cleanly. See Order to cash.

A worked example

Build 10 units from 20 parts bought at 5 each. Perpetual inventory, no extra costs, rounding ignored.

OperationJournalInventory 1340WIP 1320
Receive 20 parts @ 5 Dr Inventory 100 / Cr GRNI 100 +100
Issue components Dr WIP 100 / Cr Inventory 100 −100 → 0 +100
Complete 10 (unit cost 10) Dr Inventory 100 / Cr WIP 100 +100 → 100 −100 → 0
Sell all 10 Dr COGS 100 / Cr Inventory 100 −100 → 0

Inventory and WIP both finish at zero. GRNI sits at −100 until the supplier's bill clears it, exactly as it would for goods you bought to resell.

Costing method changes the detail, not the shape

Everything above describes the default weighted average: components are relieved at the product's running average cost.

Under FIFO, the same steps instead relieve component cost layers at their actual cost, oldest first — or soonest-expiring first for lot-tracked materials — and completion mints a production layer at the built unit cost, tagged to the production lot where the finished good is lot-tracked. Cancelling re-enters the returned components as layers at their snapshot cost.

The choice is workspace-wide and lives with the other inventory settings under Settings → Accounting. See Stock lifecycle for how the two methods differ.

Cancelling a work order

Three outcomes, depending on how far the order got:

StateWhat cancel does
Planned — nothing issued A paperwork flip. Nothing to undo; the order goes to cancelled.
In progress — components issued, nothing completed Every issued component returns to stock at its snapshot cost via reversal movements, so net consumption for the order is zero. WIP and any extra costs reverse. Serial units this order consumed are restored.
In progress — something already completed Cancel is refused. Finished goods are already on the shelf, so the correct action is to close short — take the good units and write off the residue.

Make to order — the other model

Not everything is built ahead of time. A restaurant doesn't hold finished burgers on a shelf; it holds mince, buns and cheese, and assembles on demand. For that, each product carries a Fulfilment setting.

FulfilmentWhat selling one does
Build to stock (the default — this page) Relieves the finished product's own stock. The units had to be produced first by a work order.
Make to order Consumes the active BOM's ingredients from stock instead, at their cost — no finished-goods stock, no work order. The cost of goods sold is the ingredient cost.

Leaving a product's setting empty inherits the workspace default. Short ingredients block the sale unless the register allows overselling. Selling a made-to-order product never creates a work order — production stays a deliberate act.

Reporting

/mfg-reports carries three views built directly off the records above:

  • WIP valuation — open work orders and the value sitting in them. This is the figure you reconcile against the work-in-progress account.
  • Production history — what was built, when, and at what unit cost.
  • Component consumption — where your materials went.

Work orders themselves are also browsable as a standard entity at /mfg-work-orders, with the full cost trail on each record.

When production doesn't add up

"Issue was refused and I'm sure we have the parts"

Check the warehouse. The work order names a component warehouse, and availability is checked there — parts sitting in another location don't count. Transfer them first (/pos-transfer) or set the work order's component warehouse correctly. The issue is all-or-nothing: one short line cancels the whole call, so read the error for which component it named.

"WIP won't go to zero"

An order left in progress is holding its WIP legitimately — you issued components and haven't completed. To finish it, either complete the remaining planned units, or complete with close short, which sweeps the leftover WIP to the write-off account as scrap. Partial receipts intentionally leave WIP behind; only a final or short close clears it.

"The finished unit cost looks too high or too low"

The unit cost is the WIP swept into the receipt divided by the good units received. So it moves if: you issued extra components as top-ups (spoilage raises it), you added labour or overhead cost lines, or you received fewer good units than planned. Check the work order's cost trail — issued value, extra costs and completed quantity are all on the record.

A component with a wrong cost propagates straight through. If a material was received without a unit cost its average never updated, and the build inherits that. Fix it on the purchase side, not here.

"I completed a build and the ledger shows nothing"

Inventory method is on the default periodic. Manufacturing then moves stock but posts nothing at all — which is correct for a periodic business, where cost of sales is worked out from opening stock, purchases and closing stock rather than transaction by transaction.

Note that production postings work differently from POS sales and goods receipts: they aren't behind an auto-action toggle. Under perpetual they always post, because they're mandatory — without the WIP legs, selling the finished good would relieve component value that was never moved, and the inventory account would go negative.

"I can't activate a second BOM version"

You can — activating one archives the other automatically, on purpose. One active recipe per product means a work order raised tomorrow can't quietly explode a recipe you thought you'd retired. If you need to compare, keep the old version as archived; it stays readable.

"A sub-assembly didn't get built automatically"

By design. A component that has its own BOM is consumed from stock like any other component — it isn't exploded recursively and no child work order is created. Build the sub-assembly with its own work order first, then build the parent. The editor flags sub-assembly lines so you know which ones need doing first.

"Selling my product didn't reduce its stock"

Its Fulfilment is set to make to order, so the sale consumed the recipe's ingredients instead of finished-goods stock. That's the intended behaviour for kitchens and assemble-on-demand items. Switch the product to build to stock if you want it to draw down produced units instead.

"A colleague can browse production but can't run it"

Reading BOMs, work orders and reports needs plain access to the Manufacturing app. Every action that moves stock or posts to the ledger — create, issue, complete, cancel — needs the build capability, which starts admin-only until granted. The server enforces it regardless of what the buttons look like.

Where to go next