mirror of
https://github.com/we-promise/sure.git
synced 2026-05-11 22:55:00 +00:00
feat(enable-banking): enhance transaction import, metadata handling, and UI (#1406)
* feat(enable-banking): enhance transaction import, metadata handling, and UI * fix(enable-banking): address security, sync edge cases and PR feedback * fix(enable-banking): resolve silent failures, auth overrides, and sync logic bugs * fix(enable-banking): resolve sync logic bugs, trailing whitespaces, and apply safe_psu_headers * test(enable-banking): mock set_current_balance to return success result * fix(budget): properly filter pending transactions and classify synced loan payments * style: fix trailing whitespace detected by rubocop * refactor: address code review feedback for Enable Banking sync and reporting --------- Signed-off-by: Louis <contact@boul2gom.com> Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
class EnableBankingAccount::Processor
|
||||
class ProcessingError < StandardError; end
|
||||
include CurrencyNormalizable
|
||||
|
||||
attr_reader :enable_banking_account
|
||||
@@ -37,23 +38,47 @@ class EnableBankingAccount::Processor
|
||||
|
||||
account = enable_banking_account.current_account
|
||||
balance = enable_banking_account.current_balance || 0
|
||||
available_credit = nil
|
||||
|
||||
# For credit cards, compute balance based on credit limit
|
||||
if account.accountable_type == "CreditCard"
|
||||
available_credit = account.accountable.available_credit || 0
|
||||
balance = available_credit - balance
|
||||
# For liability accounts, ensure positive balances
|
||||
elsif account.accountable_type == "Loan"
|
||||
balance = -balance
|
||||
# For liability accounts, ensure balance sign is correct.
|
||||
# DELIBERATE UX DECISION: For CreditCards, we display the available credit (credit_limit - outstanding debt)
|
||||
# rather than the raw outstanding debt. Do not revert this behavior, as future maintainers should understand
|
||||
# users expect to see how much credit they have left rather than their debt balance.
|
||||
# The 'available_credit' calculation overrides the 'balance' variable.
|
||||
if account.accountable_type == "Loan"
|
||||
balance = balance.abs
|
||||
elsif account.accountable_type == "CreditCard"
|
||||
if enable_banking_account.credit_limit.present?
|
||||
available = enable_banking_account.credit_limit - balance.abs
|
||||
available_credit = [ available, 0 ].max
|
||||
balance = available_credit
|
||||
unless account.accountable.present?
|
||||
Rails.logger.warn "EnableBankingAccount::Processor - CreditCard accountable missing for account #{account.id}"
|
||||
end
|
||||
else
|
||||
# Fallback: no credit_limit from API — display raw outstanding balance
|
||||
# We cannot derive available credit without knowing the limit; leave balance unchanged.
|
||||
end
|
||||
end
|
||||
|
||||
currency = parse_currency(enable_banking_account.currency) || account.currency || "EUR"
|
||||
|
||||
account.update!(
|
||||
balance: balance,
|
||||
cash_balance: balance,
|
||||
currency: currency
|
||||
)
|
||||
# Wrap both writes in a transaction so a failure on either rolls back both.
|
||||
ActiveRecord::Base.transaction do
|
||||
if account.accountable.present? && account.accountable.respond_to?(:available_credit=)
|
||||
account.accountable.update!(available_credit: available_credit)
|
||||
end
|
||||
account.update!(currency: currency, cash_balance: balance)
|
||||
|
||||
# Use set_current_balance to create a current_anchor valuation entry.
|
||||
# This enables Balance::ReverseCalculator, which works backward from the
|
||||
# bank-reported balance — eliminating spurious cash adjustment spikes.
|
||||
result = account.set_current_balance(balance)
|
||||
raise ProcessingError, "Failed to set current balance: #{result.error}" unless result.success?
|
||||
end
|
||||
|
||||
# TODO: pass explicit window_start_date to sync_later to avoid full history recalculation on every sync
|
||||
# Currently relies on set_current_balance's implicit sync trigger; window params would require refactor
|
||||
end
|
||||
|
||||
def process_transactions
|
||||
|
||||
Reference in New Issue
Block a user