425 Planning
Today: 9 Nov 2026

Budgets

Twelve months per account for one cost center. Saving runs one batch of MERGE statements.

AccountJanFebMarAprMayJunJulAugSepOctNovDecYear
4000 Software sales rev 0
4100 Consulting services rev 0
4200 Training income rev 0
4800 Interest income rev 0
5000 Cost of services exp 0
5100 Salaries and wages exp 0
5110 Social security contributions exp 0
5200 Office rent exp 0
5300 Utilities exp 0
5400 Marketing and advertising exp 0
5500 Travel exp 0
5600 Office supplies exp 0
5700 Software subscriptions exp 0
5800 Professional fees exp 0
5850 Depreciation exp 0
5900 Bank charges exp 0
5960 Interest expense exp 0
Total0000000000000
Empty or 0 = no budget (the row is deleted by the MERGE).

Fill from actual figures

Copies each month's actual amount for this cost center, adjusted by the percentage and rounded to hundreds.
How this works - feature 425 A 12-month budget per account and cost center.

Concepts

  • One row per year / account / cost center / month, protected by a UNIQUE constraint.
  • Saving the grid runs one batch of MERGE statements: update, insert or delete each cell.
  • 'Fill from actual' copies last year's figures (or this year's) +/- a percentage.

Read the code

  • service/BudgetService#save
  • domain/BudgetLine

SQL behind this page

MERGE budget_line AS t
USING (SELECT :year AS fiscal_year, :account AS account_id, :cc AS cost_center_id, :month AS period_month, :amount AS amount) AS s
   ON t.fiscal_year = s.fiscal_year AND t.account_id = s.account_id
  AND t.cost_center_id = s.cost_center_id AND t.period_month = s.period_month
WHEN MATCHED AND s.amount = 0 THEN DELETE
WHEN MATCHED THEN UPDATE SET amount = s.amount
WHEN NOT MATCHED AND s.amount <> 0 THEN
     INSERT (fiscal_year, account_id, cost_center_id, period_month, amount)
     VALUES (s.fiscal_year, s.account_id, s.cost_center_id, s.period_month, s.amount);