# CreateGoodsIssue

## Permission Scope

inventoryOperation

## Overview

createGoodsIssue creates a DRAFT InventoryExecution with `executionType=GOODS_ISSUE`.
Each line records the outbound stock effect that will be posted later by postGoodsIssue.

## Business Rules

- At least one line is required
- effectiveDate is required and is stored as the intended issue posting date
- sourceDocumentType and sourceDocumentId are required and become immutable source references
- Each line quantity must be greater than zero
- Each line item must exist; inactive items are accepted because issues may post long after the source sales or transfer document was created
- Each line storage location must exist; inactive locations are accepted for historical issue execution continuity
- quantity and unitId preserve the source/business issue unit, such as the sales order unit
- primaryQuantity must be greater than zero and stores the converted quantity in primaryUnitId
- primaryUnitId must equal Item.unitId
- unitConversionRate must be greater than zero and records the multiplier used to derive primaryQuantity from quantity
- Unit conversion is resolved before calling this command; this command stores both source-unit and primary-unit snapshots
- Goods issue valuation derives cost from the active valuation policy during posting; unit cost is not accepted as command input
- Lines are stored with `direction=OUT` and `stockType=AVAILABLE`
- No StockLevel, InventoryLedger, LotStockLevel, SerialNumber, or valuation changes occur while the execution is DRAFT

## Process Flow

```mermaid
flowchart TD
    A[Create goods issue request] --> D{At least one line?}
    D -->|No| E0[Return error: EMPTY_ISSUE_LINES]
    D -->|Yes| E[Validate each line]
    E --> F0{All quantities positive?}
    F0 -->|No| F[Return error: INVALID_QUANTITY]
    F0 -->|Yes| G{Items and locations valid?}
    G -->|No| H[Return validation error]
    G -->|Yes| I[Create DRAFT InventoryExecution]
    I --> J[Create OUT InventoryExecutionLine rows]
    J --> K[Return execution and lines]
```

## External Dependencies

- [item-management::Item](../../../item-management/docs/model/Item.md) - Validates referenced items
- [inventory::StorageLocation](../model/StorageLocation.md) - Validates issuing locations
- [inventory::InventoryExecution](../model/InventoryExecution.md) - Creates the goods issue execution header and outbound execution lines

## Error Scenarios

- **EMPTY_ISSUE_LINES**: No goods issue lines were provided
- **INVALID_QUANTITY**: Quantity is zero or negative
- **PRIMARY_UNIT_MISMATCH**: primaryUnitId differs from Item.unitId
- **INVALID_UNIT_CONVERSION_RATE**: Unit conversion rate is zero or negative
- **ITEM_NOT_FOUND**: Referenced item does not exist
- **STORAGE_LOCATION_NOT_FOUND**: Referenced storage location does not exist
- **LOT_NOT_FOUND**: Referenced lot does not exist
- **SERIAL_NOT_FOUND**: Referenced serial number does not exist

## Test Cases

- returns error when no lines are provided
- returns error when line quantity is zero or negative
- returns error when line primary quantity is zero or negative
- returns error when line unit conversion rate is zero or negative
- returns error when item does not exist
- returns error when primary unit differs from item primary unit
- creates a DRAFT goods issue execution with outbound lines
- accepts inactive item and location references
