1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-24 23:59:40 +02:00

Handle missing exchange rate provider, allow fallback for missing rates (#955)

* Clean up exchange rate logic

* Remove stale method
This commit is contained in:
Zach Gollwitzer 2024-07-08 09:04:59 -04:00 committed by GitHub
parent bef335c631
commit 6767aaed1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 383 additions and 609 deletions

View file

@ -2,7 +2,10 @@ class Money
include Comparable, Arithmetic
include ActiveModel::Validations
attr_reader :amount, :currency
class ConversionError < StandardError
end
attr_reader :amount, :currency, :store
validate :source_must_be_of_known_type
@ -16,20 +19,27 @@ class Money
end
end
def initialize(obj, currency = Money.default_currency)
def initialize(obj, currency = Money.default_currency, store: ExchangeRate)
@source = obj
@amount = obj.is_a?(Money) ? obj.amount : BigDecimal(obj.to_s)
@currency = obj.is_a?(Money) ? obj.currency : Money::Currency.new(currency)
@store = store
validate!
end
# TODO: Replace with injected rate store
def exchange_to(other_currency, date = Date.current)
if currency == Money::Currency.new(other_currency)
def exchange_to(other_currency, date: Date.current, fallback_rate: nil)
iso_code = currency.iso_code
other_iso_code = Money::Currency.new(other_currency).iso_code
if iso_code == other_iso_code
self
elsif rate = ExchangeRate.find_rate(from: currency, to: other_currency, date: date)
Money.new(amount * rate.rate, other_currency)
else
exchange_rate = store.find_rate(from: iso_code, to: other_iso_code, date: date)&.rate || fallback_rate
raise ConversionError.new("Couldn't find exchange rate from #{iso_code} to #{other_iso_code} on #{date}") unless exchange_rate
Money.new(amount * exchange_rate, other_iso_code)
end
end