Budgeting Module¶
Статус: ⚠️ Частково реалізовано — MVP (2026-04-22)
✅ Реалізовано (Phase F-4): - Окремий backend app
budgeting/з 2 моделями:Budget+BudgetLine. -Budget: header(year, version, organization)UNIQUE per tenant. Поля:is_locked(заборона редагування),version(default 'base'). -BudgetLine: одна сума на (account або expense_item) × period_month × dimensions (project / department). - Сервісcompute_variance(budget)— для кожногоBudgetLine: - Будує період (year, period_month→ start..end дня місяця). - АгрегуєIncomeExpenseJournal.debit/creditза тим самим account / expense_item / project / organization. - Convention: для рахунків класу 7actual = credit − debit, для рештиactual = debit − credit. - Повертаєplanned,actual,variance,variance_pct. - EndpointGET /api/v1/budgeting/budgets/{id}/variance/— повний JSON з рядками + summary (total_planned / total_actual / total_variance). - REST:/api/v1/budgeting/{budgets,budget-lines}/(CRUD). - 4 backend-тести покривають порожній бюджет, агрегацію facts, period-фільтр, endpoint summary. - Frontend: - GenericMasterDataPageдляbudgets/budgetLines. - Спеціальна сторінка BudgetVarianceReport.tsx — Plan vs Actual з KPI-картками, табл. рядків, кольоровим variance. - Окремий sidebar-sectionbudgetingSection(config:budgeting.ts).appBudgeting→ statusinstalled.📋 Planned-розширення (детально в "Очікувана архітектура" нижче): - Multi-version comparison (rev 1 vs rev 3 vs actual). - Budget templates / копіювання попереднього року. - What-if scenarios з sensitivity analysis. - Forecast at period-end (плановий + прогноз залишку періоду). - Workflow погодження (
BudgetApproval). - Інтеграція з Consolidator (бюджет групи компаній).
Призначення¶
Модуль фінансового планування:
- Бюджети доходів/витрат за статтями (ExpenseItem, BusinessDirection)
- Сценарії (optimistic / realistic / pessimistic)
- Plan-vs-Actual variance
- Прогноз на кінець періоду (forecast)
- Узгодження бюджету (workflow)
Реалізована модель — детально (MVP)¶
Budget (MasterDataModel)¶
(year, version, organization)UNIQUE per tenant.is_locked— після постановки lock рядки не редагуються.- Серіалізатор повертає
line_count,total_planned.
BudgetLine (TenantAwareModel)¶
budget,period_month(1..12).- Один з:
account(FK ChartOfAccounts) абоexpense_item(FK ExpenseItem) — щонайменше один має бути заданий. - Опціональні dimensions:
project(BusinessDirection),department. planned_amount(Decimal),notes.
compute_variance(budget) → List[Dict]¶
for line in budget.lines:
start, end = period_range(year, line.period_month)
qs = IncomeExpenseJournal.filter(
tenant=tenant, date__between=(start, end)
)
if budget.organization: qs.filter(organization=...)
if line.account: qs.filter(account=line.account)
if line.expense_item: qs.filter(expense_item=...)
if line.project: qs.filter(project=...)
debit, credit = qs.aggregate(d, c)
actual = (credit − debit) if account.code.startswith('7') else (debit − credit)
variance = planned − actual
Endpoint /variance/¶
{
"budget_id": 5,
"name": "2026 Base",
"year": 2026,
"version": "base",
"lines": [
{
"period_month": 3,
"account_code": "6240", "account_name": "Transport",
"expense_item": "", "project": "", "department": "",
"planned": 1000, "actual": 800, "variance": 200, "variance_pct": 20.0,
"notes": ""
}
],
"summary": {
"total_planned": 6000, "total_actual": 800, "total_variance": 5200
}
}
Frontend¶
- Budgeting → Budgets → Plans → Budgets (CRUD заголовків).
- Budgeting → Budgets → Plans → Budget Lines (CRUD рядків).
- Budgeting → Analytics → Reports → Budget Variance —
BudgetVarianceReport.tsxз фільтром бюджету + Plan vs Actual таблицею.
Очікувана архітектура (planned scope для повного модуля)¶
Multi-version budget comparison¶
Мотивація: порівняти rev 1 vs rev 3 vs actual
Чому відкладено: MVP підтримує декілька version, але без UI для порівняння — потрібен звіт «multi-version variance».
Trigger: після перших користувачів зі сценарієм перепланування
Budget templates / copying¶
Мотивація: новий рік — скопіювати старий бюджет як основу Чому відкладено: після MVP Trigger: друге планування
What-if scenarios + sensitivity analysis¶
Мотивація: "якщо виручка впаде на 10% — як зміниться прибуток?" Чому відкладено: потрібен formula engine Trigger: запит CFO
Integration з Consolidator¶
Мотивація: бюджет групи компаній (multi-organization) Чому відкладено: очікує реалізації Consolidator Trigger: після релізу Consolidator