Files
odoo_source/addons/stock/report/report_package_barcode.xml
T
Arnold Moyaux f613ce968d [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>
2022-11-30 10:05:27 +01:00

141 lines
9.2 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="report_package_barcode">
<t t-call="web.basic_layout">
<!-- quantity patterns are always 3 digit codes + 1 digit for number of digits (excluding units) -->
<t t-set="uom_unit_id" t-value="env.ref('uom.product_uom_unit').id"/>
<t t-set="gs1_uom_patterns" t-value="{rule.associated_uom_id.id: rule.pattern[1:4] + str(len(str('{:.10f}'.format(rule.associated_uom_id.rounding).rstrip('0')).split('.')[1])) for rule in env['barcode.rule'].search([('associated_uom_id', '!=', False), ('associated_uom_id.id', '!=', uom_unit_id), ('is_gs1_nomenclature', '=', True)])}"/>
<t t-foreach="docs" t-as="o">
<t>
<div class="page">
<div class="oe_structure"/>
<table class="table table-condensed" style="border-bottom: 0px solid white !important;">
<tr>
<th>
<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">
<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': 'ECC200DataMatrix', 'width': 100, 'height': 100}"/>
</div>
</t>
<t t-else="">
<div t-field="o.name" t-options="{'widget': 'barcode', 'width': 600, 'height': 100, 'img_style': 'width:300px;height:50px;'}"/>
<p t-field="o.name"/>
</t>
</th>
</tr>
</table>
<div class="row mt32 mb32">
<div t-if="o.pack_date" class="col-auto">
<strong>Pack Date:</strong>
<p t-field="o.pack_date"/>
</div>
<div t-if="o.package_type_id" class="o_packaging_type col-auto">
<strong>Package Type:</strong>
<p t-field="o.package_type_id.name"/>
</div>
</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="any(valid_ean for valid_ean in o.quant_ids.product_id.mapped('valid_ean'))" />
<thead>
<tr>
<th>Product</th>
<th name="th_quantity" class="text-end">Quantity</th>
<th name="th_uom" groups="uom.group_uom"/>
<th name="th_serial" class="text-end" t-if="has_serial_number">Lot/Serial Number</th>
<th name="th_barcode" class="text-end" t-if="has_ean_barcode"/>
</tr>
</thead>
<tbody>
<tr t-foreach="o.quant_ids" t-as="l">
<td>
<span t-field="l.product_id.name"/>
</td>
<td class="text-end">
<span t-field="l.quantity"/>
</td>
<td groups="uom.group_uom">
<span t-field="l.product_id.uom_id.name"/>
</td>
<td class="text-end" t-if="has_serial_number">
<t t-if="l.lot_id"><span t-field="l.lot_id.name"/></t>
</td>
<td class="text-end" t-if="has_ean_barcode">
<t t-if="l.product_id.valid_ean">
<t t-set="product_barcode" t-value="'01' + '0' * (14 - len(l.product_id.barcode)) + l.product_id.barcode"/>
<t t-set="gs1_pattern" t-value="gs1_uom_patterns.get(l.product_uom_id.id, False)"/>
<t t-if="(gs1_pattern or l.product_uom_id.id == uom_unit_id) and l.quantity &gt;= 0">
<t t-if="gs1_pattern">
<t t-set="qty_str" t-value="str(int(l.quantity/l.product_uom_id.rounding))"/>
<t t-if="len(qty_str) &lt;= 6" t-set="product_barcode" t-value="product_barcode + gs1_pattern + '0' * (6 - len(qty_str)) + qty_str"/>
</t>
<t t-else="">
<!-- GS1 have no decimal indicator for unit uom => round for now.. -->
<t t-set="qty_str" t-value="str(int(round(l.quantity)))"/>
<t t-if="len(qty_str) &lt;=8" t-set="product_barcode" t-value="product_barcode + '30' + '0' * (8 - len(qty_str)) + qty_str"/>
</t>
</t>
<!-- 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': 'ECC200DataMatrix', 'img_style': 'width:17mm;height:17mm'}"/>
</t>
</td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</t>
</template>
<template id="report_package_barcode_small">
<t t-call="web.basic_layout">
<t t-foreach="docs" t-as="o">
<t>
<div class="page">
<div class="oe_structure"/>
<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': '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>
<div t-if="o.package_type_id" class="row" name="datamatrix_pack_type">Package Type: <span t-field="o.package_type_id.name"/></div>
</div>
</div>
</t>
<t t-else="">
<div class="row">
<div class="text-center col-12">
<div t-field="o.name" t-options="{'widget': 'barcode', 'width': 600, 'height': 100, 'img_style': 'width:600px;height:100px;'}"/>
<div t-field="o.name" style="font-size:20px;"/>
</div>
</div>
<div t-if="o.pack_date" class="col-12 text-center" style="font-size:24px; font-weight:bold;">Pack Date: <span t-field="o.pack_date"/></div>
<div class="row o_packaging_type" t-if="o.package_type_id">
<div class="col-12 text-center" style="font-size:24px; font-weight:bold;"><span>Package Type: </span><span t-field="o.package_type_id.name"/></div>
</div>
</t>
</div>
</t>
</t>
</t>
</template>
<template id="report_picking_packages">
<t t-set="docs" t-value="docs.move_line_ids.mapped('result_package_id')"/>
<t t-call="stock.report_package_barcode"/>
</template>
</data>
</odoo>