# PurchaseOrder

## Description

PurchaseOrder is the commercial procurement document that turns supplier pricing and payment terms into a concrete supplier commitment. It owns the supplier reference, receiving site, ordered lines, agreed unit prices, payment-term snapshot, and the fulfillment progress that later receipts and supplier bills consume.

The model combines document-control states with fulfillment states so procurement can answer both questions at once: "has this order been commercially approved?" and "how much of it is still open to receive or bill?"

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createPurchaseOrder
    Draft --> Draft: updatePurchaseOrder
    Draft --> Submitted: submitPurchaseOrder
    Submitted --> Draft: rejectPurchaseOrder
    Submitted --> Ordered: approvePurchaseOrder
    Draft --> Cancelled: cancelPurchaseOrder
    Submitted --> Cancelled: cancelPurchaseOrder
    Ordered --> Cancelled: cancelPurchaseOrder
    Ordered --> PartiallyReceived: postGoodsReceipt
    Ordered --> Received: postGoodsReceipt
    PartiallyReceived --> PartiallyReceived: postGoodsReceipt
    PartiallyReceived --> Received: postGoodsReceipt
    Ordered --> PartiallyBilled: matchPurchaseBill
    Ordered --> Billed: matchPurchaseBill
    PartiallyReceived --> PartiallyBilled: matchPurchaseBill
    PartiallyReceived --> Billed: matchPurchaseBill
    Received --> PartiallyBilled: matchPurchaseBill
    Received --> Billed: matchPurchaseBill
    PartiallyBilled --> PartiallyBilled: matchPurchaseBill
    PartiallyBilled --> Billed: matchPurchaseBill
    PartiallyReceived --> Closed: closePurchaseOrder
    Received --> Closed: closePurchaseOrder
    PartiallyBilled --> Closed: closePurchaseOrder
    Billed --> Closed: closePurchaseOrder
```

### Command Definitions

- [createPurchaseOrder](../commands/CreatePurchaseOrder.md) - Create a new draft purchase order with one or more lines
- [updatePurchaseOrder](../commands/UpdatePurchaseOrder.md) - Revise mutable draft commercial fields and line content
- [submitPurchaseOrder](../commands/SubmitPurchaseOrder.md) - Validate draft completeness and move the order into submitted review
- [rejectPurchaseOrder](../commands/RejectPurchaseOrder.md) - Return a submitted order to draft with a rejection reason
- [approvePurchaseOrder](../commands/ApprovePurchaseOrder.md) - Freeze commercial terms and release a submitted order to the supplier
- [cancelPurchaseOrder](../commands/CancelPurchaseOrder.md) - Cancel an order before downstream fulfillment or billing makes it irreversible
- [closePurchaseOrder](../commands/ClosePurchaseOrder.md) - Close remaining open quantity after fulfillment or explicit write-off
- [postGoodsReceipt](../commands/PostGoodsReceipt.md) - Update receipt progress and receiving status from posted goods receipts
- [matchPurchaseBill](../commands/MatchPurchaseBill.md) - Update billed progress and billing status from matched supplier bills

### Query Definitions

- [getPurchaseOrder](../queries/GetPurchaseOrder.md) - Retrieve a purchase order with its lines, snapshots, and fulfillment totals

### Models

- PurchaseOrder
- PurchaseOrderLine
- PurchaseOrderPaymentTermSnapshot
- PurchaseOrderLinePriceSnapshot

### Invariants

- A purchase order always belongs to exactly one company and one supplier
- Submitted, ordered, fulfilled, billed, and closed orders must contain at least one line
- Every line references an active item, has ordered quantity greater than zero, and has a non-negative agreed unit price
- Lines that require physical receipt must carry a receiving site before the order can leave draft
- Commercial fields that define the supplier commitment are mutable only while the order is in `DRAFT`
- The payment term snapshot and ordered unit price snapshot are immutable after the order enters `ORDERED`
- Cumulative received quantity and cumulative billed quantity cannot be negative and cannot exceed business tolerance rules for the line
- Cancellation is not allowed once a posted receipt or a matched supplier bill already exists
- External supplier order reference is unique within one company when provided

### Relationships

- **Belongs To BusinessPartner**: Each order references one supplier [BusinessPartner](../../../business-partner/docs/models/BusinessPartner.md)
- **Belongs To Site**: Each order belongs to one receiving [Site](../../../organization/docs/models/Site.md) at document level, with line-level overrides allowed as an extension
- **Has Many PurchaseOrderLines**: Each order contains one or more commercial commitment lines
- **Snapshots PurchasePaymentTerm**: The order stores one immutable [PurchasePaymentTerm](./PurchasePaymentTerm.md) snapshot for downstream bill calculation
- **Snapshots PurchasePriceRule**: Each line may preserve the matched [PurchasePriceRule](./PurchasePriceRule.md) reference and final ordered price
- **Referenced By GoodsReceipt**: [GoodsReceipt](./GoodsReceipt.md) lines consume open ordered quantity
- **Referenced By PurchaseBill**: [PurchaseBill](./PurchaseBill.md) lines consume open billed quantity
