# purchase-order-lifecycle

## Overview

Manages the full lifecycle of a purchase order from creation through closure or cancellation. A Purchaser creates a PO in DRAFT status with supplier, currency, receiving site, and line items (item, quantity, unit price). The PO is then submitted for approval. An Approver reviews and either approves or rejects the PO. Approval transitions it to ORDERED status which commits the order to the supplier; rejection returns it to DRAFT with a reason so the Purchaser can revise and resubmit. An ORDERED PO can be amended — lines can be added, modified, or removed with revision tracking and downstream constraint enforcement. A Purchaser can cancel a PO at any stage (DRAFT, SUBMITTED, or ORDERED) provided no posted inbound shipments exist. Once all goods are received, the PO is closed. Multi-currency is supported — currency is locked at confirmation time.

## Actors Involved

- [Purchaser](../../actor/purchaser.md) — creates, edits, and submits purchase orders
- [Approver](../../actor/approver.md) — reviews, approves, or rejects submitted purchase orders

See [action-matrix.md](./action-matrix.md) for models involved and the action visibility matrix.

## Flow Diagram

```mermaid
sequenceDiagram
    participant P as Purchaser
    participant S as System
    participant A as Approver

    P->>S: Create PO (supplier, currency, site, line items)
    S-->>P: PO created in DRAFT status with auto-generated doc number

    P->>S: Edit PO (update quantities, add/remove lines, change supplier)
    S-->>P: PO updated

    P->>S: Submit PO for approval
    S-->>P: PO status → SUBMITTED
    S-->>A: Notification: PO pending approval

    alt Approve
    A->>S: Approve PO
    S-->>A: PO status → ORDERED, confirmedAt set
    S->>S: Lock currency (no further currency changes)
    S->>S: Calculate incoming inventory for PO line items
    else Reject
    A->>S: Reject PO with reason
    S-->>A: PO status → DRAFT, rejectionReason set
    A-->>P: PO returned for revision
    P->>S: Edit and resubmit PO
    end

    Note over P,S: Amendment available while PO is ORDERED

    P->>S: Amend PO (add/modify/remove lines with reason)
    S-->>P: PO revisionNumber incremented, line revisions recorded

    Note over P,S: Inbound shipment happens in a separate flow

    P->>S: Close PO (after all receipts settled)
    S-->>P: PO status → CLOSED, closedAt set
    S->>S: Incoming inventory → 0

    Note over P,S: Cancellation available at any stage before fulfillment

    P->>S: Cancel PO
    alt no posted inbound shipments and no matched PBs
        S-->>P: PO status → CANCELLED
    else posted inbound shipments exist
        Note over S: rejects with "Cannot cancel: posted receipts exist for this order"
        S-->>P: Error
    end
```

## Stories

- [Create Purchase Order](./story/purchaser--create-purchase-order.md)
- [Edit Purchase Order](./story/purchaser--edit-purchase-order.md)
- [Submit Purchase Order](./story/purchaser--submit-purchase-order.md)
- [Approve Purchase Order](./story/approver--approve-purchase-order.md)
- [Reject Purchase Order](./story/approver--reject-purchase-order.md)
- [Amend Purchase Order](./story/purchaser--amend-purchase-order.md)
- [Close Purchase Order](./story/purchaser--close-purchase-order.md)
- [Cancel Purchase Order](./story/purchaser--cancel-purchase-order.md)
- [View Purchase Order List](./story/purchaser--view-purchase-order-list.md)
