# CreateSalesOrder

## Permission Scope

salesOrder

## Overview

CreateSalesOrder establishes a new sales order with `orderStatus=DRAFT` and one or more order lines. It captures the initial customer, company, transaction currency, address, optional external payment-term reference, and pricing context needed to begin the commercial review flow.

## Business Rules

- Order is always created with `orderStatus=DRAFT`; execution projections remain null.
- CustomerAccount must match the order company and be available for transactions.
- Company must exist and the currency must be the company's base currency.
- At least one order line is required at creation time.
- Each order line must reference an ACTIVE item, a positive quantity, and a non-negative unit price.
- Each line's item must hold a [SalesItem](../model/SalesItem.md) record; an item that is not adopted for selling cannot be sold.
- `requiresPhysicalFulfillment` is not a line input: it is resolved from the item's selling record and frozen onto the line.
- Quantities and unit prices are supplied as decimal strings.
- All customer and item references must belong to the same company scope.

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B[Validate company and customer]
    B --> C[Validate order lines, references, and selling records]
    C --> C2{Company exists and currency is its base currency?}
    C2 -->|No| C3[Return company or currency error]
    C2 -->|Yes| D[Freeze the fulfillment expectation from each selling record]
    D --> E[Create SalesOrder and SalesOrderLine records]
    E --> F[Set orderStatus to DRAFT]
    F --> G[Return created sales order id]
```

## External Dependencies

- [business-partner::GetCustomerAccount](../../../business-partner/docs/query/GetCustomerAccount.md) - Validate the referenced customer exists and is active.
- [item-management::GetItem](../../../item-management/docs/query/GetItem.md) - Validate each referenced sellable item.
- [organization::GetCompany](../../../organization/docs/query/GetCompany.md) - Validate the company and its base currency.

## Error Scenarios

- **COMPANY_NOT_FOUND**: Referenced company does not exist
- **CURRENCY_MISMATCH**: Currency is not the company's base currency
- **CUSTOMER_NOT_FOUND**: Referenced customer does not exist.
- **CUSTOMER_NOT_ACTIVE**: Referenced customer is not in ACTIVE status
- **ITEM_NOT_FOUND**: One or more referenced items do not exist
- **ITEM_NOT_ACTIVE**: One or more referenced items are not in ACTIVE status
- **ITEM_NOT_SELLABLE**: Referenced item holds no selling record and cannot be sold
- **EMPTY_ORDER_NOT_ALLOWED**: Sales order has no lines
- **INVALID_ORDER_LINE**: Order line is missing quantity, price, or item context
- **CROSS_COMPANY_REFERENCE**: One or more referenced records belong to a different company

## Test Cases

- creates a draft sales order with valid customer and lines
- throws when the company does not exist
- throws when the currency is not the company's base currency
- throws when customer does not exist
- throws when customer account is unavailable for transactions
- throws when an order line references an inactive item
- throws when an order line references an item with no selling record
- freezes the fulfillment expectation from the selling record onto each line
- throws when line quantity is zero or unit price is negative
- throws when references cross company boundaries
