The GL speaks one currency. But each line remembers where it came from.
Daily automatic FOREX, <code>OriginalCurrency</code> and <code>OriginalAmount</code> on every GL line, queryable rate history and two variance modes. Built on the proven P4 Books model with two additive improvements.
Single-currency GL, multi-currency metadata
One base currency per tenant
The general ledger speaks one currency. Translations happen at transaction entry — no parallel multi-currency ledger.
Preserved on every line
Every GL line stores <code>OriginalCurrency</code> and <code>OriginalAmount</code>. Reporting in source currency without losing traceability.
Daily automatic update
Hangfire job at midnight UTC refreshes rates. <code>ExchangeRateHistory</code> makes every conversion auditable.
The architectural call
A multi-currency ledger (a balance per currency) forces impossible reconciliations and endless audits. The industry standard for SMB and mid-market — QuickBooks, Xero, NetSuite — is a single-currency GL with origin metadata. We do that, well.
- Translation at entry. A USD invoice is recorded in the base currency using the rate of the invoice day. The GL always balances in one currency.
- Original metadata intact. The invoice is still USD 1,200 — not "USD 1,200 converted, rounded to PAB 1,200.03". The AR-by-customer report can show the currency it was issued in.
- Queryable history.
ExchangeRateHistorykeeps every rate used. Any report can recompute on different dates for analysis.
Two modes for your accounting policy
- Simple mode (default). All FX differences go to a single
FxVarianceBankFeesaccount. Appropriate for low-volume SMB. - Separated mode. Realized FX gain and realized FX loss go to distinct accounts. Appropriate for businesses with material FX exposure.
- Role-based binding, not code-based. Accounts are assigned by role (
DefaultAR,FxVarianceBankFees,RetainedEarnings). You can rename freely without breaking the system. - No period-end revaluation. IAS 21 open-balance revaluation is deferred indefinitely — appropriate for SMB, not for audited statements. Documented honestly.
How we keep rates alive
- Per-tenant dispatcher fanout. Each tenant has its own cron honoring its local timezone — tenants don't all refresh at the same UTC hour.
- Manual overrides allowed. A permissioned user can force a rate for a specific date. The event is written to
AuditEvents. - Fallback to last known rate. If the FX provider fails, the previous rate stays effective until a new one is confirmed.
- Elevated currencies table.
Currencieslives in the control plane (CiferaHQ_master) — a single authoritative list shared across all tenants.
Multi-currency demo with your chart of accounts
Bring your COA; we'll show you what a close with real FX variance looks like.