Skip to content

Nesting & execution

When a finished good’s bill containing an assembly bill (also called a sub-assemblySub-assemblyA reusable assembly block that composes into bigger bills: define it once, include it in any bill of materials, and Assemblified expands it into its own components at execution time. The app now calls it an assembly bill. Read more → ) fires, the assembly is recursively expanded into its own components. Quantities multiply through each layer; pre-assembled stockPre-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 → at each layer is consumed first.

This page walks through the expansion mechanics with worked examples.

  • Quantity multiplication through layers
  • Pre-assembled drawdown at each layer
  • A worked end-to-end example
  • Waste percentage handling
  • Loops, and why you cannot create one

A bill containing an assembly bill carries a quantity on that reference. The assembly’s own components are then multiplied by (parent quantity × reference quantity).

Example. Order 4 units of finished good B, where:

  • B contains 2 × Assembly bill S (the reference quantity is 2).

The expansion produces 4 × 2 = 8 of whatever is inside S, before any pre-assembled drawdown.

This compounds across layers. If S contains 3 × Assembly bill T, and T contains 5 × Raw R, then:

  • 4 units of B → 8 of S → 24 of T → 120 of R.

At each layer of the recursion, the assembly’s pre-assembled shelf is consumed before falling through to its components.

Example. Same setup as above. S has 3 in pre-assembled stock.

Order 4 of B.
Frame { B, multiplier=4 }:
No B-level pre-assembled.
Recurse into S edge with multiplier 4 × 2 = 8.
Frame { S, multiplier=8 }:
Consume from S's shelf: min(3, 8) = 3. Shelf → 0. Remainder = 5.
Recurse into T edge with multiplier 5 × 3 = 15.
Frame { T, multiplier=15 }:
No T-level pre-assembled.
Emit Raw R × (15 × 5) = 75.

Net effect: 75 of Raw R consumed, plus 3 of S’s pre-assembled shelf. Without S’s pre-assembled, you’d have consumed 24 of T (which would have consumed 120 of R). The shelf cut consumption by 60%.

Waste is a percentage on one line of one recipe, and it is applied there. It does not compound across layers. If a raw material carries 10% waste on its line in the assembly’s recipe, the multiplier is 1.10 at that single emission. A nested assembly reference carries no waste percentage of its own.

So a chain like:

  • B has 1 × Assembly bill S (no waste on that line).
  • S has 5 × Raw R with 10% waste.

For an order of 4 units of B: emit Raw R × (4 × 1 × 5 × 1.10) = 22.

If you want waste at several layers (for example, the assembly itself has assembly loss), model it as an extra raw material on the parent bill, not as cumulative percentages.

A “Vanilla Candle 8oz” finished good contains:

  • 1 × Glass jar
  • 1 × Assembly bill “Wick assembly” (qty 1)
  • 1 × Vanilla scent oil (raw material)

The “Wick assembly” assembly bill contains:

  • 1 × Raw wick (8% waste)
  • 0.5 × Wick clip
  • 1 × Assembly bill “Wax block” (qty 1)

The “Wax block” assembly bill contains:

  • 0.25 × Wax (1kg block, 5% waste)

Setup:

  • “Wick assembly” pre-assembled stock: 5
  • “Wax block” pre-assembled stock: 0
  • Finished good pre-assembled: 0

Customer orders 4 units of “Vanilla Candle 8oz”.

Expansion:

  1. Finished-good level. No pre-assembled there. Order quantity 4.
  2. Direct components. Emit:
    • 4 × Glass jar (qty 1) = 4 jars.
    • 4 × Vanilla scent oil (qty 1) = 4 oils.
  3. Recurse into “Wick assembly” with multiplier 4.
  4. “Wick assembly” pre-assembled. Consume min(5, 4) = 4. Shelf → 1. Remainder = 0.
  5. Recursion into “Wick assembly“‘s children stops because remainder is 0. No raw wick, wick clip, or wax block needed!

Final result: 4 jars, 4 oils, and a -4 to “Wick assembly” pre-assembled shelf.

If the order had been for 7 units instead:

  • “Wick assembly” pre-assembled covers 5; remainder = 2.
  • Recurse into “Wick assembly“‘s children with multiplier 2.
  • Emit Raw wick × (2 × 1 × 1.08) = 2.16.
  • Emit Wick clip × (2 × 0.5) = 1.
  • Recurse into “Wax block” with multiplier 2 × 1 = 2.
  • “Wax block” has no pre-assembled. Emit Wax × (2 × 0.25 × 1.05) = 0.525.

An assembly bill cannot contain itself, directly or through a chain (S → T → S, or any longer one). The app checks every nesting before it is written and refuses the save if it would close a loop, naming the loop in the message: Cannot add “T” to “S”: “T” already contains “S”, so this would create a loop, followed by the path. Adding a bill to itself is refused with “S” cannot contain itself.

The check runs on the write, not in the browser, so it covers every way a nesting can be made: the Materials tab, the structure canvas, a bulk material edit and a version restore. The pickers also leave out the bills that would be refused, so in normal use you never see the message.

That means the expansion described on this page always terminates. There is no loop for it to fall into.