[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:
@@ -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.
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
Reference in New Issue
Block a user