Fees & finance
Finance setup and usage
Standing up budgets and then running the month: spend requests, expenses, vendor bills with three-way match, the cash position, and closing a period so reported numbers stop moving.
Fees & finance guide for day and boarding schools.
Last updated August 29, 2026
Setup, once a year
Finance has one hard prerequisite: a budget. Requests, expenses and vendor bills all hang off budget lines, and payroll posts its consolidated cost against one, so a deployment with no budget can still record spend but cannot report against a plan. Build it at the start of the financial year, before the first purchase order of the term, and build it at the level you actually want to answer questions at - department or activity, not a single line called Expenses.
- Create the annual budget at /finance/budgets, one per department or cost centre, with the allocated amount for the year.
- Add the budget line items that spend will be coded to. This is the granularity every later report inherits, so it is worth an argument up front.
- Confirm who has finance access. It is the same five roles as fees - Platform Admin, Principal, Vice Principal, Support Staff - Finance and Admin - and students and parents are refused outright.
- Make sure there are at least two of them. Every money decision refuses the person who raised it, so a single finance account cannot complete a cycle.
- Decide the high-value threshold. Anything at or above FINANCE_HIGH_VALUE_INR, twenty-five thousand rupees by default, needs Principal or Vice Principal rather than any leadership role.
The monthly cycle
| Task | Where | How it moves |
|---|---|---|
| Staff ask for spend | /finance/budget-requests | DRAFT, then the requester submits; a finance reviewer approves, funds and closes it. A rejection can go back to DRAFT |
| Record an expense | /finance/expenses | Coded to a budget line, then approved by someone else. Only expenses in PAID count as an outflow in reporting |
| Supplier invoice | /finance/vendor-bills | Three-way match against the purchase order and goods receipt within a 2% tolerance, giving MATCHED, VARIANCE, PENDING or UNLINKED, then approve and pay |
| Budget against actual | /finance/planning | Allocated, committed and spent, with variance per line |
| Cash position | /finance/cash-flow | Monthly inflow against outflow with a running cumulative net, also available as the finance-cash-flow report |
| What is still to collect | /fees/forecast | Overdue now, plus what falls due in the next 30, 60 and 90 days, for the receivables side of the same conversation |
| Payroll cost | /payroll/runs | Finalising a run with a budget id creates one consolidated expense for the net total; the budget spent figure only moves when the run is finalised as paid |
| Stop the month moving | Finance closed-periods API | A closed period rejects new expense and vendor-bill activity dated inside it with a 409 and FINANCE_PERIOD_CLOSED |
The cash-flow report is worth understanding rather than trusting. Inflow is completed fee payments by payment date plus paid admission application fees. Outflow is expenses in PAID by expense date, plus any finalised or paid payroll run that has not yet been posted as an expense, counted at its net total on the period end date so payroll appears exactly once. That last rule is why the outflow total will not equal the sum of your expense list, and why an approved-but-unpaid invoice is invisible in the cash position on purpose.
Handoffs across module boundaries
- From fees: completed fee payments become the fee inflow line in cash flow, and /fees/forecast supplies the forward receivables view. No fee data is posted into a budget.
- From procurement: purchase orders and goods receipts are what the vendor-bill three-way match compares against. A bill with neither is recorded as UNLINKED rather than blocked.
- From payroll: one consolidated expense per finalised run, category ADMINISTRATION, stored on the run so it cannot be created twice.
- From admissions: paid application fees count as an inflow, separately from student fees, so a strong admissions season is visible in the cash position.
Limits
- Not a general ledger. There is no chart of accounts, no journal entry and no trial balance, and no bank reconciliation - the accounting package the school already runs keeps the statutory books, fed by CSV export.
- No accounting-package sync. The accountingSyncStatus fields in the schema are written by no application code, so there is no QuickBooks, Xero or Tally integration in either direction.
- Period close has an API but no screen, so it is a deployment-level control rather than something a bursar self-serves.
- Budgets and expenses carry no school id, so a deployment holding more than one school shares one set of finance records.
Common questions
Quick answers in plain language.
Who can move a budget request from SUBMITTED to APPROVED?+
A finance reviewer, and not the requester. The requester owns only the moves into SUBMITTED and back to DRAFT; approving, funding and closing belong to finance. The allowed path is DRAFT, SUBMITTED, APPROVED, FUNDED, CLOSED, with a rejection able to return to DRAFT - anything off that path is refused rather than silently allowed.
A vendor bill shows UNLINKED instead of MATCHED. Is that an error?+
No. UNLINKED means the bill has no purchase order or goods receipt to compare against, so there is nothing to match rather than a mismatch. Link the order and the receipt and it will evaluate to MATCHED when the three values agree within the 2% tolerance, or VARIANCE with the difference recorded when they do not.
Why does the finance budget show no payroll cost even though the run is finalised?+
Because no budget id was supplied at finalise. The consolidated expense is created only in that moment, and there is no way to attach it later - the correction is a reversal run followed by a new one. Note also that the budget spent figure moves only when a run is finalised as paid; finalised without that, it appears as an approved expense rather than as spend.
How do we prevent last month being edited after the governors have seen the numbers?+
Close the period through the finance closed-periods API. New expense and vendor-bill activity dated inside a closed month is rejected with a 409 and a FINANCE_PERIOD_CLOSED code. There is no settings screen for it yet, so closing and reopening is done at API level by someone with finance access.
Related searches
School leaders and IT teams often search for: how to finance workflows in school management software, best fee management software for K-12 schools, Schoolyi finance workflows guide, finance workflows step by step, online fee collection software, school billing software, and fee receipt software schools.

