diff --git a/addons/l10n_ch/i18n_extra/l10n_ch.pot b/addons/l10n_ch/i18n_extra/l10n_ch.pot
index 8cff14a83ca..441e37ee846 100644
--- a/addons/l10n_ch/i18n_extra/l10n_ch.pot
+++ b/addons/l10n_ch/i18n_extra/l10n_ch.pot
@@ -4,10 +4,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 13.0\n"
+"Project-Id-Version: Odoo Server 13.0+e\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-28 09:52+0000\n"
-"PO-Revision-Date: 2020-06-17 10:00+0000\n"
+"POT-Creation-Date: 2020-07-09 16:03+0000\n"
+"PO-Revision-Date: 2020-07-09 16:03+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -334,6 +334,11 @@ msgstr ""
msgid "Acceptance point"
msgstr ""
+#. module: l10n_ch
+#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
+msgid "Account / Payable to
"
+msgstr ""
+
#. module: l10n_ch
#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
msgid "Additional information
"
@@ -344,11 +349,6 @@ msgstr ""
msgid "Amount
"
msgstr ""
-#. module: l10n_ch
-#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
-msgid "Account / Payable to
"
-msgstr ""
-
#. module: l10n_ch
#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
msgid "Currency
"
@@ -359,11 +359,6 @@ msgstr ""
msgid "Payable by
"
msgstr ""
-#. module: l10n_ch
-#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
-msgid "Payable to
"
-msgstr ""
-
#. module: l10n_ch
#: model_terms:ir.ui.view,arch_db:l10n_ch.l10n_ch_swissqr_template
msgid "Reference
"
@@ -1027,7 +1022,6 @@ msgid "Immeubles d’exploitation"
msgstr ""
#. module: l10n_ch
-#: model:account.fiscal.position,name:l10n_ch.1_fiscal_position_template_import
#: model:account.fiscal.position.template,name:l10n_ch.fiscal_position_template_import
msgid "Import/Export"
msgstr ""
@@ -1080,6 +1074,11 @@ msgstr ""
msgid "Journal Entries"
msgstr ""
+#. module: l10n_ch
+#: model:ir.model.fields,field_description:l10n_ch.field_account_move__l10n_ch_isr_needs_fixing
+msgid "L10N Ch Isr Needs Fixing"
+msgstr ""
+
#. module: l10n_ch
#: model:ir.model.fields,field_description:l10n_ch.field_account_move__l10n_ch_isr_number
msgid "L10N Ch Isr Number"
@@ -1216,6 +1215,13 @@ msgstr ""
msgid "Plan comptable 2015 (Suisse)"
msgstr ""
+#. module: l10n_ch
+#: model_terms:ir.ui.view,arch_db:l10n_ch.isr_invoice_form
+msgid ""
+"Please fill in a correct ISR reference in the payment reference. The banks "
+"will refuse your payment file otherwise."
+msgstr ""
+
#. module: l10n_ch
#: code:addons/l10n_ch/models/res_bank.py:0
#, python-format
@@ -1419,7 +1425,6 @@ msgid "Subventions, taxes touristiques à 0%"
msgstr ""
#. module: l10n_ch
-#: model:account.fiscal.position,name:l10n_ch.1_fiscal_position_template_1
#: model:account.fiscal.position.template,name:l10n_ch.fiscal_position_template_1
msgid "Suisse national"
msgstr ""
@@ -1576,11 +1581,27 @@ msgstr ""
msgid "TVA due à 7.7% (Incl. TN)"
msgstr ""
+#. module: l10n_ch
+#: code:addons/l10n_ch/models/res_bank.py:0
+#, python-format
+msgid ""
+"The ISR subcription {} for {} number is not valid.\n"
+"It must starts with {} and we a valid postal number format. eg. {}"
+msgstr ""
+
#. module: l10n_ch
#: model:ir.model.fields,help:l10n_ch.field_account_move__l10n_ch_currency_name
msgid "The name of this invoice's currency"
msgstr ""
+#. module: l10n_ch
+#: code:addons/l10n_ch/models/res_bank.py:0
+#, python-format
+msgid ""
+"The postal number {} is not valid.\n"
+"It must be a valid postal number format. eg. 10-8060-7"
+msgstr ""
+
#. module: l10n_ch
#: model:ir.model.fields,help:l10n_ch.field_account_move__l10n_ch_isr_number
msgid "The reference number associated with this invoice"
@@ -1627,6 +1648,13 @@ msgstr ""
msgid "Travaux en cours"
msgstr ""
+#. module: l10n_ch
+#: model:ir.model.fields,help:l10n_ch.field_account_move__l10n_ch_isr_needs_fixing
+msgid ""
+"Used to show a warning banner when the vendor bill needs a correct ISR "
+"payment reference. "
+msgstr ""
+
#. module: l10n_ch
#: model:account.account.template,name:l10n_ch.ch_coa_3940
msgid "Variation de la valeur des prestations non facturées"
diff --git a/addons/l10n_ch/models/account_invoice.py b/addons/l10n_ch/models/account_invoice.py
index 3ed18cbad8a..1760ca4d2b6 100644
--- a/addons/l10n_ch/models/account_invoice.py
+++ b/addons/l10n_ch/models/account_invoice.py
@@ -27,6 +27,7 @@ class AccountMove(models.Model):
l10n_ch_isr_sent = fields.Boolean(default=False, help="Boolean value telling whether or not the ISR corresponding to this invoice has already been printed or sent by mail.")
l10n_ch_currency_name = fields.Char(related='currency_id.name', readonly=True, string="Currency Name", help="The name of this invoice's currency") #This field is used in the "invisible" condition field of the 'Print ISR' button.
+ l10n_ch_isr_needs_fixing = fields.Boolean(compute="_compute_l10n_ch_isr_needs_fixing", help="Used to show a warning banner when the vendor bill needs a correct ISR payment reference. ")
@api.depends('partner_bank_id.l10n_ch_isr_subscription_eur', 'partner_bank_id.l10n_ch_isr_subscription_chf')
def _compute_l10n_ch_isr_subscription(self):
@@ -154,6 +155,33 @@ class AccountMove(models.Model):
record.l10n_ch_isr_subscription and \
record.l10n_ch_currency_name in ['EUR', 'CHF']
+ @api.depends('move_type', 'partner_bank_id', 'payment_reference')
+ def _compute_l10n_ch_isr_needs_fixing(self):
+ for inv in self:
+ if inv.move_type == 'in_invoice' and inv.company_id.country_id.code == "CH":
+ partner_bank = inv.partner_bank_id
+ if partner_bank._is_isr_issuer() and not inv._has_isr_ref():
+ inv.l10n_ch_isr_needs_fixing = True
+ continue
+ inv.l10n_ch_isr_needs_fixing = False
+
+ def _has_isr_ref(self):
+ """Check if this invoice has a valid ISR reference (for Switzerland)
+ e.g.
+ 12371
+ 000000000000000000000012371
+ 210000000003139471430009017
+ 21 00000 00003 13947 14300 09017
+ """
+ self.ensure_one()
+ ref = self.payment_reference or self.ref
+ if not ref:
+ return False
+ ref = ref.replace(' ', '')
+ if re.match(r'^(\d{2,27})$', ref):
+ return ref == mod10r(ref[:-1])
+ return False
+
def split_total_amount(self):
""" Splits the total amount of this invoice in two parts, using the dot as
a separator, and taking two precision digits (always displayed).
@@ -173,7 +201,7 @@ class AccountMove(models.Model):
self.l10n_ch_isr_sent = True
return self.env.ref('l10n_ch.l10n_ch_isr_report').report_action(self)
else:
- raise ValidationError(_("""You cannot generate an ISR yet.\n
+ raise ValidationError(_("""You cannot generate an ISR yet.\n
For this, you need to :\n
- set a valid postal account number (or an IBAN referencing one) for your company\n
- define its bank\n
diff --git a/addons/l10n_ch/models/res_bank.py b/addons/l10n_ch/models/res_bank.py
index 5f6337541c0..63e704c2671 100644
--- a/addons/l10n_ch/models/res_bank.py
+++ b/addons/l10n_ch/models/res_bank.py
@@ -4,25 +4,39 @@
import re
from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError
from odoo.tools.misc import mod10r
from odoo.exceptions import UserError
import werkzeug.urls
+ISR_SUBSCRIPTION_CODE = {'CHF': '01', 'EUR': '03'}
+CLEARING = "09000"
+_re_postal = re.compile('^[0-9]{2}-[0-9]{1,6}-[0-9]$')
+
+
def _is_l10n_ch_postal(account_ref):
- """ Returns True iff the string account_ref is a valid postal account number,
+ """ Returns True if the string account_ref is a valid postal account number,
i.e. it only contains ciphers and is last cipher is the result of a recursive
modulo 10 operation ran over the rest of it. Shorten form with - is also accepted.
"""
- if re.match('^[0-9]{2}-[0-9]{1,6}-[0-9]$', account_ref or ''):
+ if _re_postal.match(account_ref or ''):
ref_subparts = account_ref.split('-')
- account_ref = ref_subparts[0] + ref_subparts[1].rjust(6,'0') + ref_subparts[2]
+ account_ref = ref_subparts[0] + ref_subparts[1].rjust(6, '0') + ref_subparts[2]
if re.match('\d+$', account_ref or ''):
account_ref_without_check = account_ref[:-1]
return mod10r(account_ref_without_check) == account_ref
return False
+def _is_l10n_ch_isr_issuer(account_ref, currency_code):
+ """ Returns True if the string account_ref is a valid a valid ISR issuer
+ An ISR issuer is postal account number that starts by 01 (CHF) or 03 (EUR),
+ """
+ if (account_ref or '').startswith(ISR_SUBSCRIPTION_CODE[currency_code]):
+ return _is_l10n_ch_postal(account_ref)
+ return False
+
class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank'
@@ -40,6 +54,38 @@ class ResPartnerBank(models.Model):
l10n_ch_isr_subscription_eur = fields.Char(string='EUR ISR Subscription Number', help='The subscription number provided by the bank or Postfinance to identify the bank, used to generate ISR in EUR. eg. 03-162-5')
l10n_ch_show_subscription = fields.Boolean(compute='_compute_l10n_ch_show_subscription', default=lambda self: self.env.company.country_id.code == 'CH')
+ def _is_isr_issuer(self):
+ return (_is_l10n_ch_isr_issuer(self.l10n_ch_postal, 'CHF')
+ or _is_l10n_ch_isr_issuer(self.l10n_ch_postal, 'EUR'))
+
+ @api.constrains("l10n_ch_postal", "partner_id")
+ def _check_postal_num(self):
+ """Validate postal number format"""
+ for rec in self:
+ if rec.l10n_ch_postal and not _is_l10n_ch_postal(self.l10n_ch_postal):
+ # l10n_ch_postal is used for the purpose of Client Number on your own accounts, so don't do the check there
+ if rec.partner_id and not rec.partner_id.ref_company_ids:
+ raise ValidationError(
+ _("The postal number {} is not valid.\n"
+ "It must be a valid postal number format. eg. 10-8060-7").format(rec.l10n_ch_postal))
+ return True
+
+ @api.constrains("l10n_ch_isr_subscription_chf", "l10n_ch_isr_subscription_eur")
+ def _check_subscription_num(self):
+ """Validate ISR subscription number format
+ Subscription number can only starts with 01 or 03
+ """
+ for rec in self:
+ for currency in ["CHF", "EUR"]:
+ subscrip = rec.l10n_ch_isr_subscription_chf if currency == "CHF" else rec.l10n_ch_isr_subscription_eur
+ if subscrip and not _is_l10n_ch_isr_issuer(subscrip, currency):
+ example = "01-162-8" if currency == "CHF" else "03-162-5"
+ raise ValidationError(
+ _("The ISR subcription {} for {} number is not valid.\n"
+ "It must starts with {} and we a valid postal number format. eg. {}"
+ ).format(subscrip, currency, ISR_SUBSCRIPTION_CODE[currency], example))
+ return True
+
@api.depends('partner_id', 'company_id')
def _compute_l10n_ch_show_subscription(self):
for bank in self:
@@ -89,19 +135,45 @@ class ResPartnerBank(models.Model):
record.l10n_ch_postal = record.acc_number.split(" ")[0]
else:
record.l10n_ch_postal = record.acc_number
- if record.partner_id:
- record.acc_number = record.acc_number + ' ' + record.partner_id.name
+ # In case of ISR issuer, this number is not
+ # unique and we fill acc_number with partner
+ # name to give proper information to the user
+ if record.partner_id and record.acc_number[:2] in ["01", "03"]:
+ record.acc_number = ("{} {}").format(record.acc_number, record.partner_id.name)
+
+ @api.model
+ def _is_postfinance_iban(self, iban):
+ """Postfinance IBAN have format
+ CHXX 0900 0XXX XXXX XXXX K
+ Where 09000 is the clearing number
+ """
+ return iban.startswith('CH') and iban[4:9] == CLEARING
+
+ @api.model
+ def _pretty_postal_num(self, number):
+ """format a postal account number or an ISR subscription number
+ as per specifications with '-' separators.
+ eg. 010001628 -> 01-162-8
+ """
+ if re.match('^[0-9]{2}-[0-9]{1,6}-[0-9]$', number or ''):
+ return number
+ currency_code = number[:2]
+ middle_part = number[2:-1]
+ trailing_cipher = number[-1]
+ middle_part = middle_part.lstrip("0")
+ return currency_code + '-' + middle_part + '-' + trailing_cipher
@api.model
def _retrieve_l10n_ch_postal(self, iban):
- """ Reads a swiss postal account number from a an IBAN and returns it as
+ """Reads a swiss postal account number from a an IBAN and returns it as
a string. Returns None if no valid postal account number was found, or
- the given iban was not from Switzerland.
+ the given iban was not from Swiss Postfinance.
+
+ CH09 0900 0000 1000 8060 7 -> 10-8060-7
"""
- if iban[:2] == 'CH':
- #the IBAN corresponds to a swiss account
- if _is_l10n_ch_postal(iban[-12:]):
- return iban[-12:]
+ if self._is_postfinance_iban(iban):
+ # the IBAN corresponds to a swiss account
+ return self._pretty_postal_num(iban[-9:])
return None
def _get_qr_code_url(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
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
similarity index 98%
rename from addons/l10n_ch/tests/test_l10n_ch_isr.py
rename to 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
diff --git a/addons/l10n_ch/views/account_invoice_view.xml b/addons/l10n_ch/views/account_invoice_view.xml
index 046dc2b3544..1c5a59284a8 100644
--- a/addons/l10n_ch/views/account_invoice_view.xml
+++ b/addons/l10n_ch/views/account_invoice_view.xml
@@ -60,6 +60,12 @@
groups="base.group_user"
/>
+