# CreateAllocationCycle

## Permission Scope

accounting

## Overview

createAllocationCycle establishes a new allocation cycle in DRAFT status. An allocation cycle groups a set of allocation rules that define how overhead costs are distributed from sender cost centers to receiver cost objects. It requires a name, allocation type (ASSESSMENT or DISTRIBUTION), a company reference, and an accounting period reference.

## Business Rules

- Allocation cycle is always created in DRAFT status
- Requires a valid `companyId` referencing an ACTIVE company from the organization module
- Requires a valid `name`
- Requires a valid `type` of either ASSESSMENT or DISTRIBUTION
- Requires a valid `accountingPeriodId` referencing an existing accounting period from finance-ledger
- Allocation cycles are scoped to a company; cycles from different companies are fully isolated
- Emits an audit event recording the acting user, timestamp, and initial field values

## Process Flow

```mermaid
flowchart TD
    A[Receive create allocation cycle request] --> B{Company exists and is ACTIVE?}
    B -->|No| C[Return error: COMPANY_NOT_FOUND]
    B -->|Yes| D{Valid allocation type?}
    D -->|No| E[Return error: INVALID_ALLOCATION_TYPE]
    D -->|Yes| F{Accounting period exists?}
    F -->|No| G[Return error: ACCOUNTING_PERIOD_NOT_FOUND]
    F -->|Yes| H{Name provided?}
    H -->|No| I[Return error: INVALID_NAME]
    H -->|Yes| J[Create allocation cycle in DRAFT status]
    J --> K[Emit audit event]
    K --> L[Return created allocation cycle]
```

## External Dependencies

- [organization::getCompany](../../../organization/docs/queries/GetCompany.md) — Validates that the referenced company exists and is ACTIVE
- [finance-ledger::getAccountingPeriod](../../../finance-ledger/docs/queries/GetAccountingPeriod.md) — Validates that the referenced accounting period exists

## Error Scenarios

- **COMPANY_NOT_FOUND**: Referenced company does not exist or is not in ACTIVE status
- **INVALID_ALLOCATION_TYPE**: Type is not ASSESSMENT or DISTRIBUTION
- **ACCOUNTING_PERIOD_NOT_FOUND**: Referenced accounting period does not exist
- **INVALID_NAME**: Name is empty, whitespace-only, or not provided

## Test Cases

- creates allocation cycle in DRAFT status with required fields
- returns error when company does not exist
- returns error when company is not ACTIVE
- returns error when allocation type is invalid
- returns error when accounting period does not exist
- returns error when name is missing
- allocation cycles from different companies are isolated
- emits audit event recording acting user, timestamp, and initial field values
