# VarianceReport

## Description

VarianceReport is the management accounting report entity that compares planned (budget) amounts against actual costs and revenues by cost object and accounting period. Each report carries a cost object type and id (polymorphic reference to cost center, profit center, or internal order), accounting period reference, company scope, summary totals (total planned, total actual, total variance), and a status following a DRAFT to FINAL lifecycle. Actual amounts are sourced from posted journal entries in the finance-ledger module, aggregated by cost element, period, and cost object. Planned amounts are sourced from BudgetLineItems in budget-management. Each report contains one or more VarianceReportLine child records that provide cost-element-level detail, enabling managers to diagnose which cost types are driving deviations.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: generateVarianceReport
    Draft --> Final: finalizeVarianceReport
```

### Command Definitions

- [generateVarianceReport](../commands/GenerateVarianceReport.md) - Generate a variance report in DRAFT status by collecting actuals and plan amounts, computing variances per cost element
- [finalizeVarianceReport](../commands/FinalizeVarianceReport.md) - Finalize a DRAFT variance report, locking it for distribution to management

### Query Definitions

- [GetVarianceReport](../queries/GetVarianceReport.md) - Retrieve a variance report by id with all detail lines

### Models

- VarianceReport
- VarianceReportLine

### Invariants

- Variance report can only be created in DRAFT status
- Variance report must reference a valid companyId; the company must be in ACTIVE status
- Variance report must reference a valid accounting period from finance-ledger
- Variance report must reference a valid cost object (cost center, profit center, or internal order)
- Variance report summary totals (total planned, total actual, total variance) are computed from the sum of its detail lines
- Variance report can transition from DRAFT to FINAL
- Variance report in FINAL status cannot be transitioned back to DRAFT
- A FINAL variance report cannot be modified
- A DRAFT variance report can be updated before finalization
- A variance report cannot be generated if no budget line items exist for the specified cost object and period
- Actual amounts are sourced exclusively from POSTED journal entries; DRAFT journal entries are excluded
- Regenerating a variance report for the same cost object and period replaces the existing DRAFT report
- A FINAL variance report is not overwritten by regeneration; a new DRAFT is created alongside it
- Variance reports are scoped to a single company; data from other companies is excluded
- Multiple variance reports can exist for the same cost object across different accounting periods

### Relationships

- **References Company**: Each variance report is scoped to a Company via companyId (organization module)
- **References AccountingPeriod**: Each variance report references an AccountingPeriod via accountingPeriodId (finance-ledger module)
- **Polymorphic Cost Object**: Each variance report references a cost object via costObjectType and costObjectId, which can be a CostCenter, ProfitCenter, or InternalOrder
- **Has Many VarianceReportLine**: A variance report contains one or more variance report lines providing cost-element-level detail
