Skip to content

Commit

Permalink
Add method to parse bank transactions as JSON
Browse files Browse the repository at this point in the history
This implements parsing of the Account Information Service format as
defined in the Berlin Group Group NextGenPSD2 XS2A Framework, which
is widely used across various European banks.

This is a first step to replace the current bank import features with
a standardized JSON interface.
  • Loading branch information
paroga committed Feb 17, 2021
1 parent f7c7b56 commit 9dbe369
Show file tree
Hide file tree
Showing 2 changed files with 450 additions and 0 deletions.
51 changes: 51 additions & 0 deletions app/models/bank_account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,55 @@ def assign_unlinked_transactions
end
count
end

def last_transaction_date
bank_transactions.order(date: :desc).first.try(:date)
end

def import_account_information!(content)
return nil if content.empty?
data = JSON.parse content, symbolize_names: true

booked = data.try(:fetch, :transactions, nil).try(:fetch, :booked, nil) || []

ret = 0
booked.each do |t|
amount = parse_account_information_amount t[:transactionAmount]
entityName = amount < 0 ? t[:creditorName] : t[:debtorName]
entityAccount = amount < 0 ? t[:creditorAccount] : t[:debtorAccount]

bank_transactions.where(external_id: t[:transactionId]).first_or_create.update({
date: t[:bookingDate],
amount: amount,
iban: entityAccount && entityAccount[:iban],
reference: t[:remittanceInformationUnstructured],
text: entityName,
receipt: t[:additionalInformation],
})
ret += 1
end

balances = Hash[ data[:balances] ? data[:balances].map { |b| [b[:balanceType], b[:balanceAmount]] } : [] ]
balance = balances.values.first
%w(closingBooked expected authorised openingBooked interimAvailable forwardAvailable nonInvoiced).each do |type|
value = balances[type]
if value then
balance = value
break
end
end

self.balance = parse_account_information_amount(balance) || bank_transactions.sum(:amount)
self.import_continuation_point = booked.first.try(:fetch, :entryReference, nil)
self.last_import = Time.now
save!

ret
end

private

def parse_account_information_amount(value)
value && value[:amount].to_f
end
end
Loading

0 comments on commit 9dbe369

Please sign in to comment.