Skip to content

Multi-entity & FX

Consolidation and currency are where finance UIs quietly produce wrong numbers, because both involve summing things that look summable and aren't.


1. The consolidation model

type Entity = {
  id: string; name: string; legalName: string;
  functionalCurrency: string;       // the currency it primarily operates in
  parentId?: string;
  ownershipPct: number;             // of the immediate parent's interest
  consolidationMethod: "full" | "equity" | "proportional" | "none";
  fiscalCalendar: FiscalCalendar;   // subsidiaries can differ from the parent
};
Ownership Method Treatment
Control (presumed > 50% of votes; a VIE or IFRS 10 power-and-returns test can override) Full consolidation Line-by-line, with non-controlling interest for the minority share
20–50% Equity method One line: investment in associate, moving with the share of profit
< 20% Cost / fair value An investment asset
Joint control Equity method for a joint venture IFRS 11 joint operations recognise their share of assets and liabilities; US GAAP allows proportionate consolidation only in narrow industries

UI rules:

  • The consolidation scope is always stated in the statement header. "Northwind Holdings Ltd. and subsidiaries" versus "Northwind Holdings Ltd. (standalone)" are different statements and must never be confused.
  • Entity selection is explicit, never inferred from a user's default. A user who thinks they're looking at the group and is looking at one subsidiary is being misled.
  • Non-controlling interest appears on both statements — as a component of equity on the balance sheet, and as an allocation of net income on the P&L. Omitting it overstates the parent's share.
  • Subsidiaries with different fiscal year-ends require either aligned reporting or a stated adjustment. The UI flags the mismatch rather than silently summing.

2. Intercompany

Transactions between group entities must eliminate on consolidation. They are real for each entity and unreal for the group.

  Entity A sells $100k of services to Entity B
  ─────────────────────────────────────────────
  A: Dr IC receivable 100k / Cr Revenue 100k
  B: Dr Expense 100k        / Cr IC payable 100k
  Group elimination: Dr Revenue 100k / Cr Expense 100k
                     Dr IC payable 100k / Cr IC receivable 100k
  Group effect: zero

UI rules:

  • The intercompany matrix must net to zero. IntercompanyMatrix renders an entity × entity grid of balances; every cell must have an equal and opposite counterpart. Non-zero cells are the exception queue, and they're the most common cause of a consolidation that doesn't tie.
  • Common breaks the UI must name: timing differences (one side booked in a later period), FX differences (each side translated at a different rate), and one-sided entries (the other entity never booked it). These have different fixes, so the matrix labels the break type rather than showing a bare difference.
  • Unrealized profit in inventory — goods sold intercompany and still on hand — must be eliminated too. Flagged, not computed, because it requires knowing what's still in stock.
  • Elimination entries are source: "elimination" and exist only at the consolidated level. They never appear in an entity's standalone statements, and the UI makes that boundary visible.

3. Functional vs. presentation currency

The distinction that causes the most confusion, and the one that decides whether an FX difference hits the P&L or equity.

Definition
Transaction currency What the invoice was denominated in
Functional currency The currency of the entity's primary economic environment
Presentation currency What the statements are shown in — IAS 21's term; ASC 830 calls it the reporting currency

Two different processes, two different destinations:

Remeasurement Translation
Converts Transaction → functional Functional → presentation
FX difference goes to P&L (FX gain/loss — ASC 830-20-35-1) Equity (CTA, in OCI — ASC 830-30-45-12)
Applies to Monetary items held in a foreign currency An entire subsidiary's statements

This is not a detail. A EUR receivable held by a USD-functional entity produces a P&L gain or loss when rates move. That same entity's statements translated into a GBP-presentation group produce a CTA in OCI that bypasses the P&L until the foreign operation is sold or substantially liquidated, when it is reclassified to earnings. Confusing them misstates earnings.


4. Translation rates

Item Rate
Assets and liabilities Closing rate at the balance sheet date
Income and expenses Average rate for the period (or transaction-date rates if volatile)
Equity Historical rate at the date of each contribution
Retained earnings Rolled forward, not re-translated

Because these use different rates, the translated balance sheet does not balance — and the plug is the cumulative translation adjustment, recorded in other comprehensive income.

UI rules:

  • CTA is displayed as its own equity line, never buried. It is the arithmetic consequence of the method, and hiding it makes the balance sheet look inexplicable.
  • Every translated statement shows the rates used — closing, average, and the source. A translated number without its rate is unverifiable.
  • Average rate methodology is stated (simple average of daily, monthly weighted, transaction-date). Different methods give different results and comparability depends on knowing which.
  • Hyperinflationary economies differ by framework: IFRS (IAS 29) restates for inflation, then translates; US GAAP (ASC 830) remeasures as if the reporting currency were functional, with differences in the P&L. The UI flags the jurisdiction and the framework rather than attempting it.

5. FX gain and loss

Three events, three rates, on a single foreign-currency invoice:

  1. Invoice issued 1 Sep    €10,000 @ 1.0850 = $10,850   → AR recorded
  2. Period end 30 Sep       €10,000 @ 1.0920 = $10,920   → unrealized gain $70
  3. Payment received 12 Oct €10,000 @ 1.0790 = $10,790   → Sep unrealized gain reverses (−$70)
                                                              realized loss $60 vs. invoice rate
                                                            (October P&L −$130; cumulative −$60)

UI rules:

  • Realized and unrealized are separate lines and never combined. Unrealized reverses; realized doesn't. Presenting one number destroys the reader's ability to tell what actually happened.
  • The revaluation entry at period end is a system entry with the rate and source shown, reversing at the start of the next period.
  • Only monetary items are revalued. Cash, receivables, payables, and debt — yes. Inventory, fixed assets, and prepaids — no, they stay at historical rate. Revaluing a non-monetary item is a common and material error, and the UI derives this from the account classification rather than trusting a flag.
  • The rate source and timestamp are recorded on every conversion. A rate without provenance is not auditable.

6. Rate management

type ExchangeRate = {
  from: string; to: string;
  rate: number;
  asOf: Date;
  type: "spot" | "closing" | "average" | "historical" | "budget";
  source: string;                  // "ECB" | "OANDA" | "manual"
  enteredBy?: string;              // manual rates need an actor
};
  • Rate type is not optional. The same pair on the same date has a different closing rate and average rate, and using the wrong one is a silent misstatement.
  • Manual rate overrides require a reason and an approver, and are visibly distinguished from sourced rates everywhere they're used.
  • A missing rate is a blocking error, never a silent 1.0. Defaulting to parity is the worst possible failure mode here.
  • Inverse rates are computed, never stored separately — storing both invites them to drift.
  • Rounding: rates carry 5–6 significant figures; converted amounts round once, at the end, per the currency's minor unit.

7. Multi-entity UI rules

  1. Entity is a required dimension on every transaction.
  2. Every number states its entity scope and its currency. Both, always.
  3. Never sum across currencies without a stated conversion, with the rate, the type, and the as-of date reachable.
  4. A converted value is marked with ≈ and its basis in a tooltip.
  5. Entity switching is a full context change, so nothing animates and every cached figure is invalidated. A stale figure from the previous entity displayed for even one frame is a serious error.
  6. Consolidated and standalone views are visually distinct, not just differently labeled — the consolidated view carries a persistent scope chip in the header.
  7. A user with access to a subset of entities sees totals for that subset only, and the UI says so explicitly rather than presenting a partial total as a group total.

8. Component set

Component Purpose
EntitySelector Explicit scope, with standalone/consolidated distinction
ConsolidationView Entity columns + eliminations + group total
IntercompanyMatrix Entity × entity, with break types named
EliminationEntry Consolidation-level only, clearly scoped
NciPanel Non-controlling interest on both statements
TranslationSummary Rates used, by type, with sources
CtaRollForward Opening CTA → movement → closing
FxRevaluation Period-end revaluation preview and posting
FxGainLossPanel Realized and unrealized, separated
RateTable By pair, date, and type, with source and overrides flagged

Built against this document

The surfaces that implement what this argues — running, computing, or shaped by it.

Told when this spec changes

The docs are the contract the components are built against. When one changes, the component changes with it — and the copy in your repo does not. One email when that happens.

One address, no list rental, unsubscribe in one click.

Works in your QuickBooks Online or Xero file

Get your books closed every month

Lopifi is building AI bookkeeping that keeps your books closed on US GAAP as transactions happen, with a CPA review every quarter, for $200 a month. We’re not open yet.

$200/month when we open. No card now.