# AccountingPeriod

## Description

AccountingPeriod represents a discrete time segment (typically a month, quarter, or custom interval) within a fiscal year, scoped to a single company via companyId. Each period carries a start date, end date, period name, period type (OPERATING or ADJUSTMENT), and a five-state status that governs whether journal entries can be posted. The five-state lifecycle (NEVER_OPENED, FUTURE_ENTERABLE, OPEN, CLOSED, PERMANENTLY_CLOSED) mirrors the industry-standard model used by Oracle Financials and provides granular control over when and how transactions flow into each period. Accounting periods are the temporal backbone of the general ledger — every journal entry must reference a valid period, and the period's current status determines whether that posting is accepted or rejected.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> NeverOpened: createAccountingPeriod
    NeverOpened --> FutureEnterable: openForAdvanceEntry
    NeverOpened --> Open: openPeriod
    FutureEnterable --> Open: openPeriod
    Open --> Closed: closePeriod
    Closed --> Open: reopenPeriod
    Closed --> PermanentlyClosed: permanentlyClosePeriod
    PermanentlyClosed --> [*]
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| openForAdvanceEntry | NEVER_OPENED | FUTURE_ENTERABLE | [openForAdvanceEntry](../commands/OpenForAdvanceEntry.md) |
| openPeriod | NEVER_OPENED, FUTURE_ENTERABLE | OPEN | [openPeriod](../commands/OpenPeriod.md) |
| closePeriod | OPEN | CLOSED | [closePeriod](../commands/ClosePeriod.md) |
| reopenPeriod | CLOSED | OPEN | [reopenPeriod](../commands/ReopenPeriod.md) |
| permanentlyClosePeriod | CLOSED | PERMANENTLY_CLOSED | [permanentlyClosePeriod](../commands/PermanentlyClosePeriod.md) |

### Command Definitions

- [createAccountingPeriod](../commands/CreateAccountingPeriod.md) - Create a new accounting period in NEVER_OPENED status within a fiscal year
- [openForAdvanceEntry](../commands/OpenForAdvanceEntry.md) - Transition a NEVER_OPENED period to FUTURE_ENTERABLE to allow advance postings
- [openPeriod](../commands/OpenPeriod.md) - Transition a NEVER_OPENED or FUTURE_ENTERABLE period to OPEN
- [closePeriod](../commands/ClosePeriod.md) - Transition an OPEN period to CLOSED
- [reopenPeriod](../commands/ReopenPeriod.md) - Transition a CLOSED period back to OPEN for adjustments
- [permanentlyClosePeriod](../commands/PermanentlyClosePeriod.md) - Transition a CLOSED period to PERMANENTLY_CLOSED (irreversible)
- [deleteAccountingPeriod](../commands/DeleteAccountingPeriod.md) - Delete an accounting period with no associated journal entries

### Query Definitions

- [GetAccountingPeriod](../queries/GetAccountingPeriod.md) - Retrieve an accounting period by id
- [ListAccountingPeriods](../queries/ListAccountingPeriods.md) - List accounting periods for a fiscal year or company with optional status filter
- [GetPeriodByDate](../queries/GetPeriodByDate.md) - Find the accounting period for a given date and company

### Models

- AccountingPeriod

### Invariants

- Accounting periods can only be created in NEVER_OPENED status
- Period name is required and must be non-empty
- Period must have a valid start date and end date, with start date strictly before end date
- Period must reference a valid companyId from the organization module
- Period must belong to a fiscal year that is scoped to the same company
- Periods within the same fiscal year must not have overlapping date ranges
- Periods within the same fiscal year must cover the full fiscal year date range without gaps
- Two periods in the same fiscal year cannot have identical start and end dates unless one is an adjustment period
- Period type must be OPERATING or ADJUSTMENT
- Adjustment periods share the same end date as the final regular period but are typed as ADJUSTMENT
- A PERMANENTLY_CLOSED period cannot transition to any other status (irreversible)
- An OPEN period cannot transition directly to PERMANENTLY_CLOSED (must go through CLOSED first)
- A NEVER_OPENED period cannot transition directly to CLOSED
- A period cannot be deleted if it has any associated journal entries regardless of status
- Journal entries can only be posted to periods in OPEN or FUTURE_ENTERABLE status
- All period status transitions emit audit events via the audit module recording the acting user, timestamp, and previous and new status values

### Relationships

- **References Company**: Each accounting period is scoped to a Company via companyId (organization module)
- **References FiscalYear**: Each accounting period belongs to a FiscalYear via fiscalYearId
- **Has Many JournalEntry**: An accounting period may have journal entries posted to it
- **Has One PeriodClose**: An accounting period may have at most one active PeriodClose record
