Files
enterprise-addons/l10n_be_coda/tests/test_import_bank_statement.py
T

251 lines
15 KiB
Python

# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# Copyright (c) 2012 Noviat nv/sa (www.noviat.be). All rights reserved.
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
from odoo.tools import file_open
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestCodaFile(AccountTestInvoicingCommon):
@classmethod
@AccountTestInvoicingCommon.setup_country('be')
def setUpClass(cls):
super().setUpClass()
cls.bank_journal = cls.company_data['default_journal_bank']
cls.coda_file = cls._get_coda_file('l10n_be_coda/test_coda_file/Ontvangen_CODA.2013-01-11-18.59.15.txt')
cls.coda_globalisation_file = cls._get_coda_file('l10n_be_coda/test_coda_file/test_coda_globalisation.txt')
cls.coda_32_increment_file = cls._get_coda_file('l10n_be_coda/test_coda_file/test_coda_with_32_incrementation.txt')
cls.coda_without_label = cls._get_coda_file('l10n_be_coda/test_coda_file/coda_without_label.txt')
@classmethod
def _get_coda_file(cls, coda_file_path):
with file_open(coda_file_path, 'rb') as coda_file:
return coda_file.read()
def test_coda_file_import(self):
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'Ontvangen_CODA.2013-01-11-18.59.15.txt',
'raw': self.coda_file,
}).ids)
imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)])
self.assertRecordValues(imported_statement, [{
'balance_start': 11812.70,
'balance_end_real': 13646.05,
}])
def test_coda_file_import_twice(self):
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'Ontvangen_CODA.2013-01-11-18.59.15.txt',
'raw': self.coda_file,
}).ids)
with self.assertRaises(Exception):
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'Ontvangen_CODA.2013-01-11-18.59.15.txt',
'raw': self.coda_file,
}).ids)
def test_coda_special_chars(self):
coda_special_chars = """0000001022372505 0123456789JOHN DOE KREDBEBB 00477472701 00000 2
12001BE68539007547034 EUR0000000000100000310123DEMO COMPANY KBC Business Account 027
2100010000ABCDEFG123456789000010000000000025500010223001500000Théâtre d'Hélène à Dümùß 01022302701 0
2200010000 GEBABEBB 1 0
2300010000BE55173363943144 ODOO SA 0 0
8027BE68539007547034 EUR0000000000125500010223 0
9 000005000000000000000000000000025500 2"""
encodings = ('utf_8', 'cp850', 'cp858', 'cp1140', 'cp1252', 'iso8859_15', 'utf_32', 'utf_16', 'windows-1252')
for enc in encodings:
statements = self.company_data['default_journal_bank']._parse_bank_statement_file(coda_special_chars.encode(enc))[0][-1]
self.assertEqual(statements[0]['transactions'][0]['payment_ref'][:24], "Théâtre d'Hélène à Dümùß")
def test_coda_zero_date(self):
coda_zero_date = """0000001122472505 0123456789JOHN DOE KREDBEBB 00477472701 00000 2
12001BE68539007547034 EUR0000000000100000310123DEMO COMPANY KBC Business Account 027
2100010000ABCDEFG123456789000010000000000025500010223001500000Payment Reference 00000002701 0
2200010000 GEBABEBB 1 0
2300010000BE55173363943144 ODOO SA 0 0
8027BE68539007547034 EUR0000000000125500000000 0
9 000005000000000000000000000000025500 2"""
statements = self.company_data['default_journal_bank']._parse_bank_statement_file(coda_zero_date.encode('utf-8'))[0][-1]
self.assertEqual(statements[0]['transactions'][0]['date'], '2024-12-01')
def test_coda_import_currency_symbol(self):
coda_currency_symbols = """0000001122472505 0123456789JOHN DOE KREDBEBB 00477472701 00000 2
12001BE68539007547034 EUR0000000000100000310123DEMO COMPANY KBC Business Account 027
2100010000ABCDEFG123456789000010000000000025500010223001500000Payment Reference €$£¥¢ 00000002701 0
2200010000 GEBABEBB 1 0
2300010000BE55173363943144 ODOO SA 0 0
8027BE68539007547034 EUR0000000000125500000000 0
9 000005000000000000000000000000025500 2"""
statements = self.company_data['default_journal_bank']._parse_bank_statement_file(coda_currency_symbols.encode('utf-8'))[0][-1]
# If this fails, the error will probably talk about the date, it's because one of the decoded currency symbols became multiple
# characters and the index of the date moved (from [115:121] to [117:123] for example)
self.assertEqual(statements[0]['transactions'][0]['payment_ref'][:23], "Payment Reference €$£¥¢")
def test_coda_multi_accounts(self):
bank_1, bank_2 = self.env['res.partner.bank'].create([
{'acc_number': 'BE33737018595246', 'partner_id': self.env.company.partner_id.id},
{'acc_number': 'BE33737018595247', 'partner_id': self.env.company.partner_id.id},
])
journal_1 = self.bank_journal
journal_1.bank_account_id = bank_1
journal_2 = journal_1.copy({'bank_account_id': bank_2.id})
with file_open('l10n_be_coda/test_coda_file/multi_accounts.COD', 'rb') as coda_file:
coda_file = coda_file.read()
action = self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'multi_accounts.COD',
'raw': coda_file,
}).ids)
self.assertEqual(
self.env['account.bank.statement.line'].search(action['domain'])['journal_id'],
journal_1 + journal_2,
)
def test_coda_import_atm_pos_transaction_import_partner_from_struct_com(self):
coda = """0000001122472505 0123456789JOHN DOE KREDBEBB 00477472701 00000 2 2
12001BE68539007547034 EUR0000000000100000310123DEMO COMPANY KBC Business Account 027
2100020001DALZ15199 BKTBPFBECPG1000000000380500250325804021000 25032506110 0
2100030000OL98R57W3GBKTOTBBEPOS10000000000062002503250040200011135127880000006588101902254978525032512037TOYOTA EVE25032506101 0
2200030000RE EVERE 000000000000000000000000000 0000000 1 0
2300030000 00000 0 0
8027BE68539007547034 EUR0000000000125500000000 0
9 000005000000000000000000000000025500 2"""
statements = self.company_data['default_journal_bank']._parse_bank_statement_file(coda.encode('utf-8'))[0][-1]
self.assertEqual(statements[0]['transactions'][0]['partner_name'], "TOYOTA EVERE (EVERE)")
def test_globalisation_split_transactions(self):
self.company_data['default_journal_bank'].coda_split_transactions = True
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'test_coda_globalisation.coda',
'raw': self.coda_globalisation_file,
}).ids)
imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)])
self.assertRecordValues(imported_statement.line_ids, [
{'amount': -435.00, 'payment_ref': 'MEDEDELING PARTNER 1 Facture Test - 2026'},
{'amount': 3044.45, 'payment_ref': '+++240/2838/42818+++'},
{'amount': -419.92, 'payment_ref': 'KBC-INVESTERINGSKREDIET 737-6543210-21 - Codes proper to each bank - Fixed loan advance - reimbursement'},
{'amount': -59.12, 'payment_ref': 'KBC-INVESTERINGSKREDIET 737-6543210-21 - Codes proper to each bank - Interest paid'},
{'amount': -419.92, 'payment_ref': 'KBC-INVESTERINGSKREDIET 737-6543210-21 - Codes proper to each bank - Fixed loan advance - reimbursement'},
{'amount': -59.12, 'payment_ref': 'KBC-INVESTERINGSKREDIET 737-6543210-21 - Codes proper to each bank - Interest paid'},
{'amount': 63.74, 'payment_ref': 'TERUGGAVE 37232481 8400083296 .'},
{'amount': -1718.48, 'payment_ref': 'Original amount of the transaction'},
{'amount': -1077.21, 'payment_ref': 'Original amount of the transaction'},
{'amount': -8.00, 'payment_ref': '1983756643.95654 AC123456789123 - Costs relating to outgoing foreign transfers and non-SEPA transfers - Payment commission'},
{'amount': -1.68, 'payment_ref': 'Method of calculation (VAT, withholding tax on income, commission, etc.)'},
])
self.assertRecordValues(imported_statement, [{
'balance_start': 11812.70,
'balance_end': 10722.44,
'balance_end_real': 10722.44,
}])
def test_globalisation_no_split_transactions(self):
self.company_data['default_journal_bank'].coda_split_transactions = False
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'test_coda_globalisation.coda',
'raw': self.coda_globalisation_file,
}).ids)
imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)])
self.assertRecordValues(imported_statement.line_ids, [
{'amount': -435.00},
{'amount': 3044.45},
{'amount': -479.04},
{'amount': -479.04},
{'amount': 63.74},
{'amount': -2795.69},
{'amount': -9.68},
])
self.assertRecordValues(imported_statement, [{
'balance_start': 11812.70,
'balance_end': 10722.44,
'balance_end_real': 10722.44,
}])
def test_coda_file_with_32_incrementation_import(self):
"""
Ensure the file can be imported even if the bank give a document with incorrect 3.2 incrementation
"""
self.company_data['default_journal_bank'].coda_split_transactions = False
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'test_coda_with_32_incrementation.coda',
'raw': self.coda_32_increment_file,
}).ids)
imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)])
self.assertRecordValues(imported_statement.line_ids, [
{'amount': -435.00},
{'amount': 3044.45},
{'amount': -479.04},
{'amount': -479.04},
{'amount': 63.74},
{'amount': -2795.69},
{'amount': -9.68},
])
self.assertRecordValues(imported_statement, [{
'balance_start': 11812.70,
'balance_end': 10722.44,
'balance_end_real': 10722.44,
}])
def test_coda_parsing_ignore_statements(self):
"""
In some cases, we do not need the returning statements but only the currency and account_number
"""
coda_attachment = self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'test_coda_globalisation.coda',
'raw': self.coda_globalisation_file,
})
journal_eur = self.company_data['default_journal_bank']
journal_eur.currency_id = self.env.ref('base.EUR').id
journal_usd = self.company_data['default_journal_bank'].copy({
"name": "J2",
"code": "J2",
"currency_id": self.env.ref('base.USD').id,
})
journals = journal_eur | journal_usd
with self.assertRaisesRegex(ValueError, r"Expected singleton"):
journals._parse_bank_statement_file(coda_attachment.raw)
currency, __, __, __ = journals.with_context(ignore_statements=True)._parse_bank_statement_file(coda_attachment.raw)[0]
self.assertEqual(currency, "EUR")
def test_coda_without_label(self):
self.company_data['default_journal_bank'].create_document_from_attachment(self.env['ir.attachment'].create({
'mimetype': 'application/text',
'name': 'test_coda_globalisation.coda',
'raw': self.coda_without_label,
}).ids)
imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)])
# When no label we will fallback on the transaction type
self.assertRecordValues(imported_statement.line_ids, [
{'payment_ref': '6703420000000301201946342016831102518305DELHAIZE P - Payment by means of a payment card within the Eurozone - Gross amount', 'transaction_type': 'Detail of Simple amount with detailed data: Cards (Payment by means of a payment card within the Eurozone)'},
{'payment_ref': '6703420000000301201946303764002112514455DELHAIZE P - Payment by means of a payment card within the Eurozone - Gross amount', 'transaction_type': 'Detail of Simple amount with detailed data: Cards (Payment by means of a payment card within the Eurozone)'},
{'payment_ref': 'Amount as totalised by the customer: Domestic or local SEPA credit transfers (Payment of wages, etc.)', 'transaction_type': 'Amount as totalised by the customer: Domestic or local SEPA credit transfers (Payment of wages, etc.)'},
])