# ReverseJournalEntry

## Permission Scope

journalEntry

## Overview

reverseJournalEntry creates a mirror journal entry with all debit and credit amounts inverted from the original posted entry, and automatically posts the reversal entry. The original entry transitions from POSTED to REVERSED status. This is the only way to correct a posted journal entry, as posted entries cannot be modified or deleted. The reversal entry must target a period that is in OPEN or FUTURE_ENTERABLE status.

## Business Rules

- Original journal entry must exist and be in POSTED status
- DRAFT entries cannot be reversed (they should be deleted instead)
- Already REVERSED entries cannot be reversed again
- A new mirror journal entry is created with all debit amounts swapped to credits and vice versa
- The reversal entry references the original entry
- The reversal entry is automatically posted upon creation
- The original entry status transitions from POSTED to REVERSED
- The reversal entry must target an accounting period in OPEN or FUTURE_ENTERABLE status
- Multi-currency lines are reversed with the same currency and exchange rate as the original
- Emits an audit event recording the status transition from POSTED to REVERSED, the reversal entry reference, and the acting user

## Process Flow

```mermaid
flowchart TD
    A[Receive reverse journal entry request] --> B{Original entry exists?}
    B -->|No| C[Return error: journal entry not found]
    B -->|Yes| D{Original entry status is POSTED?}
    D -->|No| E[Return error: invalid status for reversal]
    D -->|Yes| F{Reversal period OPEN or FUTURE_ENTERABLE?}
    F -->|No| G[Return error: invalid period status]
    F -->|Yes| H[Create mirror entry with inverted debits/credits]
    H --> I[Auto-post reversal entry]
    I --> J[Transition original entry to REVERSED]
    J --> K[Emit audit event]
    K --> L[Return reversal entry]
```

## External Dependencies

- None

## Error Scenarios

- **JOURNAL_ENTRY_NOT_FOUND**: Referenced journal entry does not exist
- **INVALID_STATUS_FOR_REVERSAL**: Journal entry is not in POSTED status; only POSTED entries can be reversed
- **ALREADY_REVERSED**: Journal entry has already been reversed
- **INVALID_PERIOD_STATUS**: Target accounting period is not in OPEN or FUTURE_ENTERABLE status

## Test Cases

- returns error when journal entry does not exist
- returns error when journal entry is in DRAFT status
- returns error when journal entry is already REVERSED
- returns error when reversal period is in NEVER_OPENED status
- returns error when reversal period is in CLOSED status
- returns error when reversal period is in PERMANENTLY_CLOSED status
- creates mirror entry with all debit/credit amounts inverted
- reversal entry references the original entry
- reversal entry is automatically posted
- original entry transitions from POSTED to REVERSED
- reversal entry targets the specified accounting period
- multi-currency lines are reversed with same currency and exchange rate
- emits audit event recording status transition, reversal entry reference, and acting user
