2024-07-10 11:22:59 -04:00
|
|
|
class Account::Balance::Syncer
|
|
|
|
def initialize(account, start_date: nil)
|
|
|
|
@account = account
|
2024-10-18 14:37:42 -04:00
|
|
|
@provided_start_date = start_date
|
2024-07-10 11:22:59 -04:00
|
|
|
@sync_start_date = calculate_sync_start_date(start_date)
|
2024-10-18 14:37:42 -04:00
|
|
|
@loader = Account::Balance::Loader.new(account)
|
|
|
|
@converter = Account::Balance::Converter.new(account, sync_start_date)
|
|
|
|
@calculator = Account::Balance::Calculator.new(account, sync_start_date)
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
2024-10-18 14:37:42 -04:00
|
|
|
daily_balances = calculator.calculate(is_partial_sync: is_partial_sync?)
|
|
|
|
daily_balances += converter.convert(daily_balances) if account.currency != account.family.currency
|
2024-07-10 11:22:59 -04:00
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
loader.load(daily_balances, account_start_date)
|
2024-08-16 12:13:48 -04:00
|
|
|
rescue Money::ConversionError => e
|
|
|
|
account.observe_missing_exchange_rates(from: e.from_currency, to: e.to_currency, dates: [ e.date ])
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
attr_reader :sync_start_date, :provided_start_date, :account, :loader, :converter, :calculator
|
2024-07-10 11:22:59 -04:00
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
def account_start_date
|
|
|
|
@account_start_date ||= begin
|
|
|
|
oldest_entry = account.entries.chronological.first
|
2024-07-10 11:22:59 -04:00
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
return Date.current unless oldest_entry.present?
|
2024-07-10 11:22:59 -04:00
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
if oldest_entry.account_valuation?
|
|
|
|
oldest_entry.date
|
|
|
|
else
|
|
|
|
oldest_entry.date - 1.day
|
|
|
|
end
|
|
|
|
end
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
def calculate_sync_start_date(provided_start_date)
|
|
|
|
return provided_start_date if provided_start_date.present? && prior_balance_available?(provided_start_date)
|
2024-07-10 11:22:59 -04:00
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
account_start_date
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
def prior_balance_available?(date)
|
|
|
|
account.balances.find_by(currency: account.currency, date: date - 1.day).present?
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
2024-10-18 14:37:42 -04:00
|
|
|
def is_partial_sync?
|
|
|
|
sync_start_date == provided_start_date && sync_start_date < Date.current
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
end
|