WC Inventory Overview 1.22.0
WC Inventory Overview 1.22.0
Canonical standalone release from magpern/wc-inventory-overview.
Prerequisite
Upgrade from 1.21.0 (M4 Receipt Engine, schema v8).
What changed
Milestone M5 — Purchase Order Receiving — connects Purchase Orders (M2) to the Goods Receipt engine (M4). qty_received becomes a real, maintained column on wc_io_purchase_order_lines (the full INV-4 formula: qty_outstanding = GREATEST(0, qty_ordered - qty_received - qty_cancelled)). Schema v9 — one column addition, zero new tables (M4 had already prepared receipt_line.po_line_id and goods_receipt.source for this moment).
Goods_Receipt_Serviceremains the sole stock/cost mutator (D3/INV-2, unchanged) and gains a second responsibility: sole business orchestrator forqty_receivedchanges. It never writesqty_receiveditself — it delegates to a new class,PO_Receiving_Sync, the sole owner of that mutation, which in turn is the only caller ofPurchase_Order_Lines::increment_qty_received(), the sole physical writer. No second mutation path was introduced anywhere — every tier of this three-tier chain is architecture-guard enforced.- Two new PO statuses,
partially_received/received, auto-transitioned only via a pure, direction-agnostic recompute function — never operator-selected, never reachable through the manual transition table. - Receiving against a PO: a "Receive" button on the PO detail page pre-fills a new Goods Receipt draft from the PO's outstanding lines, reusing the existing M4 draft/post/void flow unchanged. Mixed receipts (PO-linked + direct lines) and multi-PO receipts both work.
- Over-receipt is allowed, never blocked (per D5) — warned at post-confirmation, recorded in the PO event log with an
over_receipt/qty_overmarker. - Correct, order-independent void reversal: both mandatory regression scenarios pass — post A, post B, void A (B's contribution survives); and post A, post B, void B, void A (order-independence,
qty_received/outstanding/PO status correct at every one of the four steps). - Reconciliation CLI:
wp wc-io reconcile-qty-received [--fix] [--po=<id>]— read-only drift report by default;--fixrepairs through the sole-owner class only, every repair individually logged and recorded as its own PO event. - The M3 Incoming regression fix: Inventory Position's "Incoming" figure now correctly decreases as receipts post against PO lines — the recomputation M3's own plan explicitly deferred to this milestone.
- 60 new dedicated tests (full INV-4 formula, status-recompute direction-agnostic behavior,
PO_Receiving_Syncend-to-end, PO-linked post/void including the forced-failure rollback test and both mandatory void-order regressions, pre-transaction validation,po_line_idpersistence, the M3 regression, architecture guards) — 290 tests / 1,305 assertions total in the M1–M5 focused suite, all passing. - Pre-tag audit remediation: an independent audit found four gaps against this plan's own Definition of Done — a missing outstanding-quantity display in the receipt editor, a missing mandatory over-receipt warning at post-confirmation, an N+1 query pattern in the pre-transaction PO-line validation step, and
close_short()not accounting forqty_receivedwhen cancelling a line's remainder. All four were fixed on this branch (seedocs/architecture-audit.md's "M5 audit remediation" subsection) without touching the ownership chain, schema, or transaction boundaries — 292 tests / 1,317 assertions in the M1–M5 focused suite, all passing, with the integration suite's pre-existing 4 errors + 7 failures + 2 skips unchanged.
Explicitly not in this release:
- No new stock/cost mutation path —
Restock_Service's caller set gained zero new entries. - No header-level
po_idcolumn onwc_io_goods_receipts(D6: line-level linkage only, unchanged from M4). - No new value written to the per-line
wc_io_purchase_order_lines.statuscolumn — "line completion" is derived fromqty_outstanding == 0, never stored as a line-level enum. - No legacy Batch Intake migration or retirement (M6). No ASN, barcode receiving, or warehouse scanning.
- No changes to Batch Intake, Quick Restock, Cost Adjustment, or Supplier admin business logic.
Install / upgrade
- Download
wc-inventory-overview-1.22.0.zipfrom this release. - Upload via Plugins → Add New → Upload, or use Dashboard → Updates on production.
DB_VERSIONbumps from 8 to 9 — theqty_receivedcolumn addition runs automatically on activation/upgrade. Every existing PO line starts atqty_received = 0(correct-by-construction — no PO line created before M5 could ever have had a receipt posted against it).
Before tagging
Per docs/release-runbook.md: confirm CI (unit, M1–M5 blocking, and cumulative integration suites) passes with zero new failures, confirm DB_VERSION is 9 and the schema assertion is ok: true (dispatcher-routing double-checked — the same v(n-1)/v(n) trap M4 already flagged repeats identically at v8/v9), walk through receive-against-PO (partial → complete → void) and verify qty_received/PO status/Inventory Position match by hand, confirm over-receipt is possible and audited (not blocked), and confirm Batch Intake / Quick Restock / Cost Adjustment / M4's Quick Receive Without PO remain unaffected.
Rollback
Read this before rolling back a site that has posted any PO-linked receipts. Like 1.21.0, this release mutates state a code-only rollback cannot reverse — a plugin-code rollback to 1.21.0 does not reverse the qty_received/PO-status effects of receipts already posted under 1.22.0. Use Void (on the current version) to reverse a specific receipt instead of rolling back code. See docs/rollback-plan.md for the full explanation and the catastrophic full-restore path if a genuine rollback is unavoidable.
Changelog: CHANGELOG.md