Wiki · Sales order · PATH 3 · R592

Path 3 · dropship (POs FROM SO + vendor side)

Vendor ships directly to the customer (or to GFS for crossdock). A Purchase Order is created FROM the SO, threading the customer PO# through memo and lineFields.links[].tranid. Vendor Bill carries the same threading on memo, tranid, and initialtranid.

PATH 3 REAL ★ Finance alert pending NS automation
What this is

Drop-ship via PO · vendor side runs in parallel

Path 3 covers SO lines where the vendor ships product directly. For each dropship_line, a PO is created FROM the SO (purchaseorder.createdfrom = so.id). Customer PO# threads via PO.bodyFields.memo = SO.otherrefnum and PO.lineFields.links[].tranid = " / " (the SO/customer-PO combo string).

After Item Receipt closes the PO line and Item Fulfillment ships to the customer, the Vendor Bill is entered carrying three fields with the customer PO# thread: memo, tranid, and initialtranid. This is the path with the richest threading — the customer PO# appears in 7+ field positions across 5 NS records.

Diagram: ns-sales-order-path-3-dropship.html.

When to use it

Trigger conditions

★ The handoff

After Item Fulfillment, the automation alert fires to Finance for the customer-side invoice cycle. The vendor-side cycle runs in parallel (vendor bill entered + paid per vendor terms).

Worked example

Driscoll 3 dropship lines via Cardinal Foods

Scenario

Driscoll's SO 1217 (PO# 72622) includes 3 dropship lines totaling $4,800 via Cardinal Foods vendor #891.

PO-7833 created FROM SO 1217: createdfrom = 1217, bodyFields.memo = "72622", lineFields.links[].tranid = "1217 / 72622", entity = 891. Manually transmitted to Cardinal Foods (email PDF; EDI 850 outbound is STUB).

Cardinal ships direct to Driscoll. Item Receipt closes PO line. Item Fulfillment posted: createdfrom = 1217, otherrefnum = "72622". ★ Finance alert fires.

Customer side: CustInvc with otherrefnum = "72622", $4,800, Net 30. Driscoll pays day 24.

Vendor side (parallel): Cardinal sends invoice; Finance enters VendBill memo = "72622", tranid = "1217 / 72622", initialtranid = "1217 / 72622", createdfrom = "PO-7833". Paid per vendor terms.

Step-by-step what happens

PO create → ship → receipt → fulfillment → Finance · vendor bill parallel

  1. 01

    Create PO FROM SO

    NS PurchOrd: createdfrom = so.id, memo = customer_po_number, lineFields.links[].tranid = " / ", entity = vendor_id.

    PO# threads SO.otherrefnum → PO.memo
  2. 02

    Transmit PO to vendor

    Manual today (email PDF). EDI 850 outbound is STUB.

  3. 03

    Vendor ships

    Direct to customer or to GFS crossdock. Tracking + ETA captured.

  4. 04

    Item Receipt against PO

    NS ItemRcpt: createdfrom = po.id, status = "Received". PO line closes.

  5. 05

    Item Fulfillment to customer

    NS ItemFulfill: createdfrom = so.id (the SO, not the PO), otherrefnum = "72622" from SO.

  6. 06

    ★ Finance alert (STUB)

    Fires events.so.finance_alert_fired.

  7. 07

    Customer Invoice

    Same Finance steps as Path 1. CustInvc.otherrefnum = "72622".

  8. 08

    Customer Payment · SO closes

  9. 09

    Vendor Bill entered (parallel)

    NS VendBill: memo = "72622", tranid = "1217 / 72622", initialtranid = "1217 / 72622", createdfrom = po.id, entity = vendor_id.

    PO# threads memo + tranid + initialtranid all carry "72622"
  10. 10

    Vendor Bill paid per vendor terms

    NS VendPymt: appliedto = vendor_bill.id.

Outcomes

What's different after the cycle

SO
Closed
paid + applied
Vendor side
Bill paid
parallel cycle
PO# trace
5 records
7+ field positions
Inventory
Untouched
(crossdock transient)
Failure modes

What can go wrong

PO sent but vendor never shipped

PO transmitted, no Item Receipt after expected lead time. Customer-side SO blocked. Vendor outreach required.

Vendor bill prematurely entered

Sign of receipt confusion. Pause and reconcile against PO state.

PO.memo missing customer PO# thread

Customer PO# threading broken. Vendor can't reference the customer order. Patch PO.memo to SO.otherrefnum; resync to NS.

VendBill tranid/initialtranid don't match expected combo

Expected: " / ". If different, reconcile vs originating PO.

Related

Adjacent flows + diagrams

For developers

Code paths + invariants

ConcernWhere
Workflow contractso_lifecycle_dropship_path
PO ↔ SO linkpurchaseorder.createdfrom = transactions.id
VendBill ↔ PO linkvendor_bills.createdfrom = purchase_orders.id
PO# thread on POPO.memo = SO.otherrefnum
PO# thread on PO linesPO.lineFields.links[].tranid = " / "
PO# thread on VendBillmemo = tranid (parsed) = initialtranid (parsed) = customer PO#
EDI 850 outboundSTUB — manual email today
// Path 3 threading invariant — verify across customer + vendor side SELECT po.memo, so.otherrefnum, vb.memo, vb.tranid FROM purchase_orders po JOIN transactions so ON po.createdfrom = so.id LEFT JOIN vendor_bills vb ON vb.po_id = po.id WHERE so.id = ? // expected: po.memo = so.otherrefnum AND vb.memo = so.otherrefnum // AND vb.tranid LIKE '%' || so.otherrefnum
Changelog

Dated trail

DateRoundChangeTouched by
2026-05-26R592Split into master + 3 path-detail docs; added Customer PO# threading schema (including VendBill memo/tranid/initialtranid).Mike + Claude
Schema · data contract

The machine-readable spec

workflow_type · so_lifecycle_dropship_path · risk_level · 3.

Customer PO# threading (Path 3 · PO + vendor side)

NS recordFieldSample value
Sales OrderbodyFields.otherrefnum (thread origin)"72622"
Purchase OrderbodyFields.memo"72622"
Purchase OrderlineFields.links[].tranid"1217 / 72622"
Item Receiptinherits via NS std linkage from POtraces via createdfrom = po.id
Item Fulfillmentinherits via NS std linkage from SO — createdfrom = so.idcarries otherrefnum = "72622"
Customer InvoicebodyFields.otherrefnum"72622"
Vendor BillbodyFields.memo"72622"
Vendor BillbodyFields.tranid"1217 / 72622"
Vendor BillbodyFields.initialtranid"1217 / 72622"

D1 tables touched

TableOperation
purchase_ordersINSERT (createdfrom, memo, lineFields)
item_receiptsINSERT (createdfrom = po.id)
item_fulfillmentsINSERT (createdfrom = so.id, otherrefnum)
customer_invoicesINSERT (otherrefnum threaded)
customer_paymentsINSERT
payment_applicationsINSERT
vendor_billsINSERT (memo, tranid, initialtranid all carry PO#)
vendor_paymentsINSERT
transactionsUPDATE (SO + PO + Invoice status changes)
eventsINSERT (purchaseorder.created, so.finance_alert_fired, vendor_bill.paid, order.closed)
Runbook · when it breaks

It broke at 2am

Scenario · PO sent but vendor didn't ship

Path 3 stalled.

  1. Check PO status: SELECT id, status, trandate FROM purchase_orders WHERE createdfrom=?
  2. Vendor outreach: contact vendor with PO + customer PO# combo (e.g. "1217 / 72622").
  3. Check premature vendor bill: SELECT * FROM vendor_bills WHERE po_id=? — if present, pause + reconcile.
  4. Alternate source: close original PO, post Item Receipt against the new source.

Scenario · PO.memo missing customer PO# thread

Threading invariant broken on customer side.

  1. Verify: SELECT po.memo, so.otherrefnum FROM purchase_orders po JOIN transactions so ON po.createdfrom=so.id WHERE po.id=?
  2. Patch: UPDATE purchase_orders SET memo = ? WHERE id = ? with SO.otherrefnum value.
  3. NS push back: stage proposed_action to update NS PurchOrd.memo.

Scenario · VendBill tranid/initialtranid don't match expected combo

Vendor-side threading broken.

  1. Verify: SELECT memo, tranid, initialtranid FROM vendor_bills WHERE createdfrom=?
  2. Expected pattern: memo = customer_po_number, tranid = initialtranid = " / ".
  3. Patch all three fields: threading depends on all three carrying the same combo.

Logs to check

Backlog · open questions

What's not done