# StockReservation

## Description

StockReservation stores one time-phased reservation slice for a source-document line at one site. Reservations are demand commitments against available stock; they do not represent a physical stock type and therefore do not create InventoryLedger rows or mutate StockLevel quantities.

StockReservation is the reservation balance cache used by site-level availability queries and reservation commands. Available-to-promise at site level is computed as the sum of `StockLevel(stockType=AVAILABLE)` across active locations in the site minus OPEN reservation quantity for that item and site, where open reservation quantity is `max(reservedQuantity - consumedQuantity, 0)`.

Reservations are source-driven and must reference a source document line, but the source line is a trace key rather than the row identity. A single source line may create multiple StockReservation rows when the reserved quantity is split by site, storage location, required date, lot, or future supply source. Optional `storageLocationId` can be set when the reservation has already been allocated to a specific location; ordinary reservations are site-level and leave location selection to later picking or allocation workflows.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Open: createStockReservation
    Open --> Open: updateStockReservation
    Open --> Open: issue consumption
    Open --> Closed: closeStockReservation
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| update | OPEN | OPEN | [updateStockReservation](../command/UpdateStockReservation.md) |
| consume | OPEN | OPEN | internal issue execution |
| close | OPEN | CLOSED | [closeStockReservation](../command/CloseStockReservation.md) |

### Command Definitions

- [createStockReservation](../command/CreateStockReservation.md) - Creates a reservation slice after validating available-to-promise
- [updateStockReservation](../command/UpdateStockReservation.md) - Sets the current slice quantity and requirement fields after delta-aware available-to-promise validation
- [closeStockReservation](../command/CloseStockReservation.md) - Closes the reservation slice when it no longer contributes reservation demand

### Query Definitions

- [getStockLevel](../query/GetStockLevel.md) - Reads location-specific open reservation quantity for the item-location pair
- [listStockLevels](../query/ListStockLevels.md) - Computes available quantity by subtracting location-specific open reservation quantity
- [getSiteStockSummary](../query/GetSiteStockSummary.md) - Aggregates open reservation quantity at site level

### Models

- StockReservation

### Invariants

- `id` is the reservation slice identity
- `(sourceType, sourceLineId)` is non-unique and groups slices created from the same source line
- Source-line reservation state is derived by aggregating rows by `(sourceType, sourceLineId)`
- `sourceType` must be one of `SALES_ORDER`, `TRANSFER_ORDER`, or `MANUFACTURING_ORDER`
- `siteId` is required; `storageLocationId` is optional
- `status` must be one of `OPEN` or `CLOSED`
- `reservedQuantity` and `consumedQuantity` cannot be negative
- Open reservation quantity is derived as `max(reservedQuantity - consumedQuantity, 0)`
- `consumedQuantity` is internal to inventory execution and is not writable through create/update
- Quantities are stored in the item's base unit of measure
- Reservation commands do not create InventoryLedger entries
- Reservation commands do not mutate StockLevel quantities
- Reservation rows are retained when closed

### Relationships

- **References Item**: Each reservation references an Item from the item-management module
- **References Site**: Each reservation belongs to the site where demand is promised
- **Optionally References StorageLocation**: Allocated reservations can point to a specific storage location
