# StockAdjustment

## Description

StockAdjustment represents an inventory adjustment request that follows a submit-then-confirm workflow. Adjustments cover four types: CORRECTION (fix quantity errors), SCRAP (write off damaged/expired stock), BLOCK (quarantine stock), and UNBLOCK (release quarantined stock). Each adjustment requires a reasonCode explaining why the change is needed and an adjustmentDate representing the business date when the adjustment should affect inventory.

A StockAdjustment progresses through a simple lifecycle: it is created as a DRAFT, submitted for review (SUBMITTED), then either confirmed or rejected. Confirmation executes the actual stock changes — creating InventoryLedger entries and updating StockLevel. A draft adjustment can be cancelled, and a rejected adjustment can be updated and resubmitted.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createStockAdjustment
    Draft --> Submitted: submitStockAdjustment
    Draft --> Draft: updateStockAdjustment
    Draft --> Cancelled: cancelStockAdjustment
    Submitted --> Confirmed: confirmStockAdjustment
    Submitted --> Rejected: rejectStockAdjustment
    Rejected --> Draft: updateStockAdjustment (resubmit)
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| submit | DRAFT | SUBMITTED | [submitStockAdjustment](../command/SubmitStockAdjustment.md) |
| cancel | DRAFT | CANCELLED | [cancelStockAdjustment](../command/CancelStockAdjustment.md) |
| confirm | SUBMITTED | CONFIRMED | [confirmStockAdjustment](../command/ConfirmStockAdjustment.md) |
| reject | SUBMITTED | REJECTED | [rejectStockAdjustment](../command/RejectStockAdjustment.md) |
| resubmit | REJECTED | DRAFT | [updateStockAdjustment](../command/UpdateStockAdjustment.md) |

### Command Definitions

- [createStockAdjustment](../command/CreateStockAdjustment.md) - Create a new stock adjustment in DRAFT status with adjustment type, reason code, and lines
- [updateStockAdjustment](../command/UpdateStockAdjustment.md) - Update a DRAFT or REJECTED adjustment (modify lines, reason code); REJECTED transitions back to DRAFT
- [submitStockAdjustment](../command/SubmitStockAdjustment.md) - Submit a draft adjustment for review, transitioning to SUBMITTED
- [confirmStockAdjustment](../command/ConfirmStockAdjustment.md) - Approve and execute a submitted adjustment, creating InventoryLedger entries and updating StockLevel
- [rejectStockAdjustment](../command/RejectStockAdjustment.md) - Reject a submitted adjustment, transitioning to REJECTED
- [cancelStockAdjustment](../command/CancelStockAdjustment.md) - Cancel a draft adjustment, transitioning to CANCELLED

### Query Definitions

- [getStockAdjustment](../query/GetStockAdjustment.md) - Retrieve a stock adjustment by id
- [listStockAdjustments](../query/ListStockAdjustments.md) - List stock adjustments with optional filters by status, adjustmentType, date range

### Models

- StockAdjustment

### Invariants

- adjustmentType must be one of: CORRECTION, SCRAP, BLOCK, UNBLOCK
- reasonCode is required for all adjustments
- adjustmentDate is required and becomes the effectiveDate of the InventoryLedger rows posted when the adjustment is confirmed
- Only DRAFT adjustments can be submitted
- Only SUBMITTED adjustments can be confirmed or rejected
- Only DRAFT adjustments can be cancelled
- A rejected adjustment returns to DRAFT via updateStockAdjustment and can be resubmitted
- Confirmation creates InventoryLedger entries for each line and updates StockLevel
- Must have at least one StockAdjustmentLine before submission

### Relationships

- **Has many StockAdjustmentLine**: Each adjustment contains one or more lines specifying item-location quantity changes
- **Creates InventoryLedger**: On confirmation, each line is posted through `postInventoryLedger`, generating InventoryLedger entries with `sourceType=STOCK_ADJUSTMENT` that reference the StockAdjustment via `sourceId`
