# LotStockLevel

## Description

LotStockLevel tracks the on-hand and blocked quantities of a specific lot at a specific storage location. It provides the lot-level granularity needed for traceability, FEFO (First Expired, First Out) picking strategies, and lot-scoped holds.

Two quantity types are maintained: `onHand` (the total physical quantity of the lot at the location) and `blocked` (the portion of onHand that is quarantined or otherwise unavailable). The available quantity at the lot level is derived as `onHand - blocked`. Lot stock levels are updated internally when stock movements referencing a lot are executed (postGoodsReceipt, postGoodsIssue, confirmStockAdjustment).

## Domain Model Definitions

### Model type

Standard

### Command Definitions

- Lot stock levels are updated internally by stock movement commands when a lotId is specified:
  - [postGoodsReceipt](../command/PostGoodsReceipt.md) - Increments onHand
  - [postGoodsIssue](../command/PostGoodsIssue.md) - Decrements onHand
  - [confirmStockAdjustment](../command/ConfirmStockAdjustment.md) - Updates onHand/blocked based on adjustmentType and fromStockCategory

### Query Definitions

- Lot stock levels are included in lot queries

### Models

- LotStockLevel

### Invariants

- Unique per lot-storageLocation pair
- `onHand` is the total physical quantity of the lot at the location (includes blocked portion)
- `blocked` is the portion of onHand under quarantine or another hold; 0 <= blocked <= onHand
- Available at the lot level = `onHand - blocked` (computed, never negative)
- Goods issue from available cannot exceed `onHand - blocked`
- Goods issue from blocked cannot exceed `blocked`
- Internal transfer preserves the lot association

### Relationships

- **Belongs to Lot**: Each lot stock level belongs to a single lot
- **References StorageLocation**: Each lot stock level tracks quantity at a specific storage location
