Skip to main content
Version: v1.0.0(int)

W115: Delete purchase order

Wipes a PO and every inventory effect it produced. Triggered from the Purchase Order Detail page.

Steps

  1. Load the PO. Call PurchaseOrders.getPoById to confirm existence and capture poNumber.

  2. Gather the PO's source ids. Before anything cascades, list the PO's items and its receipts' items so their ledger rows can be found: the line ids (po_item) and the receipt-item ids (po_receipt).

  3. Physically delete the PO's ledger rows. Call deleteBySource on both ledgers for po_item (the status-driven ORDER rows) and po_receipt (the receipt-driven RECEIVE rows). The rows are removed outright. Because every row tied to a line — forward, reverse, or edit-trail — shares that line's source id, deleting by (source_type, source_id) sweeps them all, including any leftover reversal pairs from earlier line edits.

  4. Detach documents. Call Documents.listByEntity('purchase_order', poId) and Documents.delete for each.

  5. Delete the PO row. Call PurchaseOrders.deletePo. Items, receipts, and receipt items cascade away at the DB layer.

Returns

Nothing.

Business rules

  • Hard delete, not reversal. Deleting the PO removes its ledger rows entirely — the record never happened. Cancellation (status → Cancelled) is the append-only path that reverses and keeps the audit trail.
  • Atomic. Steps 3 through 5 share one transaction.
  • Both ledgers, both targets. A materials-target PO lands its rows in the materials ledger and a finished-goods-target PO in the FG ledger; the sweep runs against both, so either target is cleaned up.
  • Cost cascade is still a v1 gap. The downstream FIFO/cost cascade is not implemented (see W122 steps 7-9), so no downstream cost values are recomputed here.

Errors

  • NotFoundError. The PO was not found.