# CreateChartOfAccounts

## Permission Scope

chartOfAccounts

## Overview

createChartOfAccounts establishes a new Chart of Accounts container in DRAFT status for a company. The CoA inherits its base currency from the parent company. The referenced company must be in ACTIVE status, which guarantees structural identity completeness including base currency assignment.

## Business Rules

- CoA name is required and must be non-empty
- CoA must reference a valid companyId from the organization module
- The referenced company must be in ACTIVE status; creating a CoA for a DRAFT or INACTIVE company is rejected
- CoA inherits its base currency from the parent company's base currency
- CoA is always created in DRAFT status
- Description is optional
- An optional `templateId` can be provided to initialize the CoA from a country-specific localized template; when omitted, a blank CoA is created with no pre-populated account groups or accounts
- Templates are externally managed configuration data (not owned by this module). Each template is an immutable snapshot containing pre-defined account groups (with numbering ranges) and GL accounts for a specific country or industry. Template storage, versioning, and catalog management are outside the scope of coa-management
- When `templateId` is provided, the command delegates template resolution to the template provider (external dependency). The provider must return the template's account groups and accounts. If no template provider is configured, templateId is rejected with TEMPLATE_PROVIDER_NOT_CONFIGURED
- When a valid template is resolved, the command copies the template's account groups (with numbering ranges) and GL accounts into the new CoA in DRAFT status
- Template-based creation is a convenience shortcut — all copied entities are fully mutable in DRAFT and can be modified before activation

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Company exists and is ACTIVE?}
    B -->|No| C[Return error: company not found or not active]
    B -->|Yes| D{Name non-empty?}
    D -->|No| E[Return error: name required]
    D -->|Yes| F[Inherit base currency from company]
    F --> G{templateId provided?}
    G -->|Yes| G2{Template provider configured?}
    G2 -->|No| G3[Return error: template provider not configured]
    G2 -->|Yes| H{Template exists and is valid?}
    H -->|No| I[Return error: template not found]
    H -->|Yes| J[Create CoA in DRAFT with template contents]
    G -->|No| K[Create blank CoA in DRAFT]
    J --> K2[Return created CoA]
    K --> K2
```

## External Dependencies

- [organization::getCompany](../../../organization/docs/queries/GetCompany.md) - Validates that the referenced company exists and is ACTIVE
- **Template Provider (external)** - Resolves templateId to a template snapshot containing account groups and GL accounts. Template storage, versioning, and catalog management are outside the scope of this module. When no template provider is configured, only blank CoA creation is available

## Error Scenarios

- **COMPANY_NOT_FOUND**: Referenced company does not exist or is not in ACTIVE status
- **NAME_REQUIRED**: Name is empty, whitespace-only, or not provided
- **TEMPLATE_NOT_FOUND**: Specified templateId does not reference a valid template in the template provider
- **TEMPLATE_PROVIDER_NOT_CONFIGURED**: templateId was provided but no template provider is configured

## Test Cases

- returns error when company does not exist
- returns error when company is not ACTIVE
- returns error when name is empty
- returns error when templateId is provided but no template provider is configured
- returns error when templateId does not reference a valid template
- creates blank CoA in DRAFT status when no templateId is provided
- creates CoA from template with pre-populated account groups and accounts in DRAFT status
- creates CoA from template with nested groups provided in child-first order
- creates CoA with optional description
- passes custom fields through to insert
- validates company via organizationQueries when provided
- returns error when organizationQueries reports company not found
- creates blank CoA in DRAFT status with inherited base currency when no templateId is provided
- template-copied entities are mutable and can be modified before activation
