Spec (docs/reviewed/document-lifecycle.md):
- C1: Correct GlManager::delete() description — reversal entry, not hard delete
- C3: Clarify PO status 2/3 are derived (receipt_status), never stored
- C4: Add invoice status=2 (Paid/Settled) to status table
- C5: Add full Receipt/Payment Billing Note lifecycle section
- C6: Add Quotation status table and transition rules
- C7: Document soft-delete tombstone mechanism (company_id negation)
Code (InvoiceManager.php):
- C2: voidInvoice() now blocks on active credit notes, posted receipt
billing notes, and posted payment billing notes in addition to the
existing receipt/payment checks
- M9: softDelete() skips assertPostingWindow for draft invoices (status=0)
since drafts have no GL entry and no accounting impact
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- StockManager: coerce lot_number/serial_number to trimmed string (fixes
Array-to-string warnings); validate quantity > 0 on insert; tighten
transfer pair lookup to match in/out side by column value
- PostingWindowGuard: strip time component from datetime strings before
date-format validation
- docs/tests/doc_flow_test.php: 32-assertion document flow suite covering
Stock In create + approve, Sales Order draft/confirm, Invoice from Order
(with duplicate-block check), PO create/confirm, Quotation create, and
usage increment wiring check; all 32/32 PASS against wms_codex_test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>