diff --git a/app/models/simplefin_account/processor.rb b/app/models/simplefin_account/processor.rb index b8248c707..f9ef87641 100644 --- a/app/models/simplefin_account/processor.rb +++ b/app/models/simplefin_account/processor.rb @@ -64,12 +64,17 @@ class SimplefinAccount::Processor institution: org[:name] ) rescue nil is_mapper_liability = inferred && [ "CreditCard", "Loan" ].include?(inferred.accountable_type) - is_liability = is_linked_liability || is_mapper_liability + is_liability = + if account.accountable_type.present? + is_linked_liability + else + is_mapper_liability + end if is_mapper_liability && !is_linked_liability Rails.logger.warn( - "SimpleFIN liability normalization: linked account #{account.id} type=#{account.accountable_type} " \ - "appears to be liability via mapper (#{inferred.accountable_type}). Normalizing as liability; consider relinking." + "SimpleFIN account type mismatch: linked account #{account.id} type=#{account.accountable_type} " \ + "differs from mapper inference (#{inferred.accountable_type}). Using linked account type." ) end diff --git a/test/models/simplefin_account_processor_test.rb b/test/models/simplefin_account_processor_test.rb index 11b9b4456..0c6a33b88 100644 --- a/test/models/simplefin_account_processor_test.rb +++ b/test/models/simplefin_account_processor_test.rb @@ -158,24 +158,43 @@ class SimplefinAccountProcessorTest < ActiveSupport::TestCase assert_equal BigDecimal("-25"), acct.reload.balance end - test "mislinked as asset but mapper infers credit → normalize as liability" do + test "linked depository account type takes precedence over mapper-inferred liability" do sfin_acct = SimplefinAccount.create!( simplefin_item: @item, name: "Visa Signature", - account_id: "cc_mislinked", + account_id: "cc_mislinked_asset", currency: "USD", account_type: "credit", current_balance: BigDecimal("100.00"), available_balance: BigDecimal("5000.00") ) - # Link to an asset account intentionally acct = accounts(:depository) acct.update!(simplefin_account: sfin_acct) SimplefinAccount::Processor.new(sfin_acct).send(:process_account!) - # Mapper should infer liability from name; final should be negative + # Manual selection as depository; final should be the same + assert_equal BigDecimal("100.00"), acct.reload.balance + end + + test "linked credit card account type takes precedence over mapper-inferred liability" do + sfin_acct = SimplefinAccount.create!( + simplefin_item: @item, + name: "Visa Signature", + account_id: "cc_mislinked_liability", + currency: "USD", + account_type: "credit", + current_balance: BigDecimal("100.00"), + available_balance: BigDecimal("5000.00") + ) + + acct = accounts(:credit_card) + acct.update!(simplefin_account: sfin_acct) + + SimplefinAccount::Processor.new(sfin_acct).send(:process_account!) + + # Liability has flipped sign; final should be negative assert_equal BigDecimal("-100.00"), acct.reload.balance end