All checks were successful
PR checks / checks (pull_request) Successful in 32s
Managers and superusers can cancel a PO from any state via a confirmation modal that requires typing "cancel" and a mandatory reason. A cancelled PO becomes a terminal CANCELLED state and drops out of every spend tracker/graph (those filter on POST_APPROVAL_STATUSES / explicit whitelists, none of which include CANCELLED). A cancelled PO may optionally be linked to the existing PO that supersedes it (by PO number); the replacement shows the reciprocal "supersedes" link. No vessel/account/vendor match is enforced and the link can be added any time. Cancelled POs remain visible (greyed in history) and exportable, with a diagonal "CANCELLED" watermark on both the PDF and XLSX exports. - schema: POStatus CANCELLED; cancelledAt/cancellationReason; self-referential supersededById relation; ActionType CANCELLED/SUPERSEDED (+ migration) - state machine canCancel(); cancel_po permission (MANAGER + SUPERUSER) - cancelPo / supersedePo server actions + PO_CANCELLED notification - cancel modal + supersede form; cancelled banner with reciprocal links - exhaustive CANCELLED entries in all status label/variant maps - diagonal CANCELLED watermark embedded for PDF (CSS) and XLSX (image) - integration tests (cancel from any state, reason/role guards, supersede) Inventory reversal on cancel is deferred to #55 (inventory is feature-flagged off). Closes #53 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 lines
686 B
SQL
12 lines
686 B
SQL
-- Cancel + supersede: a new terminal CANCELLED status, cancel metadata, and a
|
|
-- self-referential supersede link (cancelled PO -> the existing PO that replaces it).
|
|
ALTER TYPE "POStatus" ADD VALUE 'CANCELLED';
|
|
ALTER TYPE "ActionType" ADD VALUE 'CANCELLED';
|
|
ALTER TYPE "ActionType" ADD VALUE 'SUPERSEDED';
|
|
|
|
ALTER TABLE "PurchaseOrder" ADD COLUMN "cancelledAt" TIMESTAMP(3);
|
|
ALTER TABLE "PurchaseOrder" ADD COLUMN "cancellationReason" TEXT;
|
|
ALTER TABLE "PurchaseOrder" ADD COLUMN "supersededById" TEXT;
|
|
|
|
ALTER TABLE "PurchaseOrder" ADD CONSTRAINT "PurchaseOrder_supersededById_fkey"
|
|
FOREIGN KEY ("supersededById") REFERENCES "PurchaseOrder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|