# PurchaseChangeOrder

## Description

PurchaseChangeOrder is the formal amendment document that proposes changes to an existing ordered purchase order. Once a PurchaseOrder reaches `ORDERED` status, its commercial terms are immutable through normal update commands. A PurchaseChangeOrder captures one or more proposed line-level actions (add, modify, or remove) along with a reason for the change, and progresses through its own approval lifecycle before the changes take effect on the target purchase order.

Each change order targets one purchase order, records a revision number for optimistic concurrency, and includes a reason for the change. Change order lines specify whether to add, modify, or remove a line on the target order, along with the proposed terms.

When a change order is approved and applied, the affected purchase order lines are superseded and replaced by new ACTIVE lines carrying the revised terms. The original lines and their downstream references (matched bills, posted receipts) remain intact as historical records. The PO's `currentRevisionNumber` is incremented, and receipt and billing statuses are recalculated using lineage-aware quantities that span the full history of each line.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createPurchaseChangeOrder
    Draft --> Draft: updatePurchaseChangeOrder
    Draft --> Submitted: submitPurchaseChangeOrder
    Submitted --> Approved: approvePurchaseChangeOrder
    Submitted --> Rejected: rejectPurchaseChangeOrder
    Rejected --> Draft: (returned to draft for revision)
    Approved --> Applied: applyPurchaseChangeOrder
    Draft --> Cancelled: cancelPurchaseChangeOrder
```

### Command Definitions

- [createPurchaseChangeOrder](../commands/CreatePurchaseChangeOrder.md) - Create a draft change order targeting an ordered purchase order with one or more proposed line actions
- [updatePurchaseChangeOrder](../commands/UpdatePurchaseChangeOrder.md) - Revise change order lines or reason while the change order is in draft
- [submitPurchaseChangeOrder](../commands/SubmitPurchaseChangeOrder.md) - Submit the change order for approval review
- [approvePurchaseChangeOrder](../commands/ApprovePurchaseChangeOrder.md) - Approve the submitted change order, authorizing it for application
- [applyPurchaseChangeOrder](../commands/ApplyPurchaseChangeOrder.md) - Apply the approved change order to the target purchase order, superseding affected lines and creating new active lines
- [rejectPurchaseChangeOrder](../commands/RejectPurchaseChangeOrder.md) - Reject a submitted change order, returning it to draft for revision
- [cancelPurchaseChangeOrder](../commands/CancelPurchaseChangeOrder.md) - Cancel a draft change order

### Query Definitions

- [getPurchaseChangeOrder](../queries/GetPurchaseChangeOrder.md) - Retrieve a change order with its lines and target purchase order context

### Models

- PurchaseChangeOrder
- PurchaseChangeOrderLine

### Invariants

- A change order always targets exactly one purchase order
- Change orders can only target purchase orders in `ORDERED` status
- Only one open change order (DRAFT, SUBMITTED, or APPROVED) is allowed per purchase order at a time
- A submitted change order must contain at least one change order line
- The `fromRevisionNumber` must match the target purchase order's `currentRevisionNumber` at the time of application to prevent stale amendments
- MODIFY actions must reference an existing ACTIVE purchase order line and may only change quantity or unit price; item and unit-of-measure changes are not permitted
- MODIFY actions cannot reduce quantity below the lineage's cumulative received quantity or cumulative billed quantity (MATCHED bills)
- REMOVE actions must reference an existing ACTIVE purchase order line with no posted receipt quantity and no matched bill quantity
- ADD actions must reference an active item with quantity greater than zero and a non-negative unit price
- Every change order line specifies exactly one action: ADD, MODIFY, or REMOVE
- For MODIFY and REMOVE actions, `originalPurchaseOrderLineId` must reference a valid ACTIVE line on the target purchase order
- For ADD actions, `itemId` must be provided and reference an active item
- Applying a change order atomically supersedes affected lines, creates new active lines, increments the PO's `currentRevisionNumber`, and recalculates receipt and billing statuses

### Relationships

- **Belongs To PurchaseOrder**: Each change order targets one [PurchaseOrder](./PurchaseOrder.md) via `purchaseOrderId`
- **Has Many PurchaseChangeOrderLines**: Each change order contains one or more proposed line-level actions
- **PurchaseChangeOrderLine References PurchaseOrderLine**: For MODIFY and REMOVE actions, `originalPurchaseOrderLineId` identifies the ACTIVE purchase order line being changed or removed
- **PurchaseChangeOrderLine References Item (cross-module)**: For ADD actions, `itemId` must point to an ACTIVE item from item-management
- **PurchaseChangeOrderLine References Unit (cross-module)**: Optional `unitId` specifies the unit of measure for the line
- **PurchaseChangeOrderLine References Site (cross-module)**: Optional `receivingSiteId` allows a line-level receiving site override
