# UpdateTransferOrder

## Permission Scope

transferOrder

## Overview

updateTransferOrder updates a DRAFT TransferOrder and replaces its lines.

## Business Rules

- Only DRAFT transfer orders can be updated
- Source and destination sites can be changed but must remain different
- `plannedShipmentDate` and `expectedReceiptDate` can be changed while the order is DRAFT
- Lines are replaced as a complete set
- Replacement lines must contain at least one line
- Replacement line `unitId` values are derived from each referenced item primary unit; callers do not choose transfer-specific units
- Replacement lines are initialized with `shippedQuantity = 0` and `receivedQuantity = 0`
- No stock execution or ledger posting occurs
- No StockReservation or InventorySupplyPlan rows are created until openTransferOrder

## Process Flow

```mermaid
flowchart TD
    A[Receive update transfer order request] --> B[Lock TransferOrder]
    B --> C{TransferOrder exists and is DRAFT?}
    C -->|No| D[Return not found or state error]
    C -->|Yes| E{Sites and replacement lines valid?}
    E -->|No| F[Return validation error]
    E -->|Yes| G[Update TransferOrder header]
    G --> H[Delete existing TransferOrderLine rows]
    H --> I[Insert replacement lines with zero shipped and received quantities]
    I --> J[Return transfer order and replacement lines]
```

## External Dependencies

- [organization::Site](../../../organization/docs/model/Site.md) - Validates source and destination sites
- [item-management::Item](../../../item-management/docs/model/Item.md) - Validates referenced line items and derives each replacement line primary unit
- [inventory::TransferOrder](../model/TransferOrder.md) - Updates the transfer order header
- [inventory::TransferOrderLine](../model/TransferOrderLine.md) - Replaces the transfer order lines

## Error Scenarios

- **TRANSFER_ORDER_NOT_FOUND**: Transfer order does not exist
- **EMPTY_TRANSFER_LINES**: No transfer lines were provided
- **INVALID_QUANTITY**: Quantity is zero or negative
- **INVALID_STATE_TRANSITION**: Transfer order lifecycle transition is not allowed
- **INVALID_TRANSFER_LOCATIONS**: Source and destination sites are the same
- **ITEM_NOT_FOUND**: Referenced item does not exist
- **SITE_NOT_FOUND**: Referenced source or destination site does not exist

## Test Cases

- updates a DRAFT transfer order and replaces lines
- persists custom header and line fields
- returns error when transfer order is not DRAFT
