# UpdateInventorySupplyPlan

## Permission Scope

supplyPlan

## Overview

updateInventorySupplyPlan updates one existing expected inbound supply row by `id`. It partially updates provided expected fields while preserving omitted fields and received quantity.

## Business Rules

- Supply plan must exist for the provided `id`
- Supply plan must be OPEN
- `sourceType`, `sourceId`, `sourceLineId`, `itemId`, `siteId`, `expectedQuantity`, `unitId`, `expectedDate`, `lotId`, and `serialNumberId` are optional update fields
- Additional InventorySupplyPlan fields configured by the module caller are optional update fields
- Omitted fields are preserved
- `lotId` and `serialNumberId` can be cleared by passing null
- When `itemId` is provided, the item must exist
- When `siteId` is provided, the site must exist
- When `expectedQuantity` is provided, it must be zero or positive and already normalized to the item's primary unit (`Item.unitId`)
- `unitId` is validation-only and is not persisted; when provided, it must equal the effective `Item.unitId`
- `expectedQuantity` may be equal to or lower than `receivedQuantity`; planning queries clamp negative open quantity to zero
- Updates the plan and keeps `status = OPEN`

## Process Flow

```mermaid
flowchart TD
    A[Receive update request] --> B{Plan exists and OPEN?}
    B -->|No| C[Return error]
    B -->|Yes| D{Provided references valid?}
    D -->|No| C
    D -->|Yes| E{expectedQuantity non-negative?}
    E -->|No| F[Return error: INVALID_SUPPLY_PLAN_QUANTITIES]
    E -->|Yes| G[Update provided fields preserving omitted fields, receivedQuantity, and status OPEN]
    G --> K[Return plan]
```

## 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 when `siteId` is provided

## Error Scenarios

- **INVENTORY_SUPPLY_PLAN_NOT_FOUND**: Referenced supply plan does not exist
- **SUPPLY_PLAN_NOT_OPEN**: Supply plan is not OPEN
- **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

- updates an open supply plan and preserves received quantity
- partially updates expected quantity without rewriting omitted fields
- updates custom fields
- updates source document id for a supply slice
- allows expected quantity equal to received quantity
- allows expected quantity below received quantity
- allows expected quantity to be zero
- returns error when supply plan not found
- returns error when supply plan is closed
- returns error when item not found
- returns error when quantity unit does not match the item unit
- returns error when site not found
- returns error when expected quantity is negative
