Skip to content

FX handling

Anything not denominated in INR — SAR hotel invoices, USD flight blocks, AED visa fees — needs an exchange rate to enter the books. This runbook tells you where rates come from, how the app captures them at posting time, and what to do at month-end for open foreign-currency balances.

Base currency for the Al Huda books is INR. Every voucher ultimately posts INR values on JournalLine.debit and JournalLine.credit; the source-currency amount and the rate used are pinned alongside.


1. When FX matters

Any time you post a voucher whose source amount is not INR:

  • SAR hotel invoices (Makkah / Madinah suppliers bill in SAR).
  • USD / AED airline or ticketing DMC invoices.
  • SAR / USD ground-transport contracts.
  • Foreign agent commissions or settlements.

If the customer-facing invoice is in INR but one of your cost lines came from a foreign supplier, you still need an FX rate — but only for the cost-side posting.


2. How the rate is captured at posting

Two migrations added the audit trail for FX postings:

  • supabase/migrations/20260418060325_journal_fx_rate.sql — adds JournalEntry.fxRateUsed (the header-level rate).
  • supabase/migrations/20260418150000_journal_line_original_amounts.sql — adds JournalLine.originalDebit, originalCredit, originalCurrency, fxRate (per-line source values).

What this means in practice:

  • When you post a SAR hotel bill, the voucher stores originalDebit: 4500 SAR, fxRate: 22.10, originalCurrency: 'SAR' and debit: ₹99,450 all on the same line.
  • The rate at the moment you clicked Post is frozen. If someone later edits the supplier contract's exchange rate, the historical voucher does not change — it still reports the rate that was used when it was posted.
  • For pure INR postings, all four columns are NULL — no conversion happened.

FX rate cannot be edited after posting

Once a voucher is approved, the FX rate pinned on it is immutable in the UI. The only way to change a posted rate is to reverse the voucher and re-post with the correct rate. See the reversing-and-correcting runbook.


3. Where the rate comes from

The app asks you for the rate at posting time. It does not currently fetch from a live feed.

  1. For supplier invoices linked to an inventory record (airline block, hotel contract, ground-transfer contract), the contract's stored exchange rate is the default — the one agreed at the time the contract was booked. Use it unless the supplier bills against a different rate in the invoice itself.
  2. For standalone supplier invoices (a one-off SAR bill with no inventory contract), use the RBI reference rate for the invoice date. Source: https://www.rbi.org.in/scripts/ReferenceRateArchive.aspx
  3. For customer receipts in foreign currency (rare), use the rate at which the bank actually credited your INR account — that's the honest number.

Record the rate source in the memo

Always write the rate source in the voucher memo, e.g. Rate: RBI ref 2026-04-14 — 1 SAR = 22.10 INR. This saves the auditor a round-trip. It is also free evidence if the rate is ever questioned.


4. Posting a foreign-currency voucher — worked example

Scenario: Hotel Al Haram, Makkah, bills SAR 45,000 for April block. You agreed rate at contract was SAR 1 = INR 22.10.

Steps

  1. Finance → Vouchers → Journal (or the supplier-linked voucher form, if the invoice ties back to a hotel inventory record).
  2. Currency: set to SAR.
  3. Original Amount: 45,000.00.
  4. FX Rate: 22.10. The form auto-computes the INR column (9,94,500.00).
  5. Fill the rest of the voucher exactly like an INR bill — expense line debits 5101 Hotel Purchases, credit line credits the supplier's creditor account. Amounts in the INR columns flow from your rate.
  6. In the Memo, note the rate source: SAR 45,000 @ 22.10 (contract rate) = INR 9,94,500 — Hotel Al Haram April invoice INV-2326.
  7. Verify Total Dr = Total Cr in INR terms.
  8. Click Post.

What the journal stores

Column Debit line (expense) Credit line (supplier)
debit 994500.00
credit 994500.00
originalDebit 45000.00
originalCredit 45000.00
originalCurrency SAR SAR
fxRate 22.10 22.10

Header fxRateUsed is also 22.10.


5. Period-end FX revaluation

Open foreign-currency balances (unpaid SAR invoices, USD advances still sitting with suppliers) carry a rate risk: the rupee moves, so the INR value of those balances at period-end is different from the INR value captured when they were posted.

Current capability

Revaluation is not currently automated

The app does not run an automated period-end FX revaluation job. There is no "Revalue open FX balances" button. If your Finance Manager has decided revaluation is material this month, you run a manual adjustment journal per the procedure below.

Manual revaluation procedure

  1. Get the period-end closing rate from the RBI reference page for every foreign currency you have open balances in.
  2. For each supplier / customer with an open foreign-currency balance: a. Pull their ledger. Note the open balance in source currency. b. Compute period-end INR value = (source-currency balance) × (period-end rate). c. Compute the difference vs the INR value currently on the books. This is your unrealised gain or loss.
  3. Post one adjustment journal per currency with a row per supplier / customer affected:
    • If rupee has weakened (foreign currency worth more INR):
      • Debit 5501 FX Loss (Unrealised) or Credit 4501 FX Gain (Unrealised) depending on net direction.
      • Opposite side hits the supplier creditor / customer debtor per-party.
    • Memo: Period-end FX revaluation, April 2026 close, RBI rate 1 SAR = 22.45 (prev contract 22.10).
  1. Approve the revaluation journal via the normal maker-checker flow.
  2. At the start of the next period, post a reversing entry for the whole revaluation (see reversing-and-correcting.md §1). Without the reversal, next month the revaluation sits on top of the actual realised FX gain/loss when the invoice finally settles.

Why reverse at period start

Standard Indian accounting practice: unrealised FX adjustments at period-end are reversed on Day 1 of the next period so that when the invoice is actually paid, the realised gain/loss hits the books as a single number, not mixed with the prior-period estimate.


6. Verifying an FX voucher posted correctly

  • [ ] Trial Balance: run in INR (default). The voucher contributes the correct INR debit and INR credit; overall balance is zero.
  • [ ] Drill into the journal (Journal tab → click the voucher row): the Voucher Detail dialog should show both the INR amounts and the original-currency amounts side by side, with the rate.
  • [ ] Supplier ledger: the invoice is visible. If you drill into the line, the source-currency amount is carried through.
  • [ ] Audit log: the finance.voucher.create entry records the voucher id; header fxRateUsed is populated.

Reports are INR-only

Trial Balance, Balance Sheet, P&L, Aging — every report prints in INR. The source-currency information is only visible on the individual voucher / ledger line. If the auditor asks for a foreign-currency report, you export the relevant account statement and filter the originalCurrency column.


7. Common mistakes

  1. Typing the wrong rate direction1 SAR = 22.10 INR is correct. 1 INR = 22.10 SAR is wrong. The form accepts either number, but the INR amount will be off by a factor of 500+ if you invert it. Sanity check: if your INR amount has one more digit than it should, you probably inverted the rate.
  2. Using today's rate for an old invoice — the rate should match the invoice date, not today. RBI reference page has historical rates.
  3. Forgetting to note the rate source in the memo — auditors will always ask. Put it in once, save everyone the email chain.
  4. Revaluing then forgetting to reverse on day 1 of next period — you end up double-counting FX gain / loss next month when the invoice actually settles.