# PurchasePriceRule

## Description

PurchasePriceRule defines the exact purchasing condition used to price a draft purchase-order line. A rule can target an item, purchasing unit of measure, transaction currency, validity window, minimum quantity break, and explicit priority, allowing procurement to model annual contracts, temporary promotions, and tiered supplier pricing.

The rule lives as an independently managed record because procurement needs to retire, reactivate, or update individual supplier conditions without changing the enclosing contract container.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Active: createPurchasePriceRule
    Active --> Inactive: deactivatePurchasePriceRule
    Inactive --> Active: activatePurchasePriceRule
    Active --> Active: updatePurchasePriceRule
    Inactive --> Inactive: updatePurchasePriceRule
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| deactivate | ACTIVE | INACTIVE | [deactivatePurchasePriceRule](../commands/DeactivatePurchasePriceRule.md) |
| activate | INACTIVE | ACTIVE | [activatePurchasePriceRule](../commands/ActivatePurchasePriceRule.md) |

### Command Definitions

- [createPurchasePriceRule](../commands/CreatePurchasePriceRule.md) - Add a new active supplier purchase price rule to a list
- [updatePurchasePriceRule](../commands/UpdatePurchasePriceRule.md) - Update the condition fields of a price rule without changing historical order snapshots
- [activatePurchasePriceRule](../commands/ActivatePurchasePriceRule.md) - Re-enable a retired rule for future price resolution
- [deactivatePurchasePriceRule](../commands/DeactivatePurchasePriceRule.md) - Stop a rule from being selected for new draft orders

### Query Definitions

- [getPurchasePriceList](../queries/GetPurchasePriceList.md) - Retrieve rules through their parent price list
- [calculatePurchasePrice](../queries/CalculatePurchasePrice.md) - Apply rule precedence and quantity logic to a draft order line

### Models

- PurchasePriceRule

### Invariants

- Unit price must be strictly positive
- Minimum quantity must be zero or greater
- Effective end date, when provided, must be on or after the effective start date
- Operational use requires the referenced item, currency, and purchase unit to exist and remain active
- Rules with indistinguishable precedence for the same supplier, item, date, UoM, currency, and quantity context are invalid because price resolution must always choose a single winner
- Multi-currency price conversion is out of scope inside purchase pricing; rules are matched only when the requested transaction currency equals the rule currency
- Purchase orders snapshot the applied rule reference and unit price so later edits or deactivation never rewrite historical commercial terms

### Relationships

- **Belongs To PurchasePriceList**: Each rule is owned by one [PurchasePriceList](./PurchasePriceList.md)
- **References Item**: The rule prices one [Item](../../../item-management/docs/models/Item.md) or another explicitly documented purchasing scope
- **References Currency**: The rule price is denominated in one [Currency](../../../primitives/docs/models/Currency.md)
- **References Unit**: The rule is keyed to one purchasing [Unit](../../../primitives/docs/models/Unit.md); quantity comparison may require [convertQuantity](../../../primitives/docs/queries/ConvertQuantity.md)
- **Snapshotted By PurchaseOrderLine**: The final agreed price and matched rule reference are frozen onto [PurchaseOrder](./PurchaseOrder.md) lines
