Skip to content

Commit 36bec4c

Browse files
committed
refactor: use sepa_file_parser instead of camt_parser
we used a forked `camt_parser` version which was outdated. To use the `sepa_file_parser` gem we extended the mapping factory in order to keep the code impact as small as possible. NOTE: thanks to the mapping the transaction_id is now better found which caused a few spec to break due to invalid expectations. Those were removed.
1 parent 2b5ca1e commit 36bec4c

24 files changed

+897
-182
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ruby "3.3.2"
66

77
gem "activesupport"
88
gem "camt_parser", git: "https://github.com/railslove/camt_parser.git"
9+
gem "sepa_file_parser"
910
gem "cmxl", git: "https://github.com/railslove/cmxl"
1011
gem "epics"
1112
gem "faraday"

Gemfile.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ GEM
5555
database_cleaner-sequel (2.0.2)
5656
database_cleaner-core (~> 2.0.0)
5757
sequel
58+
date (3.4.1)
5859
diff-lcs (1.5.1)
5960
domain_name (0.5.20190701)
6061
unf (>= 0.0.5, < 1.0.0)
@@ -210,6 +211,10 @@ GEM
210211
sentry-sidekiq (5.22.1)
211212
sentry-ruby (~> 5.22.1)
212213
sidekiq (>= 3.0)
214+
sepa_file_parser (0.4.0)
215+
bigdecimal
216+
nokogiri
217+
time
213218
sepa_king (0.12.0)
214219
activemodel (>= 3.1)
215220
iban-tools
@@ -239,6 +244,8 @@ GEM
239244
rubocop-performance (~> 1.21.0)
240245
statsd-ruby (1.5.0)
241246
tilt (2.4.0)
247+
time (0.4.1)
248+
date
242249
timecop (0.9.10)
243250
tzinfo (2.0.6)
244251
concurrent-ruby (~> 1.0)
@@ -287,6 +294,7 @@ DEPENDENCIES
287294
rubocop
288295
sentry-ruby
289296
sentry-sidekiq
297+
sepa_file_parser
290298
sepa_king
291299
sequel
292300
sidekiq

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace :migration_tasks do
8686

8787
bank_statements = Box::BankStatement.where(account_id: account_id).all
8888
bank_statements.each do |bank_statement|
89-
parser = bank_statement.content.starts_with?(":") ? Cmxl : CamtParser::Format053::Statement
89+
parser = bank_statement.content.starts_with?(":") ? Cmxl : SepaFileParser::Camt053::Statement
9090
begin
9191
result = parser.parse(bank_statement.content)
9292
transactions = result.is_a?(Array) ? result.first.transactions : result.transactions

box/business_processes/import_bank_statement.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def self.find_or_create_bank_statement(raw_bank_statement, account)
5757
bs.account_id = account.id
5858
bs.sequence = raw_bank_statement.sequence
5959
bs.year = extract_year_from_bank_statement(raw_bank_statement)
60-
bs.remote_account = raw_bank_statement.account_identification.source
60+
bs.remote_account = raw_bank_statement.account_identification.iban
6161
bs.opening_balance = as_big_decimal(raw_bank_statement.opening_or_intermediary_balance) # this will be final or intermediate
6262
bs.closing_balance = as_big_decimal(raw_bank_statement.closing_or_intermediary_balance) # this will be final or intermediate
6363
bs.transaction_count = raw_bank_statement.transactions.count
@@ -85,7 +85,7 @@ def self.as_big_decimal(input)
8585

8686
def self.extract_year_from_bank_statement(raw_bank_statement)
8787
first_transaction = raw_bank_statement.transactions.first
88-
first_transaction&.date&.year
88+
first_transaction.date&.year
8989
end
9090

9191
def self.checksum(raw_bank_statement, account)

box/business_processes/import_statements.rb

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# frozen_string_literal: true
22

3-
require "cmxl"
4-
require "camt_parser"
3+
require "sepa_file_parser"
54

65
require_relative "../models/account"
76
require_relative "../models/bank_statement"
87
require_relative "../models/event"
98
require_relative "../../lib/checksum_generator"
9+
require_relative "../../lib/data_mapping/statement_factory"
1010

1111
module Box
1212
module BusinessProcesses
1313
class ImportStatements
14-
PARSERS = {"mt940" => Cmxl, "camt53" => CamtParser::Format053::Statement}.freeze
14+
PARSERS = {"mt940" => Cmxl, "camt53" => SepaFileParser::Camt053::Statement}.freeze
1515

1616
def self.from_bank_statement(bank_statement, upcoming = false)
1717
bank_transactions = parse_bank_statement(bank_statement)
@@ -28,7 +28,9 @@ def self.from_bank_statement(bank_statement, upcoming = false)
2828
def self.parse_bank_statement(bank_statement)
2929
parser = PARSERS.fetch(bank_statement.account.statements_format, Cmxl)
3030
result = parser.parse(bank_statement.content)
31-
result.is_a?(Array) ? result.first.transactions : result.transactions
31+
statement_data = result.is_a?(Array) ? result.first : result
32+
statement = DataMapping::StatementFactory.new(statement_data, bank_statement.account).call
33+
statement.transactions
3234
end
3335

3436
def self.create_statement(bank_statement, bank_transaction, upcoming = false)
@@ -71,51 +73,47 @@ def self.checksum(transaction, bank_statement)
7173
end
7274

7375
def self.checksum_attributes(transaction, remote_account)
74-
return [remote_account, transaction.transaction_id] if transaction.try(:transaction_id).present?
76+
return [remote_account, transaction.transaction_id] if transaction.transaction_id.present?
7577

7678
payload_from_transaction_attributes(transaction, remote_account)
7779
end
7880

7981
def self.payload_from_transaction_attributes(transaction, remote_account)
80-
eref = transaction.respond_to?(:eref) ? transaction.eref : transaction.sepa["EREF"]
81-
mref = transaction.respond_to?(:mref) ? transaction.mref : transaction.sepa["MREF"]
82-
svwz = transaction.respond_to?(:svwz) ? transaction.svwz : transaction.sepa["SVWZ"]
83-
8482
[
8583
remote_account,
8684
transaction.date,
8785
transaction.amount_in_cents,
8886
transaction.iban,
8987
transaction.name,
9088
transaction.sign,
91-
eref,
92-
mref,
93-
svwz,
89+
transaction.eref,
90+
transaction.mref,
91+
transaction.svwz,
9492
transaction.information.gsub(/\s/, "")
9593
]
9694
end
9795

9896
def self.statement_attributes_from_bank_transaction(transaction, bank_statement)
9997
{
100-
sha: checksum(transaction, bank_statement),
101-
date: transaction.date,
102-
entry_date: transaction.entry_date,
10398
amount: transaction.amount_in_cents,
104-
sign: transaction.sign,
105-
debit: transaction.debit?,
106-
swift_code: transaction.swift_code,
107-
reference: transaction.reference,
10899
bank_reference: transaction.bank_reference,
109100
bic: transaction.bic,
101+
creditor_identifier: transaction.creditor_identifier,
102+
date: transaction.date,
103+
debit: transaction.debit?,
104+
description: transaction.description,
105+
entry_date: transaction.entry_date,
106+
eref: transaction.eref,
110107
iban: transaction.iban,
111-
name: transaction.name,
112108
information: transaction.information,
113-
description: transaction.description,
114-
eref: transaction.respond_to?(:eref) ? transaction.eref : transaction.sepa["EREF"],
115-
mref: transaction.respond_to?(:mref) ? transaction.mref : transaction.sepa["MREF"],
116-
svwz: transaction.respond_to?(:svwz) ? transaction.svwz : transaction.sepa["SVWZ"],
117-
tx_id: transaction.try(:primanota) || transaction.try(:transaction_id),
118-
creditor_identifier: transaction.respond_to?(:creditor_identifier) ? transaction.creditor_identifier : transaction.sepa["CRED"]
109+
mref: transaction.mref,
110+
name: transaction.name,
111+
reference: transaction.reference,
112+
sha: checksum(transaction, bank_statement),
113+
sign: transaction.sign,
114+
svwz: transaction.svwz,
115+
swift_code: transaction.swift_code,
116+
tx_id: transaction.transaction_id
119117
}
120118
end
121119
end

box/jobs/fetch_statements.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require "sidekiq-scheduler"
44
require "active_support/all"
5-
require "camt_parser"
5+
require "sepa_file_parser"
66
require "cmxl"
77
require "epics"
88
require "sequel"
@@ -84,7 +84,7 @@ def camt53(client, from, to)
8484
combined_camt = client.C53(from.to_s(:db), to.to_s(:db))
8585
return unless combined_camt.any?
8686

87-
combined_camt.map { |chunk| CamtParser::String.parse(chunk).statements }.flatten
87+
combined_camt.map { |chunk| SepaFileParser::String.parse(chunk).statements }.flatten
8888
end
8989

9090
def mt940(client, from, to)

box/jobs/fetch_upcoming_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require "sidekiq-scheduler"
44
require "active_support/all"
5-
require "camt_parser"
5+
require "sepa_file_parser"
66
require "cmxl"
77
require "epics"
88
require "sequel"

box/jobs/queue_fetch_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require "sidekiq-scheduler"
44
require "active_support/all"
5-
require "camt_parser"
5+
require "sepa_file_parser"
66
require "cmxl"
77
require "epics"
88
require "sequel"

box/jobs/queue_fetch_upcoming_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require "sidekiq-scheduler"
44
require "active_support/all"
5-
require "camt_parser"
5+
require "sepa_file_parser"
66
require "cmxl"
77
require "epics"
88
require "sequel"

lib/data_mapping/camt53/statement.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require_relative "transaction"
2+
13
module DataMapping
24
module Camt53
35
class Statement
@@ -12,27 +14,29 @@ def blank?
1214
end
1315

1416
def account_identification
15-
raw_bank_statement.account_identification
17+
raw_bank_statement.account
1618
end
1719

1820
def closing_or_intermediary_balance
19-
raw_bank_statement.closing_or_intermediary_balance
21+
raw_bank_statement.closing_balance
2022
end
2123

2224
def sequence
2325
raw_bank_statement.electronic_sequence_number
2426
end
2527

2628
def opening_or_intermediary_balance
27-
raw_bank_statement.closing_or_intermediary_balance
29+
raw_bank_statement.opening_balance
2830
end
2931

3032
def source
3133
raw_bank_statement.source
3234
end
3335

3436
def transactions
35-
raw_bank_statement.transactions
37+
raw_bank_statement.entries.map do |entry|
38+
Transaction.new(entry)
39+
end
3640
end
3741
end
3842
end

0 commit comments

Comments
 (0)