diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index e61feaaa..eb82f376 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -7,7 +7,7 @@ class TransactionsController < ApplicationController def index @q = search_params - search_query = Current.family.transactions.search(@q) + search_query = Current.family.transactions.search(@q).active set_focused_record(search_query, params[:focused_record_id], default_per_page: 50) diff --git a/app/models/account.rb b/app/models/account.rb index 23aaaf71..bef15abf 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -184,6 +184,8 @@ class Account < ApplicationRecord .joins("JOIN accounts inflow_accounts ON inflow_accounts.id = inflow_candidates.account_id") .joins("JOIN accounts outflow_accounts ON outflow_accounts.id = outflow_candidates.account_id") .where("inflow_accounts.family_id = ? AND outflow_accounts.family_id = ?", self.family_id, self.family_id) + .where("inflow_accounts.is_active = true AND inflow_accounts.scheduled_for_deletion = false") + .where("outflow_accounts.is_active = true AND outflow_accounts.scheduled_for_deletion = false") .where("inflow_candidates.entryable_type = 'Account::Transaction' AND outflow_candidates.entryable_type = 'Account::Transaction'") .where(existing_transfers: { id: nil }) .order("date_diff ASC") # Closest matches first diff --git a/app/models/account/entry.rb b/app/models/account/entry.rb index 4a222014..8ec0175b 100644 --- a/app/models/account/entry.rb +++ b/app/models/account/entry.rb @@ -24,6 +24,10 @@ class Account::Entry < ApplicationRecord ) } + scope :active, -> { + joins(:account).where(accounts: { is_active: true, scheduled_for_deletion: false }) + } + scope :reverse_chronological, -> { order( date: :desc, diff --git a/test/models/account/entry_test.rb b/test/models/account/entry_test.rb index 8521f227..4f0c1b15 100644 --- a/test/models/account/entry_test.rb +++ b/test/models/account/entry_test.rb @@ -81,4 +81,27 @@ class Account::EntryTest < ActiveSupport::TestCase assert_equal 200, totals.expense_total assert_equal "USD", totals.currency end + + test "active scope only returns entries from active, non-scheduled-for-deletion accounts" do + # Create transactions for all account types + active_transaction = create_transaction(account: accounts(:depository), name: "Active transaction") + inactive_transaction = create_transaction(account: accounts(:credit_card), name: "Inactive transaction") + deletion_transaction = create_transaction(account: accounts(:investment), name: "Scheduled for deletion transaction") + + # Update account statuses + accounts(:credit_card).update!(is_active: false) + accounts(:investment).update!(scheduled_for_deletion: true) + + # Test the scope + active_entries = Account::Entry.active + + # Should include entry from active account + assert_includes active_entries, active_transaction + + # Should not include entry from inactive account + assert_not_includes active_entries, inactive_transaction + + # Should not include entry from account scheduled for deletion + assert_not_includes active_entries, deletion_transaction + end end diff --git a/test/models/account_test.rb b/test/models/account_test.rb index 3e29a5a1..066693c7 100644 --- a/test/models/account_test.rb +++ b/test/models/account_test.rb @@ -99,4 +99,43 @@ class AccountTest < ActiveSupport::TestCase @account.auto_match_transfers! end end + + test "transfer_match_candidates only matches between active accounts" do + active_account = accounts(:depository) + another_active_account = accounts(:credit_card) + inactive_account = accounts(:investment) + inactive_account.update!(is_active: false) + + # Create matching transactions + active_inflow = active_account.entries.create!( + date: Date.current, + amount: -100, + currency: "USD", + name: "Test transfer", + entryable: Account::Transaction.new + ) + + active_outflow = another_active_account.entries.create!( + date: Date.current, + amount: 100, + currency: "USD", + name: "Test transfer", + entryable: Account::Transaction.new + ) + + inactive_outflow = inactive_account.entries.create!( + date: Date.current, + amount: 100, + currency: "USD", + name: "Test transfer", + entryable: Account::Transaction.new + ) + + # Should find matches between active accounts + candidates = active_account.transfer_match_candidates + assert_includes candidates.map(&:outflow_transaction_id), active_outflow.entryable_id + + # Should not match with inactive account + assert_not_includes candidates.map(&:outflow_transaction_id), inactive_outflow.entryable_id + end end