Loading

General Ledger

Double-entry journals as the system of record, with three currency amounts stored at post time, immutable postings and period close.

The Ledger as System of Record

The general ledger holds the double-entry record of what the business has done. The design decision worth stating plainly is its direction of travel: the ledger is the system of record, and external accounting packages feed into it. Xero, QuickBooks, Sage and your bank are sources. They are not the destination.

Why that direction

The usual arrangement — an operational system that exports to an accounts package which then becomes the truth — leaves you with two sets of books and a reconciliation problem. Questions like "why does the sales figure in the report not match the accounts?" are then permanent, because the two systems genuinely disagree and neither is wrong.

Making the ledger the destination removes the second set of books. Operational documents post into it, feeds bring external transactions into it, and a report and a trial balance are answering from the same data.

What a journal is

A journal is a balanced set of lines, each debiting or crediting an account, belonging to an entity and dated to a period. Nothing posts unbalanced. A journal may be created by hand, generated when a document reaches a status, or produced by a bank feed.

Posted journals are immutable

Once posted, a journal cannot be edited or deleted. A correction is a reversing entry — a second journal that undoes the first — followed by the correct posting.

Users sometimes find this frustrating, and it is worth explaining rather than defending. The alternative is a system where last month's reported figures can change after they were reported, which makes every historical statement provisional. The reversing entry leaves the mistake and the correction both visible, which is what an audit expects to see.

Nothing double-posts

Every journal carries a unique key derived from what caused it. If a webhook is redelivered, a scheduled task retried, or a feed cursor overlaps, the second attempt is recognised as the same event and does not post again. Duplicated postings are the classic failure of integrations that retry, and it is prevented structurally rather than by hoping retries do not happen.

Getting started

Set up your chart of accounts and your entities first, then decide which documents post and at which status. Post at the point the business considers the transaction real — usually approval or despatch, rarely draft.

Journals, Currency and Consolidation

Every journal line stores three amounts, not one:

  • The transaction amount — the currency the transaction actually happened in.
  • The functional amount — the entity's own currency, the one that company keeps its books in.
  • The reporting amount — the group's currency, the one consolidated statements are produced in.

All three are computed once, at the moment of posting, using the rates applicable then.

Why store all three

The tempting alternative is to store the transaction amount and translate on demand. It is simpler, and it is wrong, because the answer changes every time you ask. Run last year's trial balance today and again next month and you get different figures, because the rate moved. Financial statements that will not reproduce are not financial statements.

Storing all three at post time means a closed period returns the same numbers next year as it did on the day it closed. A rate correction after the fact is a posting, visible as such, rather than a silent restatement of history.

Single-currency systems

If you operate in one currency the three amounts are identical and you can largely ignore the distinction. It costs nothing to have them, and it means adding a second currency later is a configuration change rather than a re-engineering job.

Intercompany

A transaction between two of your own companies posts to both, in one operation, with each side in its own functional currency. This is precisely why entity is a separate dimension from tenant — tenant isolation forbids writing across the boundary, and an intercompany journal has to.

Consolidation

A consolidated view reads every entity at once and reports in the group currency, using the reporting amounts already stored on each line. Because the translation happened at post time, consolidation is a matter of adding up figures that already exist rather than re-translating history.

Practical advice

Set each entity's functional and reporting currency when you create it, before anything posts. Changing a functional currency after postings exist means every stored amount was computed against the wrong basis, and there is no clean automatic fix.

Periods and Closing

A journal belongs to an accounting period as well as to a date. Periods are what let the business say a month is finished and have that mean something.

What closing does

Closing a period stops further postings being dated into it. That is the whole mechanism, and it is enough — the figures reported for that month can no longer change, so a statement produced from them stays true.

Without it, a late invoice dated into a closed month silently changes a figure somebody has already circulated. That is the problem periods exist to prevent.

A late transaction after close

Post it into the current open period rather than reopening the old one. Reopening a closed period invalidates everything already reported from it; posting into the current period is visible, explicable and leaves the closed month intact.

Where the timing genuinely matters for reporting, an accrual in the closed period and a reversal in the new one is the accounting answer — and both are ordinary postings, so both are visible.

Before you close

  • Check every feed has been processed and the inbox is empty.
  • Confirm documents that should have posted have reached the status that posts them.
  • Run the calculated-field recalculation sweep if there have been imports.
  • Review the trial balance for the period and confirm it balances and looks sane.

Closing is a decision, not a routine

Do not automate it on a schedule. Closing asserts that the figures are final, and that assertion should be made by a person who has looked at them. Automating it means the assertion is made by a timer.

Reporting from closed periods

Because amounts were translated at post time and postings are immutable, a report over a closed period is reproducible indefinitely. That is the payoff for the discipline: the number you quote in March is the number the system still gives in December.