1
0
Fork 0
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:
Jakub Kottnauer 2024-05-16 21:57:21 +02:00 committed by GitHub
parent daf7ff8ef4
commit 3d9ff3ad2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 50 additions and 17 deletions

View file

@ -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

View file

@ -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")

View file

@ -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