From afdcae74ba2fac9c8473e75fee73395bc0b0921d Mon Sep 17 00:00:00 2001 From: Iryna Vushnevska Date: Tue, 7 Jan 2020 15:56:13 +0200 Subject: [PATCH] [IMP] account_bank_statement_import_camt_oca Apply black --- .../__manifest__.py | 20 +- .../models/account_bank_statement_import.py | 12 +- .../models/account_bank_statement_line.py | 9 +- .../models/account_journal.py | 9 +- .../models/bank_statement.py | 8 +- .../models/parser.py | 220 +++++++++--------- .../tests/test_import_bank_statement.py | 188 +++++++-------- 7 files changed, 228 insertions(+), 238 deletions(-) diff --git a/account_bank_statement_import_camt_oca/__manifest__.py b/account_bank_statement_import_camt_oca/__manifest__.py index f7445a48..10ec288d 100644 --- a/account_bank_statement_import_camt_oca/__manifest__.py +++ b/account_bank_statement_import_camt_oca/__manifest__.py @@ -1,16 +1,12 @@ # Copyright 2013-2017 Therp BV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { - 'name': 'CAMT Format Bank Statements Import', - 'version': '13.0.1.0.0', - 'license': 'AGPL-3', - 'author': 'Therp BV, Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/bank-statement-import', - 'category': 'Banking addons', - 'depends': [ - 'account_bank_statement_import', - ], - 'data': [ - 'views/account_bank_statement_import.xml', - ], + "name": "CAMT Format Bank Statements Import", + "version": "13.0.1.0.0", + "license": "AGPL-3", + "author": "Therp BV, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/bank-statement-import", + "category": "Banking addons", + "depends": ["account_bank_statement_import"], + "data": ["views/account_bank_statement_import.xml"], } diff --git a/account_bank_statement_import_camt_oca/models/account_bank_statement_import.py b/account_bank_statement_import_camt_oca/models/account_bank_statement_import.py index f375da92..ec02ff2c 100644 --- a/account_bank_statement_import_camt_oca/models/account_bank_statement_import.py +++ b/account_bank_statement_import_camt_oca/models/account_bank_statement_import.py @@ -1,20 +1,21 @@ # Copyright 2013-2016 Therp BV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). import logging -from io import BytesIO import zipfile -from odoo import api, models +from io import BytesIO + +from odoo import models _logger = logging.getLogger(__name__) class AccountBankStatementImport(models.TransientModel): - _inherit = 'account.bank.statement.import' + _inherit = "account.bank.statement.import" def _parse_file(self, data_file): """Parse a CAMT053 XML file.""" try: - parser = self.env['account.bank.statement.import.camt.parser'] + parser = self.env["account.bank.statement.import.camt.parser"] _logger.debug("Try parsing with camt.") return parser.parse(data_file) except ValueError: @@ -32,6 +33,5 @@ class AccountBankStatementImport(models.TransientModel): except (zipfile.BadZipFile, ValueError): pass # Not a camt file, returning super will call next candidate: - _logger.debug("Statement file was not a camt file.", - exc_info=True) + _logger.debug("Statement file was not a camt file.", exc_info=True) return super(AccountBankStatementImport, self)._parse_file(data_file) diff --git a/account_bank_statement_import_camt_oca/models/account_bank_statement_line.py b/account_bank_statement_import_camt_oca/models/account_bank_statement_line.py index 823490f3..63022be1 100644 --- a/account_bank_statement_import_camt_oca/models/account_bank_statement_line.py +++ b/account_bank_statement_import_camt_oca/models/account_bank_statement_line.py @@ -1,13 +1,12 @@ # Copyright 2019 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, models +from odoo import models class AccountBankStatementLine(models.Model): _inherit = "account.bank.statement.line" - @api.multi def write(self, vals): """ Purpose of this hook is catch updates for records with name == '/' @@ -18,11 +17,11 @@ class AccountBankStatementLine(models.Model): and this makes search results wrong and partner assignment randomly """ if ( - self.env.context.get('no_reassign_empty_name') + self.env.context.get("no_reassign_empty_name") and len(self) == 1 and len(vals.keys()) == 1 - and 'partner_id' in vals - and self.name == '/' + and "partner_id" in vals + and self.name == "/" ): return True return super(AccountBankStatementLine, self).write(vals) diff --git a/account_bank_statement_import_camt_oca/models/account_journal.py b/account_bank_statement_import_camt_oca/models/account_journal.py index ccc523c2..55ff4dc6 100644 --- a/account_bank_statement_import_camt_oca/models/account_journal.py +++ b/account_bank_statement_import_camt_oca/models/account_journal.py @@ -1,14 +1,15 @@ # Copyright 2019 ACSONE SA/NV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import models, _ +from odoo import _, models class AccountJournal(models.Model): _inherit = "account.journal" def _get_bank_statements_available_import_formats(self): - res = super(AccountJournal, self).\ - _get_bank_statements_available_import_formats() - res.extend([_('camt.053.001.02'), _('camt.054.001.02')]) + res = super( + AccountJournal, self + )._get_bank_statements_available_import_formats() + res.extend([_("camt.053.001.02"), _("camt.054.001.02")]) return res diff --git a/account_bank_statement_import_camt_oca/models/bank_statement.py b/account_bank_statement_import_camt_oca/models/bank_statement.py index 72dc5c01..313e5c17 100644 --- a/account_bank_statement_import_camt_oca/models/bank_statement.py +++ b/account_bank_statement_import_camt_oca/models/bank_statement.py @@ -1,13 +1,13 @@ # Copyright 2019 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, models +from odoo import models class AccountBankStatement(models.Model): _inherit = "account.bank.statement" - @api.multi def reconciliation_widget_preprocess(self): - return super(AccountBankStatement, self.with_context( - no_reassign_empty_name=True)).reconciliation_widget_preprocess() + return super( + AccountBankStatement, self.with_context(no_reassign_empty_name=True) + ).reconciliation_widget_preprocess() diff --git a/account_bank_statement_import_camt_oca/models/parser.py b/account_bank_statement_import_camt_oca/models/parser.py index 009e8a84..971b4206 100644 --- a/account_bank_statement_import_camt_oca/models/parser.py +++ b/account_bank_statement_import_camt_oca/models/parser.py @@ -3,14 +3,15 @@ # Copyright 2017 Open Net Sàrl # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). import re + from lxml import etree from odoo import models class CamtParser(models.AbstractModel): - _name = 'account.bank.statement.import.camt.parser' - _description = 'Account Bank Statement Import CAMT parser' + _name = "account.bank.statement.import.camt.parser" + _description = "Account Bank Statement Import CAMT parser" def parse_amount(self, ns, node): """Parse element that contains Amount and CreditDebitIndicator.""" @@ -18,22 +19,21 @@ class CamtParser(models.AbstractModel): return 0.0 sign = 1 amount = 0.0 - sign_node = node.xpath('ns:CdtDbtInd', namespaces={'ns': ns}) + sign_node = node.xpath("ns:CdtDbtInd", namespaces={"ns": ns}) if not sign_node: - sign_node = node.xpath( - '../../ns:CdtDbtInd', namespaces={'ns': ns}) - if sign_node and sign_node[0].text == 'DBIT': + sign_node = node.xpath("../../ns:CdtDbtInd", namespaces={"ns": ns}) + if sign_node and sign_node[0].text == "DBIT": sign = -1 - amount_node = node.xpath('ns:Amt', namespaces={'ns': ns}) + amount_node = node.xpath("ns:Amt", namespaces={"ns": ns}) if not amount_node: amount_node = node.xpath( - './ns:AmtDtls/ns:TxAmt/ns:Amt', namespaces={'ns': ns}) + "./ns:AmtDtls/ns:TxAmt/ns:Amt", namespaces={"ns": ns} + ) if amount_node: amount = sign * float(amount_node[0].text) return amount - def add_value_from_node( - self, ns, node, xpath_str, obj, attr_name, join_str=None): + def add_value_from_node(self, ns, node, xpath_str, obj, attr_name, join_str=None): """Add value to object from first or all nodes found with xpath. If xpath_str is a list (or iterable), it will be seen as a series @@ -42,7 +42,7 @@ class CamtParser(models.AbstractModel): if not isinstance(xpath_str, (list, tuple)): xpath_str = [xpath_str] for search_str in xpath_str: - found_node = node.xpath(search_str, namespaces={'ns': ns}) + found_node = node.xpath(search_str, namespaces={"ns": ns}) if found_node: if join_str is None: attr_value = found_node[0].text @@ -55,84 +55,98 @@ class CamtParser(models.AbstractModel): """Parse TxDtls node.""" # message self.add_value_from_node( - ns, node, [ - './ns:RmtInf/ns:Ustrd|./ns:RtrInf/ns:AddtlInf', - './ns:AddtlNtryInf', - './ns:Refs/ns:InstrId', - ], transaction, 'name', join_str='\n') + ns, + node, + [ + "./ns:RmtInf/ns:Ustrd|./ns:RtrInf/ns:AddtlInf", + "./ns:AddtlNtryInf", + "./ns:Refs/ns:InstrId", + ], + transaction, + "name", + join_str="\n", + ) # name self.add_value_from_node( - ns, node, [ - './ns:AddtlTxInf', - ], transaction, 'note', join_str='\n') + ns, node, ["./ns:AddtlTxInf"], transaction, "note", join_str="\n" + ) # eref self.add_value_from_node( - ns, node, [ - './ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref', - './ns:Refs/ns:EndToEndId', - './ns:Ntry/ns:AcctSvcrRef' + ns, + node, + [ + "./ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref", + "./ns:Refs/ns:EndToEndId", + "./ns:Ntry/ns:AcctSvcrRef", ], - transaction, 'ref' + transaction, + "ref", ) amount = self.parse_amount(ns, node) if amount != 0.0: - transaction['amount'] = amount + transaction["amount"] = amount # remote party values - party_type = 'Dbtr' - party_type_node = node.xpath( - '../../ns:CdtDbtInd', namespaces={'ns': ns}) - if party_type_node and party_type_node[0].text != 'CRDT': - party_type = 'Cdtr' + party_type = "Dbtr" + party_type_node = node.xpath("../../ns:CdtDbtInd", namespaces={"ns": ns}) + if party_type_node and party_type_node[0].text != "CRDT": + party_type = "Cdtr" party_node = node.xpath( - './ns:RltdPties/ns:%s' % party_type, namespaces={'ns': ns}) + "./ns:RltdPties/ns:%s" % party_type, namespaces={"ns": ns} + ) if party_node: name_node = node.xpath( - './ns:RltdPties/ns:%s/ns:Nm' % party_type, - namespaces={'ns': ns}) + "./ns:RltdPties/ns:%s/ns:Nm" % party_type, namespaces={"ns": ns} + ) if name_node: self.add_value_from_node( - ns, party_node[0], './ns:Nm', transaction, 'partner_name') + ns, party_node[0], "./ns:Nm", transaction, "partner_name" + ) else: self.add_value_from_node( - ns, party_node[0], './ns:PstlAdr/ns:AdrLine', - transaction, 'partner_name') + ns, + party_node[0], + "./ns:PstlAdr/ns:AdrLine", + transaction, + "partner_name", + ) # Get remote_account from iban or from domestic account: account_node = node.xpath( - './ns:RltdPties/ns:%sAcct/ns:Id' % party_type, - namespaces={'ns': ns} + "./ns:RltdPties/ns:%sAcct/ns:Id" % party_type, namespaces={"ns": ns} ) if account_node: - iban_node = account_node[0].xpath( - './ns:IBAN', namespaces={'ns': ns}) + iban_node = account_node[0].xpath("./ns:IBAN", namespaces={"ns": ns}) if iban_node: - transaction['account_number'] = iban_node[0].text + transaction["account_number"] = iban_node[0].text else: self.add_value_from_node( - ns, account_node[0], './ns:Othr/ns:Id', transaction, - 'account_number' + ns, + account_node[0], + "./ns:Othr/ns:Id", + transaction, + "account_number", ) def parse_entry(self, ns, node): """Parse an Ntry node and yield transactions""" - transaction = {'name': '/', 'amount': 0} # fallback defaults - self.add_value_from_node( - ns, node, './ns:BookgDt/ns:Dt', transaction, 'date') + transaction = {"name": "/", "amount": 0} # fallback defaults + self.add_value_from_node(ns, node, "./ns:BookgDt/ns:Dt", transaction, "date") amount = self.parse_amount(ns, node) if amount != 0.0: - transaction['amount'] = amount + transaction["amount"] = amount + self.add_value_from_node(ns, node, "./ns:AddtlNtryInf", transaction, "name") self.add_value_from_node( - ns, node, './ns:AddtlNtryInf', transaction, 'name') - self.add_value_from_node( - ns, node, [ - './ns:NtryDtls/ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref', - './ns:NtryDtls/ns:Btch/ns:PmtInfId', - './ns:NtryDtls/ns:TxDtls/ns:Refs/ns:AcctSvcrRef' + ns, + node, + [ + "./ns:NtryDtls/ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref", + "./ns:NtryDtls/ns:Btch/ns:PmtInfId", + "./ns:NtryDtls/ns:TxDtls/ns:Refs/ns:AcctSvcrRef", ], - transaction, 'ref' + transaction, + "ref", ) - details_nodes = node.xpath( - './ns:NtryDtls/ns:TxDtls', namespaces={'ns': ns}) + details_nodes = node.xpath("./ns:NtryDtls/ns:TxDtls", namespaces={"ns": ns}) if len(details_nodes) == 0: yield transaction return @@ -154,16 +168,15 @@ class CamtParser(models.AbstractModel): """ start_balance_node = None end_balance_node = None - for node_name in ['OPBD', 'PRCD', 'CLBD', 'ITBD']: + for node_name in ["OPBD", "PRCD", "CLBD", "ITBD"]: code_expr = ( - './ns:Bal/ns:Tp/ns:CdOrPrtry/ns:Cd[text()="%s"]/../../..' % - node_name + './ns:Bal/ns:Tp/ns:CdOrPrtry/ns:Cd[text()="%s"]/../../..' % node_name ) - balance_node = node.xpath(code_expr, namespaces={'ns': ns}) + balance_node = node.xpath(code_expr, namespaces={"ns": ns}) if balance_node: - if node_name in ['OPBD', 'PRCD']: + if node_name in ["OPBD", "PRCD"]: start_balance_node = balance_node[0] - elif node_name == 'CLBD': + elif node_name == "CLBD": end_balance_node = balance_node[0] else: if not start_balance_node: @@ -172,85 +185,78 @@ class CamtParser(models.AbstractModel): end_balance_node = balance_node[-1] return ( self.parse_amount(ns, start_balance_node), - self.parse_amount(ns, end_balance_node) + self.parse_amount(ns, end_balance_node), ) def parse_statement(self, ns, node): """Parse a single Stmt node.""" result = {} self.add_value_from_node( - ns, node, [ - './ns:Acct/ns:Id/ns:IBAN', - './ns:Acct/ns:Id/ns:Othr/ns:Id', - ], result, 'account_number' + ns, + node, + ["./ns:Acct/ns:Id/ns:IBAN", "./ns:Acct/ns:Id/ns:Othr/ns:Id"], + result, + "account_number", ) - self.add_value_from_node( - ns, node, './ns:Id', result, 'name') - self.add_value_from_node( - ns, node, './ns:Acct/ns:Ccy', result, 'currency') - result['balance_start'], result['balance_end_real'] = ( - self.get_balance_amounts(ns, node)) - entry_nodes = node.xpath('./ns:Ntry', namespaces={'ns': ns}) + self.add_value_from_node(ns, node, "./ns:Id", result, "name") + self.add_value_from_node(ns, node, "./ns:Acct/ns:Ccy", result, "currency") + result["balance_start"], result["balance_end_real"] = self.get_balance_amounts( + ns, node + ) + entry_nodes = node.xpath("./ns:Ntry", namespaces={"ns": ns}) transactions = [] for entry_node in entry_nodes: transactions.extend(self.parse_entry(ns, entry_node)) - result['transactions'] = transactions - result['date'] = None + result["transactions"] = transactions + result["date"] = None if transactions: - result['date'] = sorted(transactions, - key=lambda x: x['date'], - reverse=True - )[0]['date'] + result["date"] = sorted( + transactions, key=lambda x: x["date"], reverse=True + )[0]["date"] return result def check_version(self, ns, root): """Validate validity of camt file.""" # Check whether it is camt at all: - re_camt = re.compile( - r'(^urn:iso:std:iso:20022:tech:xsd:camt.' - r'|^ISO:camt.)' - ) + re_camt = re.compile(r"(^urn:iso:std:iso:20022:tech:xsd:camt." r"|^ISO:camt.)") if not re_camt.search(ns): - raise ValueError('no camt: ' + ns) + raise ValueError("no camt: " + ns) # Check whether version 052 ,053 or 054: re_camt_version = re.compile( - r'(^urn:iso:std:iso:20022:tech:xsd:camt.054.' - r'|^urn:iso:std:iso:20022:tech:xsd:camt.053.' - r'|^urn:iso:std:iso:20022:tech:xsd:camt.052.' - r'|^ISO:camt.054.' - r'|^ISO:camt.053.' - r'|^ISO:camt.052.)' + r"(^urn:iso:std:iso:20022:tech:xsd:camt.054." + r"|^urn:iso:std:iso:20022:tech:xsd:camt.053." + r"|^urn:iso:std:iso:20022:tech:xsd:camt.052." + r"|^ISO:camt.054." + r"|^ISO:camt.053." + r"|^ISO:camt.052.)" ) if not re_camt_version.search(ns): - raise ValueError('no camt 052 or 053 or 054: ' + ns) + raise ValueError("no camt 052 or 053 or 054: " + ns) # Check GrpHdr element: - root_0_0 = root[0][0].tag[len(ns) + 2:] # strip namespace - if root_0_0 != 'GrpHdr': - raise ValueError('expected GrpHdr, got: ' + root_0_0) + root_0_0 = root[0][0].tag[len(ns) + 2 :] # strip namespace + if root_0_0 != "GrpHdr": + raise ValueError("expected GrpHdr, got: " + root_0_0) def parse(self, data): """Parse a camt.052 or camt.053 or camt.054 file.""" try: - root = etree.fromstring( - data, parser=etree.XMLParser(recover=True)) + root = etree.fromstring(data, parser=etree.XMLParser(recover=True)) except etree.XMLSyntaxError: # ABNAmro is known to mix up encodings - root = etree.fromstring( - data.decode('iso-8859-15').encode('utf-8')) + root = etree.fromstring(data.decode("iso-8859-15").encode("utf-8")) if root is None: - raise ValueError( - 'Not a valid xml file, or not an xml file at all.') - ns = root.tag[1:root.tag.index("}")] + 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 = [] currency = None account_number = None for node in root[0][1:]: statement = self.parse_statement(ns, node) - if len(statement['transactions']): - if 'currency' in statement: - currency = statement.pop('currency') - if 'account_number' in statement: - account_number = statement.pop('account_number') + if len(statement["transactions"]): + if "currency" in statement: + currency = statement.pop("currency") + if "account_number" in statement: + account_number = statement.pop("account_number") statements.append(statement) return currency, account_number, statements diff --git a/account_bank_statement_import_camt_oca/tests/test_import_bank_statement.py b/account_bank_statement_import_camt_oca/tests/test_import_bank_statement.py index d7fbf807..ac0d0688 100644 --- a/account_bank_statement_import_camt_oca/tests/test_import_bank_statement.py +++ b/account_bank_statement_import_camt_oca/tests/test_import_bank_statement.py @@ -2,165 +2,153 @@ # Copyright 2017 Open Net Sàrl # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). import base64 -from datetime import date import difflib import pprint import tempfile +from datetime import date - -from odoo.tests.common import TransactionCase from odoo.modules.module import get_module_resource +from odoo.tests.common import TransactionCase class TestParser(TransactionCase): """Tests for the camt parser itself.""" + def setUp(self): super(TestParser, self).setUp() - self.parser = self.env['account.bank.statement.import.camt.parser'] + self.parser = self.env["account.bank.statement.import.camt.parser"] def _do_parse_test(self, inputfile, goldenfile): testfile = get_module_resource( - 'account_bank_statement_import_camt_oca', - 'test_files', - inputfile, + "account_bank_statement_import_camt_oca", "test_files", inputfile ) - with open(testfile, 'rb') as data: + with open(testfile, "rb") as data: res = self.parser.parse(data.read()) - with tempfile.NamedTemporaryFile(mode='w+', - suffix='.pydata') as temp: + with tempfile.NamedTemporaryFile(mode="w+", suffix=".pydata") as temp: pprint.pprint(res, temp, width=160) goldenfile_res = get_module_resource( - 'account_bank_statement_import_camt_oca', - 'test_files', - goldenfile, + "account_bank_statement_import_camt_oca", "test_files", goldenfile ) - with open(goldenfile_res, 'r') as golden: + with open(goldenfile_res, "r") as golden: temp.seek(0) diff = list( - difflib.unified_diff(golden.readlines(), - temp.readlines(), - golden.name, - temp.name)) + difflib.unified_diff( + golden.readlines(), temp.readlines(), golden.name, temp.name + ) + ) if len(diff) > 2: self.fail( - "actual output doesn't match expected " + - "output:\n%s" % - "".join(diff)) + "actual output doesn't match expected " + + "output:\n%s" % "".join(diff) + ) def test_parse(self): - self._do_parse_test( - 'test-camt053', - 'golden-camt053.pydata') + self._do_parse_test("test-camt053", "golden-camt053.pydata") def test_parse_txdtls(self): - self._do_parse_test( - 'test-camt053-txdtls', - 'golden-camt053-txdtls.pydata') + self._do_parse_test("test-camt053-txdtls", "golden-camt053-txdtls.pydata") def test_parse_no_ntry(self): - self._do_parse_test( - 'test-camt053-no-ntry', - 'golden-camt053-no-ntry.pydata') + self._do_parse_test("test-camt053-no-ntry", "golden-camt053-no-ntry.pydata") class TestImport(TransactionCase): """Run test to import camt import.""" + transactions = [ { - 'account_number': 'NL46ABNA0499998748', - 'amount': -754.25, - 'date': date(year=2014, month=1, day=5), - 'ref': '435005714488-ABNO33052620', + "account_number": "NL46ABNA0499998748", + "amount": -754.25, + "date": date(year=2014, month=1, day=5), + "ref": "435005714488-ABNO33052620", }, { - 'remote_account': 'NL46ABNA0499998748', - 'transferred_amount': -564.05, - 'value_date': date(year=2014, month=1, day=5), - 'ref': 'TESTBANK/NL/20141229/01206408', + "remote_account": "NL46ABNA0499998748", + "transferred_amount": -564.05, + "value_date": date(year=2014, month=1, day=5), + "ref": "TESTBANK/NL/20141229/01206408", }, { - 'remote_account': 'NL46ABNA0499998748', - 'transferred_amount': -100.0, - 'value_date': date(year=2014, month=1, day=5), - 'ref': 'TESTBANK/NL/20141229/01206407', + "remote_account": "NL46ABNA0499998748", + "transferred_amount": -100.0, + "value_date": date(year=2014, month=1, day=5), + "ref": "TESTBANK/NL/20141229/01206407", }, { - 'remote_account': 'NL69ABNA0522123643', - 'transferred_amount': 1405.31, - 'value_date': date(year=2014, month=1, day=5), - 'ref': '115', + "remote_account": "NL69ABNA0522123643", + "transferred_amount": 1405.31, + "value_date": date(year=2014, month=1, day=5), + "ref": "115", }, ] def setUp(self): super(TestImport, self).setUp() - bank = self.env['res.partner.bank'].create({ - 'acc_number': 'NL77ABNA0574908765', - 'partner_id': self.env.ref('base.main_partner').id, - 'company_id': self.env.ref('base.main_company').id, - 'bank_id': self.env.ref('base.res_bank_1').id, - }) - self.env['res.partner.bank'].create({ - 'acc_number': 'NL46ABNA0499998748', - 'partner_id': self.env.ref('base.main_partner').id, - 'company_id': self.env.ref('base.main_company').id, - 'bank_id': self.env.ref('base.res_bank_1').id, - }) - self.env['account.journal'].create({ - 'name': 'Bank Journal - (test camt)', - 'code': 'TBNKCAMT', - 'type': 'bank', - 'bank_account_id': bank.id, - }) + bank = self.env["res.partner.bank"].create( + { + "acc_number": "NL77ABNA0574908765", + "partner_id": self.env.ref("base.main_partner").id, + "company_id": self.env.ref("base.main_company").id, + "bank_id": self.env.ref("base.res_bank_1").id, + } + ) + self.env["res.partner.bank"].create( + { + "acc_number": "NL46ABNA0499998748", + "partner_id": self.env.ref("base.main_partner").id, + "company_id": self.env.ref("base.main_company").id, + "bank_id": self.env.ref("base.res_bank_1").id, + } + ) + self.env["account.journal"].create( + { + "name": "Bank Journal - (test camt)", + "code": "TBNKCAMT", + "type": "bank", + "bank_account_id": bank.id, + } + ) def test_statement_import(self): """Test correct creation of single statement.""" testfile = get_module_resource( - 'account_bank_statement_import_camt_oca', - 'test_files', - 'test-camt053', + "account_bank_statement_import_camt_oca", "test_files", "test-camt053" ) - with open(testfile, 'rb') as datafile: + with open(testfile, "rb") as datafile: camt_file = base64.b64encode(datafile.read()) - self.env['account.bank.statement.import'].create( - { - 'attachment_ids': [(0, 0, { - 'name': 'test file', - 'datas': camt_file, - })] - }).import_file() - - bank_st_record = self.env['account.bank.statement'].search([ - ('name', '=', '1234Test/1')], limit=1) + self.env["account.bank.statement.import"].create( + {"attachment_ids": [(0, 0, {"name": "test file", "datas": camt_file})]} + ).import_file() + + bank_st_record = self.env["account.bank.statement"].search( + [("name", "=", "1234Test/1")], limit=1 + ) statement_lines = bank_st_record.line_ids - self.assertTrue(any( - all( - line[key] == self.transactions[0][key] - for key in ['amount', 'date', 'ref'] - ) and - line.bank_account_id.acc_number == - self.transactions[0]['account_number'] - for line in statement_lines - )) + self.assertTrue( + any( + all( + line[key] == self.transactions[0][key] + for key in ["amount", "date", "ref"] + ) + and line.bank_account_id.acc_number + == self.transactions[0]["account_number"] + for line in statement_lines + ) + ) def test_zip_import(self): """Test import of multiple statements from zip file.""" testfile = get_module_resource( - 'account_bank_statement_import_camt_oca', - 'test_files', - 'test-camt053.zip', + "account_bank_statement_import_camt_oca", "test_files", "test-camt053.zip" ) - with open(testfile, 'rb') as datafile: + with open(testfile, "rb") as datafile: camt_file = base64.b64encode(datafile.read()) - self.env['account.bank.statement.import'].create( - { - 'attachment_ids': [(0, 0, { - 'name': 'test file', - 'datas': camt_file, - })] - }).import_file() - bank_st_record = self.env['account.bank.statement'].search([ - ('name', 'in', ['1234Test/2', '1234Test/3'])]) + self.env["account.bank.statement.import"].create( + {"attachment_ids": [(0, 0, {"name": "test file", "datas": camt_file})]} + ).import_file() + bank_st_record = self.env["account.bank.statement"].search( + [("name", "in", ["1234Test/2", "1234Test/3"])] + ) self.assertTrue(all([st.line_ids for st in bank_st_record]))