Skip to content

Commit

Permalink
[IMP] account_statement_import_camt: multi account support
Browse files Browse the repository at this point in the history
The module account_statement_import_file supports handling files
containing informations related to multiple accounts, but this was not
taken advantage of by account_statement_import_camt.

We update the structure returned by parser.parse() to use the expected
format in case of multiple accounts encountered in CAMT file.

This has the side effect of fixing a bug in the previous implementation,
when all the transactions in a CAMT file would be parsed as being on the
same account (the one on the last statement found in the file), and
possibly even more wrong, in the currency of the last statement).
  • Loading branch information
gurneyalex committed Feb 6, 2024
1 parent 401b855 commit 63932d5
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 169 deletions.
14 changes: 6 additions & 8 deletions account_statement_import_camt/models/account_statement_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ def _parse_file(self, data_file):
except ValueError:
try:
with zipfile.ZipFile(BytesIO(data_file)) as data:
currency = None
account_number = None
transactions = []
result = []
for member in data.namelist():
currency, account_number, new = self._parse_file(
data.open(member).read()
)
transactions.extend(new)
return currency, account_number, transactions
res = self._parse_file(data.open(member).read())
if isinstance(res, tuple):
res = [res]

Check warning on line 28 in account_statement_import_camt/models/account_statement_import.py

View check run for this annotation

Codecov / codecov/patch

account_statement_import_camt/models/account_statement_import.py#L28

Added line #L28 was not covered by tests
result += res
return result
# pylint: disable=except-pass
except (zipfile.BadZipFile, ValueError):
pass
Expand Down
10 changes: 7 additions & 3 deletions account_statement_import_camt/models/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright 2017 Open Net Sàrl
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import re
from collections import defaultdict

from lxml import etree

Expand Down Expand Up @@ -444,7 +445,7 @@ def parse(self, data):
raise ValueError("Not a valid xml file, or not an xml file at all.")
ns = root.tag[1 : root.tag.index("}")]
self.check_version(ns, root)
statements = []
statements = defaultdict(list)
currency = None
account_number = None
for node in root[0][1:]:
Expand All @@ -454,5 +455,8 @@ def parse(self, data):
currency = statement.pop("currency")
if "account_number" in statement:
account_number = statement.pop("account_number")
statements.append(statement)
return currency, account_number, statements
statements[(currency, account_number)].append(statement)
return [
(currency, account_number, statement_list)
for (currency, account_number), statement_list in statements.items()
]
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(None, None, [])
[]
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
('CHF',
'CH1111000000123456789',
[{'balance_end_real': 79443.15,
'balance_start': 75960.15,
'date': '2017-03-22',
'name': '20170323123456789012345',
'transactions': [{'account_number': 'CH2222000000123456789',
'amount': 2187.0,
'date': '2017-03-22',
'narration': 'Partner Name (RltdPties/Nm): Banque Cantonale Vaudoise\n'
'Partner Account Number (RltdPties/Acct): CH2222000000123456789\n'
'Transaction Date (BookgDt): 2017-03-22\n'
'Reference: 302388292000011111111111111\n'
'Communication: \n'
'Transaction Type (BkTxCd): PMNT-RCDT-VCOM\n'
'Additional Entry Information (AddtlNtryInf): CRÉDIT GROUPÉ BVR TRAITEMENT DU 22.03.2017 NUMÉRO CLIENT 01-70884-3 PAQUET ID: '
'123456CHCAFEBABE\n'
'Reversal Indicator (RvslInd): false\n'
'Structured Reference (RmtInf/Strd/CdtrRefInf/Ref): 302388292000011111111111111\n'
'Account Servicer Reference (Refs/AcctSvcrRef): 123456CHCAFEBABE\n'
'Postal Address (PstlAdr): Place Saint-François | 14 | 1003 | Lausanne | CH1',
'partner_name': 'Banque Cantonale Vaudoise',
'payment_ref': '/',
'ref': '302388292000011111111111111',
'transaction_type': 'PMNT-RCDT-VCOM'},
{'account_number': 'CH3333000000123456789',
'amount': 1296.0,
'date': '2017-03-22',
'narration': 'Partner Name (RltdPties/Nm): Banque Cantonale Vaudoise\n'
'Partner Account Number (RltdPties/Acct): CH3333000000123456789\n'
'Transaction Date (BookgDt): 2017-03-22\n'
'Reference: 302388292000022222222222222\n'
'Communication: \n'
'Transaction Type (BkTxCd): PMNT-RCDT-VCOM\n'
'Additional Entry Information (AddtlNtryInf): CRÉDIT GROUPÉ BVR TRAITEMENT DU 22.03.2017 NUMÉRO CLIENT 01-70884-3 PAQUET ID: '
'123456CHCAFEBABE\n'
'Reversal Indicator (RvslInd): false\n'
'Structured Reference (RmtInf/Strd/CdtrRefInf/Ref): 302388292000022222222222222\n'
'Account Servicer Reference (Refs/AcctSvcrRef): 123456CHCAFEBABE\n'
'Postal Address (PstlAdr): Place Saint-François | 14 | 1003 | Lausanne | CH2',
'partner_name': 'Banque Cantonale Vaudoise',
'payment_ref': '/',
'ref': '302388292000022222222222222',
'transaction_type': 'PMNT-RCDT-VCOM'}]}])
[('CHF',
'CH1111000000123456789',
[{'balance_end_real': 79443.15,
'balance_start': 75960.15,
'date': '2017-03-22',
'name': '20170323123456789012345',
'transactions': [{'account_number': 'CH2222000000123456789',
'amount': 2187.0,
'date': '2017-03-22',
'narration': 'Partner Name (RltdPties/Nm): Banque Cantonale Vaudoise\n'
'Partner Account Number (RltdPties/Acct): CH2222000000123456789\n'
'Transaction Date (BookgDt): 2017-03-22\n'
'Reference: 302388292000011111111111111\n'
'Communication: \n'
'Transaction Type (BkTxCd): PMNT-RCDT-VCOM\n'
'Additional Entry Information (AddtlNtryInf): CRÉDIT GROUPÉ BVR TRAITEMENT DU 22.03.2017 NUMÉRO CLIENT 01-70884-3 PAQUET '
'ID: 123456CHCAFEBABE\n'
'Reversal Indicator (RvslInd): false\n'
'Structured Reference (RmtInf/Strd/CdtrRefInf/Ref): 302388292000011111111111111\n'
'Account Servicer Reference (Refs/AcctSvcrRef): 123456CHCAFEBABE\n'
'Postal Address (PstlAdr): Place Saint-François | 14 | 1003 | Lausanne | CH1',
'partner_name': 'Banque Cantonale Vaudoise',
'payment_ref': '/',
'ref': '302388292000011111111111111',
'transaction_type': 'PMNT-RCDT-VCOM'},
{'account_number': 'CH3333000000123456789',
'amount': 1296.0,
'date': '2017-03-22',
'narration': 'Partner Name (RltdPties/Nm): Banque Cantonale Vaudoise\n'
'Partner Account Number (RltdPties/Acct): CH3333000000123456789\n'
'Transaction Date (BookgDt): 2017-03-22\n'
'Reference: 302388292000022222222222222\n'
'Communication: \n'
'Transaction Type (BkTxCd): PMNT-RCDT-VCOM\n'
'Additional Entry Information (AddtlNtryInf): CRÉDIT GROUPÉ BVR TRAITEMENT DU 22.03.2017 NUMÉRO CLIENT 01-70884-3 PAQUET '
'ID: 123456CHCAFEBABE\n'
'Reversal Indicator (RvslInd): false\n'
'Structured Reference (RmtInf/Strd/CdtrRefInf/Ref): 302388292000022222222222222\n'
'Account Servicer Reference (Refs/AcctSvcrRef): 123456CHCAFEBABE\n'
'Postal Address (PstlAdr): Place Saint-François | 14 | 1003 | Lausanne | CH2',
'partner_name': 'Banque Cantonale Vaudoise',
'payment_ref': '/',
'ref': '302388292000022222222222222',
'transaction_type': 'PMNT-RCDT-VCOM'}]}])]
Loading

0 comments on commit 63932d5

Please sign in to comment.