1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-24 15:49:39 +02:00

Basic Account Balance Sync Algorithm (#501)

* Sketch out sync interface

* Add basic account sync algorithm

* Update logic for final balance in series

* Remove start_date concept

* Clean up tests

* Improve clarity of test

* Update app/models/account.rb

Co-authored-by: Rob Zolkos <rob@zolkos.com>
Signed-off-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>

* Update app/models/transaction.rb

Co-authored-by: Rob Zolkos <rob@zolkos.com>
Signed-off-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>

* Update app/models/valuation.rb

Co-authored-by: Rob Zolkos <rob@zolkos.com>
Signed-off-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>

* Re-organize code, simplify job interface

* Consolidate balance calculations

* More cleanup

---------

Signed-off-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
Co-authored-by: Rob Zolkos <rob@zolkos.com>
This commit is contained in:
Zach Gollwitzer 2024-02-29 08:32:52 -05:00 committed by GitHub
parent fb657856a5
commit dbf575c02a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 207 additions and 175 deletions

View file

@ -1 +1,2 @@
checking: {}
savings: {}

View file

@ -5,10 +5,10 @@ generic:
balance: 1200
# Account with only valuations
collectible:
collectable:
family: dylan_family
name: Collectible Account
balance: 500
name: Collectable Account
balance: 550
# Account with only transactions
checking:

View file

@ -25,7 +25,7 @@ checking_four:
checking_five:
name: Netflix
date: <%= 30.days.ago.to_date %>
date: <%= 29.days.ago.to_date %>
amount: 15
account: checking
@ -50,6 +50,6 @@ savings_three:
savings_four:
name: Check Deposit
date: <%= 30.days.ago.to_date %>
date: <%= 29.days.ago.to_date %>
amount: -500
account: savings_with_valuation_overrides

View file

@ -1,18 +1,18 @@
# For collectible account that only has valuations (no transactions)
collectible_one:
# For collectable account that only has valuations (no transactions)
collectable_one:
value: 550
date: <%= 4.days.ago.to_date %>
account: collectible
account: collectable
collectible_two:
collectable_two:
value: 700
date: <%= 12.days.ago.to_date %>
account: collectible
account: collectable
collectible_three:
collectable_three:
value: 400
date: <%= 30.days.ago.to_date %>
account: collectible
account: collectable
# For checking account that has valuations and transactions
savings_one:
@ -24,3 +24,8 @@ savings_two:
value: 19500
date: <%= 12.days.ago.to_date %>
account: savings_with_valuation_overrides
savings_three:
value: 21000
date: <%= 25.days.ago.to_date %>
account: savings_with_valuation_overrides

View file

@ -0,0 +1,50 @@
require "test_helper"
class Account::BalanceCalculatorTest < ActiveSupport::TestCase
test "syncs account with only valuations" do
account = accounts(:collectable)
account.accountable = account_other_assets(:one)
daily_balances = Account::BalanceCalculator.new(account).daily_balances
expected_balances = [
400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
400, 400, 400, 400, 400, 400, 400, 400, 700, 700,
700, 700, 700, 700, 700, 700, 550, 550, 550, 550,
550
].map(&:to_d)
assert_equal expected_balances, daily_balances.map { |b| b[:balance] }
end
test "syncs account with only transactions" do
account = accounts(:checking)
account.accountable = account_depositories(:checking)
daily_balances = Account::BalanceCalculator.new(account).daily_balances
expected_balances = [
4000, 3985, 3985, 3985, 3985, 3985, 3985, 3985, 5060, 5060,
5060, 5060, 5060, 5060, 5060, 5040, 5040, 5040, 5010, 5010,
5010, 5010, 5010, 5010, 5010, 5000, 5000, 5000, 5000, 5000,
5000
].map(&:to_d)
assert_equal expected_balances, daily_balances.map { |b| b[:balance] }
end
test "syncs account with both valuations and transactions" do
account = accounts(:savings_with_valuation_overrides)
account.accountable = account_depositories(:savings)
daily_balances = Account::BalanceCalculator.new(account).daily_balances
expected_balances = [
21250, 21750, 21750, 21750, 21750, 21000, 21000, 21000, 21000, 21000,
21000, 21000, 19000, 19000, 19000, 19000, 19000, 19000, 19500, 19500,
19500, 19500, 19500, 19500, 19500, 19700, 19700, 20500, 20500, 20500,
20000
].map(&:to_d)
assert_equal expected_balances, daily_balances.map { |b| b[:balance] }
end
end

View file

@ -0,0 +1,32 @@
require "test_helper"
class Account::SyncableTest < ActiveSupport::TestCase
test "account has no balances until synced" do
account = accounts(:savings_with_valuation_overrides)
account.accountable = account_depositories(:savings)
assert_equal 0, account.balances.count
end
test "account has balances after syncing" do
account = accounts(:savings_with_valuation_overrides)
account.accountable = account_depositories(:savings)
account.sync
assert_equal 31, account.balances.count
end
test "stale balances are purged after syncing" do
account = accounts(:savings_with_valuation_overrides)
account.accountable = account_depositories(:savings)
# Create old, stale balances that should be purged (since they are before account start date)
account.balances.create!(date: 1.year.ago, balance: 1000)
account.balances.create!(date: 2.years.ago, balance: 2000)
account.balances.create!(date: 3.years.ago, balance: 3000)
account.sync
assert_equal 31, account.balances.count
end
end