WO for inventory build (no parent SO)
Path 2 covers stock builds — the company assembling product into inventory for future sales / sell-through. Build reasons include reorder_point breach, sales forecast, bid pre-build, USDA drawdown commit, or R&D pilot. WO is entered standalone in NetSuite (workorder.createdfrom = NULL). Item / qty / location / component requirements are confirmed, production runs, Assembly Build is entered (Mike approves at /assembly-build.html), FG is added to inventory at the correct location, components are consumed through the build process, and the WO closes naturally. FG remains available for future Sales Orders.
No customer side. No Item Fulfillment, no Finance handoff on the WO itself. Finance enters later when a future SO actually sells the FG. This is why Path 2 is risk 2 (vs Path 1 risk 3) — no customer pressure, no AR cycle, no order.closed event on this contract.
Diagram: ns-work-order-path-2-inventory-build.html. Master wiki: wiki-ns-work-order-master.html. Other path: Path 1 from sales order. Workflow contract: wo_lifecycle_inventory_build_path (risk 2).
Trigger
reorder_pointbreach — assembly's quantityavailable below reorder threshold.forecast— planned production for projected demand.bid_pre_build— e.g. ahead of a B5875 QBL release order.usda_drawdown— entitlement commit (barrel cheddar processing, etc.).rd_pilot— validating a new BOM at small qty.
Path 2 has no parent SO, no customer PO#, no Item Fulfillment, no Finance handoff on the WO itself. WO terminates at FG availability. Finance enters when the FG is eventually sold via a future SO.
Mike's TBD on WO.memo (Path 1 customer PO# threading) does not block Path 2 — there's no customer PO# to thread. On Path 2, memo carries freeform operator notes (e.g. "bid B5875 pre-build for QBL"). But every WO Schema reference still globally flagged TBD until Mike confirms the Path 1 semantic.
Pre-build RSF burrito kits for B5875 QBL
RSF-BURR-KIT on-hand = 0, reorder_point = 240, B5875 QBL approaching. Operator dispatches Path 2; WO-4499 created standalone (createdfrom = NULL), assemblyitem "RSF-BURR-KIT", quantity 480, location 3 (Heartland), custbody_build_reason = "bid_pre_build", memo = "bid B5875 pre-build for QBL" (operator note — not a customer PO#). Item / qty / location / components confirmed. BOM lookup: TORTILLA-LG, BEAN-1LB, SAUCE-PAC on hand at location 3. Production runs; crew completes build for 472 (8 waste). Mike approves Assembly Build (AB-1902, createdfrom = 4499, quantity_built = 472, waste = 8, location = 3). FG credited: inventory_balance.quantityavailable += 472 for RSF-BURR-KIT at location 3 (was 0, now 472). Components consumed (WkOrdIss per line: TORTILLA-LG -480, BEAN-1LB -480, SAUCE-PAC -480). WO closes naturally (status='Built'). FG remains available for future SOs. When B5875 release order arrives next week, the SO will allocate against this FG.
Code paths + invariants
| Concern | Where |
|---|---|
| Standalone invariant | workorder.createdfrom IS NULL |
| Assembly Build linkage | assemblybuild.createdfrom = wo.id |
| FG credit | inventory_balance.quantityavailable += quantity_built at location_id |
| Components consumed | transactions (WkOrdIss) per BOM line |
| No customer side | no item_fulfillments row; no customer_invoices row; no wo.finance_alert_fired event |
| HITL gate | /assembly-build.html → proposed_actions → Mike approves |
| Future SO consumption | SO Path 1 inventory allocates this FG when ordered |
Dated trail
| Date | Round | Change | Touched by |
|---|---|---|---|
2026-05-26 | R593 | Path 2 wiki created as part of WO master split (matches R592 SO pattern). Split into master + 2 path-details. Mike + Claude. | Mike + Claude |
Path 2 sub-contract spec
Sub-contract: wo_lifecycle_inventory_build_path · risk 2 · dispatched by WO master when origin = inventory_build.
Path 2 NS records (field-level)
| NS record | Key fields | Sample values | Status |
|---|---|---|---|
| WorkOrd | tranid, createdfrom, assemblyitem, quantity, location | "WO-4499", NULL, "RSF-BURR-KIT", 480, 3 | REAL |
| WorkOrd | bodyFields.memo — operator note (NOT customer PO# — no parent SO) | "bid B5875 pre-build for QBL" | REAL (but field still TBD globally per Mike review) |
| WorkOrd | bodyFields.custbody_build_reason | "bid_pre_build" | REAL |
| WkOrdIss (per component) | per-component consume | TORTILLA-LG -480 · BEAN-1LB -480 · SAUCE-PAC -480 | REAL |
| AsmBuild | tranid, createdfrom, quantity_built, waste, location | "AB-1902", 4499, 472, 8, 3 | REAL |
Path 2 verify_checks
| name | window | expected |
|---|---|---|
wo_standalone | 60 min | work_orders.createdfrom IS NULL (no parent SO) |
assembly_build_posted | 2880 min | assembly_builds.wo_id has ≥1 row |
fg_credited | 2880 min | inventory_balance.quantityavailable increased by build qty at location_id |
components_debited | 2880 min | transactions WHERE type='WkOrdIss' AND wo_id=? has ≥1 row per BOM line |
wo_closed | 2880 min | work_orders.status = 'Built' |
fg_available_for_future_so | 2880 min | inventory_balance.quantityavailable > 0 (allocatable to future SOs) |
Inputs
| Field | Type | Description |
|---|---|---|
assembly_item | string | NS assembly item_code. Required. |
quantity | integer | Target build qty. Required. |
location_id | integer | NS location id where FG will land. Required. |
build_reason | enum | reorder_point · forecast · bid_pre_build · usda_drawdown · rd_pilot · other. Optional. |
When Path 2 breaks
FG landed at wrong location
- Find the FG row:
SELECT * FROM inventory_balance WHERE item_code=? ORDER BY updated_at DESC LIMIT 5 - Check WO.location vs AsmBuild.location: SELECT id, location FROM work_orders / assembly_builds
- NS location transfer: issue a transfer order from wrong-location to correct-location for the FG qty
Components short during build (Path 2 can stage PO first)
- Check on-hand:
SELECT item_code, quantityavailable FROM inventory_balance WHERE item_code IN (?) AND location_id=? - Stage PO: if any component short, manually stage a PO before kicking off the build (no customer pressure on Path 2)
- Auto-stage (backlog): when review_components verify returns warn, auto-stage PO
Open questions for Path 2
-
OPEN
Auto-stage PO if components short
Today operator stages PO manually. Could auto-stage when
review_componentsverify_check returns warn. -
DEFER
Cost rollup at WO close (Path 2)
Path 2 doesn't fire an order.closed event, but actual cost (components + labor + overhead) vs estimated cost is still worth capturing for cost-per-unit drift detection.
-
TBD
WO.memo semantic on Path 2 (operator note vs reserved field)
If Mike confirms
WO.memoas the customer PO# field on Path 1, then Path 2's operator-note use ofmemomay need to migrate to a different field (e.g.custbody_operator_note) to keep the semantic clean.