[IMP] base: improve qweb barcode widget
When printing barcodes for a large amount of records, wkhtmltopdf will make the same amount of http requests to the server in order to retrieve barcodes. This can lead to performance issues or wkhtml to crash. Fortunately, an already existsing qweb widget exists that include barcodes images as inline base64. With this commit, the web widget is a bit improved to accept attributes for the generated image tag. Each option dictionary key starting with `img_` will be converted into a tag attribute with the corresponding value. e.g.: `'img_alt': 'Barcode'` will result in `<img alt="Barcode"...` The `alt` img attribute now defaults to `'Barcode %s' % value` with the barcode value. Also, the `quiet` reportlab option is also avalaible in the widget options, as well as the `mask` option. Finally, if the `symbology` option is not given, the widget defaults to `Code128`. If `symbology` is set to `auto`, the action report will try to guess the barcode type, based on the len of the value.
This commit is contained in:
@@ -507,6 +507,9 @@ class IrActionsReport(models.Model):
|
||||
barcode_type = 'EAN13'
|
||||
if len(value) in (11, 12):
|
||||
value = '0%s' % value
|
||||
elif barcode_type == 'auto':
|
||||
symbology_guess = {8: 'EAN8', 13: 'EAN13'}
|
||||
barcode_type = symbology_guess.get(len(value), 'Code128')
|
||||
try:
|
||||
width, height, humanreadable, quiet = int(width), int(height), bool(int(humanreadable)), bool(int(quiet))
|
||||
# for `QR` type, `quiet` is not supported. And is simply ignored.
|
||||
|
||||
@@ -651,17 +651,25 @@ class BarcodeConverter(models.AbstractModel):
|
||||
width=dict(type='integer', string=_('Width'), default_value=600),
|
||||
height=dict(type='integer', string=_('Height'), default_value=100),
|
||||
humanreadable=dict(type='integer', string=_('Human Readable'), default_value=0),
|
||||
quiet=dict(type='integer', string='Quiet', default_value=1),
|
||||
mask=dict(type='string', string='Mask', default_value='')
|
||||
)
|
||||
return options
|
||||
|
||||
@api.model
|
||||
def value_to_html(self, value, options=None):
|
||||
if not value:
|
||||
return ''
|
||||
barcode_symbology = options.get('symbology', 'Code128')
|
||||
barcode = self.env['ir.actions.report'].barcode(
|
||||
barcode_symbology,
|
||||
value,
|
||||
**{key: value for key, value in options.items() if key in ['width', 'height', 'humanreadable']})
|
||||
return u'<img src="data:png;base64,%s">' % base64.b64encode(barcode).decode('ascii')
|
||||
**{key: value for key, value in options.items() if key in ['width', 'height', 'humanreadable', 'quiet', 'mask']})
|
||||
img_attributes = {k[4:]: v for k, v in options.items() if k.startswith('img_')}
|
||||
if 'alt' not in img_attributes:
|
||||
img_attributes.update({'alt': 'Barcode %s' % value})
|
||||
attributes = ' '.join(['%s="%s"' % attrs for attrs in img_attributes.items()])
|
||||
return u'<img src="data:png;base64,%s" %s>' % (base64.b64encode(barcode).decode('ascii'), attributes)
|
||||
|
||||
|
||||
class Contact(models.AbstractModel):
|
||||
|
||||
@@ -557,6 +557,30 @@ class TestQWebNS(TransactionCase):
|
||||
rendered = view2.with_context(lang=current_lang)._render().strip()
|
||||
self.assertEqual(rendered, b'9/000/000*00')
|
||||
|
||||
def test_render_barcode(self):
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'bacode_test',
|
||||
'barcode': 'test'
|
||||
})
|
||||
|
||||
view = self.env['ir.ui.view'].create({
|
||||
'name': "a_barcode_view",
|
||||
'type': 'qweb',
|
||||
})
|
||||
|
||||
view.arch = u"""<div t-field="partner.barcode" t-options="{'widget': 'barcode', 'width': 100, 'height': 30}"/>"""
|
||||
rendered = view._render(values={'partner': partner}).strip().decode()
|
||||
self.assertRegex(rendered,r'<div><img src="data:png;base64,\S+" alt="Barcode test"></div>')
|
||||
|
||||
partner.barcode = '4012345678901'
|
||||
view.arch = u"""<div t-field="partner.barcode" t-options="{'widget': 'barcode', 'symbology': 'EAN13', 'width': 100, 'height': 30, 'img_style': 'width:100%;', 'img_alt': 'Barcode'}"/>"""
|
||||
ean_rendered = view._render(values={'partner': partner}).strip().decode()
|
||||
self.assertRegex(ean_rendered,r'<div><img src="data:png;base64,\S+" style="width:100%;" alt="Barcode"></div>')
|
||||
|
||||
view.arch = u"""<div t-field="partner.barcode" t-options="{'widget': 'barcode', 'symbology': 'auto', 'width': 100, 'height': 30, 'img_style': 'width:100%;', 'img_alt': 'Barcode'}"/>"""
|
||||
auto_rendered = view._render(values={'partner': partner}).strip().decode()
|
||||
self.assertRegex(auto_rendered,r'<div><img src="data:png;base64,\S+" style="width:100%;" alt="Barcode"></div>')
|
||||
|
||||
|
||||
from copy import deepcopy
|
||||
class FileSystemLoader(object):
|
||||
|
||||
Reference in New Issue
Block a user