NetSuite sales order — master

Email intake → SO entry (capture otherrefnum=customer PO#) → branch into 3 path sub-contracts → converge at Item Fulfillment → ★ Finance handoff → invoice → payment / dunning

High-altitude master view of the entire SO process. Customer orders arrive at orders@globalfoodsolutions.co or danielle@globalfoodsolutions.co. The team reviews each one against the customer file and keys it into NetSuite as a Sales Order, capturing the otherrefnum field as the customer PO#. From there the SO branches by item type into three path sub-contracts — Path 1 inventory, Path 2 assembly (Work Orders FROM the SO), or Path 3 dropship (POs FROM the SO). All three paths converge at Item Fulfillment, which fires the ★ automation alert to Finance. The customer PO# (entered as otherrefnum on the SO) threads through every connected NS record — PO memo, Invoice otherrefnum, Vendor Bill memo / tranid / initialtranid. This is the trace thread for "where did Driscoll's PO 72622 go." See path detail docs for field-level depth.

D1-mirrored from NS HITL outside guardrails Path 1 · inventory Path 2 · assembly Path 3 · dropship EDI 850 auto-intake STUB

Pipeline — email intake → 3 fulfillment paths → finance convergence

idle
NS sales order lifecycle — email intake → SO review + entry → branch by item type into 3 paths (inventory / assembly / dropship) → Item Fulfillment → Finance alert (key handoff) → invoice → payment → close (dunning loopback if past due) 01 / Email intake 02 / SO review + entry (capture otherrefnum = customer PO#) 03 / Branch by item type · dispatch to sub-contract PATH 1 / Inventory fulfillment · see ns-sales-order-path-1-inventory.html PATH 2 / Assembly build · see ns-sales-order-path-2-assembly.html PATH 3 / Drop ship · see ns-sales-order-path-3-dropship.html 04 / Item Fulfillment (converge) 05 / Finance handoff · ★ STUB (pending NS automation deploy) 06 / Invoice · payment · close (dunning loopback) EMAIL INTAKE — Most customer orders arrive by email at two mailboxes. MAILBOXES orders@globalfoodsolutions.co danielle@globalfoodsolutions.co SOURCE customer email — PO body, attached spreadsheet, or freeform EDI 850 — lands here today, keyed manually into NS (STUB autoparse) portal — customer portal upload form STATUS: REAL (manual intake) · STUB (EDI auto-parse) customer email intake orders@globalfoodsolutions.co danielle@globalfoodsolutions.co EXTERNAL · EMAIL ROUTING i OTHER INTAKE CHANNELS — Less common than email today, but real. CHANNELS NS UI direct entry customer portal upload EDI 850 — STUB auto-parse phone → keyed by CS STATUS: REAL · EDI STUB other channels NS UI · portal · phone EDI 850 (manual keying) EXTERNAL · EDI STUB i REVIEW + CONFIRM — Team reads the order against the customer file before keying. CHECKS customer record exists + correct ship-to item details (pack/size/UOM match) pricing alignment (contract / program / list) shipping requirements special instructions / delivery windows TABLES read: customers · pricing_master · customer_programs · contracts STATUS: REAL · operator-driven review customer order customer file · items · ship-to pricing · special instructions DATABASE · customers · pricing i ENTER SO IN NETSUITE — SO posted as system-of-record. Captures customer PO# on otherrefnum. ACTION create: NS Sales Order (SalesOrd) capture: bodyFields.otherrefnum = customer PO# (e.g. "72622") capture: bodyFields.tranid = NS-assigned SO number (e.g. "1217") mirror: D1 transactions + so_lines on next hot-tier sync (2min) TABLES write: NS SalesOrd · D1 transactions · so_lines THREADING otherrefnum threads to Item Fulfillment + CustInvc on this SO chain STATUS: REAL enter SO in NetSuite otherrefnum = customer PO# · tranid = NS SO# D1 sync (2-min hot tier) BACKEND · NS + D1 mirror i CLASSIFY EACH LINE BY ITEM TYPE — A single SO routinely spans multiple paths. LOGIC per so_line.item.type: inventory_item → Path 1 (fulfill from inventory) assembly_item → Path 2 (work order created from SO) dropship_item OR special_order → Path 3 (PO created from SO) TABLES read: items.itemtype · items.cost_method STATUS: REAL (operator-driven today) · STUB (auto-classify on /api/so/create) classify each line by item type inventory · assembly · dropship single SO can hit all 3 paths SECURITY · operator-driven · auto STUB i PATH 1 · FULFILL FROM INVENTORY — Summary. See ns-sales-order-path-1-inventory.html for field-level depth. WORKFLOW so_lifecycle_inventory_path (sub-contract dispatched from master) SUMMARY inventory_balance check → reserve → pick → pack → stage → Item Fulfillment LINKAGE itemfulfillment.createdfrom = so.id itemfulfillment inherits otherrefnum from SO (customer PO# threading) NO PRODUCTION · NO PO STATUS: REAL PATH 1 · fulfill from inventory reserve · pick · pack · stage · Item Fulfillment itemfulfillment.createdfrom = so.id otherrefnum threads from SO → IF → Invoice PATH 1 · so_lifecycle_inventory_path DATABASE · see ns-sales-order-path-1-inventory.html i PATH 2 · ASSEMBLY BUILD — Summary. See ns-sales-order-path-2-assembly.html for field-level depth. WORKFLOW so_lifecycle_assembly_path (sub-contract dispatched from master) SUMMARY Per assembly_line: WO created FROM SO → BOM consume → assembly build → FG credit → Item Fulfillment ALTERNATE If FG already on hand → fulfill from inventory + close WO (marked "unused") LINKAGE workorder.createdfrom = so.id WO customer PO# field: TBD (Mike review pending; expected pattern bodyFields.memo) HITL /assembly-build.html → proposed_actions → Mike approves STATUS: REAL PATH 2 · Work Orders FROM SO workorder.createdfrom = so.id · BOM consume · build · FG credit alt: FG on hand → fulfill from inventory + close WO WO PO# field: TBD (Mike review pending) PATH 2 · so_lifecycle_assembly_path MESSAGEBUS · see ns-sales-order-path-2-assembly.html i PATH 3 · DROPSHIP — Summary. See ns-sales-order-path-3-dropship.html for field-level depth. WORKFLOW so_lifecycle_dropship_path (sub-contract dispatched from master) SUMMARY Per dropship_line: PO created FROM SO → transmit → vendor ships → Item Receipt → Item Fulfillment Vendor side: Vendor Bill entered → paid per vendor terms (parallel cycle) LINKAGE purchaseorder.createdfrom = so.id PO.bodyFields.memo = customer PO# (e.g. "72622") PO.lineFields.links[].tranid = " / " (e.g. "1217 / 72622") VendBill.memo / tranid / initialtranid = customer PO# threading STATUS: REAL PATH 3 · POs FROM SO + vendor side purchaseorder.createdfrom = so.id · transmit · IR · Item Fulfillment PO.memo = customer PO# · lineFields.links[].tranid = "1217 / 72622" VendBill.memo · tranid · initialtranid all thread PO# PATH 3 · so_lifecycle_dropship_path MESSAGEBUS · see ns-sales-order-path-3-dropship.html i ITEM FULFILLMENT COMPLETED — All 3 paths converge here. SO fulfilled to customer. ACTION status: itemfulfillment → 'Shipped' inventory: decrement by shipped qty generate: BOL · ASN if EDI customer links: SO ↔ itemfulfillment ↔ (WO|PO if applicable) TABLES write: itemfulfillment (Shipped) · inventory_balance · transactions NOTE Convergence point — single SO with mixed-path lines hits this once per fulfillment event STATUS: REAL Item Fulfillment completed itemfulfillment → Shipped · inventory decremented · BOL/ASN CONVERGENCE · all 3 paths land here i ★ AUTOMATION ALERT → FINANCE — THE KEY HANDOFF SIGNAL. TRIGGER itemfulfillment.status changes to 'Shipped' ACTION fire: NS workflow / scheduled script alert to Finance fire: events row so.finance_alert_fired SPEC see spec doc for finance alert NS automation (next round) STATUS: STUB — platform-side event fires (REAL); NS workflow build pending next round (Mike to deploy) ★ automation alert → Finance STUB · REAL once NS automation deployed (next round) FINANCE · emits so.finance_alert_fired event i FINANCE REVIEW — Finance reviews the fulfillment before invoicing. CHECKS fulfilled qty matches expected pricing carried through correctly customer terms + tax handling correct any short-ships flagged TABLES read: itemfulfillment · so_lines · customer.terms STATUS: REAL · Finance-driven Finance review qty · pricing · terms · tax CLOUD · Finance role i INVOICE CUSTOMER — Finance posts the customer invoice. ACTION generate: invoice_lines from shipped qty (not ordered qty) post: CustInvc transaction · AR balance updates TABLES write: transactions (CustInvc) · invoice_lines · v_customer_ar_aging STATUS: REAL invoice customer CustInvc · AR balance BACKEND · CustInvc i INVOICE OPEN · MONITOR PAYMENT TERMS — Track invoice until customer pays. ACTION monitor: due_date vs today surface: AR aging buckets (current / 30 / 60 / 90+) TABLES read: transactions · payment_applications · v_customer_ar_aging STATUS: REAL monitor terms AR aging · due_date DATABASE · v_*_aging i PAST DUE → DUNNING — If payment_terms exceeded, dunning workflow fires. ACTION trigger: ar_aging_action_plan workflow draft: dunning email at escalating tone (30/60/90+) TABLES read: v_customer_ar_aging · customers write: proposed_actions (dunning_email_draft) LOOPBACK emails sent → wait for payment → loop until paid OR service hold STATUS: REAL (workflow contract) · email send still HITL past due → dunning ar_aging_action_plan SECURITY · HITL email i PAYMENT RECEIVED · APPLY — Customer remits; CustPymt posted. ACTION receive: customer_payments row apply: payment_applications match payment to invoice(s) TABLES write: customer_payments · payment_applications · transactions (CustPymt) STATUS: REAL payment received CustPymt · apply DATABASE · CustPymt i CLOSE ORDER — SO closed once fully shipped + invoiced + paid. ACTION status: SO → 'Closed' or 'Billed' fire: events.order.closed for customer health watcher TABLES write: transactions (status) · events STATUS: REAL close order SO status · events fire BACKEND · order.closed i VENDOR-SIDE (Path 3 only) — Drop-ship orders also produce a vendor bill cycle. ACTION enter: vendor bill against PO pay: vendor bill per vendor terms TABLES write: vendor_bills · vendor_payments NOTE Runs in parallel to customer-side invoice/payment. Separate cash cycle. STATUS: REAL vendor bill cycle (Path 3) enter · pay per terms MESSAGEBUS · vendor side i → Path 1 (sub-contract) → Path 2 (sub-contract) → Path 3 (sub-contract) all 3 paths converge → Item Fulfillment ★ automation alert loop: 30 / 60 / 90+ days until paid or service hold LEGEND Path 1 inventory Path 2 assembly Path 3 dropship ★ Finance handoff HITL / dunning CUSTOMER PO# THREADING · trace one PO across the entire SO chain (sample: customer PO# 72622, NS SO# 1217) Sales Order otherrefnum "72622" tranid "1217" Purchase Order (Path 3) memo · lineFields.links[].tranid "72622" / "1217 / 72622" createdfrom = so.id Customer Invoice otherrefnum "72622" createdfrom = so.id Vendor Bill (Path 3) memo · tranid · initialtranid "72622" / "1217 / 72622" createdfrom = po.id Work Order (Path 2) · TBD expected: bodyFields.memo "72622" (TBD) Mike review pending Item Fulfillment / Receipt inherits via NS std linkage otherrefnum → "72622" IF from SO · IR from PO Trace the customer PO# across every record — grep otherrefnum / memo / tranid / initialtranid for "72622" lights up every record in this SO chain.

Phase detail — Mike's actual 3-path process

01 Customer email intake REAL · manual EDI auto STUB

Most orders arrive by email at two mailboxes. EDI 850 lands here too but is keyed manually into NS today.
Mailboxes
orders@globalfoodsolutions.co · danielle@globalfoodsolutions.co
Other channels
NS UI · customer portal · phone · EDI (manual keying)
STUB
EDI 850 auto-parse into /api/so/create

02 Review customer order REAL · operator-driven

Team reads the order against the customer file before keying. Confirms item details, customer details, shipping, pricing, and special instructions.
Checks
customer record · ship-to · pack/UOM · pricing alignment · ship windows
Tables read
customers · pricing_master · customer_programs · contracts

03 Enter SO in NetSuite REAL

SO posted as system-of-record. D1 mirrors on next 2-min hot-tier sync.
NS record
SalesOrd
Tables write
transactions (SalesOrd) · so_lines

04 Classify each line by item type REAL · operator auto STUB

A single SO routinely spans multiple paths because line items differ in type. Today operators route mentally; auto-classification on intake is a stub.
Path 1
inventory_item → fulfill from inventory
Path 2
assembly_item → Work Order created FROM SO
Path 3
dropship_item / special order → Purchase Order created FROM SO

P1 Option 1 — Fulfill from inventory PATH 1 REAL

Items already on hand. No production. No PO. Pull, pick, pack, stage.
Steps
check qty → reserve → pick list → pack → stage
Tables write
itemfulfillment (open) · inventory_balance.reserved_qty

P2 Option 2 — Work Orders FROM SO PATH 2 REAL

For assembly items needing production. Work Orders are created from the Sales Order (parent_so_id preserved) so records stay linked end-to-end. If the assembly is already in inventory, fulfill from stock and close the WO.
NS records
workorder · assemblybuild
Linkage
WO.parent_so_id → SO.id
HITL
/assembly-build.htmlproposed_actions → Mike approves
Alternate
if FG on hand → fulfill from inventory + close WO

P3 Option 3 — Purchase Orders FROM SO PATH 3 REAL

For drop-ship items. PO created from the Sales Order (parent_so_id preserved). Vendor ships product (direct to customer or crossdock). Item Receipt closes the PO line. A vendor-bill cycle runs separately on the vendor side.
NS records
purchaseorder · itemreceipt · vendorbill
Linkage
PO.parent_so_id → SO.id
Vendor side
vendor bill entered → paid per terms (separate from customer-side invoice cycle)

05 Item Fulfillment completed (converge) REAL

All 3 paths land here. Itemfulfillment closes; inventory decrements; BOL/ASN generated.
NS record
itemfulfillment (status='Shipped')
Tables write
transactions (ItemShip) · inventory_balance

06 ★ Automation alert → Finance REAL (concept) code path verify

The single named handoff between Operations and Finance. Fires automatically on every Item Fulfillment completion. Finance is the next-step owner.
Trigger
itemfulfillment.status → 'Shipped'
Action
NS workflow / scheduled script alerts Finance queue
STUB
actual NS workflow trigger config needs code-level verification

07 Finance review REAL

Finance checks fulfilled qty matches expected, pricing carried correctly, customer terms + tax handling correct, any short-ships flagged.
Tables read
itemfulfillment · so_lines · customers.terms

08 Invoice customer REAL

Finance posts CustInvc using shipped qty. AR balance updates.
NS record
CustInvc
Tables write
transactions (CustInvc) · invoice_lines · v_customer_ar_aging

09 Monitor payment terms · past-due → dunning REAL

Invoice stays open until payment is received. If past due, dunning fires via the ar_aging_action_plan workflow. Loops at 30/60/90+ days until paid or escalated to service hold.
View
v_customer_ar_aging
Workflow
ar_aging_action_plan
HITL
dunning email send still operator-confirmed

10 Payment received · apply · close REAL

Customer remits; CustPymt posted; payment_applications matches payment to invoice(s). SO closes; order.closed event fires to customer health watcher.
NS record
CustPymt
Tables write
customer_payments · payment_applications
Event
events.order.closed

P3+ Vendor-side cycle (drop-ship only) PATH 3 sidecar REAL

Runs in parallel to the customer-side invoice/payment. Vendor bill is entered against the PO and paid per vendor terms.
NS records
vendorbill · vendorpayment

Tables, endpoints, code paths

kindnamepurpose
Mailboxorders@globalfoodsolutions.coprimary customer order intake
Mailboxdanielle@globalfoodsolutions.cosecondary customer order intake
D1 tabletransactionsSalesOrd, WorkOrd, PurchOrd, ItemShip, ItemRcpt, CustInvc, CustPymt, VendBill rows
D1 tableso_lines / transaction_linesline-level SO data · item, qty, price, parent_so_id
D1 tablework_ordersPath 2 — WO records linked to parent SO
D1 tablepurchase_ordersPath 3 — PO records linked to parent SO
D1 tableitem_receiptsPath 3 — vendor receipt closes PO line
D1 tablevendor_billsPath 3 — vendor-side billing
D1 tableitem_fulfillmentsconvergence point — all 3 paths land here
D1 tableinvoice_linesFinance-issued invoice from shipped qty
D1 tablecustomer_invoicesCustInvc mirror
D1 tablecustomer_paymentsCustPymt mirror
D1 tablepayment_applicationsmatches payment to invoice(s)
D1 viewv_customer_ar_agingdunning trigger · buckets current/30/60/90+
Workflowar_aging_action_plandunning sequence at 30/60/90+
NS recordSalesOrd · WorkOrd · PurchOrd · ItemShip · ItemRcpt · CustInvc · CustPymt · VendBillsystem-of-record across the 3 paths + finance tail
Code pathsrc/email.tsinbound email pipeline (5 mailboxes incl. orders@ + danielle@)

Open gaps — honest punch list

  • EDI 850 auto-intake STUB: We receive EDI orders in NS today, but the parser is not wired to /api/so/create. EDI files land in the mailbox; an operator keys them in.
  • Auto-classify path STUB: The branch decision (inventory / assembly / dropship) is operator-driven today. A classifier on intake would surface mixed-path orders earlier.
  • Automation alert → Finance: Documented as concept but the actual NS workflow trigger needs code-level verification. Confirm in NS workflow studio + check ns_pending_pushes.
  • Backorder workflow currently flags only; no auto-PO / cross-warehouse rebalance.
  • ASN generation for EDI customers is currently NS-native; the platform doesn't yet author them.

Path detail docs