XCubes

Build financial statements from a ledger export

You have a ledger export — journal lines or a trial balance, each row carrying an account code and a debit/credit pair or a signed balance — and you want statement cubes: a balance sheet, a P&L. The mechanics are a Link through an allocation table, and they are the easy part.

The hard part is that every failure mode is silent. A code no rule matches is skipped without an error. A wrong sign flips a line. Two wrong lines can offset so the grand total still looks right. This guide is the method that catches all of that before any data lands in a cube. The running example is a French FEC (plan comptable général account classes), but the method applies to any chart of accounts.

1. Establish the ground truth before writing any rule

The export usually travels with its own statements — a Balance tab, a Bilan or P&L built by the accountant, a prior-year report. That document is the specification: it fixes the line labels, each line's account range, the presentation sign, and the expected value.

Before encoding a single allocation rule, reconstruct every target line directly from the trial balance — sum the account balances over the line's range — and check the result against the statement. Only when each line reproduces do you translate the ranges into rules. If no target statement exists, write down the expected per-line values first and have them confirmed. The first tie-out must happen outside the cube, not after the numbers are in it.

2. Check every range for sign splits before trusting a prefix rule

Prefix rules (70* → Revenue) are the workhorse. But some ranges route by the sign of each account's balance, not by its code — and there a prefix rule is guaranteed wrong. Classic cases on a French balance sheet:

Range Debit balances go to… Credit balances go to…
40 suppliers assets (advances paid) liabilities (payables)
4248 staff, state, misc assets (receivables) liabilities (payables)
5 cash assets (bank balances) liabilities (overdrafts)
28/29 depreciation reduces the asset line

The mechanical test: within a candidate range, list each account's balance. If the balances straddle zero and the target statement routes the two sides to different lines, stop — that range needs per-account (or per-side) rules immediately, not as a fallback after a bad first run.

3. Set the sign per destination line, never by a global convention

The allocation table's sign column is decided by how the destination line presents, not by a blanket "credit-normal → invert" table:

Applying one sign rule uniformly to an account class is how a technically credit-normal contra account ends up increasing the line it should reduce.

4. Order the rules: specific before catch-all

Exact codes beat patterns, and among patterns the first listed wins — see allocation tables. That ordering is how you split one class across statement sections. Example: a P&L that routes 790000791599 to operating income (reprises, transferts de charges) but 791600+ to financial income. The table lists the narrow patterns first — 7916*, 7917*, 7918*, 7919*, 792*799* — and the catch-all 79* last, so it only receives what the specific rules let through.

5. Prove coverage, then preview

A source code matching no rule is skipped without an error. So before the first run:

6. Tie out every line, not just the total

A matching grand total can hide two offsetting errors. Compare every statement line: input lines against the preview, subtotals against the cube's formula items. Only at zero variance on all lines do you run the Link. Then read the cube back (get_cube_data includes computed formulas) and repeat the comparison — this second pass verifies the formula wiring, not just the mapping.

7. Compute cross-statement ties — never retype them

Net income on the P&L must equal the result line inside equity on the balance sheet. Retyping it invites rounding drift: a hand-entered -7 382 497 against a computed -7 382 497.09 leaves the balance sheet nine cents out of balance — small, visible, and real. Compute the tie instead:

Where the model allows it, add a check row (Check = TotalAssets − TotalLiabilitiesAndEquity) so the tie is asserted continuously rather than inspected once.

8. Re-running when the ledger changes

Keep the Links in replace mode so re-runs are idempotent — a replace Link clears the cells it no longer produces. And run in dependency order: the ledger → statement Links first, then the P&L → balance-sheet tie Link. A tie Link re-run before the P&L refresh carries the stale result forward.


For the matching mechanics — exact vs. pattern, case rules, signs — see Mapping codes — Allocation tables. For transfer modes, preview and revert, see Populating cubes — Links & integrations.