summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authoroco-odoo <oco@odoo.com>2020-02-07 10:10:09 +0000
committeroco-odoo <oco@odoo.com>2020-03-30 11:28:41 +0000
commit0eef278268d1f4cce30c97bfef723f769b1a48e0 (patch)
treeae9df84a16740d8a41b079da599017a3f55f0a2d /odoo
parentc1f3596bd32efcbec40e66c29930ccdc29072f92 (diff)
[IMP] base, account, l10n_ch, website_sale, payment, web: make payment QR-code generation more generic
This new modelling makes it easier to add new QR-code formats, and allows using all of them in website_sale and account.payment's form view as well (so, Swiss QR codes are now available there, while they were restricted to only invoices in the past). All barcodes are now generated as reports, from a dedicated route. This was only partly the case before : Swiss QR added a cross on top of the QR-code directly in the template, it wasn't part of the image returned by the route; now it is. [ADD] base_qr_code_sepa: new module decoupling SEPA QR-codes generation from the base module Each new QR-code generation option should thus be done in a dedicated module (or added to a localization) in the future. [IMP] base_qr_code_sepa: update the generated QR codes to version 2 of the specification Version 1 is still supported, so no need to backport this. [IMP] l10n_ch: make Swiss QR-codes compatible with the new version of the specification (the old one is deprecated) This will be backported to 11.0 and 12.0, as these QR-codes will soon replace ISR. [IMP] account: make it possible to mark manual payments as sent with a button on the form view This way, when making them directly with a QR-code (or doing a more classical wire transfer), people can keep track of what they already have asked the bank to do, and what they still have to treat. closes odoo/odoo#44839 Related: odoo/enterprise#8262 Related: odoo/upgrade#992 Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/base/models/ir_actions_report.py24
-rw-r--r--odoo/addons/base/models/res_bank.py26
2 files changed, 26 insertions, 24 deletions
diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py
index 18b64b3c1c1..283d572de7e 100644
--- a/odoo/addons/base/models/ir_actions_report.py
+++ b/odoo/addons/base/models/ir_actions_report.py
@@ -491,7 +491,7 @@ class IrActionsReport(models.Model):
return report_obj.with_context(context).search(conditions, limit=1)
@api.model
- def barcode(self, barcode_type, value, width=600, height=100, humanreadable=0, quiet=1):
+ def barcode(self, barcode_type, value, width=600, height=100, humanreadable=0, quiet=1, mask=None):
if barcode_type == 'UPCA' and len(value) in (11, 12, 13):
barcode_type = 'EAN13'
if len(value) in (11, 12):
@@ -502,6 +502,15 @@ class IrActionsReport(models.Model):
barcode_type, value=value, format='png', width=width, height=height,
humanReadable=humanreadable, quiet=quiet
)
+
+ # If a mask is asked and it is available, call its function to
+ # post-process the generated QR-code image
+ if mask:
+ available_masks = self.get_available_barcode_masks()
+ mask_to_apply = available_masks.get(mask)
+ if mask_to_apply:
+ mask_to_apply(width, height, barcode)
+
return barcode.asString('png')
except (ValueError, AttributeError):
if barcode_type == 'Code128':
@@ -510,6 +519,19 @@ class IrActionsReport(models.Model):
return self.barcode('Code128', value, width=width, height=height,
humanreadable=humanreadable, quiet=quiet)
+ @api.model
+ def get_available_barcode_masks(self):
+ """ Hook for extension.
+ This function returns the available QR-code masks, in the form of a
+ list of (code, mask_function) elements, where code is a string identifying
+ the mask uniquely, and mask_function is a function returning a reportlab
+ Drawing object with the result of the mask, and taking as parameters:
+ - width of the QR-code, in pixels
+ - height of the QR-code, in pixels
+ - reportlab Drawing object containing the barcode to apply the mask on
+ """
+ return {}
+
def render_template(self, template, values=None):
"""Allow to render a QWeb template python-side. This function returns the 'ir.ui.view'
render but embellish it with some variables/methods used in reports.
diff --git a/odoo/addons/base/models/res_bank.py b/odoo/addons/base/models/res_bank.py
index be7b8245ca8..edd0c68f68a 100644
--- a/odoo/addons/base/models/res_bank.py
+++ b/odoo/addons/base/models/res_bank.py
@@ -6,6 +6,7 @@ import collections
from odoo import api, fields, models, _
from odoo.osv import expression
+from odoo.exceptions import UserError
import werkzeug.urls
@@ -49,12 +50,12 @@ class Bank(models.Model):
domain = ['&'] + domain
bank_ids = self._search(domain + args, limit=limit, access_rights_uid=name_get_uid)
return models.lazy_name_get(self.browse(bank_ids).with_user(name_get_uid))
-
+
@api.onchange('country')
def _onchange_country_id(self):
if self.country and self.country != self.state.country_id:
self.state = False
-
+
@api.onchange('state')
def _onchange_state(self):
if self.state.country_id:
@@ -86,7 +87,6 @@ class ResPartnerBank(models.Model):
sequence = fields.Integer(default=10)
currency_id = fields.Many2one('res.currency', string='Currency')
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.company, ondelete='cascade')
- qr_code_valid = fields.Boolean(string="Has all required arguments", compute="_validate_qr_code_arguments")
_sql_constraints = [
('unique_number', 'unique(sanitized_acc_number, company_id)', 'Account Number must be unique'),
@@ -125,23 +125,3 @@ class ResPartnerBank(models.Model):
args[pos] = ('sanitized_acc_number', op, value)
pos += 1
return super(ResPartnerBank, self)._search(args, offset, limit, order, count=count, access_rights_uid=access_rights_uid)
-
- @api.model
- def build_qr_code_url(self, amount, comment):
- communication = ""
- if comment:
- communication = (comment[:137] + '...') if len(comment) > 140 else comment
- qr_code_string = 'BCD\n001\n1\nSCT\n%s\n%s\n%s\nEUR%s\n\n\n%s' % (self.bank_bic or "", self.company_id.name, self.acc_number, amount, communication)
- qr_code_url = '/report/barcode/?' + werkzeug.urls.url_encode({'type': 'QR', 'value': qr_code_string, 'width': 128, 'height': 128, 'humanreadable': 1})
- return qr_code_url
-
- def _validate_qr_code_arguments(self):
- sepa_zones_codes = [c.code for c in self.env.ref('base.sepa_zone').country_ids]
- # Some country instances share the same IBAN country code (e.g. Åland Islands and Finland IBANs are "FI", but Åland Islands code is "AX").
- # Therefore sepa_zones_codes is too permissive, "AX" is not a valid IBAN country code.
- not_iban_codes = ("AX", "NC", "YT", "TF", "BL", "RE", "MF", "GP", "PM", "PF", "GF", "MQ", "JE", "GG", "IM")
- sepa_zones_codes = [code for code in sepa_zones_codes if code not in not_iban_codes]
- for bank in self:
- bank.qr_code_valid = (bank.company_id.name and
- bank.acc_number and
- bank.sanitized_acc_number[:2] in sepa_zones_codes)