413 Ledger & statements
Today: 9 Nov 2026

JV-2026-0022

Salaries - head office

#AccountCost centerMemoDebitCredit
1 5100 Salaries and wages HQ 85,000.00
2 1010 Bank - KBank current account 85,000.00
Total85,000.0085,000.00

Entry details

Date25 Jan 2026 Created byExpense record DocumentEXP-2026-0004 CurrencyTHB Exchange rate1.0000
Debits = credits. The entry balances.

Lines are always in THB. Debit lines are written first, credit lines indented - the way accountants write a journal.

How this works - feature 413 Chart of accounts, trial balance, journals and account ledgers.

Concepts

  • Double entry: every entry has debits = credits; JournalService.post refuses anything else.
  • CHECK constraint: a line is either a debit or a credit, never negative.
  • Trial balance: if total debits = total credits the books are in balance.
  • Ledger running balance: SUM(...) OVER (ORDER BY ... ROWS UNBOUNDED PRECEDING).
  • Document numbers come from one MERGE ... OUTPUT statement (NumberingService).

Read the code

  • service/JournalService
  • service/JournalDraft
  • service/ReportService#trialBalance
  • service/NumberingService

SQL behind this page

SELECT a.id, a.code, a.name, a.type,
       COALESCE(SUM(l.debit), 0)  AS debit,
       COALESCE(SUM(l.credit), 0) AS credit
FROM account a
LEFT JOIN v_ledger l ON l.account_id = a.id AND l.entry_date <= :asOf
GROUP BY a.id, a.code, a.name, a.type
ORDER BY a.code

-- account ledger
SELECT entry_id, entry_no, entry_date, entry_description, source_type, source_ref, memo, debit, credit,
       SUM(natural_amount) OVER (ORDER BY entry_date, entry_id, line_id
                                 ROWS UNBOUNDED PRECEDING) AS running
FROM v_ledger
WHERE account_id = :accountId AND entry_date BETWEEN :from AND :to
ORDER BY entry_date, entry_id, line_id