# ReverseAllocationCycle

## Permission Scope

accounting

## Overview

reverseAllocationCycle transitions an allocation cycle from POSTED to REVERSED status by creating reversal journal entries with inverted amounts. This offsets the original allocation postings to zero. An already REVERSED cycle cannot be reversed again. The reversal period must be in OPEN or FUTURE_ENTERABLE status.

## Business Rules

- Allocation cycle must exist
- Allocation cycle must be in POSTED status to be reversed
- Reversing an already REVERSED cycle is rejected
- Creates reversal journal entries with inverted (negated) amounts
- Reversal journal entries must target a period that is in OPEN or FUTURE_ENTERABLE status
- Transitions status from POSTED to REVERSED
- Original allocation postings remain in the ledger for auditability
- Emits an audit event recording the status transition and acting user

## Process Flow

```mermaid
flowchart TD
    A[Receive reverse allocation cycle request] --> B{Allocation cycle exists?}
    B -->|No| C[Return error: ALLOCATION_CYCLE_NOT_FOUND]
    B -->|Yes| D{Status is POSTED?}
    D -->|No| E[Return error: INVALID_STATE]
    D -->|Yes| F{Reversal period is OPEN or FUTURE_ENTERABLE?}
    F -->|No| G[Return error: PERIOD_NOT_OPEN]
    F -->|Yes| H[Create reversal journal entries with inverted amounts]
    H --> I[Post reversal entries via finance-ledger]
    I --> J[Transition status from POSTED to REVERSED]
    J --> K[Emit audit event]
    K --> L[Return reversed allocation cycle]
```

## External Dependencies

- [finance-ledger::getAccountingPeriod](../../../finance-ledger/docs/queries/GetAccountingPeriod.md) — Validates that the reversal period is in OPEN or FUTURE_ENTERABLE status
- [finance-ledger::createJournalEntry](../../../finance-ledger/docs/commands/CreateJournalEntry.md) — Creates reversal journal entries

## Error Scenarios

- **ALLOCATION_CYCLE_NOT_FOUND**: Allocation cycle with the specified ID does not exist
- **INVALID_STATE**: Target entity is not in a valid status for this operation
- **PERIOD_NOT_OPEN**: Accounting period is not in OPEN or FUTURE_ENTERABLE status

## Test Cases

- reverses a POSTED allocation cycle transitioning it to REVERSED status
- returns error when allocation cycle does not exist
- returns error when allocation cycle is not in POSTED status
- returns error when allocation cycle is already REVERSED
- returns error when reversal period is not OPEN or FUTURE_ENTERABLE
- returns error when allocation cycle is in DRAFT status
- returns error when allocation cycle is in VALIDATED status
- emits audit event recording the status transition and acting user
