Skip to content

Pre-assembled stock

Sub-assemblies, like BOMs, can carry their own pre-assembled stockPre-Assembled InventoryStock of finished sub-assemblies and BOM items that have already been built and are sitting on the shelf. When a work order needs a sub-assembly, it draws from pre-assembled inventory first and only builds fresh ones if the shelf comes up short. Read more → . When a parent BOM expands the sub-assembly during execution, the sub-assembly’s shelf is consumed first — only the remainder pulls the sub-assembly’s own components.

The mechanics mirror the BOM-level pre-assembled feature, with one important difference: the sub-assembly shelf is consumed inside the recursive expansion, at the layer where the sub-assembly lives.

  • What sub-assembly pre-assembled stock is
  • The drawdown layer (where it gets consumed)
  • Multi-layer drawdown across nested sub-assemblies
  • Adjustment surfaces
  • Restoration on parent BOM cancel/refund

Sub-assembly pre-assembled stock is finished bundles you’ve already built — not yet incorporated into a sellable BOM, but ready to be used.

It’s stored as:

  • A per-SA aggregate number.
  • Per-location entries.

Sub-assemblies don’t have Shopify variants, so the per-location storage uses synthetic IDs internally.

When a parent BOM fires, the recursion produces a per-layer cascade of pre-assembled drawdown:

BOM B (no pre-assembled)
└── Sub-assembly S (5 in pre-assembled)
└── Sub-assembly T (2 in pre-assembled)
└── Raw R

Order 8 units of B. Expansion:

  1. BOM B layer. No pre-assembled. Order qty 8.
  2. Recurse into S with multiplier 8.
  3. S layer. Consume from S’s shelf: min(5, 8) = 5. Shelf → 0. Remainder = 3.
  4. Recurse into T with multiplier 3.
  5. T layer. Consume from T’s shelf: min(2, 3) = 2. Shelf → 0. Remainder = 1.
  6. Recurse into R with multiplier 1.
  7. Emit: Raw R × 1.

Net effect for the order:

  • BOM B: 8 ordered.
  • S’s pre-assembled: -5.
  • T’s pre-assembled: -2.
  • Raw R: -1.

This stacking is the killer feature of multi-layer sub-assemblies: every layer with pre-assembled stock is an opportunity to not go all the way down to raw materials.

You can adjust pre-assembled stock for a sub-assembly:

  • From the SA detail page — there’s an inline adjustment widget. Per-location adjustments.
  • From the SA list page — a quick reconcile control on the row.
  • Programmatically — the same /api/adjust-preassembled-inventory endpoint that BOMs use; the API detects the entity type.

Adjustments write to both the per-location table and the per-SA aggregate atomically.

When the parent BOM is cancelled/refunded, the SA’s pre-assembled shelf may or may not be replenished, depending on the cascade rule. Briefly:

  • Parent BOM’s flag on: the BOM’s pre-assembled gets +N. The SA’s shelf is unchanged.
  • Parent off, SA flag on: the SA’s shelf gets +N×qty (the SA’s reference quantity). The SA’s components stay inside.
  • Parent off, SA flag off: the SA’s components return to their inventory tables. The SA’s shelf is unchanged.

Full coverage in Keep-assembled cascade.

  • The shelf is per-layer in the recursion. Each sub-assembly node has its own opportunity to absorb the requirement before falling through.
  • Decimal pre-assembled is supported per-location but the aggregate per-SA number is integer. Trust the per-location table for fractional cases.
  • No Shopify-side stock for sub-assemblies. The pre-assembled count is purely Assemblified-side. There’s no Shopify inventory adjustment when SA pre-assembled changes.
  • Synthetic IDs. SA rows in the per-location pre-assembled table use synthetic IDs since SAs don’t have Shopify inventory items. You can’t filter by Shopify inventoryItemId and find them.