What it is
Purchase order lines — header and line combined in one row (order_no + sku), Katana-compatible. Each row is one article on one supplier order, with ordered vs. received quantities, expected arrival, price, and a full provenance trail (who created it — user or agent — and who approved it).
The status machine is draft → pending_approval → ordered → partially_received → received (or cancelled). Katana mapping: draft→DRAFT, ordered→NOT_RECEIVED, partially_received→PARTIALLY_RECEIVED, received→RECEIVED (pending_approval is a Concierca addition, exported as DRAFT). Open quantity is always computed as quantity_ordered − quantity_received, never stored.
Open lines feed the Procurement Queue: open_purchase_order_quantity and arrival dates there are aggregated from lines in ordered / partially_received. A unique index on recommendation_key over open lines is the physical double-order lock — one queue recommendation can never spawn two open orders.
How it gets data
Three paths write here: the procurement agent creates draft lines from queue recommendations, admins edit in the app, and external systems (e.g. an existing PO list) push through the Ingest API:- One JSON record per request; unknown fields are dropped.
- Idempotent upsert on
(tenant_id, external_id)— use a stable per-line id (e.g.PO-2026-014-1). tenant_id/workspace_idcome from the API key context, never from the body.product_name,supplier_name,variant_external_id,product_external_idare filled by a database trigger from the SKU — don’t send or maintain them by hand.
Fields
Order line
Snapshot columns (trigger-filled)
Provenance, approval & external sync
✓ = editable in the app, settable on create, and accepted on ingest. “trigger” = computed by the database on write. “API only” = real database column not registered as a visible app column — readable via query, maintained by the system or specialized flows.
Like every workspace table, purchase order lines also carry the system columns
id, tenant_id, workspace_id, created_at, and updated_at — set automatically, never sent by integrations.