1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-10 07:55:21 +02:00

Remove unnecessary currency conversion during sync

This commit is contained in:
Zach Gollwitzer 2025-03-06 14:28:41 -05:00
parent 45187d855e
commit 52730df177
2 changed files with 8 additions and 64 deletions

View file

@ -21,11 +21,6 @@ class Account::Syncer
update_account_info(balances, holdings)
end
unless account.currency == account.family.currency
Rails.logger.info("Converting #{balances.size} balances and #{holdings.size} holdings from #{account.currency} to #{account.family.currency}")
convert_records_to_family_currency(balances, holdings)
end
# Enrich if user opted in or if we're syncing transactions from a Plaid account on the hosted app
if account.family.data_enrichment_enabled? || (plaid_sync? && Rails.application.config.app_mode.hosted?)
Rails.logger.info("Enriching transaction data for account #{account.name}")
@ -78,49 +73,6 @@ class Account::Syncer
calculated_balances
end
def convert_records_to_family_currency(balances, holdings)
from_currency = account.currency
to_currency = account.family.currency
exchange_rates = ExchangeRate.find_rates(
from: from_currency,
to: to_currency,
start_date: balances.min_by(&:date).date
)
converted_balances = balances.map do |balance|
exchange_rate = exchange_rates.find { |er| er.date == balance.date }
next unless exchange_rate.present?
account.balances.build(
date: balance.date,
balance: exchange_rate.rate * balance.balance,
currency: to_currency
)
end.compact
converted_holdings = holdings.map do |holding|
exchange_rate = exchange_rates.find { |er| er.date == holding.date }
next unless exchange_rate.present?
account.holdings.build(
security: holding.security,
date: holding.date,
qty: holding.qty,
price: exchange_rate.rate * holding.price,
amount: exchange_rate.rate * holding.amount,
currency: to_currency
)
end.compact
Account.transaction do
load_balances(converted_balances)
load_holdings(converted_holdings)
end
end
def load_balances(balances = [])
current_time = Time.now
account.balances.upsert_all(

View file

@ -13,35 +13,27 @@ class Account::SyncerTest < ActiveSupport::TestCase
)
end
test "converts foreign account balances and holdings to family currency" do
@account.family.update! currency: "USD"
@account.update! currency: "EUR"
@account.entries.create!(date: 1.day.ago.to_date, currency: "EUR", amount: 500, name: "Buy AAPL", entryable: Account::Trade.new(security: securities(:aapl), qty: 10, price: 50, currency: "EUR"))
ExchangeRate.create!(date: 1.day.ago.to_date, from_currency: "EUR", to_currency: "USD", rate: 1.2)
ExchangeRate.create!(date: Date.current, from_currency: "EUR", to_currency: "USD", rate: 2)
test "persists holdings and balances" do
@account.entries.create!(date: 1.day.ago.to_date, currency: "USD", amount: 1000, name: "Buy AAPL", entryable: Account::Trade.new(security: securities(:aapl), qty: 10, price: 50, currency: "USD"))
Account::ForwardSeriesCalculator.any_instance.expects(:calculate).returns(
[
Account::Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "EUR"),
Account::Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "EUR")
Account::Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "USD"),
Account::Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "USD")
]
)
Account::Holding::ForwardCalculator.any_instance.expects(:calculate).returns(
[
Account::Holding.new(security: securities(:aapl), date: 1.day.ago.to_date, qty: 10, price: 50, amount: 500, currency: "EUR"),
Account::Holding.new(security: securities(:aapl), date: Date.current, qty: 10, price: 50, amount: 500, currency: "EUR")
Account::Holding.new(security: securities(:aapl), date: 1.day.ago.to_date, qty: 10, price: 50, amount: 500, currency: "USD"),
Account::Holding.new(security: securities(:aapl), date: Date.current, qty: 10, price: 50, amount: 500, currency: "USD")
]
)
Account::Syncer.new(@account).run
assert_equal [ 1000, 1000 ], @account.balances.where(currency: "EUR").chronological.map(&:balance)
assert_equal [ 1200, 2000 ], @account.balances.where(currency: "USD").chronological.map(&:balance)
assert_equal [ 500, 500 ], @account.holdings.where(currency: "EUR").chronological.map(&:amount)
assert_equal [ 600, 1000 ], @account.holdings.where(currency: "USD").chronological.map(&:amount)
assert_equal [ 1000, 1000 ], @account.balances.where(currency: "USD").chronological.map(&:balance)
assert_equal [ 500, 500 ], @account.holdings.where(currency: "USD").chronological.map(&:amount)
end
test "purges stale balances and holdings" do