Learn: how Finance Lab is built
Spring Boot 3.5 · Java 21 · Spring Data JPA + JdbcTemplate · Flyway · SQL Server · Thymeleaf
The one idea behind everything: double entry
Every feature ends in a journal entry whose debits equal its credits. Reports never read invoices or bills -
they read the journal lines through the view v_ledger. That is why the trial balance always balances and why
the balance sheet, P&L and cash flow agree with each other.
| Account type | Grows with | Examples |
|---|---|---|
| Asset | Debit | Bank, receivables, input VAT, laptops |
| Expense | Debit | Salaries, rent, FX loss |
| Liability | Credit | Payables, output VAT, WHT payable, loan |
| Equity | Credit | Share capital, retained earnings |
| Revenue | Credit | Software sales, consulting, FX gain |
Layers - where to look
db/migration | Flyway SQL: tables, CHECK / UNIQUE constraints, filtered index, computed columns, the view v_ledger, master data |
domain | JPA entities (Lombok getters / setters), enums stored as text |
repo | Spring Data repositories, derived queries, @EntityGraph |
service | Posting rules (@Transactional), reports with NamedParameterJdbcTemplate, BigDecimal money rules |
web | Controllers, form binding + Bean Validation, PRG pattern (redirect after POST), SVG charts |
config | DemoDataSeeder - ten months of sample data posted through the real services |
Feature map 411 - 430
Every page has a "How this works" panel at the bottom with the concepts, the classes to read and its SQL.
411
Record income
Money received straight away, without an invoice.
412
Record expensesMoney paid straight away: salaries, supplies, travel, fees.
413
General ledgerChart of accounts, trial balance, journals and account ledgers.
414
Balance sheetAssets = Liabilities + Equity on any date.
415
Profit & lossRevenue - cost of sales - expenses = net profit, with comparison.
416
Cash flowWhere the cash came from and where it went.
417
Accounts payableVendor bills, what we owe, and paying them.
418
Accounts receivableWho owes us what, and for how long.
419
InvoicesSales invoices with lines, VAT, due dates and status.
420
ReceiptsMoney received against an invoice, full or partial.
421
Credit notesReduce what a customer owes: discount, return or mistake.
422
Tax calculatorVAT in / out, withholding tax with gross-up, personal income tax.
423
VAT reportOutput VAT - input VAT per month (PP 30) with the tax invoice lists.
424
Withholding taxTax we withheld (PND 3 / PND 53) and tax withheld from us.
425
BudgetsA 12-month budget per account and cost center.
426
Budget vs actualHow much of the budget is used, and where it is over.
427
Cost centersDepartments that own revenue, costs and budgets.
428
Multi-currencyDocuments in USD, EUR, JPY ... and the FX gains and losses.
429
Exchange ratesDaily rates, history chart and 'rate on a date'.
430
Payment trackingEverything still to be paid or received, by due date.
Exercises
- Record an expense with VAT 7 % and a withholding tax type, then open its journal entry: which four lines were posted?
- Create an invoice in USD, then receive it on a later date. Find the FX gain or loss line (428).
- Issue a credit note and watch the VAT report (423) for that month change.
- Post a manual journal that does not balance - read the error from
JournalService.post. - Make one cost center's budget smaller and open Budget vs actual (426).
- Run the SQL from a "How this works" panel in SQL Server Management Studio against
FinanceLabDB.
Start again
Deletes every transaction (invoices, bills, journals, budgets, exchange rates) and creates the sample data again. Accounts, contacts and cost centers stay.