WO created FROM Sales Order
Path 1 covers the case where one or more lines on a customer SO require assembly. A Work Order is created FROM the SO (workorder.createdfrom = so.id) preserving the SO ↔ WO link end-to-end. Components are reviewed at the correct location, production runs, the Assembly Build is entered in NetSuite (Mike approves at /assembly-build.html), finished goods are added to inventory, then the SO is fulfilled. Item Fulfillment fires the ★ automation alert to Finance; Finance reviews, invoices, monitors terms, applies payment, and closes the order.
Shortcut: if the FG is already on hand at the correct location, fulfill the SO from inventory and close the WO marked unused.
Diagram: ns-work-order-path-1-from-sales-order.html. Master wiki: wiki-ns-work-order-master.html. Other path: Path 2 inventory build. Workflow contract: wo_lifecycle_from_sales_order_path (risk 3).
Trigger
- SO master classifies a line as
assembly_item; SO Path 2 (assembly) dispatches WO Path 1 to actually build it. - Direct WO entry in NetSuite linked to an existing SO via
createdfrom = so.id.
Item Fulfillment closes → events.wo.finance_alert_fired emits → Finance picks up review. Same handoff signal as the SO master.
Expected pattern: bodyFields.memo threaded from SO.otherrefnum. Every WO Schema reference flagged TBD until confirmed.
Driscoll Melt Mates kit
Friday morning. Driscoll SO #1217 (otherrefnum "72622") includes 1 assembly line for Melt Mates kit qty 24. Operator dispatches Path 1; WO-4471 created with createdfrom = 1217 and memo (TBD, expected "72622"). Component review at location 3 (Heartland): CHED-2LB, PRTZL-BAG, TURKEY-PAK on hand. Production runs; crew completes build with 0 waste. Mike approves at /assembly-build.html; NS posts AB-1881 (createdfrom = 4471, quantity_built = 24, location = 3). FG credited: inventory_balance.quantityavailable += 24 for MELT-MATES-KIT-A at location 3. WO close: status='Built'. SO fulfilled: IF-2210 (createdfrom = 1217, otherrefnum "72622"). ★ Automation alert fires. Finance posts CINV-9032 for $18,420 Net 30; payment received + applied; SO closed.
Code paths + invariants
| Concern | Where |
|---|---|
| Linkage invariant | workorder.createdfrom = so.id |
| Assembly Build linkage | assemblybuild.createdfrom = wo.id |
| Item Fulfillment linkage | itemfulfillment.createdfrom = so.id (NOT wo.id) |
| FG credit | inventory_balance.quantityavailable += quantity_built at location_id |
| HITL gate | /assembly-build.html → proposed_actions → Mike approves |
| Finance alert (STUB) | events.wo.finance_alert_fired on IF.status='Shipped' |
| WO PO# field (TBD) | bodyFields.memo (expected) = SO.otherrefnum |
Dated trail
| Date | Round | Change | Touched by |
|---|---|---|---|
2026-05-26 | R593 | Path 1 wiki created as part of WO master split (matches R592 SO pattern). Split into master + 2 path-details. Mike + Claude. | Mike + Claude |
Path 1 sub-contract spec
Sub-contract: wo_lifecycle_from_sales_order_path · risk 3 · dispatched by WO master when origin = from_sales_order.
Path 1 NS records (field-level)
| NS record | Key fields | Sample values | Status |
|---|---|---|---|
| SalesOrd (upstream) | tranid, otherrefnum | "1217", "72622" | REAL |
| WorkOrd | tranid, createdfrom, assemblyitem, quantity, location | "WO-4471", 1217, "MELT-MATES-KIT-A", 24, 3 | REAL |
| WorkOrd | bodyFields.memo — customer PO# field | TBD — expected "72622" | TBD — Mike review pending |
| AsmBuild | tranid, createdfrom, quantity_built, waste, location | "AB-1881", 4471, 24, 0, 3 | REAL |
| ItemShip | tranid, createdfrom, otherrefnum, status | "IF-2210", 1217 (SO id), "72622", "Shipped" | REAL |
| CustInvc | tranid, otherrefnum, amount | "CINV-9032", "72622", 18420.00 | REAL |
| CustPymt | tranid, appliedto | "CPYMT-3120", "CINV-9032" | REAL |
Path 1 verify_checks
| name | window | expected |
|---|---|---|
wo_linked_to_so | 60 min | work_orders.createdfrom = so_id |
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 |
if_created_from_so | 2880 min | item_fulfillments.createdfrom = so.id |
finance_alert_fired | 2880 min | events.wo.finance_alert_fired exists for IF (STUB today) |
wo_memo_carries_po · TBD | 2880 min | TBD — Mike review pending; expected WO.memo = SO.otherrefnum once confirmed |
so_closed | 43200 min | transactions.status = 'Closed' |
When Path 1 breaks
Assembly Build done but SO never fulfilled
- Verify the link:
SELECT id, createdfrom, status FROM work_orders WHERE id=? - If createdfrom is NULL: patch with
UPDATE work_orders SET createdfrom=? WHERE id=? - Force resync:
POST /api/sync/run?tier=hot&table=transactions&id=<so_id> - Trigger fulfillment manually in NS: from the SO, hit "Fulfill" with the assembly on hand
WO PO# field threading break (pending Mike)
- Confirm with Mike: which WO body field carries customer PO#? Expected
bodyFields.memo - Until confirmed: trace via
createdfrom = so.idlinkage only - Schema fix post-confirmation: add
WO.memo == SO.otherrefnumverify_check
Open questions for Path 1
-
TBD
WO customer PO# field
Mike to confirm. Expected
bodyFields.memothreaded fromSO.otherrefnum. Every Schema reference flagged TBD until confirmed. -
STUB
NS workflow for Finance alert
Platform event fires; NS workflow trigger on
itemfulfillment.status='Shipped'still pending build. -
OPEN
FG on-hand shortcut auto-detection
Operator decides "fulfill from inventory + close WO unused" today. Could auto-detect at WO creation.