[FIX] base, stock, delivery: replace support datamatrix barcode printing

This reverts commit 3ebe1185a4.

The code ECC200DataMatrix already exist in reportlab (that is already a dependance).
Some differences:
- ECC200DataMatrix only supports a Type 12 (44x44) C40 encoded data matrix.
  (214 alphanumeric characters and 14 to 27% of error correcting rate)
- pylibdmtx support more type and add a default to 24x24. So it means a
  (52 characters and 20 to 35% error correcting rate). It's also smaller
  to display.

We consider the gain too small compare to maintain an extra lib.

It also fix blured datamatrix in stock report if they contains too much
data.

*If you want to test 001234560000000018 is a valid sscc for package

closes odoo/odoo#106620

X-original-commit: 54ef19f41ffc4a6f715474b65a4183a7fa75feea
Related: odoo/enterprise#34422
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
This commit is contained in:
Arnold Moyaux
2022-11-30 10:05:27 +01:00
parent 81076aa514
commit f613ce968d
6 changed files with 15 additions and 22 deletions
@@ -35,7 +35,7 @@
</t>
</xpath>
<xpath expr="//div[hasclass('o_packaging_type')]" position="after">
<t t-if="o.valid_sscc and env['ir.actions.report'].datamatrix_available()">
<t t-if="o.valid_sscc">
<!-- SSCC uses weight if necessary/available, standard barcode will not -->
<div t-if="o.shipping_weight" class="col-auto"><strong>Shipping Weight: </strong><span t-field="o.shipping_weight"/> <t t-out="o.weight_uom_name"/></div>
<div t-elif="o.weight" class="col-auto"><strong>Weight: </strong><span t-field="o.weight"/> <t t-out="o.weight_uom_name"/></div>
+1 -2
View File
@@ -8486,8 +8486,7 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:stock.res_config_settings_view_form
msgid ""
"Use GS1 nomenclature datamatrix whenever barcodes are printed for lots and "
"serial numbers. Printing datamatrix requires extra software. If software "
"can't be found then 1D barcodes will be printed."
"serial numbers."
msgstr ""
#. module: stock
+2 -2
View File
@@ -23,13 +23,13 @@
<div class="o_label_4x12" name="lot_name">
LN/SN: <span t-field="o.name"/>
</div>
<t t-if="env.user.has_group('stock.group_stock_lot_print_gs1') and env['ir.actions.report'].datamatrix_available()">
<t t-if="env.user.has_group('stock.group_stock_lot_print_gs1')">
<!-- ensure we clear barcode string when multi-record print -->
<t t-set="final_barcode" t-value="''"/>
<t t-if="o.product_id.valid_ean" t-set="final_barcode" t-value="'01' + '0' * (14 - len(o.product_id.barcode)) + o.product_id.barcode"/>
<t name="gs1_datamatrix_lot" t-if="o.product_id.tracking == 'lot'" t-set="final_barcode" t-value="(final_barcode or '') + '10' + o.name"/>
<t t-elif="o.product_id.tracking == 'serial'" t-set="final_barcode" t-value="(final_barcode or '') + '21' + o.name"/>
<div t-if="final_barcode" t-att-style="'position:absolute; right:.5px; bottom:.5px'" t-out="final_barcode" t-options="{'widget': 'barcode', 'symbology': 'DataMatrix', 'width': 45, 'height': 45}"/>
<div t-if="final_barcode" t-att-style="'position:absolute; right:.5px; bottom:.5px'" t-out="final_barcode" t-options="{'widget': 'barcode', 'symbology': 'ECC200DataMatrix', 'img_style': 'width:17mm; height:17mm'}"/>
</t>
<t t-else="">
<div t-field="o.name" t-options="{'widget': 'barcode', 'img_style': 'width:100%; height:35%'}"/>
@@ -16,11 +16,11 @@
<h1 t-field="o.name" class="mt0 float-start"/>
</th>
<th name="td_pk_barcode" style="text-align: center">
<t t-if="o.valid_sscc and env['ir.actions.report'].datamatrix_available()">
<t t-if="o.valid_sscc">
<div class="row text-start">
<t t-set="barcode" t-value="'00' + o.name"/>
<t t-if="o.pack_date" t-set="barcode" t-value="barcode + '13' + o.pack_date.strftime('%y%m%d')"/>
<div class="col-3" name="datamatrix_barcode" style="margin: 0px 20px 40px 60px" t-out="barcode" t-options="{'widget': 'barcode', 'symbology': 'DataMatrix', 'width': 100, 'height': 100}"/>
<div class="col-3" name="datamatrix_barcode" style="margin: 0px 20px 40px 60px" t-out="barcode" t-options="{'widget': 'barcode', 'symbology': 'ECC200DataMatrix', 'width': 100, 'height': 100}"/>
</div>
</t>
<t t-else="">
@@ -42,7 +42,7 @@
</div>
<table class="table table-sm table-striped" style="border-bottom: 0px solid white !important;">
<t t-set="has_serial_number" t-value="o.quant_ids.mapped('lot_id')" />
<t t-set="has_ean_barcode" t-value="env['ir.actions.report'].datamatrix_available() and any(valid_ean for valid_ean in o.quant_ids.product_id.mapped('valid_ean'))" />
<t t-set="has_ean_barcode" t-value="any(valid_ean for valid_ean in o.quant_ids.product_id.mapped('valid_ean'))" />
<thead>
<tr>
<th>Product</th>
@@ -84,7 +84,7 @@
<!-- TODO: lot/sn ALWAYS has to be last part of barcode since left padding '0's = different sn/lot name match when scanning => fix when FNC1 can be used, -->
<t name="product_barcode_lot_datamatrix" t-if="l.product_id.tracking == 'lot' and l.lot_id" t-set="product_barcode" t-value="product_barcode + '10' + l.lot_id.name"/>
<t t-elif="l.product_id.tracking == 'serial' and l.lot_id" t-set="product_barcode" t-value="product_barcode + '21' + l.lot_id.name"/>
<span t-out="product_barcode" t-options="{'widget': 'barcode', 'symbology': 'DataMatrix', 'width': 45, 'height': 45}"/>
<span t-out="product_barcode" t-options="{'widget': 'barcode', 'symbology': 'ECC200DataMatrix', 'img_style': 'width:17mm;height:17mm'}"/>
</t>
</td>
</tr>
@@ -102,11 +102,11 @@
<t>
<div class="page">
<div class="oe_structure"/>
<t t-if="o.valid_sscc and env['ir.actions.report'].datamatrix_available()">
<t t-if="o.valid_sscc">
<div class="row">
<t t-set="barcode" t-value="'00' + o.name"/>
<t t-if="o.pack_date" t-set="barcode" t-value="barcode + '13' + o.pack_date.strftime('%y%m%d')"/>
<div class="col-5 text-end" name="datamatrix_barcode" style="margin: 0px 20px 40px 60px" t-out="barcode" t-options="{'widget': 'barcode', 'symbology': 'DataMatrix', 'width': 200, 'height': 200}"/>
<div class="col-5 text-end" name="datamatrix_barcode" style="margin: 0px 20px 40px 60px" t-out="barcode" t-options="{'widget': 'barcode', 'symbology': 'ECC200DataMatrix', 'width': 200, 'height': 200}"/>
<div class="col-7 text-start" style="font-size:20px;">
<div class="row">SSCC: <span t-field="o.name"/></div>
<div t-if="o.pack_date" class="row">Pack Date: <span t-field="o.pack_date"/></div>
@@ -350,7 +350,7 @@
<field name="group_stock_lot_print_gs1" class="col-lg-1 ml16 mr0"/>
<div class="col ps-0">
<label for="group_stock_lot_print_gs1"/>
<div class="text-muted">Use GS1 nomenclature datamatrix whenever barcodes are printed for lots and serial numbers. Printing datamatrix requires extra software. If software can't be found then 1D barcodes will be printed.</div>
<div class="text-muted">Use GS1 nomenclature datamatrix whenever barcodes are printed for lots and serial numbers.</div>
</div>
</div>
</div>
+4 -10
View File
@@ -42,12 +42,6 @@ try:
except Exception:
pass
datamatrix_available = True
try:
from pylibdmtx import pylibdmtx
except Exception:
_logger.info('A package may be missing to print Data Matrix barcodes: pylibdmtx or libdmtx.')
datamatrix_available = False
def _get_wkhtmltopdf_bin():
return find_in_path('wkhtmltopdf')
@@ -221,7 +215,7 @@ class IrActionsReport(models.Model):
:return: Boolean
'''
return datamatrix_available
return True
def get_paperformat(self):
return self.paperformat_id or self.env.company.paperformat_id
@@ -542,9 +536,9 @@ class IrActionsReport(models.Model):
elif barcode_type == 'auto':
symbology_guess = {8: 'EAN8', 13: 'EAN13'}
barcode_type = symbology_guess.get(len(value), 'Code128')
elif barcode_type == 'DataMatrix' and not self.datamatrix_available():
# fallback to avoid stacktrack because reportlab won't recognize the type and error message isn't useful/will be blocking
barcode_type = 'Code128'
elif barcode_type == 'DataMatrix':
# Prevent a crash due to a lib change from pylibdmtx to reportlab
barcode_type = 'ECC200DataMatrix'
elif barcode_type == 'QR':
# for `QR` type, `quiet` is not supported. And is simply ignored.
# But we can use `barBorder` to get a similar behaviour.