mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[MIG] printer_zpl2: Migration to 13.0
This commit is contained in:
committed by
Lois Rilo
parent
18bcf0891f
commit
152267f287
@@ -1,42 +1,42 @@
|
||||
# Copyright (C) 2018 Florent de Labarre (<https://github.com/fmdl>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
import re
|
||||
import base64
|
||||
import binascii
|
||||
import io
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from PIL import Image, ImageOps
|
||||
from odoo import fields, models, _
|
||||
|
||||
from odoo import _ as translate, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import zpl2
|
||||
except ImportError:
|
||||
_logger.debug('Cannot `import zpl2`.')
|
||||
_logger.debug("Cannot `import zpl2`.")
|
||||
|
||||
|
||||
def _compute_arg(data, arg):
|
||||
vals = {}
|
||||
for i, d in enumerate(data.split(',')):
|
||||
for i, d in enumerate(data.split(",")):
|
||||
vals[arg[i]] = d
|
||||
return vals
|
||||
|
||||
|
||||
def _field_origin(data):
|
||||
if data[:2] == 'FO':
|
||||
if data[:2] == "FO":
|
||||
position = data[2:]
|
||||
vals = _compute_arg(position, ['origin_x', 'origin_y'])
|
||||
vals = _compute_arg(position, ["origin_x", "origin_y"])
|
||||
return vals
|
||||
return {}
|
||||
|
||||
|
||||
def _font_format(data):
|
||||
if data[:1] == 'A':
|
||||
data = data.split(',')
|
||||
if data[:1] == "A":
|
||||
data = data.split(",")
|
||||
vals = {}
|
||||
if len(data[0]) > 1:
|
||||
vals[zpl2.ARG_FONT] = data[0][1]
|
||||
@@ -52,15 +52,10 @@ def _font_format(data):
|
||||
|
||||
|
||||
def _default_font_format(data):
|
||||
if data[:2] == 'CF':
|
||||
args = [
|
||||
zpl2.ARG_FONT,
|
||||
zpl2.ARG_HEIGHT,
|
||||
zpl2.ARG_WIDTH,
|
||||
]
|
||||
if data[:2] == "CF":
|
||||
args = [zpl2.ARG_FONT, zpl2.ARG_HEIGHT, zpl2.ARG_WIDTH]
|
||||
vals = _compute_arg(data[2:], args)
|
||||
if vals.get(zpl2.ARG_HEIGHT, False) \
|
||||
and not vals.get(zpl2.ARG_WIDTH, False):
|
||||
if vals.get(zpl2.ARG_HEIGHT, False) and not vals.get(zpl2.ARG_WIDTH, False):
|
||||
vals.update({zpl2.ARG_WIDTH: vals.get(zpl2.ARG_HEIGHT)})
|
||||
else:
|
||||
vals.update({zpl2.ARG_HEIGHT: 10, zpl2.ARG_HEIGHT: 10})
|
||||
@@ -69,7 +64,7 @@ def _default_font_format(data):
|
||||
|
||||
|
||||
def _field_block(data):
|
||||
if data[:2] == 'FB':
|
||||
if data[:2] == "FB":
|
||||
vals = {zpl2.ARG_IN_BLOCK: True}
|
||||
args = [
|
||||
zpl2.ARG_BLOCK_WIDTH,
|
||||
@@ -84,8 +79,8 @@ def _field_block(data):
|
||||
|
||||
|
||||
def _code11(data):
|
||||
if data[:2] == 'B1':
|
||||
vals = {'component_type': zpl2.BARCODE_CODE_11}
|
||||
if data[:2] == "B1":
|
||||
vals = {"component_type": zpl2.BARCODE_CODE_11}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_CHECK_DIGITS,
|
||||
@@ -99,8 +94,8 @@ def _code11(data):
|
||||
|
||||
|
||||
def _interleaved2of5(data):
|
||||
if data[:2] == 'B2':
|
||||
vals = {'component_type': zpl2.BARCODE_INTERLEAVED_2_OF_5}
|
||||
if data[:2] == "B2":
|
||||
vals = {"component_type": zpl2.BARCODE_INTERLEAVED_2_OF_5}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -114,8 +109,8 @@ def _interleaved2of5(data):
|
||||
|
||||
|
||||
def _code39(data):
|
||||
if data[:2] == 'B3':
|
||||
vals = {'component_type': zpl2.BARCODE_CODE_39}
|
||||
if data[:2] == "B3":
|
||||
vals = {"component_type": zpl2.BARCODE_CODE_39}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_CHECK_DIGITS,
|
||||
@@ -129,8 +124,8 @@ def _code39(data):
|
||||
|
||||
|
||||
def _code49(data):
|
||||
if data[:2] == 'B4':
|
||||
vals = {'component_type': zpl2.BARCODE_CODE_49}
|
||||
if data[:2] == "B4":
|
||||
vals = {"component_type": zpl2.BARCODE_CODE_49}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -143,8 +138,8 @@ def _code49(data):
|
||||
|
||||
|
||||
def _pdf417(data):
|
||||
if data[:2] == 'B7':
|
||||
vals = {'component_type': zpl2.BARCODE_PDF417}
|
||||
if data[:2] == "B7":
|
||||
vals = {"component_type": zpl2.BARCODE_PDF417}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -159,8 +154,8 @@ def _pdf417(data):
|
||||
|
||||
|
||||
def _ean8(data):
|
||||
if data[:2] == 'B8':
|
||||
vals = {'component_type': zpl2.BARCODE_EAN_8}
|
||||
if data[:2] == "B8":
|
||||
vals = {"component_type": zpl2.BARCODE_EAN_8}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -173,8 +168,8 @@ def _ean8(data):
|
||||
|
||||
|
||||
def _upce(data):
|
||||
if data[:2] == 'B9':
|
||||
vals = {'component_type': zpl2.BARCODE_UPC_E}
|
||||
if data[:2] == "B9":
|
||||
vals = {"component_type": zpl2.BARCODE_UPC_E}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -188,8 +183,8 @@ def _upce(data):
|
||||
|
||||
|
||||
def _code128(data):
|
||||
if data[:2] == 'BC':
|
||||
vals = {'component_type': zpl2.BARCODE_CODE_128}
|
||||
if data[:2] == "BC":
|
||||
vals = {"component_type": zpl2.BARCODE_CODE_128}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -204,8 +199,8 @@ def _code128(data):
|
||||
|
||||
|
||||
def _ean13(data):
|
||||
if data[:2] == 'BE':
|
||||
vals = {'component_type': zpl2.BARCODE_EAN_13}
|
||||
if data[:2] == "BE":
|
||||
vals = {"component_type": zpl2.BARCODE_EAN_13}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -218,8 +213,8 @@ def _ean13(data):
|
||||
|
||||
|
||||
def _qrcode(data):
|
||||
if data[:2] == 'BQ':
|
||||
vals = {'component_type': zpl2.BARCODE_QR_CODE}
|
||||
if data[:2] == "BQ":
|
||||
vals = {"component_type": zpl2.BARCODE_QR_CODE}
|
||||
args = [
|
||||
zpl2.ARG_ORIENTATION,
|
||||
zpl2.ARG_MODEL,
|
||||
@@ -233,25 +228,21 @@ def _qrcode(data):
|
||||
|
||||
|
||||
def _default_barcode_field(data):
|
||||
if data[:2] == 'BY':
|
||||
args = [
|
||||
zpl2.ARG_MODULE_WIDTH,
|
||||
zpl2.ARG_BAR_WIDTH_RATIO,
|
||||
zpl2.ARG_HEIGHT,
|
||||
]
|
||||
if data[:2] == "BY":
|
||||
args = [zpl2.ARG_MODULE_WIDTH, zpl2.ARG_BAR_WIDTH_RATIO, zpl2.ARG_HEIGHT]
|
||||
return _compute_arg(data[2:], args)
|
||||
return {}
|
||||
|
||||
|
||||
def _field_reverse_print(data):
|
||||
if data[:2] == 'FR':
|
||||
if data[:2] == "FR":
|
||||
return {zpl2.ARG_REVERSE_PRINT: True}
|
||||
return {}
|
||||
|
||||
|
||||
def _graphic_box(data):
|
||||
if data[:2] == 'GB':
|
||||
vals = {'component_type': 'rectangle'}
|
||||
if data[:2] == "GB":
|
||||
vals = {"component_type": "rectangle"}
|
||||
args = [
|
||||
zpl2.ARG_WIDTH,
|
||||
zpl2.ARG_HEIGHT,
|
||||
@@ -265,48 +256,43 @@ def _graphic_box(data):
|
||||
|
||||
|
||||
def _graphic_circle(data):
|
||||
if data[:2] == 'GC':
|
||||
vals = {'component_type': 'circle'}
|
||||
args = [
|
||||
zpl2.ARG_WIDTH,
|
||||
zpl2.ARG_THICKNESS,
|
||||
zpl2.ARG_COLOR,
|
||||
]
|
||||
if data[:2] == "GC":
|
||||
vals = {"component_type": "circle"}
|
||||
args = [zpl2.ARG_WIDTH, zpl2.ARG_THICKNESS, zpl2.ARG_COLOR]
|
||||
vals.update(_compute_arg(data[2:], args))
|
||||
return vals
|
||||
return {}
|
||||
|
||||
|
||||
def _graphic_field(data):
|
||||
if data[:3] == 'GFA':
|
||||
if data[:3] == "GFA":
|
||||
vals = {}
|
||||
args = [
|
||||
'compression',
|
||||
'total_bytes',
|
||||
'total_bytes',
|
||||
'bytes_per_row',
|
||||
'ascii_data',
|
||||
"compression",
|
||||
"total_bytes",
|
||||
"total_bytes",
|
||||
"bytes_per_row",
|
||||
"ascii_data",
|
||||
]
|
||||
vals.update(_compute_arg(data[3:], args))
|
||||
|
||||
# Image
|
||||
rawData = re.sub('[^A-F0-9]+', '', vals['ascii_data'])
|
||||
rawData = re.sub("[^A-F0-9]+", "", vals["ascii_data"])
|
||||
rawData = binascii.unhexlify(rawData)
|
||||
|
||||
width = int(float(vals['bytes_per_row']) * 8)
|
||||
height = int(float(vals['total_bytes']) / width) * 8
|
||||
width = int(float(vals["bytes_per_row"]) * 8)
|
||||
height = int(float(vals["total_bytes"]) / width) * 8
|
||||
|
||||
img = Image.frombytes(
|
||||
'1', (width, height), rawData, 'raw').convert('L')
|
||||
img = Image.frombytes("1", (width, height), rawData, "raw").convert("L")
|
||||
img = ImageOps.invert(img)
|
||||
|
||||
imgByteArr = io.BytesIO()
|
||||
img.save(imgByteArr, format='PNG')
|
||||
img.save(imgByteArr, format="PNG")
|
||||
image = base64.b64encode(imgByteArr.getvalue())
|
||||
|
||||
return {
|
||||
'component_type': 'graphic',
|
||||
'graphic_image': image,
|
||||
"component_type": "graphic",
|
||||
"graphic_image": image,
|
||||
zpl2.ARG_WIDTH: width,
|
||||
zpl2.ARG_HEIGHT: height,
|
||||
}
|
||||
@@ -314,29 +300,29 @@ def _graphic_field(data):
|
||||
|
||||
|
||||
def _get_data(data):
|
||||
if data[:2] == 'FD':
|
||||
return {'data': '"%s"' % data[2:]}
|
||||
if data[:2] == "FD":
|
||||
return {"data": '"%s"' % data[2:]}
|
||||
return {}
|
||||
|
||||
|
||||
SUPPORTED_CODE = {
|
||||
'FO': {'method': _field_origin},
|
||||
'FD': {'method': _get_data},
|
||||
'A': {'method': _font_format},
|
||||
'FB': {'method': _field_block},
|
||||
'B1': {'method': _code11},
|
||||
'B2': {'method': _interleaved2of5},
|
||||
'B3': {'method': _code39},
|
||||
'B4': {'method': _code49},
|
||||
'B7': {'method': _pdf417},
|
||||
'B8': {'method': _ean8},
|
||||
'B9': {'method': _upce},
|
||||
'BC': {'method': _code128},
|
||||
'BE': {'method': _ean13},
|
||||
'BQ': {'method': _qrcode},
|
||||
'BY': {
|
||||
'method': _default_barcode_field,
|
||||
'default': [
|
||||
"FO": {"method": _field_origin},
|
||||
"FD": {"method": _get_data},
|
||||
"A": {"method": _font_format},
|
||||
"FB": {"method": _field_block},
|
||||
"B1": {"method": _code11},
|
||||
"B2": {"method": _interleaved2of5},
|
||||
"B3": {"method": _code39},
|
||||
"B4": {"method": _code49},
|
||||
"B7": {"method": _pdf417},
|
||||
"B8": {"method": _ean8},
|
||||
"B9": {"method": _upce},
|
||||
"BC": {"method": _code128},
|
||||
"BE": {"method": _ean13},
|
||||
"BQ": {"method": _qrcode},
|
||||
"BY": {
|
||||
"method": _default_barcode_field,
|
||||
"default": [
|
||||
zpl2.BARCODE_CODE_11,
|
||||
zpl2.BARCODE_INTERLEAVED_2_OF_5,
|
||||
zpl2.BARCODE_CODE_39,
|
||||
@@ -349,93 +335,93 @@ SUPPORTED_CODE = {
|
||||
zpl2.BARCODE_QR_CODE,
|
||||
],
|
||||
},
|
||||
'CF': {'method': _default_font_format, 'default': ['text']},
|
||||
'FR': {'method': _field_reverse_print},
|
||||
'GB': {'method': _graphic_box},
|
||||
'GC': {'method': _graphic_circle},
|
||||
'GFA': {'method': _graphic_field},
|
||||
"CF": {"method": _default_font_format, "default": ["text"]},
|
||||
"FR": {"method": _field_reverse_print},
|
||||
"GB": {"method": _graphic_box},
|
||||
"GC": {"method": _graphic_circle},
|
||||
"GFA": {"method": _graphic_field},
|
||||
}
|
||||
|
||||
|
||||
class WizardImportZPl2(models.TransientModel):
|
||||
_name = 'wizard.import.zpl2'
|
||||
_description = 'Import ZPL2'
|
||||
_name = "wizard.import.zpl2"
|
||||
_description = "Import ZPL2"
|
||||
|
||||
label_id = fields.Many2one(
|
||||
comodel_name='printing.label.zpl2', string='Label',
|
||||
required=True, readonly=True,)
|
||||
data = fields.Text(
|
||||
required=True, help='Printer used to print the labels.')
|
||||
comodel_name="printing.label.zpl2", string="Label", required=True, readonly=True
|
||||
)
|
||||
data = fields.Text(required=True, help="Printer used to print the labels.")
|
||||
delete_component = fields.Boolean(
|
||||
string='Delete existing components', default=False)
|
||||
string="Delete existing components", default=False
|
||||
)
|
||||
|
||||
def _start_sequence(self):
|
||||
sequences = self.mapped('label_id.component_ids.sequence')
|
||||
sequences = self.mapped("label_id.component_ids.sequence")
|
||||
if sequences:
|
||||
return max(sequences) + 1
|
||||
return 0
|
||||
|
||||
def import_zpl2(self):
|
||||
self.ensure_one()
|
||||
Zpl2Component = self.env['printing.label.zpl2.component']
|
||||
Zpl2Component = self.env["printing.label.zpl2.component"]
|
||||
|
||||
if self.delete_component:
|
||||
self.mapped('label_id.component_ids').unlink()
|
||||
self.mapped("label_id.component_ids").unlink()
|
||||
|
||||
sequence = self._start_sequence()
|
||||
default = {}
|
||||
|
||||
for i, line in enumerate(self.data.split('\n')):
|
||||
for i, line in enumerate(self.data.split("\n")):
|
||||
vals = {}
|
||||
|
||||
args = line.split('^')
|
||||
args = line.split("^")
|
||||
for arg in args:
|
||||
for key, code in SUPPORTED_CODE.items():
|
||||
component_arg = code['method'](arg)
|
||||
for _, code in SUPPORTED_CODE.items():
|
||||
component_arg = code["method"](arg)
|
||||
if component_arg:
|
||||
if code.get('default', False):
|
||||
for deft in code.get('default'):
|
||||
if code.get("default", False):
|
||||
for deft in code.get("default"):
|
||||
default.update({deft: component_arg})
|
||||
else:
|
||||
vals.update(component_arg)
|
||||
break
|
||||
|
||||
if vals:
|
||||
if 'component_type' not in vals.keys():
|
||||
vals.update({'component_type': 'text'})
|
||||
if "component_type" not in vals.keys():
|
||||
vals.update({"component_type": "text"})
|
||||
|
||||
if vals['component_type'] in default.keys():
|
||||
vals.update(default[vals['component_type']])
|
||||
if vals["component_type"] in default.keys():
|
||||
vals.update(default[vals["component_type"]])
|
||||
|
||||
vals = self._update_vals(vals)
|
||||
|
||||
seq = sequence + i * 10
|
||||
vals.update({
|
||||
'name': _('Import %s') % seq,
|
||||
'sequence': seq,
|
||||
'label_id': self.label_id.id,
|
||||
})
|
||||
vals.update(
|
||||
{
|
||||
"name": translate("Import %s") % seq,
|
||||
"sequence": seq,
|
||||
"label_id": self.label_id.id,
|
||||
}
|
||||
)
|
||||
Zpl2Component.create(vals)
|
||||
|
||||
def _update_vals(self, vals):
|
||||
if 'orientation' in vals.keys() and vals['orientation'] == '':
|
||||
vals['orientation'] = 'N'
|
||||
if "orientation" in vals.keys() and vals["orientation"] == "":
|
||||
vals["orientation"] = "N"
|
||||
|
||||
# Field
|
||||
Zpl2Component = self.env['printing.label.zpl2.component']
|
||||
Zpl2Component = self.env["printing.label.zpl2.component"]
|
||||
model_fields = Zpl2Component.fields_get()
|
||||
component = {}
|
||||
for field, value in vals.items():
|
||||
if field in model_fields.keys():
|
||||
field_type = model_fields[field].get('type', False)
|
||||
if field_type == 'boolean':
|
||||
field_type = model_fields[field].get("type", False)
|
||||
if field_type == "boolean":
|
||||
if not value or value == zpl2.BOOL_NO:
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
if field_type in ('integer', 'float'):
|
||||
if field_type in ("integer", "float"):
|
||||
value = float(value)
|
||||
if field == 'model':
|
||||
value = int(float(value))
|
||||
component.update({field: value})
|
||||
return component
|
||||
|
||||
Reference in New Issue
Block a user