---
title: "Multi-entity & FX"
description: "Consolidation and currency are where finance UIs produce wrong numbers without anyone noticing. Both ask you to add up figures that look like they add up and don't: two entities that trade with each other, or euros and dollars in one column."
canonical: "https://lopifi.com/docs/domain/multi-entity-and-fx"
---

# Multi-entity & FX

> Consolidation and currency are where finance UIs produce wrong numbers without anyone noticing. Both ask you to add up figures that look like they add up and don't: two entities that trade with each other, or euros and dollars in one column.

Source: https://lopifi.com/docs/domain/multi-entity-and-fx
Part of: Lopifi — Planned: US GAAP books on autopilot, checked by a CPA (https://lopifi.com)

---

# Multi-entity & FX

Consolidation and currency are where finance UIs produce wrong numbers without anyone noticing. Both ask you to add up figures that look like they add up and don't: two entities that trade with each other, or euros and dollars in one column.

---

## 1. The consolidation model

```ts
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 |
| Significant influence (presumed 20–50%) | **Equity method** (ASC 323) | One line: investment in an equity-method investee (IFRS: an associate), moving with the investor's share of profit |
| No significant influence (typically < 20%) | **ASC 321** | Equity securities at fair value through net income — or, where fair value is not readily determinable, the measurement alternative (cost less impairment, adjusted for observable price changes) |
| Joint control | **Equity method** for a joint venture | IFRS 11 joint operations recognize 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" and "Northwind Holdings Ltd. (standalone)" are different statements.
- **Entity selection is explicit, never inferred from a user's default.** Someone who thinks they're reading the group while looking at one subsidiary will make decisions on the wrong numbers.
- **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. Leave it out and the parent's share is overstated.
- **Subsidiaries with different fiscal year-ends** need aligned reporting or a stated adjustment. The UI flags the mismatch instead of adding them up anyway.

---

## 2. Intercompany

Transactions between group entities eliminate on consolidation. Each entity booked them, and the group never did them.

```
  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 has an equal and opposite counterpart. **Non-zero cells are the exception queue.** They're the most common reason a consolidation doesn't tie.
- **Name the break.** 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) have different fixes, so the matrix labels the break type instead of showing a bare difference.
- **Unrealized profit in inventory** (goods sold intercompany and still on hand) is eliminated too. The UI flags it and doesn't compute it, because that takes knowing what's still in stock.
- **Elimination entries are `source: "elimination"`** and exist only at the consolidated level. They never show up in an entity's standalone statements, and the UI makes that boundary visible.

---

## 3. Functional vs. presentation currency

This distinction decides whether an FX difference hits the P&L or equity, and it's an easy one to get backwards.

| | 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* |

Three different processes, two different destinations:

| | **Transaction gains and losses** | **Remeasurement** | **Translation** |
|---|---|---|---|
| Converts | A foreign-currency-denominated monetary item → functional | Books kept in another currency → functional | Functional → reporting (presentation) |
| FX difference goes to | **P&L** (ASC 830-20-35-1) | **P&L** (ASC 830-10-45-17) | **Equity** (CTA, in OCI — ASC 830-30-45-12) |
| Applies to | One receivable, payable, loan or cash balance | An entity whose ledger is not in its functional currency | An entire foreign operation's statements |

A EUR receivable held by a USD-functional entity produces a P&L gain or loss when rates move. Translate that same entity's statements into a GBP-presentation group and you get a CTA in OCI, which stays out of the P&L until the foreign operation is sold or substantially liquidated and is then reclassified to earnings. Mix the two up and earnings are misstated.

---

## 4. Translation rates

| Item | Rate |
|---|---|
| Assets and liabilities | **Closing rate** at the balance sheet date |
| Income and expenses | **Rate at the date each item is recognized** — a weighted-average rate for the period is the usual practical approximation permitted by ASC 830-30-45, and is not appropriate when rates swing within the period |
| Equity | **Historical rate** at the date of each contribution |
| Retained earnings | Rolled forward, not re-translated |

Mixing rates means **the translated balance sheet does not balance**. The plug is the **cumulative translation adjustment**, recorded in other comprehensive income.

**UI rules:**
- **CTA gets its own equity line, never buried.** It falls straight out of the method, and hiding it leaves a balance sheet nobody can explain.
- **Every translated statement shows the rates used**: closing, average and the source. Without the rate, nobody can check the translated number.
- **The average-rate method is stated** (simple average of daily, monthly weighted, transaction-date). The methods give different results, and you can't compare two periods without knowing which one each used.
- **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 and doesn't attempt the calculation.

---

## 5. FX gain and loss

Three events, three rates, on a single foreign-currency invoice (the rates are illustrative):

```
  1. Invoice issued Sep 1    €10,000 @ 1.0850 = $10,850   → AR recorded
  2. Period end Sep 30       €10,000 @ 1.0920 = $10,920   → unrealized gain $70
  3. Payment received Oct 12 €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, never combined.** Unrealized reverses and realized doesn't. Show one number and the reader can't tell what happened to the cash.
- **The period-end revaluation 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 are. Inventory, fixed assets and prepaids stay at the historical rate. Revaluing a non-monetary item is a common and material error, so the UI derives this from the account classification instead of trusting a flag.
- **Every conversion records the rate source and timestamp.** An auditor can't test a rate nobody can trace.

---

## 6. Rate management

```ts
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 required.** The same pair on the same date has a different closing rate and average rate, and the wrong one misstates the figure with nothing on screen to show it.
- **Manual rate overrides need a reason and an approver**, and look different from sourced rates everywhere they're used.
- **A missing rate is a blocking error**, never a default of 1.0. Parity is the worst fallback there is: EUR 10,000 becomes $10,000 and the totals still look plausible.
- **Inverse rates are computed, never stored separately.** Store both and they drift apart.
- 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.**
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. Showing the previous entity's figure for even one frame is a serious error.
6. **Consolidated and standalone views look different**, beyond their labels. The consolidated view carries a persistent scope chip in the header.
7. **A user with access to some of the entities sees totals for those entities only**, and the UI says so. A partial total never passes as the 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 |
