1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-23 15:19:38 +02:00

Account::Entry Delegated Type (namespace updates part 7) (#923)

* Initial entryable models

* Update transfer and tests

* Update transaction controllers and tests

* Update sync process to use new entries model

* Get dashboard working again

* Update transfers, imports, and accounts to use Account::Entry

* Update system tests

* Consolidate transaction management into entries controller

* Add permitted partial key helper

* Move account transactions list to entries controller

* Delegate transaction entries search

* Move transfer relation to entry

* Update bulk transaction management flows to use entries

* Remove test code

* Test fix attempt

* Update demo data script

* Consolidate remaining transaction partials to entries

* Consolidate valuations controller to entries controller

* Lint fix

* Remove unused files, additional cleanup

* Add back valuation creation

* Make migrations fully reversible

* Stale routes cleanup

* Migrations reversible fix

* Move types to entryable concern

* Fix search when no entries found

* Remove more unused code
This commit is contained in:
Zach Gollwitzer 2024-07-01 10:49:43 -04:00 committed by GitHub
parent 320954282a
commit c3314e62d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
105 changed files with 2150 additions and 1576 deletions

View file

@ -0,0 +1,133 @@
require "test_helper"
class Account::EntriesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
@account = accounts(:savings)
@transaction_entry = @account.entries.account_transactions.first
@valuation_entry = @account.entries.account_valuations.first
end
test "should edit valuation entry" do
get edit_account_entry_url(@account, @valuation_entry)
assert_response :success
end
test "should show transaction entry" do
get account_entry_url(@account, @transaction_entry)
assert_response :success
end
test "should show valuation entry" do
get account_entry_url(@account, @valuation_entry)
assert_response :success
end
test "should get list of transaction entries" do
get transaction_account_entries_url(@account)
assert_response :success
end
test "should get list of valuation entries" do
get valuation_account_entries_url(@account)
assert_response :success
end
test "gets new entry by type" do
get new_account_entry_url(@account, entryable_type: "Account::Valuation")
assert_response :success
end
test "should create valuation" do
assert_difference [ "Account::Entry.count", "Account::Valuation.count" ], 1 do
post account_entries_url(@account), params: {
account_entry: {
name: "Manual valuation",
amount: 19800,
date: Date.current,
currency: @account.currency,
entryable_type: "Account::Valuation",
entryable_attributes: {}
}
}
end
assert_equal "Valuation created", flash[:notice]
assert_enqueued_with job: AccountSyncJob
assert_redirected_to account_path(@account)
end
test "error when valuation already exists for date" do
assert_no_difference_in_entries do
post account_entries_url(@account), params: {
account_entry: {
amount: 19800,
date: @valuation_entry.date,
currency: @valuation_entry.currency,
entryable_type: "Account::Valuation",
entryable_attributes: {}
}
}
end
assert_equal "Date has already been taken", flash[:error]
assert_redirected_to account_path(@account)
end
test "can update entry without entryable attributes" do
assert_no_difference_in_entries do
patch account_entry_url(@account, @valuation_entry), params: {
account_entry: {
name: "Updated name"
}
}
end
assert_redirected_to account_entry_url(@account, @valuation_entry)
assert_enqueued_with(job: AccountSyncJob)
end
test "should update transaction entry with entryable attributes" do
assert_no_difference_in_entries do
patch account_entry_url(@account, @transaction_entry), params: {
account_entry: {
name: "Updated name",
date: Date.current,
currency: "USD",
amount: 20,
entryable_type: @transaction_entry.entryable_type,
entryable_attributes: {
id: @transaction_entry.entryable_id,
tag_ids: [ Tag.first.id, Tag.second.id ],
category_id: Category.first.id,
merchant_id: Merchant.first.id,
notes: "test notes",
excluded: false
}
}
}
end
assert_redirected_to account_entry_url(@account, @transaction_entry)
assert_enqueued_with(job: AccountSyncJob)
end
test "should destroy transaction entry" do
[ @transaction_entry, @valuation_entry ].each do |entry|
assert_difference -> { Account::Entry.count } => -1, -> { entry.entryable_class.count } => -1 do
delete account_entry_url(@account, entry)
end
assert_redirected_to account_url(@account)
assert_enqueued_with(job: AccountSyncJob)
end
end
private
# Simple guard to verify that nested attributes are passed the record ID to avoid new creation of record
# See `update_only` option of accepts_nested_attributes_for
def assert_no_difference_in_entries(&block)
assert_no_difference [ "Account::Entry.count", "Account::Transaction.count", "Account::Valuation.count" ], &block
end
end

View file

@ -1,40 +0,0 @@
require "test_helper"
class Account::TransactionsControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
@transaction = account_transactions(:checking_one)
@account = @transaction.account
@recent_transactions = @user.family.transactions.ordered.limit(20).to_a
end
test "should show transaction" do
get account_transaction_url(@transaction.account, @transaction)
assert_response :success
end
test "should update transaction" do
patch account_transaction_url(@transaction.account, @transaction), params: {
account_transaction: {
account_id: @transaction.account_id,
amount: @transaction.amount,
currency: @transaction.currency,
date: @transaction.date,
name: @transaction.name,
tag_ids: [ Tag.first.id, Tag.second.id ]
}
}
assert_redirected_to account_transaction_url(@transaction.account, @transaction)
assert_enqueued_with(job: AccountSyncJob)
end
test "should destroy transaction" do
assert_difference("Account::Transaction.count", -1) do
delete account_transaction_url(@transaction.account, @transaction)
end
assert_redirected_to account_url(@transaction.account)
assert_enqueued_with(job: AccountSyncJob)
end
end

View file

@ -1,71 +0,0 @@
require "test_helper"
class Account::ValuationsControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
@valuation = account_valuations(:savings_one)
@account = @valuation.account
end
test "get valuations for an account" do
get account_valuations_url(@account)
assert_response :success
end
test "new" do
get new_account_valuation_url(@account)
assert_response :success
end
test "should create valuation" do
assert_difference("Account::Valuation.count") do
post account_valuations_url(@account), params: {
account_valuation: {
value: 19800,
date: Date.current
}
}
end
assert_equal "Valuation created", flash[:notice]
assert_enqueued_with job: AccountSyncJob
assert_redirected_to account_path(@account)
end
test "error when valuation already exists for date" do
assert_difference("Account::Valuation.count", 0) do
post account_valuations_url(@account), params: {
account_valuation: {
value: 19800,
date: @valuation.date
}
}
end
assert_equal "Date has already been taken", flash[:error]
assert_redirected_to account_path(@account)
end
test "should update valuation" do
patch account_valuation_url(@account, @valuation), params: {
account_valuation: {
value: 19550,
date: Date.current
}
}
assert_equal "Valuation updated", flash[:notice]
assert_enqueued_with job: AccountSyncJob
assert_redirected_to account_path(@account)
end
test "should destroy valuation" do
assert_difference("Account::Valuation.count", -1) do
delete account_valuation_url(@account, @valuation)
end
assert_equal "Valuation deleted", flash[:notice]
assert_enqueued_with job: AccountSyncJob
assert_redirected_to account_path(@account)
end
end

View file

@ -44,7 +44,7 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest
end
test "should create an account" do
assert_difference [ "Account.count", "Account::Valuation.count" ], 1 do
assert_difference [ "Account.count", "Account::Valuation.count", "Account::Entry.count" ], 1 do
post accounts_path, params: {
account: {
accountable_type: "Depository",

View file

@ -3,8 +3,8 @@ require "test_helper"
class TransactionsControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
@transaction = account_transactions(:checking_one)
@recent_transactions = @user.family.transactions.ordered.limit(20).to_a
@transaction_entry = account_entries(:checking_one)
@recent_transaction_entries = @user.family.entries.account_transactions.reverse_chronological.limit(20).to_a
end
test "should get new" do
@ -13,88 +13,96 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
end
test "prefills account_id" do
get new_transaction_url(account_id: @transaction.account.id)
get new_transaction_url(account_id: @transaction_entry.account.id)
assert_response :success
assert_select "option[selected][value='#{@transaction.account.id}']"
assert_select "option[selected][value='#{@transaction_entry.account.id}']"
end
test "should create transaction" do
account = @user.family.accounts.first
transaction_params = {
entry_params = {
account_id: account.id,
amount: 100.45,
currency: "USD",
date: Date.current,
name: "Test transaction"
name: "Test transaction",
entryable_type: "Account::Transaction",
entryable_attributes: { category_id: categories(:food_and_drink).id }
}
assert_difference("Account::Transaction.count") do
post transactions_url, params: { transaction: transaction_params }
assert_difference [ "Account::Entry.count", "Account::Transaction.count" ], 1 do
post transactions_url, params: { account_entry: entry_params }
end
assert_equal transaction_params[:amount].to_d, Account::Transaction.order(created_at: :desc).first.amount
assert_equal entry_params[:amount].to_d, Account::Transaction.order(created_at: :desc).first.entry.amount
assert_equal "New transaction created successfully", flash[:notice]
assert_enqueued_with(job: AccountSyncJob)
assert_redirected_to account_url(account)
end
test "expenses are positive" do
assert_difference("Account::Transaction.count") do
assert_difference([ "Account::Transaction.count", "Account::Entry.count" ], 1) do
post transactions_url, params: {
transaction: {
account_entry: {
nature: "expense",
account_id: @transaction.account_id,
amount: @transaction.amount,
currency: @transaction.currency,
date: @transaction.date,
name: @transaction.name
account_id: @transaction_entry.account_id,
amount: @transaction_entry.amount,
currency: @transaction_entry.currency,
date: @transaction_entry.date,
name: @transaction_entry.name,
entryable_type: "Account::Transaction",
entryable_attributes: {}
}
}
end
created_transaction = Account::Transaction.order(created_at: :desc).first
created_entry = Account::Entry.order(created_at: :desc).first
assert_redirected_to account_url(@transaction.account)
assert created_transaction.amount.positive?, "Amount should be positive"
assert_redirected_to account_url(@transaction_entry.account)
assert created_entry.amount.positive?, "Amount should be positive"
end
test "incomes are negative" do
assert_difference("Account::Transaction.count") do
post transactions_url, params: {
transaction: {
account_entry: {
nature: "income",
account_id: @transaction.account_id,
amount: @transaction.amount,
currency: @transaction.currency,
date: @transaction.date,
name: @transaction.name
account_id: @transaction_entry.account_id,
amount: @transaction_entry.amount,
currency: @transaction_entry.currency,
date: @transaction_entry.date,
name: @transaction_entry.name,
entryable_type: "Account::Transaction",
entryable_attributes: { category_id: categories(:food_and_drink).id }
}
}
end
created_transaction = Account::Transaction.order(created_at: :desc).first
created_entry = Account::Entry.order(created_at: :desc).first
assert_redirected_to account_url(@transaction.account)
assert created_transaction.amount.negative?, "Amount should be negative"
assert_redirected_to account_url(@transaction_entry.account)
assert created_entry.amount.negative?, "Amount should be negative"
end
test "should get paginated index with most recent transactions first" do
get transactions_url
get transactions_url(per_page: 10)
assert_response :success
@recent_transactions.first(10).each do |transaction|
@recent_transaction_entries.first(10).each do |transaction|
assert_dom "#" + dom_id(transaction), count: 1
end
end
test "transaction count represents filtered total" do
get transactions_url
assert_dom "#total-transactions", count: 1, text: @user.family.transactions.select { |t| t.currency == "USD" }.count.to_s
get transactions_url(per_page: 10)
assert_dom "#total-transactions", count: 1, text: @user.family.entries.account_transactions.select { |t| t.currency == "USD" }.count.to_s
new_transaction = @user.family.accounts.first.transactions.create! \
new_transaction = @user.family.accounts.first.entries.create! \
entryable: Account::Transaction.new,
name: "Transaction to search for",
date: Date.current,
amount: 0
amount: 0,
currency: "USD"
get transactions_url(q: { search: new_transaction.name })
@ -104,28 +112,30 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
end
test "can navigate to paginated result" do
get transactions_url(page: 2)
get transactions_url(page: 2, per_page: 10)
assert_response :success
@recent_transactions[10, 10].select { |t| t.transfer_id == nil }.each do |transaction|
visible_transaction_entries = @recent_transaction_entries[10, 10].reject { |e| e.transfer.present? }
visible_transaction_entries.each do |transaction|
assert_dom "#" + dom_id(transaction), count: 1
end
end
test "loads last page when page is out of range" do
user_oldest_transaction = @user.family.transactions.ordered.reject(&:transfer?).last
user_oldest_transaction_entry = @user.family.entries.account_transactions.chronological.first
get transactions_url(page: 9999999999)
assert_response :success
assert_dom "#" + dom_id(user_oldest_transaction), count: 1
assert_dom "#" + dom_id(user_oldest_transaction_entry), count: 1
end
test "can destroy many transactions at once" do
delete_count = 10
assert_difference("Account::Transaction.count", -delete_count) do
assert_difference([ "Account::Transaction.count", "Account::Entry.count" ], -delete_count) do
post bulk_delete_transactions_url, params: {
bulk_delete: {
transaction_ids: @recent_transactions.first(delete_count).pluck(:id)
entry_ids: @recent_transaction_entries.first(delete_count).pluck(:id)
}
}
end
@ -135,36 +145,41 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
end
test "can update many transactions at once" do
transactions = @user.family.transactions.ordered.limit(20)
transactions = @user.family.entries.account_transactions.reverse_chronological.limit(20)
transactions.each do |transaction|
transaction.update! \
excluded: false,
category_id: Category.first.id,
merchant_id: Merchant.first.id,
notes: "Starting note"
date: Date.current,
entryable_attributes: {
id: transaction.account_transaction.id,
category_id: Category.first.id,
merchant_id: Merchant.first.id,
notes: "Starting note"
}
end
post bulk_update_transactions_url, params: {
bulk_update: {
date: Date.current,
transaction_ids: transactions.map(&:id),
excluded: true,
category_id: Category.second.id,
merchant_id: Merchant.second.id,
notes: "Updated note"
assert_difference [ "Account::Entry.count", "Account::Transaction.count" ], 0 do
post bulk_update_transactions_url, params: {
bulk_update: {
entry_ids: transactions.map(&:id),
date: 1.day.ago.to_date,
category_id: Category.second.id,
merchant_id: Merchant.second.id,
notes: "Updated note"
}
}
}
end
assert_redirected_to transactions_url
assert_equal "#{transactions.count} transactions updated", flash[:notice]
transactions.reload.each do |transaction|
assert_equal Date.current, transaction.date
assert transaction.excluded
assert_equal Category.second, transaction.category
assert_equal Merchant.second, transaction.merchant
assert_equal "Updated note", transaction.notes
transactions.reload
transactions.each do |transaction|
assert_equal 1.day.ago.to_date, transaction.date
assert_equal Category.second, transaction.account_transaction.category
assert_equal Merchant.second, transaction.account_transaction.merchant
assert_equal "Updated note", transaction.account_transaction.notes
end
end
end

323
test/fixtures/account/entries.yml vendored Normal file
View file

@ -0,0 +1,323 @@
# Checking account transactions
checking_one:
name: Starbucks
date: <%= 5.days.ago.to_date %>
amount: 10
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_one
checking_two:
name: Chipotle
date: <%= 12.days.ago.to_date %>
amount: 30
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_two
checking_three:
name: Amazon
date: <%= 15.days.ago.to_date %>
amount: 20
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_three
checking_four:
name: Paycheck
date: <%= 22.days.ago.to_date %>
amount: -1075
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_four
checking_five:
name: Netflix
date: <%= 29.days.ago.to_date %>
amount: 15
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_five
checking_six_payment:
name: Payment to Credit Card
date: <%= 29.days.ago.to_date %>
amount: 100
account: checking
currency: USD
entryable_type: Account::Transaction
entryable: checking_six_payment
marked_as_transfer: true
transfer: credit_card_payment
checking_seven_transfer:
name: Transfer to Savings
date: <%= 30.days.ago.to_date %>
amount: 250
account: checking
currency: USD
marked_as_transfer: true
transfer: savings_transfer
entryable_type: Account::Transaction
entryable: checking_seven_transfer
checking_eight_external_payment:
name: Transfer TO external CC account (owned by user but not known to app)
date: <%= 30.days.ago.to_date %>
amount: 800
account: checking
currency: USD
marked_as_transfer: true
entryable_type: Account::Transaction
entryable: checking_eight_external_payment
checking_nine_external_transfer:
name: Transfer FROM external investing account (owned by user but not known to app)
date: <%= 31.days.ago.to_date %>
amount: -200
account: checking
currency: USD
marked_as_transfer: true
entryable_type: Account::Transaction
entryable: checking_nine_external_transfer
savings_one:
name: Interest Received
date: <%= 5.days.ago.to_date %>
amount: -200
account: savings
currency: USD
entryable_type: Account::Transaction
entryable: savings_one
savings_two:
name: Check Deposit
date: <%= 12.days.ago.to_date %>
amount: -50
account: savings
currency: USD
entryable_type: Account::Transaction
entryable: savings_two
savings_three:
name: Withdrawal
date: <%= 18.days.ago.to_date %>
amount: 2000
account: savings
currency: USD
entryable_type: Account::Transaction
entryable: savings_three
savings_four:
name: Check Deposit
date: <%= 29.days.ago.to_date %>
amount: -500
account: savings
currency: USD
entryable_type: Account::Transaction
entryable: savings_four
savings_five_transfer:
name: Received Transfer from Checking Account
date: <%= 31.days.ago.to_date %>
amount: -250
account: savings
currency: USD
marked_as_transfer: true
transfer: savings_transfer
entryable_type: Account::Transaction
entryable: savings_five_transfer
credit_card_one:
name: Starbucks
date: <%= 5.days.ago.to_date %>
amount: 10
account: credit_card
currency: USD
entryable_type: Account::Transaction
entryable: credit_card_one
credit_card_two:
name: Chipotle
date: <%= 12.days.ago.to_date %>
amount: 30
account: credit_card
currency: USD
entryable_type: Account::Transaction
entryable: credit_card_two
credit_card_three:
name: Amazon
date: <%= 15.days.ago.to_date %>
amount: 20
account: credit_card
currency: USD
entryable_type: Account::Transaction
entryable: credit_card_three
credit_card_four_payment:
name: Received CC Payment from Checking Account
date: <%= 31.days.ago.to_date %>
amount: -100
account: credit_card
currency: USD
marked_as_transfer: true
transfer: credit_card_payment
entryable_type: Account::Transaction
entryable: credit_card_four_payment
eur_checking_one:
name: Check
date: <%= 9.days.ago.to_date %>
amount: -50
currency: EUR
account: eur_checking
entryable_type: Account::Transaction
entryable: eur_checking_one
eur_checking_two:
name: Shopping trip
date: <%= 19.days.ago.to_date %>
amount: 100
currency: EUR
account: eur_checking
entryable_type: Account::Transaction
entryable: eur_checking_two
eur_checking_three:
name: Check
date: <%= 31.days.ago.to_date %>
amount: -200
currency: EUR
account: eur_checking
entryable_type: Account::Transaction
entryable: eur_checking_three
multi_currency_one:
name: Outflow 1
date: <%= 4.days.ago.to_date %>
amount: 800
currency: EUR
account: multi_currency
entryable_type: Account::Transaction
entryable: multi_currency_one
multi_currency_two:
name: Inflow 1
date: <%= 9.days.ago.to_date %>
amount: -50
currency: USD
account: multi_currency
entryable_type: Account::Transaction
entryable: multi_currency_two
multi_currency_three:
name: Outflow 2
date: <%= 19.days.ago.to_date %>
amount: 110.85
currency: EUR
account: multi_currency
entryable_type: Account::Transaction
entryable: multi_currency_three
multi_currency_four:
name: Inflow 2
date: <%= 29.days.ago.to_date %>
amount: -200
currency: USD
account: multi_currency
entryable_type: Account::Transaction
entryable: multi_currency_four
collectable_one_valuation:
amount: 550
date: <%= 4.days.ago.to_date %>
account: collectable
currency: USD
entryable_type: Account::Valuation
entryable: collectable_one
collectable_two_valuation:
amount: 700
date: <%= 12.days.ago.to_date %>
account: collectable
currency: USD
entryable_type: Account::Valuation
entryable: collectable_two
collectable_three_valuation:
amount: 400
date: <%= 31.days.ago.to_date %>
account: collectable
currency: USD
entryable_type: Account::Valuation
entryable: collectable_three
iou_one_valuation:
amount: 200
date: <%= 31.days.ago.to_date %>
account: iou
currency: USD
entryable_type: Account::Valuation
entryable: iou_one
multi_currency_one_valuation:
amount: 10200
date: <%= 31.days.ago.to_date %>
account: multi_currency
currency: USD
entryable_type: Account::Valuation
entryable: multi_currency_one
savings_one_valuation:
amount: 19500
date: <%= 12.days.ago.to_date %>
account: savings
currency: USD
entryable_type: Account::Valuation
entryable: savings_one
savings_two_valuation:
amount: 21000
date: <%= 25.days.ago.to_date %>
account: savings
currency: USD
entryable_type: Account::Valuation
entryable: savings_two
brokerage_one_valuation:
amount: 10000
date: <%= 31.days.ago.to_date %>
account: brokerage
currency: USD
entryable_type: Account::Valuation
entryable: brokerage_one
mortgage_loan_one_valuation:
amount: 500000
date: <%= 31.days.ago.to_date %>
account: mortgage_loan
currency: USD
entryable_type: Account::Valuation
entryable: mortgage_loan_one
house_one_valuation:
amount: 550000
date: <%= 31.days.ago.to_date %>
account: house
currency: USD
entryable_type: Account::Valuation
entryable: house_one
car_one_valuation:
amount: 18000
date: <%= 31.days.ago.to_date %>
account: car
currency: USD
entryable_type: Account::Valuation
entryable: car_one

View file

@ -1,200 +1,60 @@
# Checking account transactions
checking_one:
name: Starbucks
date: <%= 5.days.ago.to_date %>
amount: 10
account: checking
category: food_and_drink
currency: USD
checking_two:
name: Chipotle
date: <%= 12.days.ago.to_date %>
amount: 30
account: checking
category: food_and_drink
currency: USD
checking_three:
name: Amazon
date: <%= 15.days.ago.to_date %>
amount: 20
account: checking
currency: USD
merchant: amazon
checking_four:
name: Paycheck
date: <%= 22.days.ago.to_date %>
amount: -1075
account: checking
category: income
currency: USD
checking_five:
name: Netflix
date: <%= 29.days.ago.to_date %>
amount: 15
account: checking
currency: USD
merchant: netflix
checking_six_payment:
name: Payment to Credit Card
date: <%= 29.days.ago.to_date %>
amount: 100
account: checking
currency: USD
marked_as_transfer: true
transfer: credit_card_payment
checking_six_payment: { }
checking_seven_transfer:
name: Transfer to Savings
date: <%= 30.days.ago.to_date %>
amount: 250
account: checking
currency: USD
marked_as_transfer: true
transfer: savings_transfer
checking_seven_transfer: { }
checking_eight_external_payment:
name: Transfer TO external CC account (owned by user but not known to app)
date: <%= 30.days.ago.to_date %>
amount: 800
account: checking
currency: USD
marked_as_transfer: true
checking_eight_external_payment: { }
checking_nine_external_transfer:
name: Transfer FROM external investing account (owned by user but not known to app)
date: <%= 30.days.ago.to_date %>
amount: -200
account: checking
currency: USD
marked_as_transfer: true
checking_nine_external_transfer: { }
# Savings account that has transactions and valuation overrides
savings_one:
name: Interest Received
date: <%= 5.days.ago.to_date %>
amount: -200
account: savings
category: income
currency: USD
savings_two:
name: Check Deposit
date: <%= 12.days.ago.to_date %>
amount: -50
account: savings
category: income
currency: USD
savings_three:
name: Withdrawal
date: <%= 18.days.ago.to_date %>
amount: 2000
account: savings
currency: USD
savings_three: { }
savings_four:
name: Check Deposit
date: <%= 29.days.ago.to_date %>
amount: -500
account: savings
category: income
currency: USD
savings_five_transfer:
name: Received Transfer from Checking Account
date: <%= 30.days.ago.to_date %>
amount: -250
account: savings
currency: USD
marked_as_transfer: true
transfer: savings_transfer
savings_five_transfer: { }
# Credit card account transactions
credit_card_one:
name: Starbucks
date: <%= 5.days.ago.to_date %>
amount: 10
account: credit_card
category: food_and_drink
currency: USD
credit_card_two:
name: Chipotle
date: <%= 12.days.ago.to_date %>
amount: 30
account: credit_card
category: food_and_drink
currency: USD
credit_card_three:
name: Amazon
date: <%= 15.days.ago.to_date %>
amount: 20
account: credit_card
currency: USD
merchant: amazon
credit_card_four_payment:
name: Received CC Payment from Checking Account
date: <%= 30.days.ago.to_date %>
amount: -100
account: credit_card
currency: USD
marked_as_transfer: true
transfer: credit_card_payment
credit_card_four_payment: { }
# eur_checking transactions
eur_checking_one:
name: Check
date: <%= 9.days.ago.to_date %>
amount: -50
currency: EUR
account: eur_checking
eur_checking_two:
name: Shopping trip
date: <%= 19.days.ago.to_date %>
amount: 100
currency: EUR
account: eur_checking
eur_checking_three:
name: Check
date: <%= 30.days.ago.to_date %>
amount: -200
currency: EUR
account: eur_checking
eur_checking_one: { }
eur_checking_two: { }
eur_checking_three: { }
# multi_currency transactions
multi_currency_one:
name: Outflow 1
date: <%= 4.days.ago.to_date %>
amount: 800
currency: EUR
account: multi_currency
multi_currency_two:
name: Inflow 1
date: <%= 9.days.ago.to_date %>
amount: -50
currency: USD
account: multi_currency
multi_currency_three:
name: Outflow 2
date: <%= 19.days.ago.to_date %>
amount: 110.85
currency: EUR
account: multi_currency
multi_currency_four:
name: Inflow 2
date: <%= 29.days.ago.to_date %>
amount: -200
currency: USD
account: multi_currency
multi_currency_one: { }
multi_currency_two: { }
multi_currency_three: { }
multi_currency_four: { }

View file

@ -1,55 +1,18 @@
# For collectable account that only has valuations (no transactions)
collectable_one:
value: 550
date: <%= 4.days.ago.to_date %>
account: collectable
collectable_one: { }
collectable_two: { }
collectable_three: { }
collectable_two:
value: 700
date: <%= 12.days.ago.to_date %>
account: collectable
iou_one: { }
collectable_three:
value: 400
date: <%= 31.days.ago.to_date %>
account: collectable
multi_currency_one: { }
iou_one:
value: 200
date: <%= 31.days.ago.to_date %>
account: iou
savings_one: { }
savings_two: { }
multi_currency_one:
value: 10200
date: <%= 31.days.ago.to_date %>
account: multi_currency
brokerage_one: { }
savings_one:
value: 19500
date: <%= 12.days.ago.to_date %>
account: savings
mortgage_loan_one: { }
savings_two:
value: 21000
date: <%= 25.days.ago.to_date %>
account: savings
house_one: { }
brokerage_one:
value: 10000
date: <%= 31.days.ago.to_date %>
account: brokerage
mortgage_loan_one:
value: 500000
date: <%= 31.days.ago.to_date %>
account: mortgage_loan
house_one:
value: 550000
date: <%= 31.days.ago.to_date %>
account: house
car_one:
value: 18000
date: <%= 31.days.ago.to_date %>
account: car
car_one: { }

View file

@ -1,33 +1,33 @@
date_offset,collectable,iou,checking,credit_card,savings,eur_checking_eur,eur_checking_usd,multi_currency,brokerage,mortgage_loan,house,car,net_worth,assets,liabilities,depositories,investments,loans,credits,properties,vehicles,other_assets,other_liabilities,spending,income,rolling_spend,rolling_income,savings_rate
31,400.00,200.00,4950.00,1040.00,20700.00,11850.00,13018.41,10200.00,10000.00,500000.00,550000.00,18000.00,126028.41,627268.41,501240.00,48868.41,10000.00,500000.00,1040.00,550000.00,18000.00,400.00,200.00,0.00,0.00,0.00,0.00,0.0000
30,400.00,200.00,4100.00,940.00,20950.00,12050.00,13165.83,10200.00,10000.00,500000.00,550000.00,18000.00,125675.83,626815.83,501140.00,48415.83,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,218.52,0.00,218.52,1.0000
29,400.00,200.00,3985.00,940.00,21450.00,12050.00,13182.70,10400.00,10000.00,500000.00,550000.00,18000.00,126277.70,627417.70,501140.00,49017.70,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,15.00,700.00,15.00,918.52,0.9837
28,400.00,200.00,3985.00,940.00,21450.00,12050.00,13194.75,10400.00,10000.00,500000.00,550000.00,18000.00,126289.75,627429.75,501140.00,49029.75,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
27,400.00,200.00,3985.00,940.00,21450.00,12050.00,13132.09,10400.00,10000.00,500000.00,550000.00,18000.00,126227.09,627367.09,501140.00,48967.09,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
26,400.00,200.00,3985.00,940.00,21450.00,12050.00,13083.89,10400.00,10000.00,500000.00,550000.00,18000.00,126178.89,627318.89,501140.00,48918.89,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
25,400.00,200.00,3985.00,940.00,21000.00,12050.00,13081.48,10400.00,10000.00,500000.00,550000.00,18000.00,125726.48,626866.48,501140.00,48466.48,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
24,400.00,200.00,3985.00,940.00,21000.00,12050.00,13062.20,10400.00,10000.00,500000.00,550000.00,18000.00,125707.20,626847.20,501140.00,48447.20,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
23,400.00,200.00,3985.00,940.00,21000.00,12050.00,13022.44,10400.00,10000.00,500000.00,550000.00,18000.00,125667.44,626807.44,501140.00,48407.44,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,918.52,0.9837
22,400.00,200.00,5060.00,940.00,21000.00,12050.00,13061.00,10400.00,10000.00,500000.00,550000.00,18000.00,126781.00,627921.00,501140.00,49521.00,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,1075.00,15.00,1993.52,0.9925
21,400.00,200.00,5060.00,940.00,21000.00,12050.00,13068.23,10400.00,10000.00,500000.00,550000.00,18000.00,126788.23,627928.23,501140.00,49528.23,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,1993.52,0.9925
20,400.00,200.00,5060.00,940.00,21000.00,12050.00,13079.07,10400.00,10000.00,500000.00,550000.00,18000.00,126799.07,627939.07,501140.00,49539.07,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,1993.52,0.9925
19,400.00,200.00,5060.00,940.00,21000.00,11950.00,12932.29,10280.04,10000.00,500000.00,550000.00,18000.00,126532.33,627672.33,501140.00,49272.33,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,228.18,0.00,243.18,1993.52,0.8780
18,400.00,200.00,5060.00,940.00,19000.00,11950.00,12934.68,10280.04,10000.00,500000.00,550000.00,18000.00,124534.72,625674.72,501140.00,47274.72,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,2000.00,0.00,2243.18,1993.52,-0.1252
17,400.00,200.00,5060.00,940.00,19000.00,11950.00,12927.51,10280.04,10000.00,500000.00,550000.00,18000.00,124527.55,625667.55,501140.00,47267.55,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2243.18,1993.52,-0.1252
16,400.00,200.00,5060.00,940.00,19000.00,11950.00,12916.76,10280.04,10000.00,500000.00,550000.00,18000.00,124516.79,625656.79,501140.00,47256.79,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2243.18,1993.52,-0.1252
15,400.00,200.00,5040.00,960.00,19000.00,11950.00,12882.10,10280.04,10000.00,500000.00,550000.00,18000.00,124442.14,625602.14,501160.00,47202.14,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,40.00,0.00,2283.18,1993.52,-0.1453
14,400.00,200.00,5040.00,960.00,19000.00,11950.00,12879.71,10280.04,10000.00,500000.00,550000.00,18000.00,124439.75,625599.75,501160.00,47199.75,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2283.18,1993.52,-0.1453
13,400.00,200.00,5040.00,960.00,19000.00,11950.00,12873.74,10280.04,10000.00,500000.00,550000.00,18000.00,124433.77,625593.77,501160.00,47193.77,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2283.18,1993.52,-0.1453
12,700.00,200.00,5010.00,990.00,19500.00,11950.00,12821.16,10280.04,10000.00,500000.00,550000.00,18000.00,125121.19,626311.19,501190.00,47611.19,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,60.00,50.00,2343.18,2043.52,-0.1466
11,700.00,200.00,5010.00,990.00,19500.00,11950.00,12797.26,10280.04,10000.00,500000.00,550000.00,18000.00,125097.29,626287.29,501190.00,47587.29,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2043.52,-0.1466
10,700.00,200.00,5010.00,990.00,19500.00,11950.00,12873.74,10280.04,10000.00,500000.00,550000.00,18000.00,125173.77,626363.77,501190.00,47663.77,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2043.52,-0.1466
9,700.00,200.00,5010.00,990.00,19500.00,12000.00,12939.60,10330.04,10000.00,500000.00,550000.00,18000.00,125289.64,626479.64,501190.00,47779.64,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,103.92,2343.18,2147.44,-0.0912
8,700.00,200.00,5010.00,990.00,19500.00,12000.00,12933.60,10330.04,10000.00,500000.00,550000.00,18000.00,125283.64,626473.64,501190.00,47773.64,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2147.44,-0.0912
7,700.00,200.00,5010.00,990.00,19500.00,12000.00,12928.80,10330.04,10000.00,500000.00,550000.00,18000.00,125278.84,626468.84,501190.00,47768.84,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2147.44,-0.0912
6,700.00,200.00,5010.00,990.00,19500.00,12000.00,12906.00,10330.04,10000.00,500000.00,550000.00,18000.00,125256.04,626446.04,501190.00,47746.04,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2147.44,-0.0912
5,700.00,200.00,5000.00,1000.00,19700.00,12000.00,12891.60,10330.04,10000.00,500000.00,550000.00,18000.00,125421.64,626621.64,501200.00,47921.64,10000.00,500000.00,1000.00,550000.00,18000.00,700.00,200.00,20.00,200.00,2363.18,2347.44,-0.0067
4,550.00,200.00,5000.00,1000.00,19700.00,12000.00,12945.60,9467.00,10000.00,500000.00,550000.00,18000.00,124462.60,625662.60,501200.00,47112.60,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,863.04,0.00,3226.22,2347.44,-0.3744
3,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13046.40,9467.00,10000.00,500000.00,550000.00,18000.00,124563.40,625763.40,501200.00,47213.40,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2347.44,-0.3744
2,550.00,200.00,5000.00,1000.00,19700.00,12000.00,12982.80,9467.00,10000.00,500000.00,550000.00,18000.00,124499.80,625699.80,501200.00,47149.80,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2347.44,-0.3744
1,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13014.00,9467.00,10000.00,500000.00,550000.00,18000.00,124531.00,625731.00,501200.00,47181.00,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2347.44,-0.3744
0,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13000.80,9467.00,10000.00,500000.00,550000.00,18000.00,124517.80,625717.80,501200.00,47167.80,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2347.44,-0.3744
31,400.00,200.00,5150.00,940.00,20950.00,12050.00,13238.13,10200.00,10000.00,500000.00,550000.00,18000.00,126798.13,627938.13,501140.00,49538.13,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,219.72,0.00,0.00,0.0000
30,400.00,200.00,4100.00,940.00,20950.00,12050.00,13165.83,10200.00,10000.00,500000.00,550000.00,18000.00,125675.83,626815.83,501140.00,48415.83,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,0.00,219.72,1.0000
29,400.00,200.00,3985.00,940.00,21450.00,12050.00,13182.70,10400.00,10000.00,500000.00,550000.00,18000.00,126277.70,627417.70,501140.00,49017.70,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,15.00,700.00,15.00,919.72,0.9837
28,400.00,200.00,3985.00,940.00,21450.00,12050.00,13194.75,10400.00,10000.00,500000.00,550000.00,18000.00,126289.75,627429.75,501140.00,49029.75,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
27,400.00,200.00,3985.00,940.00,21450.00,12050.00,13132.09,10400.00,10000.00,500000.00,550000.00,18000.00,126227.09,627367.09,501140.00,48967.09,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
26,400.00,200.00,3985.00,940.00,21450.00,12050.00,13083.89,10400.00,10000.00,500000.00,550000.00,18000.00,126178.89,627318.89,501140.00,48918.89,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
25,400.00,200.00,3985.00,940.00,21000.00,12050.00,13081.48,10400.00,10000.00,500000.00,550000.00,18000.00,125726.48,626866.48,501140.00,48466.48,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
24,400.00,200.00,3985.00,940.00,21000.00,12050.00,13062.20,10400.00,10000.00,500000.00,550000.00,18000.00,125707.20,626847.20,501140.00,48447.20,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
23,400.00,200.00,3985.00,940.00,21000.00,12050.00,13022.44,10400.00,10000.00,500000.00,550000.00,18000.00,125667.44,626807.44,501140.00,48407.44,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,919.72,0.9837
22,400.00,200.00,5060.00,940.00,21000.00,12050.00,13061.00,10400.00,10000.00,500000.00,550000.00,18000.00,126781.00,627921.00,501140.00,49521.00,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,1075.00,15.00,1994.72,0.9925
21,400.00,200.00,5060.00,940.00,21000.00,12050.00,13068.23,10400.00,10000.00,500000.00,550000.00,18000.00,126788.23,627928.23,501140.00,49528.23,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,1994.72,0.9925
20,400.00,200.00,5060.00,940.00,21000.00,12050.00,13079.07,10400.00,10000.00,500000.00,550000.00,18000.00,126799.07,627939.07,501140.00,49539.07,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,15.00,1994.72,0.9925
19,400.00,200.00,5060.00,940.00,21000.00,11950.00,12932.29,10280.04,10000.00,500000.00,550000.00,18000.00,126532.33,627672.33,501140.00,49272.33,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,228.18,0.00,243.18,1994.72,0.8781
18,400.00,200.00,5060.00,940.00,19000.00,11950.00,12934.68,10280.04,10000.00,500000.00,550000.00,18000.00,124534.72,625674.72,501140.00,47274.72,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,2000.00,0.00,2243.18,1994.72,-0.1246
17,400.00,200.00,5060.00,940.00,19000.00,11950.00,12927.51,10280.04,10000.00,500000.00,550000.00,18000.00,124527.55,625667.55,501140.00,47267.55,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2243.18,1994.72,-0.1246
16,400.00,200.00,5060.00,940.00,19000.00,11950.00,12916.76,10280.04,10000.00,500000.00,550000.00,18000.00,124516.79,625656.79,501140.00,47256.79,10000.00,500000.00,940.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2243.18,1994.72,-0.1246
15,400.00,200.00,5040.00,960.00,19000.00,11950.00,12882.10,10280.04,10000.00,500000.00,550000.00,18000.00,124442.14,625602.14,501160.00,47202.14,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,40.00,0.00,2283.18,1994.72,-0.1446
14,400.00,200.00,5040.00,960.00,19000.00,11950.00,12879.71,10280.04,10000.00,500000.00,550000.00,18000.00,124439.75,625599.75,501160.00,47199.75,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2283.18,1994.72,-0.1446
13,400.00,200.00,5040.00,960.00,19000.00,11950.00,12873.74,10280.04,10000.00,500000.00,550000.00,18000.00,124433.77,625593.77,501160.00,47193.77,10000.00,500000.00,960.00,550000.00,18000.00,400.00,200.00,0.00,0.00,2283.18,1994.72,-0.1446
12,700.00,200.00,5010.00,990.00,19500.00,11950.00,12821.16,10280.04,10000.00,500000.00,550000.00,18000.00,125121.19,626311.19,501190.00,47611.19,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,60.00,50.00,2343.18,2044.72,-0.1460
11,700.00,200.00,5010.00,990.00,19500.00,11950.00,12797.26,10280.04,10000.00,500000.00,550000.00,18000.00,125097.29,626287.29,501190.00,47587.29,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2044.72,-0.1460
10,700.00,200.00,5010.00,990.00,19500.00,11950.00,12873.74,10280.04,10000.00,500000.00,550000.00,18000.00,125173.77,626363.77,501190.00,47663.77,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2044.72,-0.1460
9,700.00,200.00,5010.00,990.00,19500.00,12000.00,12939.60,10330.04,10000.00,500000.00,550000.00,18000.00,125289.64,626479.64,501190.00,47779.64,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,103.92,2343.18,2148.64,-0.0905
8,700.00,200.00,5010.00,990.00,19500.00,12000.00,12933.60,10330.04,10000.00,500000.00,550000.00,18000.00,125283.64,626473.64,501190.00,47773.64,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2148.64,-0.0905
7,700.00,200.00,5010.00,990.00,19500.00,12000.00,12928.80,10330.04,10000.00,500000.00,550000.00,18000.00,125278.84,626468.84,501190.00,47768.84,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2148.64,-0.0905
6,700.00,200.00,5010.00,990.00,19500.00,12000.00,12906.00,10330.04,10000.00,500000.00,550000.00,18000.00,125256.04,626446.04,501190.00,47746.04,10000.00,500000.00,990.00,550000.00,18000.00,700.00,200.00,0.00,0.00,2343.18,2148.64,-0.0905
5,700.00,200.00,5000.00,1000.00,19700.00,12000.00,12891.60,10330.04,10000.00,500000.00,550000.00,18000.00,125421.64,626621.64,501200.00,47921.64,10000.00,500000.00,1000.00,550000.00,18000.00,700.00,200.00,20.00,200.00,2363.18,2348.64,-0.0062
4,550.00,200.00,5000.00,1000.00,19700.00,12000.00,12945.60,9467.00,10000.00,500000.00,550000.00,18000.00,124462.60,625662.60,501200.00,47112.60,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,863.04,0.00,3226.22,2348.64,-0.3737
3,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13046.40,9467.00,10000.00,500000.00,550000.00,18000.00,124563.40,625763.40,501200.00,47213.40,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2348.64,-0.3737
2,550.00,200.00,5000.00,1000.00,19700.00,12000.00,12982.80,9467.00,10000.00,500000.00,550000.00,18000.00,124499.80,625699.80,501200.00,47149.80,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2348.64,-0.3737
1,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13014.00,9467.00,10000.00,500000.00,550000.00,18000.00,124531.00,625731.00,501200.00,47181.00,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2348.64,-0.3737
0,550.00,200.00,5000.00,1000.00,19700.00,12000.00,13000.80,9467.00,10000.00,500000.00,550000.00,18000.00,124517.80,625717.80,501200.00,47167.80,10000.00,500000.00,1000.00,550000.00,18000.00,550.00,200.00,0.00,0.00,3226.22,2348.64,-0.3737
1 date_offset collectable iou checking credit_card savings eur_checking_eur eur_checking_usd multi_currency brokerage mortgage_loan house car net_worth assets liabilities depositories investments loans credits properties vehicles other_assets other_liabilities spending income rolling_spend rolling_income savings_rate
2 31 400.00 200.00 4950.00 5150.00 1040.00 940.00 20700.00 20950.00 11850.00 12050.00 13018.41 13238.13 10200.00 10000.00 500000.00 550000.00 18000.00 126028.41 126798.13 627268.41 627938.13 501240.00 501140.00 48868.41 49538.13 10000.00 500000.00 1040.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 219.72 0.00 0.00 0.0000
3 30 400.00 200.00 4100.00 940.00 20950.00 12050.00 13165.83 10200.00 10000.00 500000.00 550000.00 18000.00 125675.83 626815.83 501140.00 48415.83 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 218.52 0.00 0.00 218.52 219.72 1.0000
4 29 400.00 200.00 3985.00 940.00 21450.00 12050.00 13182.70 10400.00 10000.00 500000.00 550000.00 18000.00 126277.70 627417.70 501140.00 49017.70 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 15.00 700.00 15.00 918.52 919.72 0.9837
5 28 400.00 200.00 3985.00 940.00 21450.00 12050.00 13194.75 10400.00 10000.00 500000.00 550000.00 18000.00 126289.75 627429.75 501140.00 49029.75 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
6 27 400.00 200.00 3985.00 940.00 21450.00 12050.00 13132.09 10400.00 10000.00 500000.00 550000.00 18000.00 126227.09 627367.09 501140.00 48967.09 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
7 26 400.00 200.00 3985.00 940.00 21450.00 12050.00 13083.89 10400.00 10000.00 500000.00 550000.00 18000.00 126178.89 627318.89 501140.00 48918.89 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
8 25 400.00 200.00 3985.00 940.00 21000.00 12050.00 13081.48 10400.00 10000.00 500000.00 550000.00 18000.00 125726.48 626866.48 501140.00 48466.48 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
9 24 400.00 200.00 3985.00 940.00 21000.00 12050.00 13062.20 10400.00 10000.00 500000.00 550000.00 18000.00 125707.20 626847.20 501140.00 48447.20 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
10 23 400.00 200.00 3985.00 940.00 21000.00 12050.00 13022.44 10400.00 10000.00 500000.00 550000.00 18000.00 125667.44 626807.44 501140.00 48407.44 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 918.52 919.72 0.9837
11 22 400.00 200.00 5060.00 940.00 21000.00 12050.00 13061.00 10400.00 10000.00 500000.00 550000.00 18000.00 126781.00 627921.00 501140.00 49521.00 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 1075.00 15.00 1993.52 1994.72 0.9925
12 21 400.00 200.00 5060.00 940.00 21000.00 12050.00 13068.23 10400.00 10000.00 500000.00 550000.00 18000.00 126788.23 627928.23 501140.00 49528.23 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 1993.52 1994.72 0.9925
13 20 400.00 200.00 5060.00 940.00 21000.00 12050.00 13079.07 10400.00 10000.00 500000.00 550000.00 18000.00 126799.07 627939.07 501140.00 49539.07 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 15.00 1993.52 1994.72 0.9925
14 19 400.00 200.00 5060.00 940.00 21000.00 11950.00 12932.29 10280.04 10000.00 500000.00 550000.00 18000.00 126532.33 627672.33 501140.00 49272.33 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 228.18 0.00 243.18 1993.52 1994.72 0.8780 0.8781
15 18 400.00 200.00 5060.00 940.00 19000.00 11950.00 12934.68 10280.04 10000.00 500000.00 550000.00 18000.00 124534.72 625674.72 501140.00 47274.72 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 2000.00 0.00 2243.18 1993.52 1994.72 -0.1252 -0.1246
16 17 400.00 200.00 5060.00 940.00 19000.00 11950.00 12927.51 10280.04 10000.00 500000.00 550000.00 18000.00 124527.55 625667.55 501140.00 47267.55 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 2243.18 1993.52 1994.72 -0.1252 -0.1246
17 16 400.00 200.00 5060.00 940.00 19000.00 11950.00 12916.76 10280.04 10000.00 500000.00 550000.00 18000.00 124516.79 625656.79 501140.00 47256.79 10000.00 500000.00 940.00 550000.00 18000.00 400.00 200.00 0.00 0.00 2243.18 1993.52 1994.72 -0.1252 -0.1246
18 15 400.00 200.00 5040.00 960.00 19000.00 11950.00 12882.10 10280.04 10000.00 500000.00 550000.00 18000.00 124442.14 625602.14 501160.00 47202.14 10000.00 500000.00 960.00 550000.00 18000.00 400.00 200.00 40.00 0.00 2283.18 1993.52 1994.72 -0.1453 -0.1446
19 14 400.00 200.00 5040.00 960.00 19000.00 11950.00 12879.71 10280.04 10000.00 500000.00 550000.00 18000.00 124439.75 625599.75 501160.00 47199.75 10000.00 500000.00 960.00 550000.00 18000.00 400.00 200.00 0.00 0.00 2283.18 1993.52 1994.72 -0.1453 -0.1446
20 13 400.00 200.00 5040.00 960.00 19000.00 11950.00 12873.74 10280.04 10000.00 500000.00 550000.00 18000.00 124433.77 625593.77 501160.00 47193.77 10000.00 500000.00 960.00 550000.00 18000.00 400.00 200.00 0.00 0.00 2283.18 1993.52 1994.72 -0.1453 -0.1446
21 12 700.00 200.00 5010.00 990.00 19500.00 11950.00 12821.16 10280.04 10000.00 500000.00 550000.00 18000.00 125121.19 626311.19 501190.00 47611.19 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 60.00 50.00 2343.18 2043.52 2044.72 -0.1466 -0.1460
22 11 700.00 200.00 5010.00 990.00 19500.00 11950.00 12797.26 10280.04 10000.00 500000.00 550000.00 18000.00 125097.29 626287.29 501190.00 47587.29 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 0.00 2343.18 2043.52 2044.72 -0.1466 -0.1460
23 10 700.00 200.00 5010.00 990.00 19500.00 11950.00 12873.74 10280.04 10000.00 500000.00 550000.00 18000.00 125173.77 626363.77 501190.00 47663.77 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 0.00 2343.18 2043.52 2044.72 -0.1466 -0.1460
24 9 700.00 200.00 5010.00 990.00 19500.00 12000.00 12939.60 10330.04 10000.00 500000.00 550000.00 18000.00 125289.64 626479.64 501190.00 47779.64 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 103.92 2343.18 2147.44 2148.64 -0.0912 -0.0905
25 8 700.00 200.00 5010.00 990.00 19500.00 12000.00 12933.60 10330.04 10000.00 500000.00 550000.00 18000.00 125283.64 626473.64 501190.00 47773.64 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 0.00 2343.18 2147.44 2148.64 -0.0912 -0.0905
26 7 700.00 200.00 5010.00 990.00 19500.00 12000.00 12928.80 10330.04 10000.00 500000.00 550000.00 18000.00 125278.84 626468.84 501190.00 47768.84 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 0.00 2343.18 2147.44 2148.64 -0.0912 -0.0905
27 6 700.00 200.00 5010.00 990.00 19500.00 12000.00 12906.00 10330.04 10000.00 500000.00 550000.00 18000.00 125256.04 626446.04 501190.00 47746.04 10000.00 500000.00 990.00 550000.00 18000.00 700.00 200.00 0.00 0.00 2343.18 2147.44 2148.64 -0.0912 -0.0905
28 5 700.00 200.00 5000.00 1000.00 19700.00 12000.00 12891.60 10330.04 10000.00 500000.00 550000.00 18000.00 125421.64 626621.64 501200.00 47921.64 10000.00 500000.00 1000.00 550000.00 18000.00 700.00 200.00 20.00 200.00 2363.18 2347.44 2348.64 -0.0067 -0.0062
29 4 550.00 200.00 5000.00 1000.00 19700.00 12000.00 12945.60 9467.00 10000.00 500000.00 550000.00 18000.00 124462.60 625662.60 501200.00 47112.60 10000.00 500000.00 1000.00 550000.00 18000.00 550.00 200.00 863.04 0.00 3226.22 2347.44 2348.64 -0.3744 -0.3737
30 3 550.00 200.00 5000.00 1000.00 19700.00 12000.00 13046.40 9467.00 10000.00 500000.00 550000.00 18000.00 124563.40 625763.40 501200.00 47213.40 10000.00 500000.00 1000.00 550000.00 18000.00 550.00 200.00 0.00 0.00 3226.22 2347.44 2348.64 -0.3744 -0.3737
31 2 550.00 200.00 5000.00 1000.00 19700.00 12000.00 12982.80 9467.00 10000.00 500000.00 550000.00 18000.00 124499.80 625699.80 501200.00 47149.80 10000.00 500000.00 1000.00 550000.00 18000.00 550.00 200.00 0.00 0.00 3226.22 2347.44 2348.64 -0.3744 -0.3737
32 1 550.00 200.00 5000.00 1000.00 19700.00 12000.00 13014.00 9467.00 10000.00 500000.00 550000.00 18000.00 124531.00 625731.00 501200.00 47181.00 10000.00 500000.00 1000.00 550000.00 18000.00 550.00 200.00 0.00 0.00 3226.22 2347.44 2348.64 -0.3744 -0.3737
33 0 550.00 200.00 5000.00 1000.00 19700.00 12000.00 13000.80 9467.00 10000.00 500000.00 550000.00 18000.00 124517.80 625717.80 501200.00 47167.80 10000.00 500000.00 1000.00 550000.00 18000.00 550.00 200.00 0.00 0.00 3226.22 2347.44 2348.64 -0.3744 -0.3737

View file

@ -78,6 +78,6 @@ class Account::Balance::CalculatorTest < ActiveSupport::TestCase
end
def calculated_balances_for(account_key)
Account::Balance::Calculator.new(accounts(account_key)).calculate.daily_balances
Account::Balance::Calculator.new(accounts(account_key)).daily_balances
end
end

View file

@ -0,0 +1,75 @@
require "test_helper"
class Account::EntryTest < ActiveSupport::TestCase
setup do
@entry = account_entries :checking_one
@family = families :dylan_family
end
test "valuations cannot have more than one entry per day" do
new_entry = Account::Entry.new \
entryable: Account::Valuation.new,
date: @entry.date, # invalid
currency: @entry.currency,
amount: @entry.amount
assert new_entry.invalid?
end
test "triggers sync with correct start date when transaction is set to prior date" do
prior_date = @entry.date - 1
@entry.update! date: prior_date
@entry.account.expects(:sync_later).with(prior_date)
@entry.sync_account_later
end
test "triggers sync with correct start date when transaction is set to future date" do
prior_date = @entry.date
@entry.update! date: @entry.date + 1
@entry.account.expects(:sync_later).with(prior_date)
@entry.sync_account_later
end
test "triggers sync with correct start date when transaction deleted" do
prior_entry = account_entries(:checking_two) # 12 days ago
current_entry = account_entries(:checking_one) # 5 days ago
current_entry.destroy!
current_entry.account.expects(:sync_later).with(prior_entry.date)
current_entry.sync_account_later
end
test "can search entries" do
params = { search: "a" }
assert_equal 12, Account::Entry.search(params).size
params = params.merge(categories: [ "Food & Drink" ]) # transaction specific search param
assert_equal 2, Account::Entry.search(params).size
end
test "can calculate total spending for a group of transactions" do
assert_equal Money.new(2135), @family.entries.expense_total("USD")
assert_equal Money.new(1010.85, "EUR"), @family.entries.expense_total("EUR")
end
test "can calculate total income for a group of transactions" do
assert_equal -Money.new(2075), @family.entries.income_total("USD")
assert_equal -Money.new(250, "EUR"), @family.entries.income_total("EUR")
end
# See: https://github.com/maybe-finance/maybe/wiki/vision#signage-of-money
test "transactions with negative amounts are inflows, positive amounts are outflows to an account" do
inflow_transaction = account_entries(:checking_four)
outflow_transaction = account_entries(:checking_five)
assert inflow_transaction.amount < 0
assert inflow_transaction.inflow?
assert outflow_transaction.amount >= 0
assert outflow_transaction.outflow?
end
end

View file

@ -7,6 +7,32 @@ class Account::SyncableTest < ActiveSupport::TestCase
@account = accounts(:savings)
end
test "calculates effective start date of an account" do
assert_equal 31.days.ago.to_date, accounts(:collectable).effective_start_date
assert_equal 31.days.ago.to_date, @account.effective_start_date
end
test "syncs regular account" do
@account.sync
assert_equal "ok", @account.status
assert_equal 32, @account.balances.count
end
test "syncs foreign currency account" do
account = accounts(:eur_checking)
account.sync
assert_equal "ok", account.status
assert_equal 32, account.balances.where(currency: "USD").count
assert_equal 32, account.balances.where(currency: "EUR").count
end
test "syncs multi currency account" do
account = accounts(:multi_currency)
account.sync
assert_equal "ok", account.status
assert_equal 32, account.balances.where(currency: "USD").count
end
test "triggers sync job" do
assert_enqueued_with(job: AccountSyncJob, args: [ @account, Date.current ]) do
@account.sync_later(Date.current)
@ -42,31 +68,26 @@ class Account::SyncableTest < ActiveSupport::TestCase
assert_equal 19500, account.balances.find_by(date: balance_date)[:balance]
end
test "balances before sync start date are not updated after syncing" do
account = accounts(:savings)
balance_date = 10.days.ago
account.balances.create!(date: balance_date, balance: 1000)
account.sync 5.days.ago.to_date
test "can perform a partial sync with a given sync start date" do
# Perform a full sync to populate all balances
@account.sync
assert_equal 1000, account.balances.find_by(date: balance_date)[:balance]
end
# Perform partial sync
sync_start_date = 5.days.ago.to_date
balances_before_sync = @account.balances.to_a
@account.sync sync_start_date
balances_after_sync = @account.reload.balances.to_a
test "balances after sync start date are updated after syncing" do
account = accounts(:savings)
balance_date = 10.days.ago
account.balances.create!(date: balance_date, balance: 1000)
account.sync 20.days.ago.to_date
# Balances on or after should be updated
balances_after_sync.each do |balance_after_sync|
balance_before_sync = balances_before_sync.find { |b| b.date == balance_after_sync.date }
assert_equal 19500, account.balances.find_by(date: balance_date)[:balance]
end
test "balance on the sync date is updated after syncing" do
account = accounts(:savings)
balance_date = 5.days.ago
account.balances.create!(date: balance_date, balance: 1000)
account.sync balance_date.to_date
assert_equal 19700, account.balances.find_by(date: balance_date)[:balance]
if balance_after_sync.date >= sync_start_date
assert balance_before_sync.updated_at < balance_after_sync.updated_at
else
assert_equal balance_before_sync.updated_at, balance_after_sync.updated_at
end
end
end
test "foreign currency account has balances in each currency after syncing" do

View file

@ -1,55 +0,0 @@
require "test_helper"
class Account::TransactionTest < ActiveSupport::TestCase
setup do
@transaction = account_transactions(:checking_one)
@family = families(:dylan_family)
end
# See: https://github.com/maybe-finance/maybe/wiki/vision#signage-of-money
test "negative amounts are inflows, positive amounts are outflows to an account" do
inflow_transaction = account_transactions(:checking_four)
outflow_transaction = account_transactions(:checking_five)
assert inflow_transaction.amount < 0
assert inflow_transaction.inflow?
assert outflow_transaction.amount >= 0
assert outflow_transaction.outflow?
end
test "triggers sync with correct start date when transaction is set to prior date" do
prior_date = @transaction.date - 1
@transaction.update! date: prior_date
@transaction.account.expects(:sync_later).with(prior_date)
@transaction.sync_account_later
end
test "triggers sync with correct start date when transaction is set to future date" do
prior_date = @transaction.date
@transaction.update! date: @transaction.date + 1
@transaction.account.expects(:sync_later).with(prior_date)
@transaction.sync_account_later
end
test "triggers sync with correct start date when transaction deleted" do
prior_transaction = account_transactions(:checking_two) # 12 days ago
current_transaction = account_transactions(:checking_one) # 5 days ago
current_transaction.destroy!
current_transaction.account.expects(:sync_later).with(prior_transaction.date)
current_transaction.sync_account_later
end
test "can calculate total spending for a group of transactions" do
assert_equal Money.new(2135), @family.transactions.expense_total("USD")
assert_equal Money.new(1010.85, "EUR"), @family.transactions.expense_total("EUR")
end
test "can calculate total income for a group of transactions" do
assert_equal -Money.new(2075), @family.transactions.income_total("USD")
assert_equal -Money.new(250, "EUR"), @family.transactions.income_total("EUR")
end
end

View file

@ -3,19 +3,32 @@ require "test_helper"
class Account::TransferTest < ActiveSupport::TestCase
setup do
# Transfers can be posted on different dates
@outflow = accounts(:checking).transactions.create! date: 1.day.ago.to_date, name: "Transfer to Savings", amount: 100, marked_as_transfer: true
@inflow = accounts(:savings).transactions.create! date: Date.current, name: "Transfer from Savings", amount: -100, marked_as_transfer: true
@outflow = accounts(:checking).entries.create! \
date: 1.day.ago.to_date,
name: "Transfer to Savings",
amount: 100,
currency: "USD",
marked_as_transfer: true,
entryable: Account::Transaction.new
@inflow = accounts(:savings).entries.create! \
date: Date.current,
name: "Transfer from Savings",
amount: -100,
currency: "USD",
marked_as_transfer: true,
entryable: Account::Transaction.new
end
test "transfer valid if it has inflow and outflow from different accounts for the same amount" do
transfer = Account::Transfer.create! transactions: [ @inflow, @outflow ]
transfer = Account::Transfer.create! entries: [ @inflow, @outflow ]
assert transfer.valid?
end
test "transfer must have 2 transactions" do
invalid_transfer_1 = Account::Transfer.new transactions: [ @outflow ]
invalid_transfer_2 = Account::Transfer.new transactions: [ @inflow, @outflow, account_transactions(:savings_four) ]
invalid_transfer_1 = Account::Transfer.new entries: [ @outflow ]
invalid_transfer_2 = Account::Transfer.new entries: [ @inflow, @outflow, account_entries(:savings_four) ]
assert invalid_transfer_1.invalid?
assert invalid_transfer_2.invalid?
@ -23,11 +36,24 @@ class Account::TransferTest < ActiveSupport::TestCase
test "transfer cannot have 2 transactions from the same account" do
account = accounts(:checking)
inflow = account.transactions.create! date: Date.current, name: "Inflow", amount: -100
outflow = account.transactions.create! date: Date.current, name: "Outflow", amount: 100
inflow = account.entries.create! \
date: Date.current,
name: "Inflow",
amount: -100,
currency: "USD",
marked_as_transfer: true,
entryable: Account::Transaction.new
outflow = account.entries.create! \
date: Date.current,
name: "Outflow",
amount: 100,
currency: "USD",
marked_as_transfer: true,
entryable: Account::Transaction.new
assert_raise ActiveRecord::RecordInvalid do
Account::Transfer.create! transactions: [ inflow, outflow ]
Account::Transfer.create! entries: [ inflow, outflow ]
end
end
@ -35,7 +61,7 @@ class Account::TransferTest < ActiveSupport::TestCase
@inflow.update! marked_as_transfer: false
assert_raise ActiveRecord::RecordInvalid do
Account::Transfer.create! transactions: [ @inflow, @outflow ]
Account::Transfer.create! entries: [ @inflow, @outflow ]
end
end
@ -43,13 +69,13 @@ class Account::TransferTest < ActiveSupport::TestCase
@outflow.update! amount: 105
assert_raises ActiveRecord::RecordInvalid do
Account::Transfer.create! transactions: [ @inflow, @outflow ]
Account::Transfer.create! entries: [ @inflow, @outflow ]
end
end
test "multi-currency transfer transactions do not have to net to zero" do
@outflow.update! amount: 105, currency: "EUR"
transfer = Account::Transfer.create! transactions: [ @inflow, @outflow ]
transfer = Account::Transfer.create! entries: [ @inflow, @outflow ]
assert transfer.valid?
end

View file

@ -1,39 +0,0 @@
require "test_helper"
class Account::ValuationTest < ActiveSupport::TestCase
setup do
@valuation = account_valuations :savings_one
@family = families :dylan_family
end
test "one valuation per day" do
assert_equal 12.days.ago.to_date, account_valuations(:savings_one).date
invalid_valuation = Account::Valuation.new date: 12.days.ago.to_date, value: 20000
assert invalid_valuation.invalid?
end
test "triggers sync with correct start date when valuation is set to prior date" do
prior_date = @valuation.date - 1
@valuation.update! date: prior_date
@valuation.account.expects(:sync_later).with(prior_date)
@valuation.sync_account_later
end
test "triggers sync with correct start date when valuation is set to future date" do
prior_date = @valuation.date
@valuation.update! date: @valuation.date + 1
@valuation.account.expects(:sync_later).with(prior_date)
@valuation.sync_account_later
end
test "triggers sync with correct start date when valuation deleted" do
prior_valuation = account_valuations :savings_two # 25 days ago
current_valuation = account_valuations :savings_one # 12 days ago
current_valuation.destroy!
current_valuation.account.expects(:sync_later).with(prior_valuation.date)
current_valuation.sync_account_later
end
end

View file

@ -1,7 +0,0 @@
require "test_helper"
class Account::BalanceTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View file

@ -7,12 +7,6 @@ class AccountTest < ActiveSupport::TestCase
@family = families(:dylan_family)
end
test "new account should be valid" do
assert @account.valid?
assert_not_nil @account.accountable_id
assert_not_nil @account.accountable
end
test "recognizes foreign currency account" do
regular_account = accounts(:checking)
foreign_account = accounts(:eur_checking)
@ -34,20 +28,6 @@ class AccountTest < ActiveSupport::TestCase
assert_not multi_currency_account.foreign_currency?
end
test "syncs regular account" do
@account.sync
assert_equal "ok", @account.status
assert_equal 32, @account.balances.count
end
test "syncs foreign currency account" do
account = accounts(:eur_checking)
account.sync
assert_equal "ok", account.status
assert_equal 32, account.balances.where(currency: "USD").count
assert_equal 32, account.balances.where(currency: "EUR").count
end
test "groups accounts by type" do
@family.accounts.each do |account|
account.sync

View file

@ -46,6 +46,7 @@ class ImportTest < ActiveSupport::TestCase
# "Shopping" is a new category, but should only be created 1x during import
assert_difference \
-> { Account::Transaction.count } => 4,
-> { Account::Entry.count } => 4,
-> { Category.count } => 1,
-> { Tagging.count } => 4,
-> { Tag.count } => 2 do
@ -59,11 +60,13 @@ class ImportTest < ActiveSupport::TestCase
test "publishes a valid import with missing data" do
@empty_import.update! raw_csv_str: valid_csv_with_missing_data
assert_difference -> { Category.count } => 1, -> { Account::Transaction.count } => 2 do
assert_difference -> { Category.count } => 1,
-> { Account::Transaction.count } => 2,
-> { Account::Entry.count } => 2 do
@empty_import.publish
end
assert_not_nil Account::Transaction.find_sole_by(name: Import::FALLBACK_TRANSACTION_NAME)
assert_not_nil Account::Entry.find_sole_by(name: Import::FALLBACK_TRANSACTION_NAME)
@empty_import.reload

View file

@ -14,7 +14,7 @@ class SettingsTest < ApplicationSystemTestCase
[ "Tags", "Tags", tags_path ],
[ "Categories", "Categories", categories_path ],
[ "Merchants", "Merchants", merchants_path ],
[ "Rules", "Rules", account_transaction_rules_path ],
[ "Rules", "Rules", rules_transactions_path ],
[ "Imports", "Imports", imports_path ],
[ "What's New", "What's New", changelog_path ],
[ "Feedback", "Feedback", feedback_path ],

View file

@ -4,17 +4,25 @@ class TransactionsTest < ApplicationSystemTestCase
setup do
sign_in @user = users(:family_admin)
@latest_transactions = @user.family.transactions.ordered.limit(20).to_a
@page_size = 10
@latest_transactions = @user.family.entries
.account_transactions
.without_transfers
.reverse_chronological
.limit(20).to_a
@test_category = @user.family.categories.create! name: "System Test Category"
@test_merchant = @user.family.merchants.create! name: "System Test Merchant"
@target_txn = @user.family.accounts.first.transactions.create! \
@target_txn = @user.family.accounts.first.entries.create! \
name: "Oldest transaction",
date: 10.years.ago.to_date,
category: @test_category,
merchant: @test_merchant,
amount: 100
currency: @user.family.currency,
amount: 100,
entryable: Account::Transaction.new(category: @test_category,
merchant: @test_merchant)
visit transactions_url
visit transactions_url(per_page: @page_size)
end
test "can search for a transaction" do
@ -45,7 +53,7 @@ class TransactionsTest < ApplicationSystemTestCase
within "#transaction-search-filters" do
assert_text @target_txn.account.name
assert_text @target_txn.category.name
assert_text @target_txn.account_transaction.category.name
end
end
@ -75,22 +83,22 @@ class TransactionsTest < ApplicationSystemTestCase
click_button "Apply"
end
assert_text "No transactions found"
assert_text "No entries found"
# Page reload doesn't affect results
visit current_url
assert_text "No transactions found"
assert_text "No entries found"
within "ul#transaction-search-filters" do
find("li", text: @target_txn.account.name).first("a").click
find("li", text: "on or after #{10.days.ago.to_date}").first("a").click
find("li", text: "on or before #{Date.current}").first("a").click
find("li", text: @target_txn.category.name).first("a").click
find("li", text: @target_txn.merchant.name).first("a").click
find("li", text: @target_txn.account_transaction.category.name).first("a").click
find("li", text: @target_txn.account_transaction.merchant.name).first("a").click
end
assert_selector "#" + dom_id(@user.family.transactions.ordered.first), count: 1
assert_selector "#" + dom_id(@user.family.entries.reverse_chronological.first), count: 1
end
test "can select and deselect entire page of transactions" do
@ -132,17 +140,15 @@ class TransactionsTest < ApplicationSystemTestCase
private
def number_of_transactions_on_page
page_size = 10
[ @user.family.transactions.where(transfer_id: nil).count, page_size ].min
[ @user.family.entries.without_transfers.count, @page_size ].min
end
def all_transactions_checkbox
find("#selection_transaction")
find("#selection_entry")
end
def date_transactions_checkbox(date)
find("#selection_transaction_#{date}")
find("#selection_entry_#{date}")
end
def transaction_checkbox(transaction)
@ -151,9 +157,9 @@ class TransactionsTest < ApplicationSystemTestCase
def assert_selection_count(count)
if count == 0
assert_no_selector("#transaction-selection-bar")
assert_no_selector("#entry-selection-bar")
else
within "#transaction-selection-bar" do
within "#entry-selection-bar" do
assert_text "#{count} transaction#{count == 1 ? "" : "s"} selected"
end
end

View file

@ -22,45 +22,52 @@ class TransfersTest < ApplicationSystemTestCase
select savings_name, from: "To"
fill_in "account_transfer[amount]", with: 500
fill_in "Date", with: transfer_date
click_button "Create transfer"
within "#date-group-" + transfer_date.to_s do
transfer_name = "Transfer from #{checking_name} to #{savings_name}"
find("details", text: transfer_name).click
assert_text "Transfer txn name", count: 2
within "#entry-group-" + transfer_date.to_s do
assert_text "Transfer from"
end
end
test "can match 2 transactions and create a transfer" do
transfer_date = Date.current
outflow = Account::Transaction.create! name: "Outflow from savings account", date: transfer_date, account: accounts(:savings), amount: 100
inflow = Account::Transaction.create! name: "Inflow to checking account", date: transfer_date, account: accounts(:checking), amount: -100
outflow = accounts(:savings).entries.create! \
name: "Outflow from savings account",
date: transfer_date,
amount: 100,
currency: "USD",
entryable: Account::Transaction.new
inflow = accounts(:checking).entries.create! \
name: "Inflow to checking account",
date: transfer_date,
amount: -100,
currency: "USD",
entryable: Account::Transaction.new
visit transactions_url
transaction_checkbox(inflow).check
transaction_checkbox(outflow).check
transaction_entry_checkbox(inflow).check
transaction_entry_checkbox(outflow).check
bulk_transfer_action_button.click
click_on "Mark as transfers"
within "#date-group-" + transfer_date.to_s do
transfer_name = "Transfer from #{outflow.account.name} to #{inflow.account.name}"
find("details", text: transfer_name).click
assert_text inflow.name
assert_text outflow.name
within "#entry-group-" + transfer_date.to_s do
assert_text "Transfer from"
end
end
test "can mark a single transaction as a transfer" do
txn = @user.family.transactions.ordered.first
txn = @user.family.entries.reverse_chronological.first
within "#" + dom_id(txn) do
assert_text "Uncategorized"
end
transaction_checkbox(txn).check
transaction_entry_checkbox(txn).check
bulk_transfer_action_button.click
click_on "Mark as transfers"
@ -72,8 +79,8 @@ class TransfersTest < ApplicationSystemTestCase
private
def transaction_checkbox(transaction)
find("#" + dom_id(transaction, "selection"))
def transaction_entry_checkbox(transaction_entry)
find("#" + dom_id(transaction_entry, "selection"))
end
def bulk_transfer_action_button