Overview
The BudgetVarianceService provides budget-versus-actual analysis for association financial governance. It computes variances from posted journal entry data, classifies them as favorable or unfavorable using standard accounting conventions, and produces the Schedule of Revenues and Expenses — Budget and Actual that boards use for financial oversight.
All actual amounts are derived exclusively from POSTED journal entries in the general ledger — never from payment records or invoice data. The figures agree with the GL and the enforcement audit trail.
Variance Classification
Variance signs follow professional accounting convention:
| Account Type | Favorable | Unfavorable |
|---|---|---|
| Revenue (OI, NI) | Actual > Budget (more income) | Actual < Budget (less income) |
| Expense (OE, NE) | Actual < Budget (less spending) | Actual > Budget (overspending) |
The calc_variance method enforces this convention deterministically: positive variance is always favorable regardless of account type.
Variance Summary
The get_budget_variance_summary method produces the variance report:
- Income items: All revenue accounts with budgeted YTD, actual YTD, variance (dollar and percentage), and annual budget. Sorted by absolute variance descending.
- Expense items: Same structure with inverted variance convention.
- Totals: Aggregate budgeted income, actual income, income variance, budgeted expenses, actual expenses, expense variance, net budgeted, net actual, and net variance.
- Top variances: Five largest favorable and five largest unfavorable variances for quick identification.
Transaction-Level Drill-Down
The get_line_item_transactions method follows any budget line to its underlying transactions:
For a given account and date range, it returns:
- Every posted journal entry line with date, entry number, description, source type, debit/credit amounts, and vendor name
- Total debits and credits
- Net amount (based on account normal balance)
- Budgeted amount for the period
- Computed variance
A board member or auditor can trace a variance from the summary level down to individual journal entries.
Monthly Variance Trend
The get_monthly_variance_trend method produces a 12-month view for any account:
- Month-by-month budgeted vs. actual amounts
- Monthly variance with favorable/unfavorable classification
- Cumulative budgeted, actual, and variance totals
- Enables identification of seasonal patterns and trend shifts
Variance Alerts
The get_variance_alerts method identifies accounts with significant variances:
| Severity | Threshold |
|---|---|
| Medium | >= 10% variance (configurable) |
| High | >= 25% variance |
Alerts include the account, variance amount and percentage, favorable/unfavorable classification, and budgeted vs. actual amounts. They are sorted by absolute variance for prioritization.
Schedule of Revenues and Expenses — Budget and Actual
The get_statement_of_revenues_and_expenses method generates the board-facing budget-and-actual schedule, titled "Schedule of Revenues and Expenses — Budget and Actual (Unaudited)". It is supplementary information, not a financial statement, and its notes say so.
Structure
The schedule has one section per fund that has a row. Each section is grouped by the account's top-level parent and holds revenues, expenses, and transfers.
Nine amount columns per line item:
- Current Budget
- Current Actual
- Current Variance
- Current Variance %
- Year-to-Date Budget
- Year-to-Date Actual
- Year-to-Date Variance
- Year-to-Date Variance %
- Annual Budget
A positive variance is favorable: revenue above budget, or expense below it. Variance % is the variance over the budget it is measured against, and it reads 0.00 where there is no budget.
Actuals
Actuals come from the same fund matrix that the statement of revenues, expenses, and changes in fund balances reads, over two windows: the reported month, and the fiscal year to date ending with it. They exclude closing and opening entries, so a window containing a year-end close reports the year that was closed, not the zero the close leaves behind. This applies to the schedule. The variance summary, the alerts, the monthly trend, and the line-item drill-down sum the posted lines directly, so a window that contains a year-end close shows the close in those views.
Account Discovery
The report includes any account that has either:
- A budget line item in the active budget, OR
- Actual posted transactions in the YTD period
This prevents missing unbudgeted spending — if money was spent against an account with no budget, it still appears in the report with a full unfavorable variance.
Funds and Transfers
A mandatory allocation to the replacement fund is presented as replacement fund assessment revenue in the reserve column and as a transfer out of the operating column, not as an operating expense. The budget adopted on the contribution account follows it.
Fund Summary
Each fund section closes with four lines:
Total Revenues
- Total Expenses
+ Transfers
= Excess (Deficiency) of Revenues Over Expenses
The three variances add rather than subtract. An expense variance is already favorable when positive, so subtracting it would report a fund that underspent as having done worse than budget.
Grand Totals
The schedule's total is the sum of the funds' net positions.
No Adopted Budget
When no budget is on record for the association and the period, every budget column reads zero and a note says that no variance on the schedule is meaningful. The actual columns stay complete.
Verification
A report-verification check recomputes budgeted assessment revenue from units and rates over the budget's own window, per income account, and compares the two exactly. It is reported and does not block a release.
Period Handling
The get_period_info method computes deterministic date boundaries:
- Handles fiscal year != calendar year
- Supports mid-year budget starts
get_period_infostarts year to date at the budget start date, or at the start of the calendar year when no budget start date is set. The budget-and-actual schedule replaces that start with the start of the fiscal year, read from the fiscal year records- The budget year-to-date column covers the same months as the actual year-to-date column, including on a fiscal year that does not start in January
How CommunityPay Enforces This
- Variance classification follows accounting convention, and a positive variance is always favorable
- All actuals derived from posted journal entries via the general ledger; the budget-and-actual schedule excludes closing and opening entries
- The budget-and-actual schedule has one section per fund, and a mandatory reserve allocation is shown as a transfer out of operating
- Variance alerts trigger at configurable thresholds (default: 10%, elevated: 25%)
- Budgeted assessment revenue is recomputed from units and rates over the budget's own window and compared exactly