# UpdateFiscalYear

## Permission Scope

periodManagement

## Overview

updateFiscalYear modifies mutable fields of an existing fiscal year. The fiscal year name can always be updated. Start and end dates can be updated only if no accounting periods have been created for the fiscal year; once periods exist, dates become immutable to prevent date boundary changes that would invalidate existing period definitions.

## Business Rules

- Fiscal year must exist and be identified by `id`
- The `yearName` field can be updated at any time
- yearName is required and must be non-empty
- Start date and end date can be updated only if no accounting periods exist for the fiscal year
- Start date and end date are immutable once accounting periods have been created
- If dates are updated, start date must be strictly before end date
- If dates are updated, the new date range must not overlap with any other fiscal year for the same company
- Emits an audit event via the audit module recording the acting user, timestamp, and changed fields

## Process Flow

```mermaid
flowchart TD
    A[Receive update fiscal year request] --> B{Fiscal year exists?}
    B -->|No| C[Return error: fiscal year not found]
    B -->|Yes| D{Name non-empty?}
    D -->|No| E[Return error: name required]
    D -->|Yes| F{Date changes requested?}
    F -->|Yes| G{Accounting periods exist?}
    G -->|Yes| H[Return error: dates immutable]
    G -->|No| I{Start date before end date?}
    I -->|No| J[Return error: invalid date range]
    I -->|Yes| K{Overlaps with existing fiscal year?}
    K -->|Yes| L[Return error: overlapping fiscal year]
    K -->|No| M[Update fiscal year record]
    F -->|No| M
    M --> N[Emit audit event]
    N --> O[Return updated fiscal year]
```

## External Dependencies

- None (same-module read for fiscal year lookup)

## Error Scenarios

- **FISCAL_YEAR_NOT_FOUND**: Referenced fiscal year does not exist or does not belong to the specified company
- **NAME_REQUIRED**: Name is empty, whitespace-only, or not provided
- **DATES_IMMUTABLE**: Attempting to change start/end dates after accounting periods exist
- **INVALID_DATE_RANGE**: Start date is not strictly before end date
- **OVERLAPPING_FISCAL_YEAR**: The date range overlaps with an existing fiscal year for the same company

## Test Cases

- returns error when fiscal year does not exist
- returns error when name is empty
- returns error when attempting to change dates after accounting periods exist
- returns error when updated start date is not before end date
- returns error when updated date range overlaps with another fiscal year
- updates fiscal year name successfully
- updates fiscal year dates when no accounting periods exist
- emits audit event recording acting user, timestamp, and changed fields
