Multi Currency Exchange Blueprint

Manage exchange rates, perform multi-currency transactions, and revalue accounts for unrealized foreign exchange gains and losses

   
Feature multi-currency-exchange
Category Payment
Version 1.0.0
Tags multi-currency, exchange-rates, revaluation, forex, erp, accounting
YAML Source View on GitHub
JSON API multi-currency-exchange.json

Fields

Name Type Required Label Description
from_currency text Yes From Currency Validations: pattern
to_currency text Yes To Currency Validations: pattern
exchange_rate number Yes Exchange Rate Validations: min
date date Yes Date  
for_buying boolean No For Buying  
for_selling boolean No For Selling  
rounding_loss_allowance number No Rounding Loss Allowance Validations: min, max
company text Yes Company Validations: minLength
posting_date date Yes Posting Date  
accounts json No Accounts  
gain_loss_booked number No Gain Loss Booked  
gain_loss_unbooked number No Gain Loss Unbooked  

Rules

  • same_currency_rejected:
    • description: From currency and to currency cannot be the same. Same-currency exchange rate entries are rejected.
  • date_based_lookup:
    • description: Exchange rates are fetched by date and currency pair. The most recent rate for the requested date is used.
  • revaluation_journal:
    • description: Revaluation creates journal entries for unrealized gain or loss on open foreign currency balances.
  • zero_balance_exclusion:
    • description: Zero-balance accounts in foreign currency are excluded from revaluation processing.
  • rounding_loss:
    • description: Rounding loss allowance must be between 0 and 1. Amounts within this threshold are written off automatically as rounding loss.
  • direction_flags:
    • description: Exchange rates can be flagged for buying, selling, or both directions. Separate rates may exist for each direction.
  • fallback_rate:
    • description: When no rate exists for the exact date, the most recent prior rate is used as a fallback.
  • gain_loss_account:
    • description: Revaluation gain or loss is posted to a designated exchange gain/loss account in the general ledger.
  • reversal_on_rerun:
    • description: Subsequent revaluations reverse previous unrealized entries before posting new ones to avoid double counting.

Outcomes

Fetch_exchange_rate (Priority: 10) — Error: EXCHANGE_RATE_NOT_FOUND

Given:

  • from_currency exists
  • to_currency exists
  • date exists

Then:

  • call_service target: exchange_rate_provider — Fetch exchange rate for the currency pair on the specified date
  • emit_event event: exchange_rate.updated

Result: Exchange rate is returned for the specified currency pair and date

Revalue_accounts (Priority: 11) — Error: REVALUATION_NO_ACCOUNTS

Given:

  • company exists
  • posting_date exists
  • at least one foreign currency account has a non-zero balance

Then:

  • call_service target: account_revaluation_engine — Calculate unrealized gain/loss for each open foreign currency account
  • set_field target: accounts — Populated with account balances and calculated gain/loss per account
  • emit_event event: revaluation.completed

Result: All open foreign currency accounts are revalued and gain/loss amounts calculated

Create_gain_loss_journal (Priority: 12) | Transaction: atomic

Given:

  • revaluation has been completed with non-zero gain/loss amounts
  • accounts exists

Then:

  • create_record target: journal_entry — Create journal entry posting unrealized exchange gain or loss
  • set_field target: gain_loss_booked — Set to total gain/loss from revaluation
  • emit_event event: gain_loss.booked

Result: Journal entry is created for the unrealized exchange gain or loss and posted to the general ledger

Errors

Code Status Message Retry
EXCHANGE_SAME_CURRENCY 400 Source and target currencies cannot be the same. No
EXCHANGE_RATE_NOT_FOUND 404 No exchange rate found for the specified currency pair and date. No
REVALUATION_NO_ACCOUNTS 404 No foreign currency accounts with open balances found for revaluation. No

Events

Event Description Payload
exchange_rate.updated Exchange rate is fetched or manually updated for a currency pair from_currency, to_currency, exchange_rate, date
revaluation.completed Account revaluation run completes for a company company, posting_date, total_gain_loss, account_count
gain_loss.booked Journal entry for unrealized exchange gain/loss is posted journal_entry_id, company, posting_date, gain_loss_booked
Feature Relationship Reason
general-ledger required Revaluation posts journal entries to the general ledger
sales-purchase-invoicing recommended Multi-currency invoices require exchange rate conversion

AGI Readiness

Goals

Reliable Multi Currency Exchange

Manage exchange rates, perform multi-currency transactions, and revalue accounts for unrealized foreign exchange gains and losses

Success Metrics:

Metric Target Measurement
policy_violation_rate 0% Operations that violate defined policies
audit_completeness 100% All decisions have complete audit trails

Constraints:

  • regulatory (non-negotiable): All operations must be auditable and traceable

Autonomy

Level: supervised

Human Checkpoints:

  • before making irreversible changes

Escalation Triggers:

  • error_rate > 5
  • consecutive_failures > 3

Verification

Invariants:

  • error messages never expose internal system details

Tradeoffs

Prefer Over Reason
accuracy speed financial transactions must be precise and auditable

Coordination

Protocol: request_response

Consumes:

Capability From Fallback
general_ledger general-ledger fail

Safety

Action Permission Cooldown Max Auto
fetch_exchange_rate supervised - -
revalue_accounts autonomous - -
create_gain_loss_journal supervised - -
Extensions (framework-specific hints) ```yaml source: repo: https://github.com/frappe/erpnext project: ERPNext tech_stack: Python, Frappe Framework, MariaDB/PostgreSQL ```