Skip to content

Material planning & costs

This page covers the planning and costing layer beneath the canvas — what gets stored when an item is added, how operator overrides are tracked, where the three cost figures come from, and which buttons get you back to a clean state.

  • The spread, in plain language
  • Original vs. effective quantity
  • The three cost views
  • Per-item material cost (Shopify cost push)
  • Labour cost
  • Pre-assembled vs. to-build splits
  • Reset paths

When you add an item to a work order, Assemblified walks the item’s BOMBill of MaterialsA bill of materials tells Assemblified how to build one unit of a finished good. When a customer orders the finished-good variant, Assemblified deducts the right component quantities from inventory automatically. Read more → and any sub-assembliesSub-AssemblyA reusable assembly block that composes into bigger BOMs. Define it once, include it in any BOM. At execution time, Assemblified expands the sub-assembly into its own components recursively. Read more → nested inside it. For every leaf raw material the walk encounters, it adds (or finds and merges into) a row on the work order’s materials list. For every sub-assembly, it adds an SA row and recurses into the SA’s own components — but everything still ends up on one flat materials list, so when you build, you’re picking from a single pile.

That walk is the spreadSpreadThe step that walks each item's BOM (and any sub-assemblies inside it) and turns the result into the flat list of materials the work order needs. Runs automatically when you add an item — unless you choose "skip for now" and plan the materials yourself. Read more → . The result has two side-effects:

  • A flat list on the Materials tab, deduped per (material type, material id).
  • A contribution tree under the hood that records “item X needs Y units of material Z, sourced via path P.” This is what lets the canvas show you, per row, which item(s) actually require the material.

The spread runs automatically on item add and on quantity change (unless the item is decoupledDecoupleDetaching one work-order item from the live BOM so its material list stops following BOM updates. After you decouple, edits to the BOM no longer flow into this work order — useful when you've already started a build and need a frozen recipe. Read more → ). You can also run Refresh from BOM at any time to reconcile the materials list with the current BOM definitions — see canvas editor → refresh from BOM.

Each material row carries two quantities:

  • Original quantity — what the spread (or a manual add) wrote. The BOM-ratio truth, frozen at spread time.
  • Effective quantityEffective QuantityThe quantity actually consumed by the work order, after operator overrides. Starts equal to the original BOM quantity, but can be adjusted up or down per material as plans change. The effective quantity is what the pick list and cost calculations use. Read more → — what will actually be consumed when you build. Starts equal to original, but operators can edit it from the Materials tab.

Effective quantity is what every downstream system reads — pick lists, cost calculations, build-run plans. Original quantity is preserved so you can compare the two and see where operator overrides have moved away from the BOM.

When a row’s effective quantity has been manually edited, it gets flagged as manually overridden. Refresh-from-BOM respects the flag and leaves the quantity alone. Reset material quantities (see below) is the way to wipe overrides en masse.

Every work order shows three cost figures in the General tab’s summary card. Hover any of them in the UI for the same definitions.

PlannedPlanned CostThe cost of the work order based on the current operator plan — uses the effective quantities and any unit cost overrides you've set. Updates live as you edit the plan. This is the figure shown most prominently on the detail page. Read more →

Section titled “Planned”

What the current operator plan says. Uses the effective quantities and any unit cost overrides you’ve entered. Recomputes live on every canvas mutation.

This is the figure to look at when answering “if I build this exactly as planned today, what will it cost?”

BaselineBaseline CostThe cost of the work order if it were built strictly to the BOM — uses the original BOM quantities, frozen at the moment items were spread onto the work order. Compare against planned cost to see the impact of operator overrides. Read more →

Section titled “Baseline”

What the BOM said when the items were spread. Uses original quantities, master unit costs, and the original pre-assembled splits frozen at spread time. It does not move when the operator edits the plan.

This is the figure to look at when answering “what was the recipe’s expected cost before I made any adjustments?” The delta between Planned and Baseline tells you the impact of every override.

ActualActual CostWhat the work order really cost, derived from materials that have been consumed by completed build runs. Stamped into the audit ledger at the moment of consumption, so it doesn't drift if prices change later. Read more →

Section titled “Actual”

What the build runs actually cost. Derived from the inventory ledger after build runs complete: each consumption row stamps the unit cost at the moment of consumption, and Actual is the sum.

This is the figure to look at when answering “what did this work order really cost to build?” Because the cost is stamped at consumption time, a later edit to a master cost does not retroactively rewrite Actual on already-built runs.

Per-item material cost (Shopify cost push)

Section titled “Per-item material cost (Shopify cost push)”

The Update Shopify cost action computes the cost attributable to a single BOM item — separated out from the rest of the work order’s items — and pushes it to the BOM as Shopify’s per-product cost. This lets a built finished good carry the cost it actually took to produce, rather than a static recipe estimate.

The math walks the contribution tree from the item down through its sub-assemblies, scaling each sub-assembly’s contribution by its own to-build ratio so a sub-assembly that’s drawn 100% from pre-assembled stock contributes nothing fresh. Raw cost adds up, pre-assembled SA cost adds up, the divisor is the item’s completed quantity (or planned quantity if nothing’s built yet), and the per-unit figure goes to Shopify.

Sub-assembly items and bare-variant items are excluded — only BOM items are eligible for the cost push.

The edit-details dialog has a Labour cost section with two inputs: Planned and Actual.

  • Planned labour flows into the Planned cost figure on the summary card.
  • Actual labour flows into the Actual cost figure.
  • A baseline labour line is captured the first time you write a non-null planned labour cost, then frozen, so editing the planned labour later doesn’t move the baseline.

Labour cost is operator-entered. Assemblified doesn’t track time spent — that’s outside the work-order surface.

For per-unit labour that scales with order quantity (rather than per-batch), model labour as a virtual material inside the BOM. See Track building cost for the full pattern, including when to use the per-unit virtual approach vs. the per-WO field — and Check BOM margin and cost breakdown for reading the rolled-up cost.

When the spread encounters a sub-assembly material, it splits the required quantity into:

  • Quantity from pre-assembled — drawn from existing pre-assembled stock at the work order’s production location.
  • Quantity to build — built fresh from the SA’s own raw materials, which were also added to the materials list by the spread’s recursion.

The split is computed at spread time using current pre-assembled inventory. If inventory at the production location changes after you’ve planned the work order — somebody else built or consumed pre-assembled stock — the split can become stale. The Materials tab shows a banner when this happens; click Reconcile pre-assembled to rebalance.

The constraint quantityFromPreassembled + quantityToBuild = effectiveQuantity is enforced; you can’t break it through the UI.

When the plan diverges too far from the BOM and you want a clean slate, three actions get you back:

ActionScopeWhat it clearsWhat it doesn’t touch
Reset material quantitiesAll materialsEvery manual override flag; re-runs the spread for every item.Build runs, lifecycle events, items themselves.
Reset to BOM (per item)One itemDecouples flag on that item; re-runs spread for its materials.Other items’ overrides.
Reconcile pre-assembledAll sub-assembly materialsAdjusts quantityFromPreassembled to current shelf stock; rebalances quantityToBuild.Manual quantity overrides on raw materials.

All three respect the lifecycle: they’re only available in non-terminal statuses (the canvas is frozen in completed and cancelled).