1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-02 20:15:22 +02:00

Multi-currency support (#425)

* Initial foundational pass at multi-currency

* Default format currency

* More work on currency and exchanging

* Re-build currencies on change

* Currency import/setup

* Background job overhaul + cheaper OXR plan support

* Lint fixes

* Test fixes

* Multi-currency setup instructions

* Allow decimals in the balance field

* Spacing fix for form

---------

Signed-off-by: Josh Pigford <josh@joshpigford.com>
This commit is contained in:
Josh Pigford 2024-02-10 16:18:56 -06:00 committed by GitHub
parent 94f7b4ea8f
commit aa351ae616
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 634 additions and 176 deletions

View file

@ -0,0 +1,19 @@
class ConvertCurrencyJob < ApplicationJob
queue_as :default
def perform(family)
family = Family.find(family.id)
# Convert all account balances to new currency
family.accounts.each do |account|
if account.original_currency == family.currency
account.converted_balance = account.original_balance
account.converted_currency = account.original_currency
else
account.converted_balance = ExchangeRate.convert(account.original_currency, family.currency, account.original_balance)
account.converted_currency = family.currency
end
account.save!
end
end
end

View file

@ -0,0 +1,34 @@
class DailyExchangeRateJob < ApplicationJob
queue_as :default
def perform
app_id = ENV["OPEN_EXCHANGE_APP_ID"]
# Get the last date for which exchange rates were fetched for each currency
last_fetched_dates = ExchangeRate.group(:base_currency).maximum(:date)
# Loop through each currency and fetch exchange rates for each
Currency.all.each do |currency|
last_fetched_date = last_fetched_dates[currency.iso_code] || Date.yesterday
next_day = last_fetched_date + 1.day
response = Faraday.get("https://openexchangerates.org/api/historical/#{next_day}.json") do |req|
req.params["app_id"] = app_id
req.params["base"] = currency.iso_code
req.params["symbols"] = Currency.where.not(iso_code: currency.iso_code).pluck(:iso_code).join(",")
end
if response.success?
rates = JSON.parse(response.body)["rates"]
rates.each do |currency_iso_code, value|
ExchangeRate.find_or_create_by(date: Date.today, base_currency: currency.iso_code, converted_currency: currency_iso_code) do |exchange_rate|
exchange_rate.rate = value
end
puts "#{currency.iso_code} to #{currency_iso_code} on #{Date.today}: #{value}"
end
else
puts "Failed to fetch exchange rates for #{currency.iso_code} on #{Date.today}: #{response.status}"
end
end
end
end