# CreateInventorySupplyPlan

## Permission Scope

supplyPlan

## Overview

createInventorySupplyPlan records new open expected inbound supply projections for source document lines. Source modules call this command when a purchase order, transfer order, or manufacturing order commits expected supply that contributes to ATP.

## Business Rules

- Input is `{ sourceType, sourceId, supplyPlans: [...] }`
- `sourceType` and `sourceId` are provided once at source document level
- Validates every requested supply plan before inserting rows
- An empty `supplyPlans` array inserts no rows and returns an empty result
- Item must exist
- Site must exist
- `(sourceType, sourceLineId)` is unique; each source line owns at most one InventorySupplyPlan row
- Planned split deliveries are represented by splitting the source document line in standard modules
- `expectedQuantity` must be zero or positive and already normalized to the item's primary unit (`Item.unitId`)
- `unitId` is validation-only and is not persisted; it must equal `Item.unitId`
- `expectedDate` must be provided
- Additional InventorySupplyPlan fields configured by the module caller are inserted when provided
- Creates a new plan with `receivedQuantity = 0` and `status = OPEN`

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Bulk input empty?}
    B -->|Yes| C[Return empty supplyPlans]
    B -->|No| D{Every item exists and unit matches?}
    D -->|No| E[Return validation error]
    D -->|Yes| F{Every site exists?}
    F -->|No| E
    F -->|Yes| G[Insert OPEN plans receivedQuantity 0]
    G --> H[Return created supplyPlans]
```

## External Dependencies

- [item-management::Item](../../../item-management/docs/model/Item.md) - Validates that the referenced item exists and provides its primary unit
- [organization::Site](../../../organization/docs/model/Site.md) - Validates that the referenced destination site exists

## Error Scenarios

- **ITEM_NOT_FOUND**: Referenced item does not exist
- **SUPPLY_PLAN_UNIT_MISMATCH**: `unitId` differs from `Item.unitId`; caller did not normalize the quantity before inventory handoff
- **SITE_NOT_FOUND**: Referenced site does not exist
- **INVALID_SUPPLY_PLAN_QUANTITIES**: Quantity values are invalid for a supply plan

## Test Cases

- creates a new open supply plan
- creates a supply plan with custom fields
- creates a supply plan for another source line
- creates multiple supply plans in one insert
- returns no rows when supplyPlans is empty
- returns error when item not found
- returns error when quantity unit does not match the item unit
- returns error when site not found
- allows expected quantity to be zero
- returns error when expected quantity is negative
