Work orders to payment — end-to-end

5-phase swimlane: WO → assembly_build → SO (3-path) → fulfill/invoice (★ Finance alert) → payment + AR · wall-poster canvas · R589 SO update · R592 SO master + Path 2 detail links

A single canvas that stitches together the full GFS revenue cycle: production work order → assembly build (raw materials → finished goods) → sales order with allocation → fulfillment + invoice → customer payment → AR aging if unpaid. Reuses content from ns-work-order-master, ns-assembly-build-flow, and ns-sales-order-master; cross-links to each for detail. Built so you can hang it on a wall and walk a new hire through the entire flow.

5 phases · 15 nodes 3 sub-flows concatenated AR aging branch on past-due

0 · Wall-poster swimlane 5 horizontal phases · WO → Build → SO → Invoice → Payment

End-to-end revenue cycle
Work orders to payment end-to-end — 5 phases: WO assembly build → SO allocate → fulfill + invoice → payment → AR aging if unpaid Phase 1 / Work order Phase 2 / Assembly build Phase 3 / Sales order Phase 4 / Fulfill + invoice Phase 5 / Payment + AR Production demand surfaces from forecast or bid commit. Mike or production_admin role drafts a work order in NS. Linked to assembly item + qty. PHASE 1.1: WO drafted surface: NS UI · production_admin role source: forecast or bid commitment fields: workorder_id · assembly_item · qty · target_ship_date see: ns-work-order-master.html i 1.1 WO drafted production_admin · NS UI assembly_item + qty FRONTEND · forecast/bid input WO row lands in NetSuite work_order table; mirrored to D1 work_orders on next warm-tier sync (5 min). Triggers downstream raw-material requirement explosion. PHASE 1.2: WO persisted table: NS work_order · D1 work_orders sync_tier: warm (5 min) effect: BoM explosion · raw material reservation status: 'Released' i 1.2 WO persisted NS + D1 mirror BoM explosion · status=Released DATABASE · warm 5min sync NS_PUSH_QUEUE picks up the WO event. Drainer notifies production floor + reserves raw materials in inventory_locations. PHASE 1.3: Floor notification queue: NS_PUSH_QUEUE drainer: /api/ns-push/drain notifies: production floor (HITL handoff) reserves: raw materials in inventory_locations i 1.3 floor notified NS_PUSH_QUEUE drain reserves raw materials MESSAGEBUS · async Production crew completes the build on the floor. Mike enters the actual quantity built + waste + scrap in /assembly-build.html. HITL-gated: lands in proposed_actions before committing to NS. PHASE 2.1: Build entry surface: /assembly-build.html hitl: lands in proposed_actions action_type: 'assembly_build_commit' see: ns-assembly-build-flow.html i 2.1 build entry /assembly-build.html qty_built + waste + scrap SECURITY · HITL gate Mike approves the build at /proposed-actions.html. Worker drains it via the assembly_build_commit handler — pushes to NS, consumes raw materials, increments finished good qty_on_hand. PHASE 2.2: HITL approve + push action: assembly_build_commit endpoint: /api/proposed-actions/bulk-decide effect: NS assembly_build record + inventory move cost: ~$0 (single NS RESTlet call) i 2.2 HITL approve + push /api/proposed-actions/bulk-decide NS assembly_build + inventory move CLOUD · NS RESTlet push NS confirms the build. D1 inventory_balances + assembly_builds tables updated on next warm sync. Raw material qty_on_hand decreases; finished good qty_on_hand increases. PHASE 2.3: Inventory move tables: D1 inventory_balances · assembly_builds flow: raw_materials qty-- · finished_good qty++ trigger: warm sync 5 min after NS commit audit: stored in assembly_builds row i 2.3 inventory move D1 inventory_balances raw-- · finished++ DATABASE · warm sync Customer order arrives by email at orders@globalfoodsolutions.co or danielle@globalfoodsolutions.co. Team reviews against customer file then keys into NS as Sales Order. PHASE 3.1: Email intake → SO entry mailboxes: orders@globalfoodsolutions.co, danielle@globalfoodsolutions.co review: items, ship-to, pricing, special instructions surface: NS UI · order_mgmt_admin table: NS sales_order · D1 transactions see: ns-sales-order-master.html (R589 3-path) i 3.1 email → SO entry orders@ · danielle@ review + key into NS EXTERNAL · email intake SO branches by item type into 3 paths. A single SO routinely spans multiple paths. PHASE 3.2: 3-path branch Path 1: inventory_item → fulfill from inventory Path 2: assembly_item → Work Order created FROM SO (parent_so_id linked) Path 3: dropship_item → Purchase Order created FROM SO (parent_so_id linked) WO assembly path connects back to Phase 2 (this poster's left half) STUB: auto-classify on intake i 3.2 branch by item type inventory · assembly · dropship WO + PO created FROM SO SECURITY · 3-path All 3 paths converge at Item Fulfillment. Pick ticket prints, warehouse pulls + stages. Fulfillment record opens then closes as Shipped. PHASE 3.3: Pick + stage + fulfill (converge) surface: pick ticket print + /admin-dashboard effect: itemfulfillment record · convergence point triggers: ★ automation alert → Finance on close i 3.3 pick + stage + fulfill all 3 paths converge creates fulfillment record MESSAGEBUS · convergence Truck departs; driver confirms via /driver-app. Item fulfillment in NS marks SO as Shipped. POD captured (signed BOL scan to R2). PHASE 4.1: Ship + POD surface: /driver-app · NS item_fulfillment effect: SO status → 'Shipped' pod: signed BOL → R2 bucket table: D1 item_fulfillments + R2 pod_signatures/ i 4.1 ship + POD /driver-app · NS fulfillment POD → R2 CLOUD · status=Shipped Invoice auto-generates from fulfillment. Lines copy SO prices; brand-prefix routing assigns the right AR account. Lands in NS invoice + D1 invoices. PHASE 4.2: Invoice trigger: fulfillment confirmed table: NS invoice · D1 invoices ar_account: brand-prefix routed (PUB/RS/PU/AIS/BR/TT/GFS) terms: pulled from customer record i 4.2 invoice NS invoice + D1 mirror brand-prefix AR account BACKEND · auto-gen Invoice PDF rendered by Browser Rendering API; signed R2 URL emailed to customer AP contact. Tracked in invoice_delivery_log. PHASE 4.3: Invoice send render: BROWSER binding · PDF storage: R2 invoices/<customer>/<invoice_id>.pdf delivery: email + portal log: invoice_delivery_log i 4.3 invoice send PDF via Browser Rendering email + portal FRONTEND · signed R2 URL Customer payment lands as ACH, check, or wire. Cash app team applies via NS apply_customer_payment. On apply, invoice status → Paid + AR aging drops. PHASE 5.1: Payment apply surface: NS customer_payment apply: invoice → Paid d1_table: customer_payments + payment_applications audit: stored in payment_applications row i 5.1 payment apply NS customer_payment invoice → Paid CLOUD · ACH/check/wire If days_past_due > terms, invoice enters AR aging bucket (30/60/90+). Daily reactive_dunning cron sends increasingly firm notes. Mike reviews at /admin-dashboard AR aging panel. PHASE 5.2: AR aging trigger: days_past_due > terms buckets: 0-30 · 31-60 · 61-90 · 90+ cron: reactive_dunning daily surface: /admin-dashboard AR panel i 5.2 AR aging if past_due 30/60/90+ buckets SECURITY · daily dunning Final state: invoice closed, cash deposited, GL posted. AR balance reduces. Sale ages into general ledger; revenue recognized per accrual schedule. PHASE 5.3: GL closeout effect: cash deposit + revenue recognition table: NS gl_transactions · D1 gl_entries recurring: revenue rec per accrual schedule state: terminal · closed i 5.3 GL closeout cash deposit + revenue D1 gl_entries DATABASE · terminal loopback · short allocation triggers new WO 5.2 fires only if past_due LEGEND UI backend D1/NS cloud HITL/AR queue phase transition backorder loopback

Phase detail · 5 phases · 15 nodes

P1 Work order 3 sub-steps

Production WO drafted, persisted to NS + D1, floor notified. Surfaced via production_admin role.
Tables
work_orders · work_order_lines · inventory_locations
Surface
NS UI · /assembly-build.html
Detail diagram
Sync
warm tier 5 min

P2 Assembly build HITL-gated

Production crew enters qty built + waste + scrap. Mike approves at proposed_actions. Inventory moves: raw down, finished up.
Surface
/assembly-build.html
Action
assembly_build_commit
Tables
assembly_builds · inventory_balances
Detail diagram

P3 Sales order 3 sub-steps

SO from PO/bid/recurring → allocate from finished goods → pick + stage. Short allocations trigger new WO loopback.
Tables
sales_orders · sales_order_lines · inventory_balances
Allocation
FIFO + USDA drawdown
Detail diagram
Roles
order_mgmt_admin · relationship_admin

P4 Fulfill + invoice auto-gen

Truck ships, POD captured, item_fulfillment created. Invoice auto-generates from fulfillment + brand-prefix AR routing. PDF emailed.
Tables
item_fulfillments · invoices · invoice_delivery_log
POD storage
R2://pod_signatures/<invoice_id>.pdf
Render
Browser Rendering API → R2://invoices/
Brand routing
PUB/RS/PU/AIS/BR/TT/GFS — sets AR sub-account

P5 Payment + AR aging branch

Customer payment applies; invoice closes; GL posts. If past_due, dunning cron sends notes per aging bucket.
Tables
customer_payments · payment_applications · gl_entries
Aging buckets
0-30 · 31-60 · 61-90 · 90+
Cron
reactive_dunning daily
Surface
/admin-dashboard AR aging panel

Tables & cross-links

phasetables (D1)cross-link
1 · WOwork_orders · work_order_linesns-work-order-master.html
2 · Buildassembly_builds · inventory_balances · proposed_actionsns-assembly-build-flow.html
3 · SOsales_orders · sales_order_linesns-sales-order-master.html
4 · Invoiceitem_fulfillments · invoicesorder-to-cash.html
5 · Paymentcustomer_payments · payment_applications · gl_entriesfinance-admin-flow.html

Open gaps