mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 15:49:39 +02:00
Add start balance to manual accounts (#735)
* Add start_balance to accounts * Add tests * Cleanup * Refactor code and add tests * Update physical cash demo account to be manual * Do not populate start_balance in migration * Cleanup * Review fixes * Revert calc change * Update app/models/exchange_rate.rb Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com> Signed-off-by: Jakub Kottnauer <jk@jakubkottnauer.com> * Add test * Fix syncable bug and update csv tests --------- Signed-off-by: Jakub Kottnauer <jk@jakubkottnauer.com> Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
This commit is contained in:
parent
daf7ff8ef4
commit
3d9ff3ad2a
13 changed files with 50 additions and 17 deletions
|
@ -13,7 +13,7 @@ class Account::Balance::Calculator
|
|||
def calculate
|
||||
prior_balance = implied_start_balance
|
||||
|
||||
calculated_balances = ((@calc_start_date + 1.day)...Date.current).map do |date|
|
||||
calculated_balances = ((@calc_start_date + 1.day)..Date.current).map do |date|
|
||||
valuation = normalized_valuations.find { |v| v["date"] == date }
|
||||
|
||||
if valuation
|
||||
|
@ -30,8 +30,7 @@ class Account::Balance::Calculator
|
|||
|
||||
@daily_balances = [
|
||||
{ date: @calc_start_date, balance: implied_start_balance, currency: @account.currency, updated_at: Time.current },
|
||||
*calculated_balances,
|
||||
{ date: Date.current, balance: @account.balance, currency: @account.currency, updated_at: Time.current } # Last balance must always match "source of truth"
|
||||
*calculated_balances
|
||||
]
|
||||
|
||||
if @account.foreign_currency?
|
||||
|
@ -66,10 +65,7 @@ class Account::Balance::Calculator
|
|||
value = entry.send(value_key)
|
||||
|
||||
if currency != @account.currency
|
||||
rate = ExchangeRate.find_by(base_currency: currency, converted_currency: @account.currency, date: date)
|
||||
raise "Rate for #{currency} to #{@account.currency} not found" unless rate
|
||||
|
||||
value *= rate.rate
|
||||
value = ExchangeRate.convert(value:, from: currency, to: @account.currency, date:)
|
||||
currency = @account.currency
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@ module Account::Syncable
|
|||
calculator.calculate
|
||||
self.balances.upsert_all(calculator.daily_balances, unique_by: :index_account_balances_on_account_id_date_currency_unique)
|
||||
self.balances.where("date < ?", effective_start_date).delete_all
|
||||
new_balance = calculator.daily_balances.select { |b| b[:currency] == self.currency }.last[:balance]
|
||||
self.balance = new_balance
|
||||
self.save!
|
||||
|
||||
update!(status: "ok", last_sync_date: Date.today)
|
||||
rescue => e
|
||||
update!(status: "error")
|
||||
|
|
|
@ -18,5 +18,12 @@ class ExchangeRate < ApplicationRecord
|
|||
def get_rate_series(from, to, date_range)
|
||||
where(base_currency: from, converted_currency: to, date: date_range).order(:date)
|
||||
end
|
||||
|
||||
def convert(value:, from:, to:, date:)
|
||||
rate = ExchangeRate.find_by(base_currency: from, converted_currency: to, date:)
|
||||
raise "Conversion from: #{from} to: #{to} on: #{date} not found" unless rate
|
||||
|
||||
value * rate.rate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue