# Account Group Hierarchy

## Overview

Account groups organize general ledger (GL) accounts into logical categories and nestable hierarchical tree structures within a Chart of Accounts (CoA). Each group has a code, name, optional parent group reference for nesting, and a sort order that controls display sequencing. Groups define categories such as "Current Assets" or "Long-Term Liabilities" and may constrain the account number ranges assignable to their member accounts.

Groups can be nested to form a multi-level tree hierarchy that provides structural metadata for the CoA. A root group with no parent represents a top-level section (e.g., "Assets"), while child groups subdivide it into progressively finer categories. Accounts are mapped to leaf or intermediate groups. The hierarchy defines the structure; how that structure is consumed — for balance aggregation, financial statement rendering, or period-close validation — is the responsibility of downstream modules (general-ledger, reporting).

## Business Purpose

- **Logical categorization**: Groups classify GL accounts into meaningful business categories (e.g., "Cash and Cash Equivalents", "Accounts Receivable") so that users and downstream modules can reason about accounts collectively
- **Hierarchical structure**: Nested group trees define the structural organization of accounts. The hierarchy provides the metadata that downstream modules (general-ledger, reporting) consume for balance aggregation and financial statement rendering — this module owns the tree structure, not the aggregation logic
- **Account number range control**: Groups can define allowed number intervals, ensuring that accounts created within a group fall into the expected numbering range (e.g., 1000-1999 for Assets)
- **Single operational hierarchy**: Each CoA has one group hierarchy tree that defines the operational categorization of accounts. Financial statement versions (FSV) and multi-GAAP alternative hierarchies are out of scope for this module and belong to a future reporting module
- **Structural consistency**: Account group assignment is optional per account, but recommended. This module provides a query to list accounts not assigned to any group, enabling downstream consumers to validate completeness according to their own requirements

## Process Flow

```mermaid
flowchart TD
    A[Create Chart of Accounts] --> B[Define Root Groups]
    B --> C[Create Child Groups under Root]
    C --> D{More nesting needed?}
    D -- Yes --> C
    D -- No --> E[Set Account Number Ranges per Group]
    E --> F[Assign Accounts to Groups]
    F --> G[Hierarchy Structure Complete]
```

```mermaid
flowchart TD
    L1[Root Group: Assets]
    L1 --> L2A[Child Group: Current Assets]
    L1 --> L2B[Child Group: Non-Current Assets]
    L2A --> L3A[Leaf Group: Cash and Equivalents]
    L2A --> L3B[Leaf Group: Accounts Receivable]
    L3A --> A1[Account 1010: Petty Cash]
    L3A --> A2[Account 1020: Bank Account]
    L3B --> A3[Account 1100: Trade Receivables]
    L2B --> L3C[Leaf Group: Fixed Assets]
    L3C --> A4[Account 1500: Equipment]
```

## Scenario Patterns

- **Standard Balance Sheet Structure**: A controller creates root groups for Assets, Liabilities, and Equity, then nests child groups (Current Assets, Non-Current Assets, Current Liabilities, etc.) to define the account organization structure
- **Income Statement Structure**: Revenue and expense root groups are subdivided into operating and non-operating categories, with leaf groups for specific reporting classes such as operating expenses, non-operating expenses, and revenue subclasses (e.g., product revenue, service revenue)
- **Operational Hierarchy Setup**: A single group hierarchy is defined for the CoA, structuring accounts into logical sections (Balance Sheet and Income Statement categories). Downstream modules consume this hierarchy for reporting and aggregation
- **Account Range Enforcement**: An "Accounts Payable" group is configured with the number range 2000-2099; attempting to create an account numbered 3001 within this group is rejected
- **Reparenting a Group**: A "Short-Term Investments" group is moved from "Non-Current Assets" to "Current Assets" to reflect a reclassification, updating the hierarchy path
- **Unassigned Account Query**: A query lists all active accounts not assigned to any group, enabling downstream consumers (e.g., reporting module) to validate hierarchy completeness according to their own requirements

## Test Cases

- Every account group belongs to exactly one Chart of Accounts
- Account group code is required and must be unique within its CoA
- Account group code is immutable after creation
- Account group name is required and must be non-empty
- A group with no parent reference is treated as a root-level group
- A group with a parent reference must reference a valid group within the same CoA
- Circular parent references are rejected (a group cannot be its own ancestor)
- Sort order controls the display sequence of sibling groups under the same parent
- Deleting a group that contains child groups or assigned accounts is rejected
- Account number range, when defined on a group, must be a valid non-overlapping interval within the CoA
- Accounts assigned to a group must have account numbers within the group's allowed range (when a range is defined)
- Hierarchy depth is not artificially limited but must remain acyclic
- Moving a group to a new parent within the same CoA updates the hierarchy without breaking existing account assignments
- A query returns all active accounts within a CoA that are not assigned to any group
- Account group assignment is optional; accounts can exist in a CoA without belonging to any group
- The hierarchy tree structure is queryable by downstream modules for consumption (e.g., balance aggregation, report rendering)
- Creating an account group emits an audit event via the audit module recording the acting user, timestamp, and initial field values
- Updating an account group (name, sort order, number range) emits an audit event recording previous and new field values; parent changes are handled by the moveAccountGroup operation, not updateAccountGroup
- Deleting an account group emits an audit event recording the deletion and acting user
- Moving a group to a new parent emits an audit event recording the previous and new parent references

## Reference Links

- [SAP Account Groups and Number Ranges](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee5c9e37ff4f4e33a6c7e2c32f8fc3b5/4b0d35d32d6b3e41e10000000a42189c.html)
- [SAP Financial Statement Versions](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee5c9e37ff4f4e33a6c7e2c32f8fc3b5/577f8c2a397b4ce589e1ad03a64eb1ae.html)
- [Oracle General Ledger Trees and Hierarchies](https://docs.oracle.com/en/cloud/saas/financials/24d/oaglg/overview-of-accounting-hierarchies.html)
- [Odoo Account Groups](https://www.odoo.com/documentation/19.0/applications/finance/accounting/get_started/chart_of_accounts.html)
