# Budget Management

## Overview

Budget Management provides the planning and control capabilities of the accounting module, enabling organizations to create budgets with line items per cost element, manage approval workflows, track multiple budget versions, and compare budgeted amounts against actual postings from finance-ledger. A budget entity carries a name, budget holder, fiscal year, period range, total amount, status, version type, and a cost object reference (cost center, profit center, or internal order). Each budget contains one or more BudgetLineItem records that specify a cost element, planned amount, and accounting period. The corresponding GL account for each line item is derived automatically from the primary cost element's one-to-one GL account mapping defined in cost-element-management, ensuring a single authoritative planning axis while preserving traceability to the general ledger. A PlanVersion entity (BUDGET, FORECAST, or SIMULATION) supports multi-version planning so organizations can maintain an approved operating budget alongside rolling forecasts and what-if simulations.

Budgets follow a five-stage lifecycle — DRAFT, SUBMITTED, APPROVED, ACTIVE, CLOSED — enforcing segregation of duties between budget creation, approval, and cost posting. Budgetary control (funds check) provides real-time validation that prevents transactions from exceeding approved budget amounts, using the BudgetAvailability formula: `Available = Budget - (Actual + Commitments + Encumbrances)`. Actual amounts are sourced from posted journal entries in finance-ledger. Commitments represent outstanding purchase order amounts received from the purchase module via commitment events; encumbrances represent purchase requisition amounts (future extension). This three-bucket model aligns with SAP availability control and Oracle budgetary control patterns. Budget periods reference finance-ledger FiscalYear and AccountingPeriod entities for period alignment, and budget lock at period-end integrates with finance-ledger period close. All budgets are scoped to a Company.

## Business Purpose

Organizations need a structured budgeting process to plan expenditures, control costs, and measure financial performance against targets:

- **Expenditure planning**: Budgets translate strategic objectives into quantified financial plans by allocating planned amounts to cost elements across accounting periods, providing a financial roadmap for the fiscal year. The corresponding GL account is derived from each primary cost element's GL mapping, ensuring consistency between management and financial accounting without requiring dual-axis maintenance
- **Approval workflow enforcement**: The DRAFT to SUBMITTED to APPROVED progression ensures budgets are reviewed and authorized before activation, enforcing segregation of duties required by SOX and internal control frameworks — budget approval must be separate from budget creation and cost posting
- **Multi-version planning**: PlanVersion support (BUDGET, FORECAST, SIMULATION) allows organizations to maintain an approved operating budget alongside rolling forecasts and what-if simulations, enabling agile financial planning without altering the baseline commitment
- **Budgetary control (funds check)**: Real-time validation prevents transactions from exceeding available budget using the formula `Available = Budget - (Actual + Commitments + Encumbrances)`. This three-bucket availability check catches overspend at entry time, including amounts committed via purchase orders that have not yet been invoiced, preventing the common failure mode where PO-committed funds are double-spent
- **Commitment tracking**: Outstanding purchase order amounts are tracked as commitments that reduce available budget. When the purchase module confirms, receives, or invoices a PO, commitment amounts are consumed and reclassified as actuals. This integration requires consuming commitment events from the purchase module (PO confirmed, goods received, invoice matched)
- **Budget vs. actual comparison**: Comparing budgeted amounts against actual postings from finance-ledger journal entries surfaces variances early, enabling corrective action before period close
- **Cost object alignment**: Budgets reference cost centers, profit centers, or internal orders, linking financial plans to the organizational and project structures managed by the accounting module
- **Period alignment with finance-ledger**: Budget periods reference FiscalYear and AccountingPeriod from finance-ledger, ensuring budget and actual data share the same temporal boundaries for accurate variance analysis
- **Budget lock at period-end**: Closing a budget period prevents further modifications to planned amounts, integrating with finance-ledger period close to produce a frozen baseline for reporting and audit
- **Audit trail**: Every lifecycle transition — creation, submission, approval, activation, closure — is recorded with the acting user and timestamp, supporting internal and external audit requirements

## Process Flow

```mermaid
stateDiagram-v2
    [*] --> Draft: createBudget
    Draft --> Draft: updateBudget / addLineItem / removeLineItem
    Draft --> Submitted: submitBudget
    Submitted --> Approved: approveBudget
    Submitted --> Draft: rejectBudget
    Approved --> Active: activateBudget
    Active --> Closed: closeBudget
    Draft --> [*]: deleteBudget
```

```mermaid
flowchart TD
    A[Define budget scope: fiscal year, cost object, version type] --> B[Create Budget in DRAFT with header fields]
    B --> C[Add BudgetLineItem records per cost element and period]
    C --> D{All periods and cost elements covered?}
    D -- No --> C
    D -- Yes --> E[Submit budget for approval]
    E --> F{Approver reviews budget}
    F -- Reject --> G[Return to DRAFT with rejection reason]
    G --> C
    F -- Approve --> H[Budget status set to APPROVED]
    H --> I[Activate budget for budgetary control]
    I --> J[Funds check enabled: transactions validated against budget]
    J --> K{Period-end reached?}
    K -- No --> J
    K -- Yes --> L[Lock budget period and run variance analysis]
    L --> M{All periods complete?}
    M -- No --> K
    M -- Yes --> N[Close budget]
```

```mermaid
flowchart TD
    A[Transaction submitted against cost element] --> B{Budget exists and ACTIVE for cost object?}
    B -- No --> C[Transaction proceeds without funds check]
    B -- Yes --> D[Compute BudgetAvailability]
    D --> D1[Available = Budget - Actual + Commitments + Encumbrances]
    D1 --> E{Available >= transaction amount?}
    E -- Yes --> F[Transaction passes funds check]
    E -- No --> G[Transaction rejected: budget exceeded]
```

```mermaid
flowchart TD
    A[Purchase Order confirmed in purchase module] --> B[Commitment event received by accounting]
    B --> C[Record commitment amount against cost element + cost object + period]
    C --> D[BudgetAvailability reduced by commitment amount]
    D --> E{Goods receipt or invoice posted?}
    E -- Goods Receipt --> F[Reduce commitment, increase actual by received amount]
    E -- Invoice Matched --> G[Reduce remaining commitment, actual reflects invoiced amount]
    E -- PO Cancelled --> H[Release commitment amount back to available budget]
```

## Scenario Patterns

- **Annual Operating Budget Creation**: A finance manager creates a new budget for fiscal year 2026 scoped to a cost center, adds line items for each cost element (salaries, travel, office supplies) distributed across twelve monthly periods, submits for department head approval, and activates upon approval to enable funds checking
- **Rolling Forecast Update**: A financial analyst creates a FORECAST plan version based on the approved BUDGET version, adjusts planned amounts for Q3 and Q4 to reflect revised revenue projections, and submits the forecast for review — the original BUDGET version remains unchanged as the committed baseline
- **What-If Simulation**: A planning team creates a SIMULATION plan version to model the financial impact of opening a new office, copying the current budget as a base and adding incremental line items for rent, staffing, and equipment — the simulation is never activated but serves as decision support
- **Budget Rejection and Revision**: A department submits a budget that exceeds the company-wide allocation. The finance director rejects it with a note to reduce travel expenses by 15%. The budget returns to DRAFT, the submitter adjusts the travel line items, and resubmits for approval
- **Funds Check Blocking an Overspend**: An employee submits a purchase order for office furniture. The funds check computes BudgetAvailability as `Budget - (Actual + Commitments + Encumbrances)` for the office supplies cost element in the current period. The available budget is insufficient after accounting for existing PO commitments, and the transaction is rejected with a budget exceeded error
- **Commitment Tracking from Purchase Orders**: A department issues a PO for consulting services worth $50,000. The purchase module emits a commitment event, and accounting records a $50,000 commitment against the consulting cost element budget. When the first invoice for $20,000 is matched, the commitment reduces by $20,000 and actual increases by $20,000, keeping BudgetAvailability unchanged. When the PO is fully invoiced, the commitment reaches zero
- **Mid-Year Budget Transfer**: A budget holder reallocates planned amounts between cost elements within the same budget (e.g., moving unused travel budget to training) by updating line items while the budget is ACTIVE, subject to approval controls
- **Budget vs. Actual Variance Report**: At month-end, a controller compares budgeted amounts against actual postings from finance-ledger journal entries for each cost element and period. The comparison highlights a 20% overrun in consulting expenses, triggering a management review
- **Period-End Budget Lock**: As the finance-ledger accounting period for January is closed, the corresponding budget period is locked, freezing planned amounts for January and preventing retroactive adjustments to the baseline
- **Multi-Cost-Object Budgeting**: A company creates separate budgets for three profit centers within the same fiscal year, each with its own line items and approval chain, enabling decentralized budget ownership while maintaining company-level consolidation

## Test Cases

- Budget lifecycle follows DRAFT -> SUBMITTED -> APPROVED -> ACTIVE -> CLOSED state machine
- Budget can only be created in DRAFT status
- Budget requires a valid companyId; the company must be in ACTIVE status
- Budget requires a valid fiscal year reference from finance-ledger
- Budget requires a name, budget holder, and cost object reference (cost center, profit center, or internal order)
- Budget must reference a valid PlanVersion (BUDGET, FORECAST, or SIMULATION)
- A DRAFT budget can be updated (name, description, budget holder, line items)
- A DRAFT budget can be deleted; deletion removes all associated line items
- Submitting a budget transitions status from DRAFT to SUBMITTED
- A budget with no line items cannot be submitted
- Only a user different from the budget creator can approve the budget (segregation of duties)
- Approving a budget transitions status from SUBMITTED to APPROVED
- Rejecting a budget transitions status from SUBMITTED back to DRAFT
- Rejection requires a reason text
- Activating an APPROVED budget transitions status to ACTIVE and enables funds checking
- Only one ACTIVE budget of type BUDGET can exist per cost object per fiscal year
- Multiple FORECAST or SIMULATION versions can coexist for the same cost object and fiscal year
- Closing an ACTIVE budget transitions status to CLOSED; no further modifications are permitted
- A CLOSED budget cannot be reopened
- BudgetLineItem requires a valid cost element reference; the cost element must be a PRIMARY type in ACTIVE status
- BudgetLineItem derives its GL account automatically from the referenced primary cost element's GL account mapping; no separate GL account field is required
- BudgetLineItem requires a valid accounting period reference from finance-ledger
- BudgetLineItem planned amount must be a positive value
- Line items can be added to or removed from a DRAFT budget
- Line items cannot be added to or removed from a SUBMITTED, APPROVED, or CLOSED budget
- Duplicate line items (same account and period) within a single budget are rejected
- Funds check computes BudgetAvailability as `Budget - (Actual + Commitments + Encumbrances)` for the target cost element, period, and cost object
- A transaction that exceeds BudgetAvailability is rejected with a budget exceeded error when budgetary control is active
- A transaction against a cost element with no corresponding budget line item is flagged as unbudgeted
- Commitment amounts are recorded when a purchase order confirmation event is received from the purchase module
- Commitment amounts are reduced and actual amounts are increased when a goods receipt or invoice match event is received from the purchase module
- Commitment amounts are fully released when a purchase order cancellation event is received from the purchase module
- Encumbrances (purchase requisition amounts) are tracked as a future extension; the availability formula reserves the field but the initial implementation treats encumbrances as zero
- Budget vs. actual comparison retrieves actual amounts from finance-ledger posted journal entries matching the budget's cost object, cost element, and period
- Variance is computed as planned amount minus actual amount; positive variance indicates underspend, negative indicates overspend
- Budget periods align with finance-ledger AccountingPeriod boundaries; misaligned periods are rejected
- Locking a budget period prevents further modifications to planned amounts for that period
- Budget lock integrates with finance-ledger period close; closing an accounting period triggers the corresponding budget period lock
- PlanVersion of type FORECAST or SIMULATION can reference a base version from which line items are copied
- Creating a budget emits an audit event recording the acting user, timestamp, and initial field values
- Submitting, approving, rejecting, activating, and closing a budget each emit audit events recording the status transition and acting user
- Budgets are scoped to a company; budgets from different companies are fully isolated
- Only users with appropriate permissions can create, submit, approve, activate, or close budgets
- Unauthorized users receive a permission denied error when attempting budget operations

## Reference Links

- [SAP S/4HANA Budget Management and Availability Control](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/4dbfa293944e410aa3ca0e0905bda494/d0b843994f0d1014a585e2078de58ced.html)
- [Oracle Fusion Financials Budgetary Control](https://docs.oracle.com/en/cloud/saas/financials/24d/oafcf/budgetary-control.html)
- [Odoo Budget Management](https://www.odoo.com/documentation/19.0/applications/finance/accounting/reporting/budget.html)
- [NetSuite Budgets Overview](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_N2169498.html)
- [Sage Intacct Budgeting and Planning](https://www.sage.com/en-us/sage-business-cloud/intacct/features/budgeting-and-planning/)
