mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Add exchange rate feature with multi-currency transactions and transfers support (#1099)
Co-authored-by: Pedro J. Aramburu <pedro@joakin.dev>
This commit is contained in:
committed by
GitHub
parent
8e81e967fc
commit
f699660479
20
lib/money.rb
20
lib/money.rb
@@ -39,16 +39,30 @@ class Money
|
||||
validate!
|
||||
end
|
||||
|
||||
def exchange_to(other_currency, date: Date.current, fallback_rate: nil)
|
||||
# Exchange money to another currency
|
||||
# Params:
|
||||
# other_currency: target currency code (e.g. "USD")
|
||||
# date: date for historical rates (default: Date.current)
|
||||
# custom_rate: explicit exchange rate to use (skips lookup if provided, including nil check)
|
||||
# Priority:
|
||||
# 1. Use custom_rate if explicitly provided (not nil)
|
||||
# 2. Look up rate via store.find_or_fetch_rate
|
||||
# 3. Raise ConversionError if no valid rate available
|
||||
def exchange_to(other_currency, date: Date.current, custom_rate: nil)
|
||||
iso_code = currency.iso_code
|
||||
other_iso_code = Money::Currency.new(other_currency).iso_code
|
||||
|
||||
if iso_code == other_iso_code
|
||||
self
|
||||
else
|
||||
exchange_rate = store.find_or_fetch_rate(from: iso_code, to: other_iso_code, date: date)&.rate || fallback_rate
|
||||
# Use custom rate if provided, otherwise look it up
|
||||
if custom_rate.present?
|
||||
exchange_rate = custom_rate.to_d
|
||||
else
|
||||
exchange_rate = store.find_or_fetch_rate(from: iso_code, to: other_iso_code, date: date)&.rate
|
||||
end
|
||||
|
||||
raise ConversionError.new(from_currency: iso_code, to_currency: other_iso_code, date: date) unless exchange_rate
|
||||
raise ConversionError.new(from_currency: iso_code, to_currency: other_iso_code, date: date) unless exchange_rate && exchange_rate > 0
|
||||
|
||||
Money.new(amount * exchange_rate, other_iso_code)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user