# CreateCurrency

## Permission Scope

currency

## Overview

CreateCurrency establishes a new monetary unit in the system with its ISO 4217 code, display symbol, name, and decimal precision. The first currency created automatically becomes the organization's base currency. Subsequent currencies are added as available currencies for multi-currency operations.

This command supports initial system setup and market expansion scenarios where new trading currencies are needed.

## Business Rules

- ISO 4217 code must be exactly 3 uppercase letters
- ISO 4217 code must be unique across all currencies (active and inactive)
- Currency symbol is required and typically 1-3 characters
- Decimal places must be a non-negative integer (0-4 typical range)
- First currency created automatically becomes the base currency with `isBaseCurrency: true`
- Subsequent currencies are created with `isBaseCurrency: false`
- New currencies are created in Active status by default

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Validate ISO code format}
    B -->|Invalid| C[Return error: invalid ISO code]
    B -->|Valid| D{ISO code unique?}
    D -->|No| E[Return error: duplicate code]
    D -->|Yes| F{Validate decimal places}
    F -->|Invalid| G[Return error: invalid decimal places]
    F -->|Valid| H{Is first currency?}
    H -->|Yes| I[Set as base currency]
    H -->|No| J[Set isBaseCurrency: false]
    I --> K[Create currency record]
    J --> K
    K --> L[Set status: Active]
    L --> M[Return created currency]
```

## External Dependencies

- None

## Error Scenarios

- **INVALID_ISO_CODE**: Code is not exactly 3 uppercase letters
- **DUPLICATE_CURRENCY_CODE**: Currency with same code already exists
- **INVALID_DECIMAL_PLACES**: Value is negative or exceeds maximum (typically 4)

## Test Cases

- throws when ISO code is invalid format
- throws when ISO code already exists
- throws when decimal places is negative
- throws when decimal places exceeds maximum
- creates first currency as base currency
- creates subsequent currency as non-base
- passes custom fields through to insert
