Fix enable banking not respecting pending transactions setting (#2686)

* Fix enable banking not respecting pending transactions setting

* Nitpicks from coderabbit

* Add tests for include_pending true and false

* Fix RuboCop spacing in pending importer test

---------

Co-authored-by: sure-admin <sure-admin@splashblot.com>
This commit is contained in:
Otter
2026-07-17 07:57:31 +03:00
committed by GitHub
parent 0809dfa312
commit b660fcfaf2
2 changed files with 67 additions and 6 deletions

View File

@@ -250,6 +250,20 @@ class EnableBankingItem::Importer
psu_headers: enable_banking_item.build_psu_headers
)
if include_pending
# Tag any transaction in all_transactions (fetched as BOOK but actually PDNG) with _pending: true
all_transactions = all_transactions.map do |tx|
tx_ia = tx.with_indifferent_access
tx_ia[:status] == "PDNG" ? tx_ia.merge(_pending: true) : tx_ia
end
else
# If include_pending is false, we must filter out any pending transactions
# that were returned (e.g. if the bank ignores transaction_status="BOOK").
all_transactions = all_transactions.reject do |tx|
tx.with_indifferent_access[:status] == "PDNG"
end
end
pending_transactions = []
if include_pending
# Also fetch pending transactions (visible for 1-3 days before they become BOOK) if setting is enabled.
@@ -272,14 +286,16 @@ class EnableBankingItem::Importer
end
end
book_fingerprints = all_transactions
booked_transactions = all_transactions.reject { |tx| tx.with_indifferent_access[:_pending] }
book_fingerprints = booked_transactions
.map { |tx| EnableBankingEntry::Processor.compute_external_id(tx) }
.compact.to_set
# Also index all booked entry_references so a pending row that lacks
# transaction_id can still be matched when the settled BOOK row adds one
# (fingerprints differ; entry_reference stays the same across settlement).
book_entry_refs = all_transactions
book_entry_refs = booked_transactions
.map { |tx| tx.with_indifferent_access[:entry_reference].presence }
.compact.to_set
@@ -323,13 +339,13 @@ class EnableBankingItem::Importer
# no transaction_id but the settled BOOK row gained one — fingerprints
# diverge (enable_banking_<ref> vs enable_banking_<txn_id>) but the
# shared entry_reference is a reliable settlement signal.
book_fingerprints = all_transactions
.reject { |tx| tx.with_indifferent_access[:_pending] }
booked_transactions_for_settlement = all_transactions.reject { |tx| tx.with_indifferent_access[:_pending] }
book_fingerprints = booked_transactions_for_settlement
.map { |tx| EnableBankingEntry::Processor.compute_external_id(tx) }
.compact.to_set
book_entry_refs = all_transactions
.reject { |tx| tx.with_indifferent_access[:_pending] }
book_entry_refs = booked_transactions_for_settlement
.map { |tx| tx.with_indifferent_access[:entry_reference].presence }
.compact.to_set

View File

@@ -143,4 +143,49 @@ class EnableBankingItem::ImporterPdngTest < ActiveSupport::TestCase
assert_equal @enable_banking_account.id, found.id
end
# --- fetch_and_store_transactions behavior ---
test "fetch_and_store_transactions tags PDNG transaction as pending when include_pending is true" do
@importer.stubs(:include_pending?).returns(true)
# Some ASPSPs ignore transaction_status=BOOK and return PDNG transactions anyway.
tx = {
entry_reference: "tx_ref",
transaction_id: "tx_id",
booking_date: "2026-03-05",
transaction_amount: { amount: "10.00", currency: "EUR" },
status: "PDNG"
}
@importer.stubs(:fetch_paginated_transactions).with(@enable_banking_account, has_entries(transaction_status: "BOOK")).returns([ tx ])
@importer.stubs(:fetch_paginated_transactions).with(@enable_banking_account, has_entries(transaction_status: "PDNG")).returns([ tx ])
result = @importer.send(:fetch_and_store_transactions, @enable_banking_account)
assert result[:success]
stored = @enable_banking_account.raw_transactions_payload
assert_equal 1, stored.size
assert_equal true, stored.first.with_indifferent_access[:_pending]
end
test "fetch_and_store_transactions filters out PDNG transaction when include_pending is false" do
@importer.stubs(:include_pending?).returns(false)
# If include_pending is false, we must reject any PDNG transactions returned in the BOOK fetch.
tx = {
entry_reference: "tx_ref",
transaction_id: "tx_id",
booking_date: "2026-03-05",
transaction_amount: { amount: "10.00", currency: "EUR" },
status: "PDNG"
}
@importer.stubs(:fetch_paginated_transactions).with(@enable_banking_account, has_entries(transaction_status: "BOOK")).returns([ tx ])
result = @importer.send(:fetch_and_store_transactions, @enable_banking_account)
assert result[:success]
assert_nil @enable_banking_account.raw_transactions_payload
end
end