Produce Pro Module 09 — Purchasing

Ontology pack for PP module 09 (Purchasing), pinned to PP version 2401.0. Confidence: manual · Extractor: manual@2026-05-18 · Renderer: pp-module-renderer@1.0.0.

Module purpose

PP Module 09 (Purchasing) is the system-of-record for Nathel’s inbound supply side. It owns the canonical hierarchy Load → PO → POLine → Lot (Mod 09 p7) and is the source of every arrival, every receiving line, and every cost layer that flows into FIN’s events table. RP581 Load Worksheets are the canonical printed artifact of this module and serve as the manifest cross-check during receiving. FIN consumes Module 09 outputs both as scheduled CSV exports (PP Job Scheduler) and as PDF Load Worksheets emailed by the receiver pre-shift.

Business context

Buyers (Receiver / Foreman) drive PO creation in PP. Each PO carries N POLines, and each POLine is exactly one Lot — Lot # = PO # + line # (e.g. 00547534-1). The buyer enters the vendor manifest reference as a free-text slash-pair on PurchaseOrder.VendorReference (e.g. 1322208/5129518); the receiving team uses both halves as the start-of-day cross-match to the vendor’s manifest. FIN must preserve VendorReference verbatim — never parse the slash.

Canonical field reference

PP fieldBusiness meaningData typeUoMValidity rulesSentinel valuesEnum valuesLookup tableFIN mappingVersion notes
Load.LoadNumberCanonical FIN load id. Captured from the PP Load Header screen (PD030), NOT from the RP581 worksheet body. One physical truck = one Load.id_reference8-digit numeric on most Nathel loadsevents.data.load.load_number
PurchaseOrder.PONumber8-digit PO number printed on RP581 immediately before the * RELEASED * / ** HOLD ** marker. The top-of-page 8-digit (e.g. 20231715) is a print-job artifact and MUST NOT be confused with the PO number.id_reference8-digit numericevents.data.po.po_number
PurchaseOrder.HeldFlagHard-coded asterisk convention on RP581. * RELEASED * (single asterisks) = Held=N; ** HOLD ** (double asterisks) = Held=Y. This drives the sellability gate via events.data.po.held = true|false.flag* RELEASED * = Held=N (PO is released, lots can move)
** HOLD ** = Held=Y (PO is held — no allocations allowed)
events.data.po.held
PurchaseOrder.VendorReferenceSlash-pair free-text field stored as a SINGLE string on PO header line 7 (e.g. 1322208/5129518). Canonical manifest join key — both halves are vendor PO refs the buyer typed verbatim. Receiving uses analog cross-match arrival report ↔ manifest at start of day.composite_stringPreserve raw — never parse the slashevents.data.po.vendor_reference
PurchaseOrderLine.LotNumberPer-line lot id. Always PONumber + lineNumber (e.g. 00547534-1). The dash suffix is the line index within the PO, NOT a sub-lot of a parent.id_referenceFormat: <PO>-<lineNumber> — mirror verbatim, never modifyevents.data.lot.lot_number
PurchaseOrderLine.OrderQtyCases ordered for this line. Drives downstream receiving expectation + variance calculation.integercasesNon-negative0 = Nothing expected — placeholder for DNR (Did Not Receive) or cancelled lineevents.data.po_line.ordered_cases
PurchaseOrderLine.UnitCostPer-case cost in USD. Anchors cost-layering downstream.currencyUSD per caseNon-negative decimalevents.data.po_line.unit_cost_usd
PurchaseOrderLine.BrandNamePer-line carton brand printed in the LABELS column on RP581. Distinct from the PO header Vendor — brand is per-line so one PO can carry mixed brands.stringevents.data.po_line.brand
PurchaseOrderLine.ProductCodePP item-master SKU printed in the PROD column on RP581.id_referencePP item master (Module 09 + commodity master)events.data.po_line.product_code
PurchaseOrder.FreightCodeFreight terms code. F=FOB / D=Delivered (Mod 09 p9). Nathel uses inconsistently — FIN should pull storage requirements from commodity golden data, not this column.enumF, DPD060 freight-code masterevents.data.po.freight_code
PurchaseOrder.HeaderCommentsFree-text admin scratchpad printed under PO notes: on RP581. Conventions include DNR (Did Not Receive) and NATHEL 1/3 (internal flag). Not structured data — preserve verbatim, downstream consumers extract conventions heuristically.textDNR = Did Not Receive — entire PO line is a placeholder
NATHEL 1/3 = Internal Nathel split flag (1 of 3 trucks)
events.data.po.header_comments
Lot.SubLotAnnotations.ParallelLotNumberWhen a case carries a GTIN/GS1 label, PP creates a parallel lot reference. There is NO schema field for this today — flagged as net-new contract. Capture on the QC item event without mutating the PP-mirror lot id.stringNet-new contract — not in PP base schemaevents.data.qc_item.parallel_lot_numberNET-NEW per FIELD_MAPPING_AND_SAFETY_SPEC §0 — does not exist in PP base schema

Workflow state machines

PP Purchase Order lifecycle

The canonical PO state machine in Module 09. Buyer creates PO, optionally holds it, releases it for receiving, the receiver captures arrival, and the PO closes when all lines are reconciled. Hold/Release is the load-bearing gate that feeds FIN’s sellability check.

  • Initial state: Created
  • Terminal states: Closed
stateDiagram-v2
    [*] --> Created
    Created --> Held: Buyer flags PO with `** HOLD **`
    Created --> Released: Buyer flags PO with `* RELEASED *`
    Held --> Released: Buyer clears hold flag
    Released --> Receiving: First receiving event recorded against any POLine
    Receiving --> Reconciled: All POLines reach OrderQty (or DNR on remainder)
    Reconciled --> Closed: Buyer or AP closes the PO header
    Closed --> [*]

Transitions:

FromToTriggerActor roleNotes
CreatedHeldBuyer flags PO with ** HOLD **BuyerHeld PO cannot allocate inventory downstream
CreatedReleasedBuyer flags PO with * RELEASED *Buyer
HeldReleasedBuyer clears hold flagBuyer
ReleasedReceivingFirst receiving event recorded against any POLineReceiver
ReceivingReconciledAll POLines reach OrderQty (or DNR on remainder)Receiver
ReconciledClosedBuyer or AP closes the PO headerAP

Cross-references to other PP modules

ModuleTitleHandoff pointNotes
13ShippingReleased POs surface as expected inbound loads that the receiver matches against vendor manifests. Shipping documents (BOL, manifest) flow alongside the PP PO into the receiving handoff.
14Transportation & DeliveryCarrier + driver metadata on inbound loads tie back into Module 14 for the truck/route record.
16Accounts PayableClosed POs flow into AP for invoice reconciliation. The unit_cost_usd per POLine anchors AP three-way match.

Sample artifacts

KindFilenameManifest anchorNotes
pdf_report09 - Purchasing.PDFBucket 1 (Vendor manual) + Module 09 subsetModule 09 user guide (PP 2401.0)
pdf_reportRP581 Load Worksheet (Nathel training DB)FIELD_MAPPING_AND_SAFETY_SPEC §1.6Canonical printed artifact for inbound loads. Two real samples ground the field mapping table.
passing_sheetFARMERS BEST PASSING REPORT- 11106755.PDFBucket 3 — Vendor passing reportsPP receives vendor PO-Cs via email upstream of Module 09 receiving; ties into the canonical vendor_passing CIR.

Open questions / drift watch

  • `Lot.SubLotAnnotations.ParallelLotNumber` is net-new — not in PP base schema. Where does PP store the GTIN/GS1 lineage today?
    • Raised in: FIELD_MAPPING_AND_SAFETY_SPEC §0 Vendor PP-parallel lot
    • Watch artifact: Future RP581 sample with explicit GS1 lot trail
  • PO Held → Released backflow timing. Today FIN treats hold state as latest-write-wins; PP may carry a hold history we haven’t captured.
    • Raised in: Module 09 PO lifecycle workflow design
    • Watch artifact: PP PO history audit report