Skip to main content

Consolidation, intercompany and FX revaluation

Sub-ledger 7, migration 0009.
This family is built from specification, not from worked data. Sub-ledgers 1 to 6 reproduce the v12 workbook’s worked figures to the dong. Intercompany, FX revaluation and equity are proposed only in the workbook - the flows are specified with fields, enums and formulas, but no worked example exists to tie against. So this family is built from that specification, which is what the workbook intends but never executed. That is a weaker claim than the other six make, and it is stated rather than blurred.

Three capabilities

Intercompany mirrors

An intercompany invoice is meant to have two independently authoritative sides, and they must mirror: the seller’s receivable equals the buyer’s payable. The current writer can record both legs inside one organization, but two legs derived from one input are not independent counterparty evidence. IC-MIRROR reports complete only when independently authoritative entity and counterparty facts support the comparison; otherwise the family preserves a bounded partial or inconclusive state instead of certifying same-writer equality. A genuinely missing or short mirror leg means the pair will not eliminate on consolidation, which shows up as revenue and cost that exist only because the group traded with itself.

FX revaluation

An open foreign-currency item is restated at the closing or settlement rate.
The unrealized-versus-realized split is the point. An unrealized movement is a translation effect that sits in equity; a realized one has hit the P&L because the item actually settled. Collapsing them overstates or understates earnings by the whole translation swing. FX-REVAL checks the formula holds for every revaluation, and FX-RESERVE reports the net position as an explainable balance.
This is the period-end half of FX. The transaction-date half is fx.resolve_rate, which values a transaction when it posts. The two are deliberately separate: the booked rate is the historical fact, and revaluation is a later restatement of an item that is still open. Neither one changes the other’s number.

Equity

DIVIDEND-PIT checks that the withheld PIT equals ROUND(amount x 5%), the Vietnamese dividend withholding rate.

Consolidation-group authority

Migration 0060_group_authority adds the authority needed to read a group without accepting a browser-supplied organization list. It stores immutable group entity-code identities, non-overlapping effective-dated memberships, one effective parent, full-consolidation membership in v1, and revocable user read grants. The dedicated ws_group_reader role is NOLOGIN, cannot bypass RLS, and resolves its member population from server-bound group, user, and period settings. The group reader returns exact member contributions and request-time presentation-currency translation only when the whole population is comparable. A missing member, incomplete membership window, mixed or unavailable book-currency history, missing direct rate, unresolved account, or unsupported account type withholds the affected group scalar.
The group reader applies no intercompany eliminations. Its responses say that the figures are gross member contributions, not certified consolidated statements. Registry 1.14.1 still classifies greatbook.group.reporting.read as experimental and blocked, so this page does not claim a production group-report workflow.
GROUP-TB is no longer a Close checksum. Summing already balanced journals proves only the ledger’s structural debit/credit rule, not consolidation completeness, membership authority, translation, or eliminations. The inventory tests explicitly require the former tautology to remain absent rather than count it as a passed group control.

The checks

Where it is enforced

The test that would fail if it broke

backend/tests/test_consolidation.py covers the mirror, the revaluation formula in both directions, the realized and unrealized routing, and the dividend PIT split. backend/tests/test_group_authority_schema.py and langgraph_chat/agents/accountant/tests/test_group_authority_live.py cover immutable identities, effective membership, grants, RLS, and the dedicated reader role. langgraph_chat/agents/accountant/tests/test_group_reports_live.py covers incomplete populations, exact translation, and the no-eliminations disclosure. backend/tests/test_close_inventory.py requires GROUP-TB to remain absent. Because there is no worked v12 data for this family, those tests are written against the specification’s formulas rather than against reproduced figures. That is the honest position: the arithmetic is verified, the fidelity-to-a-real-book claim the other six families make is not available here yet.

What goes wrong without it

Un-eliminated intercompany trade is the classic group-accounts overstatement: revenue and cost both inflated by transactions the group had with itself, with no external counterparty and no economic substance. Missing FX revaluation leaves foreign-currency payables and receivables carried at rates from whenever they were raised, so the balance sheet reports a position in a currency that has since moved, and the correction all lands at once whenever somebody notices.