Skip to content

Execution model

A BOM executes when a Shopify order containing the finished-good variant is created (or cancelled, refunded, edited). The pipeline runs in milliseconds; the audit log captures every step. This page explains the model end-to-end so you can predict — and debug — what happens for any given order.

  • The execution pipeline at a glance
  • The order of operations inside Assemblified
  • Pre-fulfillment vs post-fulfillment timing
  • Multi-location behavior
  • The Logs page — where to find a run, and what it shows
  • Common failure modes
  1. Customer places an order in your Shopify storefront.
  2. Shopify fires a webhook to Assemblified.
  3. Assemblified disambiguates the event — is it a create, a cancel, a refund, or an edit?
  4. The work is enqueued. A background job buffers the order so it can be retried if anything goes wrong.
  5. Assemblified processes the order. It walks the BOM’s recipe and computes inventory deltas, drawing from pre-assembled inventoryPre-Assembled InventoryStock of finished goods and assembly bills already built and on the shelf, counted per location. A work order draws assembly bills from the shelf first, building fresh only if it runs short; an order consumes a finished good's shelf before its components. Read more → first.
  6. Shopify gets the inventory adjustments. Component variants are decremented; if you have dynamic adjustmentDynamic adjustmentA per-bill toggle that recalculates the bill's Shopify-displayed quantity after every order: the bottleneck-resource count plus pre-assembled stock. One of three mutually exclusive toggles — switching it on switches only-sell-pre-assembled and maintain inventory level off. Read more → on, the BOM’s displayed quantity is recalculated.
  7. An execution logBOM execution logThe record of one run Assemblified made — usually an order, sometimes a stock adjustment or a flow. It carries the run's outcome (Succeeded, Pending, Failed or Skipped), what triggered it, which bills it processed and skipped, the exact component changes it calculated and whether those reached Shopify, any pre-assembled stock it used, and any errors. Every run is listed on the **Logs** page and opens to its own detail page. Read more → entry is written. This is your audit trail, and it appears on the Logs page.

The whole pipeline typically takes 1–5 seconds for a simple BOM and a few seconds longer for BOMs with deep assembly-bill nesting or many locations.

When Assemblified processes an order, materials are sourced in a specific order. This matters because it affects what gets decremented:

  1. Pre-assembled stock first. If the BOM has pre-assembled inventoryPre-Assembled InventoryStock of finished goods and assembly bills already built and on the shelf, counted per location. A work order draws assembly bills from the shelf first, building fresh only if it runs short; an order consumes a finished good's shelf before its components. Read more → , that’s consumed before anything else. Order quantity 8, pre-assembled 5 → 5 come off the shelf, 3 still need to be sourced.

  2. Assembly bills next. For each remaining unit, expand the BOM’s assembly-bill references (also called sub-assemblies). Each one has its own pre-assembled shelf — that’s consumed before falling through to its components.

  3. Raw materials last. Whatever remains after the shelves are exhausted pulls from raw-material inventory. Shopify-linked materialsRaw materialThe atomic component of a bill of materials or an assembly bill. Two flavours: a Shopify-linked variant, whose inventory Shopify tracks, or a virtual material, which Assemblified tracks on its own and Shopify never sees. Both sit in the same component picker and are consumed the same way. Read more → are decremented through Shopify. Virtual materialsVirtual MaterialA material tracked entirely inside Assemblified — not a Shopify variant. Useful for shop-floor consumables (glue, packaging, labour units) where you need quantity tracking but don't want a Shopify product on your storefront. Read more → are decremented inside Assemblified’s own inventory (no Shopify call).

  4. Dynamic adjustment cascade. If any BOM in the order (or any other BOM that shares components with it) has dynamic adjustment on, Assemblified recomputes the displayed Shopify quantity for those BOMs from current availability.

  5. Maintain inventory level. If the BOM has Maintain inventory levelMaintain inventory levelA per-bill toggle that keeps the Shopify-displayed quantity flat after orders: Assemblified pushes a positive delta back to the bill's variant equal to what was consumed. Components decrement underneath. One of three mutually exclusive toggles: switching it on switches dynamic adjustment and only-sell-pre-assembled off. Read more → on, a positive delta equal to what Shopify just decremented is pushed back, keeping the displayed quantity flat.

  6. Auto-generate material list. If on, a new order creates a draft Material List Only work order with the material list, plus an assemble task that links to it, for the operator to pick from or download. No stock moves from this step.

  7. Log the result. All of the above becomes one run on the Logs page.

Assemblified subscribes to twelve Shopify webhook topics. Two groups matter for timing:

  • orders/updated fires on order create, edit, cancel and refund. On a single-location shop this is what drives execution, so the inventory adjustment happens at order time — before you’ve fulfilled anything.
  • Five fulfillment_orders/* topics (routing complete, placed on hold, hold released, moved, cancelled) drive the routing-time path on multi-location shops, together with the fulfillments/* topics.

Which of the two you get is a shop setting, not a per-BOM one: Settings → General → Multi-location sensitive adjustments.

  • Track BOM materials as Shopify-reserved between routing and fulfillment — on. When the order routes, the components move from available to reserved at the routed location, and fulfillment consumes them. The storefront number drops at routing.
  • Off (deduct at fulfillment). Routing records the intent and moves no stock; each fulfillment deducts available stock at its own location, so split orders and partial shipments reduce at the correct place.

Both are described in full on Order reservations.

Assemblified resolves the location for each component in this priority:

  1. A location rule at the fulfilling location. A rule can rewrite the recipe there — change a quantity, drop a material, add one the base bill doesn’t carry, or draw a component from a different location — and it can switch the bill off at that location entirely, in which case the line consumes nothing at all.
  2. The component’s own pinned location, if the recipe pins that material to one warehouse.
  3. The order’s location, if your shop has Respect order and fulfillment locations when available on in Settings → General.
  4. The shop’s default Shopify location.

So if you have multi-location inventory:

  • Set per-component locations on the BOM detail page when a specific material always comes from one warehouse.
  • Leave them blank to let the order’s location drive the choice (with the shop-level setting on).
  • Use the Locations tab on the finished good to make one location behave differently. That tab only appears once multi-location sensitive adjustments are on.

Every run — an order, a flow, a manual adjustment, an automatic adjustment — appears on Logs in the main navigation. The list carries:

  • a Type switcher: All · Orders · Flows · Manual adjustments · Automatic adjustments · Other,
  • an Outcome filter: Succeeded · Pending · Failed · Skipped,
  • a search box that takes an order number or a flow name (three characters or more),
  • columns for Outcome, Type, Subject, Bills, Location and Date.

A skipped run is not a failure — a duplicate delivery, a switched-off feature or a line with no bill are all decisions the app took on purpose — so it is badged neutrally rather than as an error.

Open a row for the run’s own page:

  • Summary — outcome, type, trigger, date, duration, location, the order it belongs to, and how many times it was retried.
  • Ordered (or Produced for a flow, Adjusted for an adjustment) — the lines that were processed, how many bills were processed and how many were skipped, each skipped one with its reason.
  • Material changes — every material, its SKU, its location and the calculated change, with a badge saying how far the Shopify write got. A second badge covers the Logistified leg when that integration is connected.
  • Pre-assembled changes — what came off (and back onto) the shelf per item and location, with before-and-after counts, and any shortfalls.
  • Errors or Warnings — what went wrong and which stage it came out of (webhook, queue, execution, bills, inventory sync, adjustment), with the technical detail behind a disclosure.

Two more tools sit in the list’s ⋯ menu: Check missing orders, which looks for orders that never produced a run, and Check duplicates.

If a BOM didn’t seem to fire, look at Bills skipped in the run’s Summary. The most common causes are an inactive bill, a bill a location rule disabled at that location, or a webhook that never arrived — which produces no run at all rather than a skipped one.

SymptomLikely cause
Order placed, no run appears on LogsThe webhook never arrived. Use Check missing orders on the Logs page; reinstalling the app re-registers the subscriptions.
The run lists the bill under Bills skippedThe bill is inactive, or a location rule disables it at the fulfilling location.
Components didn’t decrement, the run succeededThe pre-assembled shelf absorbed it. Pre-assembled changes on the run shows what came off.
Shopify shows the wrong quantity after an orderDynamic adjustment may be off for that bill, or the Shopify write failed — the run’s Material changes badge says which.
Cancel didn’t restore rawsCheck Keep Assembled on Return — if on, the units stay assembled. See Refunds & cancellations.
Inventory went negativeShopify allows negatives if your location settings permit. Lock it down at the shop level, not the BOM level.