diff options
| author | Yannick Vaucher <yannick.vaucher@camptocamp.com> | 2020-05-19 13:30:23 +0000 |
|---|---|---|
| committer | Josse Colpaert <jco@odoo.com> | 2020-07-14 14:49:15 +0000 |
| commit | da6c9027f4df6ca98420ffafcf32e37dc916d374 (patch) | |
| tree | 33837a356ace117be18be49bc7e232e59d791115 /addons/l10n_ch/tests | |
| parent | e53218964a5088cad0b2fa36390b62bd59e1fda6 (diff) | |
[IMP] l10n_ch: clearer validations for bank fields and vendor bills (ISR ref)
On res.partner.bank, we check that:
- l10n_ch_postal contains a valid postal number
- l10n_ch_isr_subscription_chf contains a valid ISR subscription number
- l10n_ch_isr_subscription_eur contains a valid ISR subscription number
ISR subscriptions numbers are postal numbers but starting with 01 or 03.
Those codes are reserved to ISR issuance.
When the bank account on a Vendor Bill is detected as
an ISR Issuer, check the reference is actually an ISR.
The 27 digits ISR Reference is error prone when typed by hand
and an error at this stage would break the payment process later.
This is required to avoid batch payment error with SEPA.
We prefer using the pretty form xx-yyyyy-z of a postal account.
The Swiss users will identify it more easily.
We always want to auto fill the field l10n_ch_postal when possible from
acc_number, which includes only 2 cases of filling acc_number:
1. a 9 position postal account number
2. an IBAN from PostFinance which includes clearing 09000
Original prs: Closes #51645, #51544, #51560
closes odoo/odoo#54455
X-original-commit: f8a3ec438e3b5fa56305db729a78304aec7a6716
Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
Signed-off-by: Josse Colpaert <jco@openerp.com>
Diffstat (limited to 'addons/l10n_ch/tests')
| -rw-r--r-- | addons/l10n_ch/tests/__init__.py | 4 | ||||
| -rw-r--r-- | addons/l10n_ch/tests/test_l10n_ch_isr_print.py (renamed from addons/l10n_ch/tests/test_l10n_ch_isr.py) | 2 | ||||
| -rw-r--r-- | addons/l10n_ch/tests/test_onchange_l10n_ch_postal.py | 108 | ||||
| -rw-r--r-- | addons/l10n_ch/tests/test_swissqr.py | 8 | ||||
| -rw-r--r-- | addons/l10n_ch/tests/test_vendor_bill_isr.py | 119 |
5 files changed, 235 insertions, 6 deletions
diff --git a/addons/l10n_ch/tests/__init__.py b/addons/l10n_ch/tests/__init__.py index 26725066f62..65de010232a 100644 --- a/addons/l10n_ch/tests/__init__.py +++ b/addons/l10n_ch/tests/__init__.py @@ -2,5 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_ch_qr_code -from . import test_l10n_ch_isr from . import test_swissqr +from . import test_l10n_ch_isr_print +from . import test_vendor_bill_isr +from . import test_onchange_l10n_ch_postal diff --git a/addons/l10n_ch/tests/test_l10n_ch_isr.py b/addons/l10n_ch/tests/test_l10n_ch_isr_print.py index 196ad01346e..bd568636706 100644 --- a/addons/l10n_ch/tests/test_l10n_ch_isr.py +++ b/addons/l10n_ch/tests/test_l10n_ch_isr_print.py @@ -34,7 +34,7 @@ class ISRTest(AccountTestInvoicingCommon): assertBankAccountValid('010391391', 'postal', expected_postal='010391391') assertBankAccountValid('010391394', 'bank') - assertBankAccountValid('CH6309000000250097798', 'iban', expected_postal='000250097798') + assertBankAccountValid('CH6309000000250097798', 'iban', expected_postal='25-9779-8') assertBankAccountValid('GR1601101250000000012300695', 'iban', expected_postal=False) def test_isr(self): diff --git a/addons/l10n_ch/tests/test_onchange_l10n_ch_postal.py b/addons/l10n_ch/tests/test_onchange_l10n_ch_postal.py new file mode 100644 index 00000000000..7763f51b0be --- /dev/null +++ b/addons/l10n_ch/tests/test_onchange_l10n_ch_postal.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.tests import common +from odoo.tests.common import Form, SavepointCase + + +CH_ISR_ISSUER = '01-162-8' +CH_IBAN = 'CH15 3881 5158 3845 3843 7' +FR_IBAN = 'FR83 8723 4133 8709 9079 4002 530' +CH_POST_IBAN = 'CH09 0900 0000 1000 8060 7' +CH_POSTAL_ACC = '10-8060-7' + + +class TestOnchangePostal(SavepointCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.partner = cls.env.ref('base.res_partner_12') + cls.ch_bank = cls.env['res.bank'].create({ + 'name': 'Alternative Bank Schweiz AG', + 'bic': 'ALSWCH21XXX', + }) + cls.post_bank = cls.env['res.bank'].search( + [('bic', '=', 'POFICHBEXXX')]) + if not cls.post_bank: + cls.post_bank = cls.env['res.bank'].create({ + 'name': 'PostFinance AG', + 'bic': 'POFICHBEXXX', + }) + + def new_partner_bank_form(self): + form = Form( + self.env['res.partner.bank'], + view="l10n_ch.isr_partner_bank_form", + ) + form.partner_id = self.partner + return form + + def test_onchange_acc_number_isr_issuer(self): + """The user entered ISR issuer number into acc_number + + We detect and move it to l10n_ch_postal. + It must be moved as it is not unique. + """ + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = CH_ISR_ISSUER + account = bank_acc.save() + + self.assertEqual( + account.acc_number, + "{} {}".format(CH_ISR_ISSUER, self.partner.name) + ) + self.assertEqual(account.l10n_ch_postal, CH_ISR_ISSUER) + self.assertEqual(account.acc_type, 'postal') + + def test_onchange_acc_number_postal(self): + """The user entered postal number into acc_number + + We detect and copy it to l10n_ch_postal. + """ + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = CH_POSTAL_ACC + account = bank_acc.save() + + self.assertEqual(account.acc_number, CH_POSTAL_ACC) + self.assertEqual(account.l10n_ch_postal, CH_POSTAL_ACC) + self.assertEqual(account.acc_type, 'postal') + + def test_onchange_acc_number_iban_ch(self): + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = CH_IBAN + account = bank_acc.save() + + self.assertEqual(account.acc_number, CH_IBAN) + self.assertFalse(account.l10n_ch_postal) + self.assertEqual(account.acc_type, 'iban') + + def test_onchange_acc_number_iban_ch_postfinance(self): + """The user enter a postal IBAN, postal number can be deduced""" + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = CH_POST_IBAN + account = bank_acc.save() + + self.assertEqual(account.acc_number, CH_POST_IBAN) + self.assertEqual(account.l10n_ch_postal, CH_POSTAL_ACC) + self.assertEqual(account.acc_type, 'iban') + + def test_onchange_acc_number_iban_foreign(self): + """Check IBAN still works changed""" + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = FR_IBAN + account = bank_acc.save() + + self.assertEqual(account.acc_number, FR_IBAN) + self.assertFalse(account.l10n_ch_postal) + self.assertEqual(account.acc_type, 'iban') + + def test_onchange_acc_number_none(self): + """Check misc format still works""" + bank_acc = self.new_partner_bank_form() + bank_acc.acc_number = 'anything' + account = bank_acc.save() + + self.assertEqual(account.acc_number, 'anything') + self.assertFalse(account.l10n_ch_postal) + self.assertEqual(account.acc_type, 'bank') diff --git a/addons/l10n_ch/tests/test_swissqr.py b/addons/l10n_ch/tests/test_swissqr.py index 1cc0092a7cd..8976f990097 100644 --- a/addons/l10n_ch/tests/test_swissqr.py +++ b/addons/l10n_ch/tests/test_swissqr.py @@ -100,12 +100,12 @@ class TestSwissQR(AccountTestInvoicingCommon): ) if ref_type == 'QRR': - self.assertTrue(invoice.invoice_payment_ref) - struct_ref = invoice.invoice_payment_ref + self.assertTrue(invoice.payment_reference) + struct_ref = invoice.payment_reference unstr_msg = invoice.ref or invoice.name or '' else: struct_ref = '' - unstr_msg = invoice.invoice_payment_ref or invoice.ref or invoice.name or '' + unstr_msg = invoice.payment_reference or invoice.ref or invoice.name or '' unstr_msg = (unstr_msg or invoice.number).replace('/', '%2F') payload = ( @@ -148,7 +148,7 @@ class TestSwissQR(AccountTestInvoicingCommon): None, invoice.partner_id, None, - invoice.invoice_payment_ref, + invoice.payment_reference, invoice.ref or invoice.name, ) self.assertEqual(url, expected_url) diff --git a/addons/l10n_ch/tests/test_vendor_bill_isr.py b/addons/l10n_ch/tests/test_vendor_bill_isr.py new file mode 100644 index 00000000000..bc76a6cc83b --- /dev/null +++ b/addons/l10n_ch/tests/test_vendor_bill_isr.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.tests import Form, common +from odoo.exceptions import ValidationError + + +CH_ISR_SUBSCRIPTION = "01-162-8" +CH_POSTAL = "10-8060-7" +CH_IBAN = "CH15 3881 5158 3845 3843 7" +ISR_REFERENCE_GOOD = "16 00011 23456 78901 23456 78901" +ISR_REFERENCE_ZEROS = "00 00000 00000 00001 23456 78903" +ISR_REFERENCE_NO_ZEROS = "1 23456 78903" +ISR_REFERENCE_BAD = "11 11111 11111 11111 11111 11111" + + +class TestVendorBillISR(common.SavepointCase): + """Check we can encode Vendor bills with ISR references + + The ISR is a structured reference with a checksum. + User are guided to ensure they don't encode wrong ISR references. + Only vendors with ISR issuer accounts send ISR references. + + ISR references can be received at least till 2022. + + """ + + @classmethod + def setUpClass(cls): + super(TestVendorBillISR, cls).setUpClass() + cls.abs_bank = cls.env["res.bank"].create( + {"name": "Alternative Bank Schweiz", "bic": "ABSOCH22XXX"} + ) + cls.supplier1 = cls.env["res.partner"].create({"name": "Supplier ISR"}) + cls.supplier2 = cls.env["res.partner"].create({"name": "Supplier postal"}) + cls.supplier3 = cls.env["res.partner"].create({"name": "Supplier IBAN"}) + + cls.bank_acc_isr = cls.env['res.partner.bank'].create({ + "acc_number": "ISR 01-162-8 Supplier ISR", + "partner_id": cls.supplier1.id, + "l10n_ch_postal": CH_ISR_SUBSCRIPTION, + }) + cls.bank_acc_postal = cls.env['res.partner.bank'].create({ + "acc_number": CH_POSTAL, + "partner_id": cls.supplier2.id, + "l10n_ch_postal": CH_POSTAL, + }) + cls.bank_acc_iban = cls.env['res.partner.bank'].create({ + "acc_number": CH_IBAN, + "partner_id": cls.supplier2.id, + "l10n_ch_postal": False, + }) + + def test_isr_ref(self): + """Enter ISR reference with ISR subscription account number + + The vendor bill can be saved. + """ + self.env.company.country_id = self.env.ref('base.ch') + form = Form(self.env["account.move"].with_context( + default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form") + form.partner_id = self.supplier1 + form.partner_bank_id = self.bank_acc_isr + + form.payment_reference = ISR_REFERENCE_GOOD + invoice = form.save() + + self.assertFalse(invoice.l10n_ch_isr_needs_fixing) + + def test_isr_ref_with_zeros(self): + """Enter ISR reference with ISR subscription account number + + An ISR Reference can have lots of zeros on the left. + + The vendor bill can be saved. + """ + self.env.company.country_id = self.env.ref('base.ch') + form = Form(self.env["account.move"].with_context( + default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form") + form.partner_id = self.supplier1 + form.partner_bank_id = self.bank_acc_isr + + form.payment_reference = ISR_REFERENCE_ZEROS + invoice = form.save() + + self.assertFalse(invoice.l10n_ch_isr_needs_fixing) + + def test_isr_ref_no_zeros(self): + """Enter ISR reference with ISR subscription account number + + An ISR Reference full of zeros can be entered starting by the + first non zero digit. + + The vendor bill can be saved. + """ + self.env.company.country_id = self.env.ref('base.ch') + form = Form(self.env["account.move"].with_context( + default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form") + form.partner_id = self.supplier1 + form.partner_bank_id = self.bank_acc_isr + + form.payment_reference = ISR_REFERENCE_NO_ZEROS + invoice = form.save() + + self.assertFalse(invoice.l10n_ch_isr_needs_fixing) + + def test_isr_wrong_ref(self): + """Mistype ISR reference with ISR subscription account number + Check it will show the warning + """ + self.env.company.country_id = self.env.ref('base.ch') + form = Form(self.env["account.move"].with_context( + default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form") + form.partner_id = self.supplier1 + form.partner_bank_id = self.bank_acc_isr + + form.payment_reference = ISR_REFERENCE_BAD + invoice = form.save() + + self.assertTrue(invoice.l10n_ch_isr_needs_fixing)
\ No newline at end of file |
