[IMP] l10n_ch: allow to use Creditor Reference in swiss payment QR-Bill

Creditor Reference is one of the 3 allowed references type in swiss QR-Bills (with None and QR-Reference)

    It is used with normal IBAN (QR-Reference must be used only with special QR-IBAN)

    Fixes #71578
    Closes #81269

closes odoo/odoo#95518

X-original-commit: 8e1d86dcb10aebc1be1a318126492573a4b74331
Signed-off-by: Olivier Colson (oco) <oco@odoo.com>
This commit is contained in:
Téo Goddet
2022-08-19 10:31:03 +02:00
parent 27fac8bb7c
commit 62fa76a044
3 changed files with 46 additions and 4 deletions
+8
View File
@@ -331,6 +331,14 @@ class AccountMove(models.Model):
i -= 5
return spaced_qrr_ref
@api.model
def space_scor_reference(self, iso11649_ref):
""" Makes the provided SCOR reference human-friendly, spacing its elements
by blocks of 5 from right to left.
"""
return ' '.join(iso11649_ref[i:i + 4] for i in range(0, len(iso11649_ref), 4))
def l10n_ch_action_print_qr(self):
'''
Checks that all invoices can be printed in the QR format.
+16 -1
View File
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from stdnum.util import clean
from odoo import api, fields, models, _
from odoo.addons.base.models.res_bank import sanitize_account_number
@@ -255,6 +256,9 @@ class ResPartnerBank(models.Model):
reference_type = 'QRR'
reference = structured_communication
acc_number = sanitize_account_number(self.l10n_ch_qr_iban)
elif self._is_iso11649_reference(structured_communication):
reference_type = 'SCOR'
reference = structured_communication.replace(' ', '')
currency = currency or self.currency_id or self.company_id.currency_id
@@ -331,11 +335,22 @@ class ResPartnerBank(models.Model):
and re.match('\d+$', reference) \
and reference == mod10r(reference[:-1])
@api.model
def _is_iso11649_reference(self, reference):
""" Checks whether the given reference is a ISO11649 (SCOR) reference.
"""
return reference \
and len(reference) >= 5 \
and len(reference) <= 25 \
and reference.startswith('RF') \
and int(''.join(str(int(x, 36)) for x in clean(reference[4:] + reference[:4], ' -.,/:').upper().strip())) % 97 == 1
# see https://github.com/arthurdejong/python-stdnum/blob/master/stdnum/iso11649.py
def _eligible_for_qr_code(self, qr_method, debtor_partner, currency, raises_error=True):
if qr_method == 'ch_qr':
error_messages = [_("The QR code could not be generated for the following reason(s):")]
if self.acc_type != 'iban':
error_messages.append(_("The account type isn't QR-IBAN."))
error_messages.append(_("The account type isn't QR-IBAN or IBAN."))
if self.partner_id.country_id.code != 'CH':
error_messages.append(_("Your company isn't located in Switzerland."))
if not debtor_partner or debtor_partner.country_id.code != 'CH':
+22 -3
View File
@@ -22,6 +22,9 @@
<t t-set="formated_amount" t-value="'{:,.2f}'.format(o.amount_residual).replace(',','\xa0')"/>
<t t-set="is_qrr" t-value="o.partner_bank_id.l10n_ch_qr_iban"/>
<t t-set="is_scor" t-value="o.partner_bank_id._is_iso11649_reference(o.payment_reference)"/>
<div class="swissqr_page_title">
<h1>QR-bill for invoice <t t-esc="o.name"/></h1>
</div>
@@ -53,15 +56,23 @@
<br/>
</div>
<t t-if="o.partner_bank_id.l10n_ch_qr_iban">
<t t-if="is_qrr or is_scor">
<div class="swissqr_text title">
<span>Reference</span>
</div>
</t>
<t t-if="is_qrr">
<div class="swissqr_text content">
<span t-esc="o.space_qrr_reference(o.payment_reference)"/><br/>
<br/>
</div>
</t>
<t t-if="is_scor">
<div class="swissqr_text content">
<span t-esc="o.space_scor_reference(o.payment_reference)"/><br/>
<br/>
</div>
</t>
<div class="swissqr_text title">
<span>Payable by</span>
@@ -157,17 +168,25 @@
<br/>
</div>
<t t-if="o.partner_bank_id.l10n_ch_qr_iban">
<t t-if="is_qrr or is_scor">
<div class="swissqr_text title">
<span class="title">Reference</span>
</div>
</t>
<t t-if="is_qrr">
<div class="swissqr_text content">
<span t-esc="o.space_qrr_reference(o.payment_reference)"/><br/>
<br/>
</div>
</t>
<t t-if="is_scor">
<div class="swissqr_text content">
<span t-esc="o.space_scor_reference(o.payment_reference)"/><br/>
<br/>
</div>
</t>
<t t-set="additional_info" t-value="(o.ref or o.name if o.partner_bank_id.l10n_ch_qr_iban else o.payment_reference or o.ref or o.name)"/>
<t t-set="additional_info" t-value="(o.ref or o.name if is_qrr or is_scor else o.payment_reference or o.ref or o.name)"/>
<t t-if="additional_info">
<div class="swissqr_text title">
<span>Additional information</span>