summaryrefslogtreecommitdiff
path: root/addons/l10n_ch/tests
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/l10n_ch/tests
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/l10n_ch/tests')
-rw-r--r--addons/l10n_ch/tests/__init__.py9
-rw-r--r--addons/l10n_ch/tests/test_ch_qr_code.py80
-rw-r--r--addons/l10n_ch/tests/test_gen_isr_reference.py108
-rw-r--r--addons/l10n_ch/tests/test_l10n_ch_isr_print.py67
-rw-r--r--addons/l10n_ch/tests/test_onchange_l10n_ch_postal.py108
-rw-r--r--addons/l10n_ch/tests/test_swissqr.py171
-rw-r--r--addons/l10n_ch/tests/test_vendor_bill_isr.py119
7 files changed, 662 insertions, 0 deletions
diff --git a/addons/l10n_ch/tests/__init__.py b/addons/l10n_ch/tests/__init__.py
new file mode 100644
index 00000000..e9792e78
--- /dev/null
+++ b/addons/l10n_ch/tests/__init__.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_ch_qr_code
+from . import test_swissqr
+from . import test_l10n_ch_isr_print
+from . import test_vendor_bill_isr
+from . import test_onchange_l10n_ch_postal
+from . import test_gen_isr_reference
diff --git a/addons/l10n_ch/tests/test_ch_qr_code.py b/addons/l10n_ch/tests/test_ch_qr_code.py
new file mode 100644
index 00000000..8bc77d8f
--- /dev/null
+++ b/addons/l10n_ch/tests/test_ch_qr_code.py
@@ -0,0 +1,80 @@
+# -*- coding:utf-8 -*-
+
+from odoo.exceptions import UserError
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+
+
+class TestSwissQRCode(AccountTestInvoicingCommon):
+ """ Tests the generation of Swiss QR-codes on invoices
+ """
+
+ @classmethod
+ def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
+ super().setUpClass(chart_template_ref=chart_template_ref)
+
+ cls.company_data['company'].qr_code = True
+ cls.company_data['company'].country_id = None
+
+ cls.swiss_iban = cls.env['res.partner.bank'].create({
+ 'acc_number': 'CH15 3881 5158 3845 3843 7',
+ 'partner_id': cls.company_data['company'].partner_id.id,
+ })
+
+ cls.swiss_qr_iban = cls.env['res.partner.bank'].create({
+ 'acc_number': 'CH21 3080 8001 2345 6782 7',
+ 'partner_id': cls.company_data['company'].partner_id.id,
+ })
+
+ cls.ch_qr_invoice = cls.env['account.move'].create({
+ 'move_type': 'out_invoice',
+ 'partner_id': cls.partner_a.id,
+ 'currency_id': cls.env.ref('base.CHF').id,
+ 'partner_bank_id': cls.swiss_iban.id,
+ 'company_id': cls.company_data['company'].id,
+ 'payment_reference': "Papa a vu le fifi de lolo",
+ 'invoice_line_ids': [
+ (0, 0, {'quantity': 1, 'price_unit': 100})
+ ],
+ })
+
+ def _assign_partner_address(self, partner):
+ partner.write({
+ 'country_id': self.env.ref('base.ch').id,
+ 'street': "Crab street, 11",
+ 'city': "Crab City",
+ 'zip': "4242",
+ })
+
+ def test_swiss_qr_code_generation(self):
+ """ Check different cases of Swiss QR-code generation, when qr_method is
+ specified beforehand.
+ """
+ self.ch_qr_invoice.qr_code_method = 'ch_qr'
+
+ # First check with a regular IBAN
+ with self.assertRaises(UserError, msg="It shouldn't be possible to generate a Swiss QR-code for partners without a complete Swiss address."):
+ self.ch_qr_invoice.generate_qr_code()
+
+ # Setting the address should make it work
+ self._assign_partner_address(self.ch_qr_invoice.company_id.partner_id)
+ self._assign_partner_address(self.ch_qr_invoice.partner_id)
+
+ self.ch_qr_invoice.generate_qr_code()
+
+ # Now, check with a QR-IBAN as the payment account
+ self.ch_qr_invoice.partner_bank_id = self.swiss_qr_iban
+
+ with self.assertRaises(UserError, msg="It shouldn't be possible to generate a Swiss QR-cde for a QR-IBAN without giving it a valid QR-reference as payment reference."):
+ self.ch_qr_invoice.generate_qr_code()
+
+ # Assigning a QR reference should fix it
+ self.ch_qr_invoice.payment_reference = '210000000003139471430009017'
+
+ def test_ch_qr_code_detection(self):
+ """ Checks Swiss QR-code auto-detection when no specific QR-method
+ is given to the invoice.
+ """
+ self._assign_partner_address(self.ch_qr_invoice.company_id.partner_id)
+ self._assign_partner_address(self.ch_qr_invoice.partner_id)
+ self.ch_qr_invoice.generate_qr_code()
+ self.assertEqual(self.ch_qr_invoice.qr_code_method, 'ch_qr', "Swiss QR-code generator should have been chosen for this invoice.")
diff --git a/addons/l10n_ch/tests/test_gen_isr_reference.py b/addons/l10n_ch/tests/test_gen_isr_reference.py
new file mode 100644
index 00000000..0ee498f4
--- /dev/null
+++ b/addons/l10n_ch/tests/test_gen_isr_reference.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.tests import common, Form
+
+QR_IBAN = 'CH21 3080 8001 2345 6782 7'
+ISR_SUBS_NUMBER = "01-162-8"
+
+
+class TestGenISRReference(AccountTestInvoicingCommon):
+ """Check condition of generation of and content of the structured ref"""
+
+ @classmethod
+ def setUpClass(cls, chart_template_ref="l10n_ch.l10nch_chart_template"):
+ super().setUpClass(chart_template_ref=chart_template_ref)
+ cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
+ cls.bank = cls.env["res.bank"].create(
+ {
+ "name": "Alternative Bank Schweiz AG",
+ "bic": "ALSWCH21XXX",
+ }
+ )
+ cls.bank_acc_isr = cls.env["res.partner.bank"].create(
+ {
+ "acc_number": "ISR",
+ "l10n_ch_isr_subscription_chf": "01-162-8",
+ "bank_id": cls.bank.id,
+ "partner_id": cls.partner_a.id,
+ }
+ )
+ cls.bank_acc_qriban = cls.env["res.partner.bank"].create(
+ {
+ "acc_number": QR_IBAN,
+ "bank_id": cls.bank.id,
+ "partner_id": cls.partner_a.id,
+ }
+ )
+ cls.invoice = cls.init_invoice("out_invoice", products=cls.product_a+cls.product_b)
+
+ def test_isr(self):
+
+ self.invoice.partner_bank_id = self.bank_acc_isr
+ self.invoice.name = "INV/01234567890"
+
+ expected_isr = "000000000000000012345678903"
+ expected_isr_spaced = "00 00000 00000 00001 23456 78903"
+ expected_optical_line = "0100001307807>000000000000000012345678903+ 010001628>"
+ self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
+ self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
+ self.assertEqual(self.invoice.l10n_ch_isr_optical_line, expected_optical_line)
+
+ def test_qrr(self):
+ self.invoice.partner_bank_id = self.bank_acc_qriban
+
+ self.invoice.name = "INV/01234567890"
+
+ expected_isr = "000000000000000012345678903"
+ expected_isr_spaced = "00 00000 00000 00001 23456 78903"
+ self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
+ self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
+ # No need to check optical line, we have no use for it with QR-bill
+
+ def test_isr_long_reference(self):
+ self.invoice.partner_bank_id = self.bank_acc_isr
+
+ self.invoice.name = "INV/123456789012345678901234567890"
+
+ expected_isr = "567890123456789012345678901"
+ expected_isr_spaced = "56 78901 23456 78901 23456 78901"
+ expected_optical_line = "0100001307807>567890123456789012345678901+ 010001628>"
+ self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
+ self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
+ self.assertEqual(self.invoice.l10n_ch_isr_optical_line, expected_optical_line)
+
+ def test_missing_isr_subscription_num(self):
+ self.bank_acc_isr.l10n_ch_isr_subscription_chf = False
+
+ self.invoice.partner_bank_id = self.bank_acc_isr
+
+ self.assertFalse(self.invoice.l10n_ch_isr_number)
+ self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
+ self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
+
+ def test_missing_isr_subscription_num_in_wrong_field(self):
+ self.bank_acc_isr.l10n_ch_isr_subscription_chf = False
+ self.bank_acc_isr.l10n_ch_postal = ISR_SUBS_NUMBER
+
+ self.invoice.partner_bank_id = self.bank_acc_isr
+
+ self.assertFalse(self.invoice.l10n_ch_isr_number)
+ self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
+ self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
+
+ def test_no_bank_account(self):
+ self.invoice.partner_bank_id = False
+
+ self.assertFalse(self.invoice.l10n_ch_isr_number)
+ self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
+ self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
+
+ def test_wrong_currency(self):
+ self.invoice.partner_bank_id = self.bank_acc_isr
+ self.invoice.currency_id = self.env.ref("base.BTN")
+
+ self.assertFalse(self.invoice.l10n_ch_isr_number)
+ self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
+ self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
diff --git a/addons/l10n_ch/tests/test_l10n_ch_isr_print.py b/addons/l10n_ch/tests/test_l10n_ch_isr_print.py
new file mode 100644
index 00000000..9bdba9b7
--- /dev/null
+++ b/addons/l10n_ch/tests/test_l10n_ch_isr_print.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.tests import tagged
+from odoo.exceptions import ValidationError
+
+
+@tagged('post_install', '-at_install')
+class ISRTest(AccountTestInvoicingCommon):
+
+ @classmethod
+ def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
+ super().setUpClass(chart_template_ref=chart_template_ref)
+
+ def print_isr(self, invoice):
+ try:
+ invoice.isr_print()
+ return True
+ except ValidationError:
+ return False
+
+ def test_l10n_ch_postals(self):
+
+ def assertBankAccountValid(account_number, expected_account_type, expected_postal=None):
+ partner_bank = self.env['res.partner.bank'].create({
+ 'acc_number': account_number,
+ 'partner_id': self.partner_a.id,
+ })
+ expected_vals = {'acc_type': expected_account_type}
+ if expected_postal is not None:
+ expected_vals['l10n_ch_postal'] = expected_postal
+
+ self.assertRecordValues(partner_bank, [expected_vals])
+
+ assertBankAccountValid('010391391', 'postal', expected_postal='010391391')
+ assertBankAccountValid('010391394', 'bank')
+ assertBankAccountValid('CH6309000000250097798', 'iban', expected_postal='25-9779-8')
+ assertBankAccountValid('GR1601101250000000012300695', 'iban', expected_postal=False)
+
+ def test_isr(self):
+ isr_bank_account = self.env['res.partner.bank'].create({
+ 'acc_number': "ISR {} number",
+ 'partner_id': self.env.company.partner_id.id,
+ 'l10n_ch_isr_subscription_chf': '01-39139-1',
+ })
+
+ invoice_chf = self.env['account.move'].create({
+ 'move_type': 'out_invoice',
+ 'partner_id': self.partner_a.id,
+ 'partner_bank_id': isr_bank_account.id,
+ 'currency_id': self.env.ref('base.CHF').id,
+ 'invoice_date': '2019-01-01',
+ 'invoice_line_ids': [(0, 0, {'product_id': self.product_a.id})],
+ })
+ invoice_chf.action_post()
+ self.assertTrue(self.print_isr(invoice_chf))
+
+ invoice_eur = self.env['account.move'].create({
+ 'move_type': 'out_invoice',
+ 'partner_id': self.partner_a.id,
+ 'partner_bank_id': isr_bank_account.id,
+ 'currency_id': self.env.ref('base.EUR').id,
+ 'invoice_date': '2019-01-01',
+ 'invoice_line_ids': [(0, 0, {'product_id': self.product_a.id})],
+ })
+ invoice_eur.action_post()
+ self.assertFalse(self.print_isr(invoice_eur))
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 00000000..7763f51b
--- /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
new file mode 100644
index 00000000..207f6e36
--- /dev/null
+++ b/addons/l10n_ch/tests/test_swissqr.py
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import time
+
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.tests import tagged
+
+CH_IBAN = 'CH15 3881 5158 3845 3843 7'
+QR_IBAN = 'CH21 3080 8001 2345 6782 7'
+
+
+@tagged('post_install', '-at_install')
+class TestSwissQR(AccountTestInvoicingCommon):
+
+ @classmethod
+ def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
+ super().setUpClass(chart_template_ref=chart_template_ref)
+
+ def setUp(self):
+ super(TestSwissQR, self).setUp()
+ # Activate SwissQR in Swiss invoices
+ self.env['ir.config_parameter'].create(
+ {'key': 'l10n_ch.print_qrcode', 'value': '1'}
+ )
+ self.customer = self.env['res.partner'].create(
+ {
+ "name": "Partner",
+ "street": "Route de Berne 41",
+ "street2": "",
+ "zip": "1000",
+ "city": "Lausanne",
+ "country_id": self.env.ref("base.ch").id,
+ }
+ )
+ self.env.user.company_id.partner_id.write(
+ {
+ "street": "Route de Berne 88",
+ "street2": "",
+ "zip": "2000",
+ "city": "Neuchâtel",
+ "country_id": self.env.ref('base.ch').id,
+ }
+ )
+ self.invoice1 = self.create_invoice('base.CHF')
+ sale_journal = self.env['account.journal'].search([("type", "=", "sale")])
+ sale_journal.invoice_reference_model = "ch"
+
+ def create_invoice(self, currency_to_use='base.CHF'):
+ """ Generates a test invoice """
+
+ product = self.env.ref("product.product_product_4")
+ acc_type = self.env.ref('account.data_account_type_current_assets')
+ account = self.env['account.account'].search(
+ [('user_type_id', '=', acc_type.id)], limit=1
+ )
+ invoice = (
+ self.env['account.move']
+ .create(
+ {
+ 'move_type': 'out_invoice',
+ 'partner_id': self.customer.id,
+ 'currency_id': self.env.ref(currency_to_use).id,
+ 'date': time.strftime('%Y') + '-12-22',
+ 'invoice_line_ids': [
+ (
+ 0,
+ 0,
+ {
+ 'name': product.name,
+ 'product_id': product.id,
+ 'account_id': account.id,
+ 'quantity': 1,
+ 'price_unit': 42.0,
+ },
+ )
+ ],
+ }
+ )
+ )
+
+ return invoice
+
+ def create_account(self, number):
+ """ Generates a test res.partner.bank. """
+ return self.env['res.partner.bank'].create(
+ {
+ 'acc_number': number,
+ 'partner_id': self.env.user.company_id.partner_id.id,
+ }
+ )
+
+ def swissqr_not_generated(self, invoice):
+ """ Prints the given invoice and tests that no Swiss QR generation is triggered. """
+ self.assertFalse(
+ invoice.partner_bank_id._eligible_for_qr_code('ch_qr', invoice.partner_id, invoice.currency_id),
+ 'No Swiss QR should be generated for this invoice',
+ )
+
+ def swissqr_generated(self, invoice, ref_type='NON'):
+ """ Prints the given invoice and tests that a Swiss QR generation is triggered. """
+ self.assertTrue(
+ invoice.partner_bank_id._eligible_for_qr_code('ch_qr', invoice.partner_id, invoice.currency_id), 'A Swiss QR can be generated'
+ )
+
+ if ref_type == 'QRR':
+ self.assertTrue(invoice.payment_reference)
+ struct_ref = invoice.payment_reference
+ unstr_msg = invoice.ref or invoice.name or ''
+ else:
+ struct_ref = ''
+ unstr_msg = invoice.payment_reference or invoice.ref or invoice.name or ''
+ unstr_msg = (unstr_msg or invoice.number).replace('/', '%2F')
+
+ payload = (
+ "SPC%0A"
+ "0200%0A"
+ "1%0A"
+ "{iban}%0A"
+ "K%0A"
+ "company_1_data%0A"
+ "Route+de+Berne+88%0A"
+ "2000+Neuch%C3%A2tel%0A"
+ "%0A%0A"
+ "CH%0A"
+ "%0A%0A%0A%0A%0A%0A%0A"
+ "42.00%0A"
+ "CHF%0A"
+ "K%0A"
+ "Partner%0A"
+ "Route+de+Berne+41%0A"
+ "1000+Lausanne%0A"
+ "%0A%0A"
+ "CH%0A"
+ "{ref_type}%0A"
+ "{struct_ref}%0A"
+ "{unstr_msg}%0A"
+ "EPD"
+ ).format(
+ iban=invoice.partner_bank_id.sanitized_acc_number,
+ ref_type=ref_type,
+ struct_ref=struct_ref or '',
+ unstr_msg=unstr_msg,
+ )
+
+ expected_url = ("/report/barcode/?type=QR&value={}"
+ "&width=256&height=256&quiet=1&mask=ch_cross").format(payload)
+
+ url = invoice.generate_qr_code()
+ self.assertEqual(url, expected_url)
+
+ def test_swissQR_missing_bank(self):
+ # Let us test the generation of a SwissQR for an invoice, first by showing an
+ # QR is included in the invoice is only generated when Odoo has all the data it needs.
+ self.invoice1.action_post()
+ self.swissqr_not_generated(self.invoice1)
+
+ def test_swissQR_iban(self):
+ # Now we add an account for payment to our invoice
+ # Here we don't use a structured reference
+ iban_account = self.create_account(CH_IBAN)
+ self.invoice1.partner_bank_id = iban_account
+ self.invoice1.action_post()
+ self.swissqr_generated(self.invoice1, ref_type="NON")
+
+ def test_swissQR_qriban(self):
+ # Now use a proper QR-IBAN, we are good to print a QR Bill
+ qriban_account = self.create_account(QR_IBAN)
+ self.assertTrue(qriban_account.acc_type, 'qr-iban')
+ self.invoice1.partner_bank_id = qriban_account
+ self.invoice1.action_post()
+ self.swissqr_generated(self.invoice1, ref_type="QRR")
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 00000000..bc76a6cc
--- /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