From 4291cca6caccebcd2e87644659244e06fb9bfadc Mon Sep 17 00:00:00 2001 From: Rod Schouteden Date: Mon, 30 Sep 2019 15:35:28 +0200 Subject: [PATCH] [MIG] printer_zpl2: Migration to 13.0 --- printer_zpl2/README.rst | 82 +- printer_zpl2/__manifest__.py | 34 +- printer_zpl2/models/printing_label_zpl2.py | 555 ++++---- .../models/printing_label_zpl2_component.py | 289 ++-- printer_zpl2/readme/CONFIGURE.rst | 17 + printer_zpl2/readme/CONTRIBUTORS.rst | 4 + printer_zpl2/readme/DESCRIPTION.rst | 5 + printer_zpl2/readme/HISTORY.rst | 8 + printer_zpl2/readme/INSTALL.rst | 1 + printer_zpl2/readme/USAGE.rst | 13 + printer_zpl2/static/description/index.html | 484 +++++++ printer_zpl2/tests/test_generate_action.py | 43 +- .../tests/test_printing_label_zpl2.py | 1246 +++++++++-------- printer_zpl2/tests/test_test_mode.py | 80 +- printer_zpl2/tests/test_wizard_import_zpl2.py | 147 +- .../tests/test_wizard_print_record_label.py | 105 +- printer_zpl2/views/printing_label_zpl2.xml | 5 +- printer_zpl2/wizard/print_record_label.py | 44 +- printer_zpl2/wizard/print_record_label.xml | 1 - printer_zpl2/wizard/wizard_import_zpl2.py | 238 ++-- requirements.txt | 1 + setup/_metapackage/setup.py | 12 +- setup/base_report_to_printer/setup.py | 5 +- 23 files changed, 2074 insertions(+), 1345 deletions(-) create mode 100644 printer_zpl2/readme/CONFIGURE.rst create mode 100644 printer_zpl2/readme/CONTRIBUTORS.rst create mode 100644 printer_zpl2/readme/DESCRIPTION.rst create mode 100644 printer_zpl2/readme/HISTORY.rst create mode 100644 printer_zpl2/readme/INSTALL.rst create mode 100644 printer_zpl2/readme/USAGE.rst create mode 100644 printer_zpl2/static/description/index.html diff --git a/printer_zpl2/README.rst b/printer_zpl2/README.rst index 14f032f..f47432e 100644 --- a/printer_zpl2/README.rst +++ b/printer_zpl2/README.rst @@ -1,10 +1,29 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 +============== +Printer ZPL II +============== -===================== -ZPL II Label printing -===================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freport--print--send-lightgray.png?logo=github + :target: https://github.com/OCA/report-print-send/tree/13.0/printer_zpl2 + :alt: OCA/report-print-send +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/report-print-send-13-0/report-print-send-13-0-printer_zpl2 + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/144/13.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| This module extends the **Report to printer** (``base_report_to_printer``) module to add a ZPL II label printing feature. @@ -12,6 +31,11 @@ module to add a ZPL II label printing feature. This module is meant to be used as a base for module development, and does not provide a GUI on its own. See below for more details. +**Table of contents** + +.. contents:: + :local: + Installation ============ @@ -55,45 +79,59 @@ You can also use the generic label printing wizard, if added on some models. :alt: Try me on Runbot :target: https://runbot.odoo-community.org/runbot/144/12.0 -Known issues / Roadmap -====================== +Changelog +========= -* Develop a "Designer" view in a separate module, to allow drawing labels with simple mouse clicks/drags +13.0.1.0.0 (2019-09-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [RELEASE] Port from V12. +* Selection lists do not support integers any longer +* Binary field now returns False when empty instead of none, + change tests to reflect this +* work around an appels vs oranges warning Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smashing it by providing a detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Images ------- +Authors +~~~~~~~ -* Odoo Community Association: `Icon `_. +* SUBTENO-IT +* FLorent de Labarre +* Apertoso NV Contributors ------------- +~~~~~~~~~~~~ * Sylvain Garancher * Florent de Labarre * Jos De Graeve +* Rod Schouteden -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/report-print-send `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/printer_zpl2/__manifest__.py b/printer_zpl2/__manifest__.py index 11ed314..72bf7f3 100644 --- a/printer_zpl2/__manifest__.py +++ b/printer_zpl2/__manifest__.py @@ -2,24 +2,20 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'Printer ZPL II', - 'version': '12.0.1.0.0', - 'category': 'Printer', - 'author': 'SUBTENO-IT, FLorent de Labarre, ' - 'Apertoso NV, Odoo Community Association (OCA)', - 'website': 'http://www.syleam.fr/', - 'license': 'AGPL-3', - 'external_dependencies': { - 'python': ['zpl2'], - }, - 'depends': [ - 'base_report_to_printer', + "name": "Printer ZPL II", + "version": "13.0.1.0.0", + "category": "Printer", + "author": "SUBTENO-IT, FLorent de Labarre, " + "Apertoso NV, Odoo Community Association (OCA)", + "website": "http://www.syleam.fr/", + "license": "AGPL-3", + "external_dependencies": {"python": ["zpl2"]}, + "depends": ["base_report_to_printer"], + "data": [ + "security/ir.model.access.csv", + "views/printing_label_zpl2.xml", + "wizard/print_record_label.xml", + "wizard/wizard_import_zpl2.xml", ], - 'data': [ - 'security/ir.model.access.csv', - 'views/printing_label_zpl2.xml', - 'wizard/print_record_label.xml', - 'wizard/wizard_import_zpl2.xml', - ], - 'installable': True, + "installable": True, } diff --git a/printer_zpl2/models/printing_label_zpl2.py b/printer_zpl2/models/printing_label_zpl2.py index e3de9d2..9093421 100644 --- a/printer_zpl2/models/printing_label_zpl2.py +++ b/printer_zpl2/models/printing_label_zpl2.py @@ -1,14 +1,16 @@ # Copyright (C) 2016 SYLEAM () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import time import base64 import datetime import io import logging +import time + import requests from PIL import Image, ImageOps -from odoo import api, exceptions, fields, models, _ + +from odoo import _, api, exceptions, fields, models from odoo.tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) @@ -16,59 +18,248 @@ _logger = logging.getLogger(__name__) try: import zpl2 except ImportError: - _logger.debug('Cannot `import zpl2`.') + _logger.debug("Cannot `import zpl2`.") class PrintingLabelZpl2(models.Model): - _name = 'printing.label.zpl2' - _description = 'ZPL II Label' - _order = 'model_id, name, id' + _name = "printing.label.zpl2" + _description = "ZPL II Label" + _order = "model_id, name, id" - name = fields.Char(required=True, help='Label Name.') + name = fields.Char(required=True, help="Label Name.") active = fields.Boolean(default=True) - description = fields.Char(help='Long description for this label.') + description = fields.Char(help="Long description for this label.") model_id = fields.Many2one( - comodel_name='ir.model', string='Model', required=True, - help='Model used to print this label.') + comodel_name="ir.model", + string="Model", + required=True, + help="Model used to print this label.", + ) origin_x = fields.Integer( - required=True, default=10, - help='Origin point of the contents in the label, X coordinate.') + required=True, + default=10, + help="Origin point of the contents in the label, X coordinate.", + ) origin_y = fields.Integer( - required=True, default=10, - help='Origin point of the contents in the label, Y coordinate.') + required=True, + default=10, + help="Origin point of the contents in the label, Y coordinate.", + ) width = fields.Integer( - required=True, default=480, - help='Width of the label, will be set on the printer before printing.') + required=True, + default=480, + help="Width of the label, will be set on the printer before printing.", + ) component_ids = fields.One2many( - comodel_name='printing.label.zpl2.component', inverse_name='label_id', - string='Label Components', - help='Components which will be printed on the label.', copy=True) + comodel_name="printing.label.zpl2.component", + inverse_name="label_id", + string="Label Components", + help="Components which will be printed on the label.", + copy=True, + ) restore_saved_config = fields.Boolean( string="Restore printer's configuration", help="Restore printer's saved configuration and end of each label ", - default=True) + default=True, + ) action_window_id = fields.Many2one( - comodel_name='ir.actions.act_window', string='Action', readonly=True) - test_print_mode = fields.Boolean(string='Mode Print') - test_labelary_mode = fields.Boolean(string='Mode Labelary') - record_id = fields.Integer(string='Record ID', default=1) - extra = fields.Text(string="Extra", default='{}') - printer_id = fields.Many2one( - comodel_name='printing.printer', string='Printer') - labelary_image = fields.Binary(string='Image from Labelary', readonly=True) + comodel_name="ir.actions.act_window", string="Action", readonly=True + ) + test_print_mode = fields.Boolean(string="Mode Print") + test_labelary_mode = fields.Boolean(string="Mode Labelary") + record_id = fields.Integer(string="Record ID", default=1) + extra = fields.Text(default="{}") + printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer") + labelary_image = fields.Binary(string="Image from Labelary", readonly=True) labelary_dpmm = fields.Selection( selection=[ - ('6dpmm', '6dpmm (152 pdi)'), - ('8dpmm', '8dpmm (203 dpi)'), - ('12dpmm', '12dpmm (300 pdi)'), - ('24dpmm', '24dpmm (600 dpi)'), - ], string='Print density', required=True, default='8dpmm') - labelary_width = fields.Float(string='Width in mm', default=140) - labelary_height = fields.Float(string='Height in mm', default=70) + ("6dpmm", "6dpmm (152 pdi)"), + ("8dpmm", "8dpmm (203 dpi)"), + ("12dpmm", "12dpmm (300 pdi)"), + ("24dpmm", "24dpmm (600 dpi)"), + ], + string="Print density", + required=True, + default="8dpmm", + ) + labelary_width = fields.Float(string="Width in mm", default=140) + labelary_height = fields.Float(string="Height in mm", default=70) + + def _generate_zpl2_components_data_repeatable( + self, component, data, label_offset_x, label_offset_y + ): + to_print = [] + # Generate a list of elements if the component is repeatable + for idx in range( + component.repeat_offset, component.repeat_offset + component.repeat_count + ): + printed_data = data + # Pick the right value if data is a collection + if isinstance(data, (list, tuple, set, models.BaseModel)): + # If we reached the end of data, quit the loop + if idx >= len(data): + break + + # Set the real data to display + printed_data = data[idx] + + position = idx - component.repeat_offset + to_print.append( + ( + component, + printed_data, + label_offset_x + component.repeat_offset_x * position, + label_offset_y + component.repeat_offset_y * position, + ) + ) + return to_print + + def _component_type_selector( + self, + component, + label_data, + component_offset_x, + component_offset_y, + offset_x, + offset_y, + data, + ): + if component.component_type == "text": + barcode_arguments = { + field_name: component[field_name] + for field_name in [ + zpl2.ARG_FONT, + zpl2.ARG_ORIENTATION, + zpl2.ARG_HEIGHT, + zpl2.ARG_WIDTH, + zpl2.ARG_REVERSE_PRINT, + zpl2.ARG_IN_BLOCK, + zpl2.ARG_BLOCK_WIDTH, + zpl2.ARG_BLOCK_LINES, + zpl2.ARG_BLOCK_SPACES, + zpl2.ARG_BLOCK_JUSTIFY, + zpl2.ARG_BLOCK_LEFT_MARGIN, + ] + } + label_data.font_data( + component_offset_x, component_offset_y, barcode_arguments, data + ) + elif component.component_type == "zpl2_raw": + label_data._write_command(data) + elif component.component_type == "rectangle": + label_data.graphic_box( + component_offset_x, + component_offset_y, + { + zpl2.ARG_WIDTH: component.width, + zpl2.ARG_HEIGHT: component.height, + zpl2.ARG_THICKNESS: component.thickness, + zpl2.ARG_COLOR: component.color, + zpl2.ARG_ROUNDING: component.rounding, + }, + ) + elif component.component_type == "diagonal": + label_data.graphic_diagonal_line( + component_offset_x, + component_offset_y, + { + zpl2.ARG_WIDTH: component.width, + zpl2.ARG_HEIGHT: component.height, + zpl2.ARG_THICKNESS: component.thickness, + zpl2.ARG_COLOR: component.color, + zpl2.ARG_DIAGONAL_ORIENTATION: component.diagonal_orientation, + }, + ) + elif component.component_type == "graphic": + # During the on_change don't take the bin_size + image = ( + component.with_context(bin_size_graphic_image=False).graphic_image + or data + ) + try: + pil_image = Image.open(io.BytesIO(base64.b64decode(image))).convert( + "RGB" + ) + except Exception: + return + if component.width and component.height: + pil_image = pil_image.resize((component.width, component.height)) + + # Invert the colors + if component.reverse_print: + pil_image = ImageOps.invert(pil_image) + + # Rotation (PIL rotates counter clockwise) + if component.orientation == zpl2.ORIENTATION_ROTATED: + pil_image = pil_image.transpose(Image.ROTATE_270) + elif component.orientation == zpl2.ORIENTATION_INVERTED: + pil_image = pil_image.transpose(Image.ROTATE_180) + elif component.orientation == zpl2.ORIENTATION_BOTTOM_UP: + pil_image = pil_image.transpose(Image.ROTATE_90) + + label_data.graphic_field(component_offset_x, component_offset_y, pil_image) + elif component.component_type == "circle": + label_data.graphic_circle( + component_offset_x, + component_offset_y, + { + zpl2.ARG_DIAMETER: component.width, + zpl2.ARG_THICKNESS: component.thickness, + zpl2.ARG_COLOR: component.color, + }, + ) + elif component.component_type == "sublabel": + component_offset_x += component.sublabel_id.origin_x + component_offset_y += component.sublabel_id.origin_y + component.sublabel_id._generate_zpl2_components_data( + label_data, + data, + label_offset_x=component_offset_x, + label_offset_y=component_offset_y, + ) + else: + if component.component_type == zpl2.BARCODE_QR_CODE: + # Adding Control Arguments to QRCode data Label + data = "{}A,{}".format(component.error_correction, data) + + barcode_arguments = { + field_name: component[field_name] + for field_name in [ + zpl2.ARG_ORIENTATION, + zpl2.ARG_CHECK_DIGITS, + zpl2.ARG_HEIGHT, + zpl2.ARG_INTERPRETATION_LINE, + zpl2.ARG_INTERPRETATION_LINE_ABOVE, + zpl2.ARG_SECURITY_LEVEL, + zpl2.ARG_COLUMNS_COUNT, + zpl2.ARG_ROWS_COUNT, + zpl2.ARG_TRUNCATE, + zpl2.ARG_MODULE_WIDTH, + zpl2.ARG_BAR_WIDTH_RATIO, + zpl2.ARG_MODEL, + zpl2.ARG_MAGNIFICATION_FACTOR, + zpl2.ARG_ERROR_CORRECTION, + zpl2.ARG_MASK_VALUE, + ] + } + label_data.barcode_data( + component.origin_x + offset_x, + component.origin_y + offset_y, + component.component_type, + barcode_arguments, + data, + ) def _generate_zpl2_components_data( - self, label_data, record, page_number=1, page_count=1, - label_offset_x=0, label_offset_y=0, **extra): + self, + label_data, + record, + page_number=1, + page_count=1, + label_offset_x=0, + label_offset_y=0, + **extra + ): self.ensure_one() # Add all elements to print in a list of tuples : @@ -76,161 +267,41 @@ class PrintingLabelZpl2(models.Model): to_print = [] for component in self.component_ids: eval_args = extra - eval_args.update({ - 'object': record, - 'page_number': str(page_number + 1), - 'page_count': str(page_count), - 'time': time, - 'datetime': datetime, - }) - data = safe_eval(component.data, eval_args) or '' + eval_args.update( + { + "object": record, + "page_number": str(page_number + 1), + "page_count": str(page_count), + "time": time, + "datetime": datetime, + } + ) + data = safe_eval(component.data, eval_args) or "" - if data == 'component_not_show': + if isinstance(data, str) and data == "component_not_show": continue - - # Generate a list of elements if the component is repeatable - for idx in range( - component.repeat_offset, - component.repeat_offset + component.repeat_count): - printed_data = data - # Pick the right value if data is a collection - if isinstance(data, (list, tuple, set, models.BaseModel)): - # If we reached the end of data, quit the loop - if idx >= len(data): - break - - # Set the real data to display - printed_data = data[idx] - - position = idx - component.repeat_offset - to_print.append(( - component, printed_data, - label_offset_x + component.repeat_offset_x * position, - label_offset_y + component.repeat_offset_y * position, - )) + to_print = self._generate_zpl2_components_data_repeatable( + component, data, label_offset_x, label_offset_y + ) for (component, data, offset_x, offset_y) in to_print: component_offset_x = component.origin_x + offset_x component_offset_y = component.origin_y + offset_y - if component.component_type == 'text': - barcode_arguments = dict([ - (field_name, component[field_name]) - for field_name in [ - zpl2.ARG_FONT, - zpl2.ARG_ORIENTATION, - zpl2.ARG_HEIGHT, - zpl2.ARG_WIDTH, - zpl2.ARG_REVERSE_PRINT, - zpl2.ARG_IN_BLOCK, - zpl2.ARG_BLOCK_WIDTH, - zpl2.ARG_BLOCK_LINES, - zpl2.ARG_BLOCK_SPACES, - zpl2.ARG_BLOCK_JUSTIFY, - zpl2.ARG_BLOCK_LEFT_MARGIN, - ] - ]) - label_data.font_data( - component_offset_x, component_offset_y, - barcode_arguments, data) - elif component.component_type == 'zpl2_raw': - label_data._write_command(data) - elif component.component_type == 'rectangle': - label_data.graphic_box( - component_offset_x, component_offset_y, { - zpl2.ARG_WIDTH: component.width, - zpl2.ARG_HEIGHT: component.height, - zpl2.ARG_THICKNESS: component.thickness, - zpl2.ARG_COLOR: component.color, - zpl2.ARG_ROUNDING: component.rounding, - }) - elif component.component_type == 'diagonal': - label_data.graphic_diagonal_line( - component_offset_x, component_offset_y, { - zpl2.ARG_WIDTH: component.width, - zpl2.ARG_HEIGHT: component.height, - zpl2.ARG_THICKNESS: component.thickness, - zpl2.ARG_COLOR: component.color, - zpl2.ARG_DIAGONAL_ORIENTATION: - component.diagonal_orientation, - }) - elif component.component_type == 'graphic': - # During the on_change don't take the bin_size - image = component.with_context(bin_size_graphic_image=False)\ - .graphic_image or data - try: - pil_image = Image.open(io.BytesIO( - base64.b64decode(image))).convert('RGB') - except Exception: - continue - if component.width and component.height: - pil_image = pil_image.resize( - (component.width, component.height)) - - # Invert the colors - if component.reverse_print: - pil_image = ImageOps.invert(pil_image) - - # Rotation (PIL rotates counter clockwise) - if component.orientation == zpl2.ORIENTATION_ROTATED: - pil_image = pil_image.transpose(Image.ROTATE_270) - elif component.orientation == zpl2.ORIENTATION_INVERTED: - pil_image = pil_image.transpose(Image.ROTATE_180) - elif component.orientation == zpl2.ORIENTATION_BOTTOM_UP: - pil_image = pil_image.transpose(Image.ROTATE_90) - - label_data.graphic_field( - component_offset_x, component_offset_y, - pil_image - ) - elif component.component_type == 'circle': - label_data.graphic_circle( - component_offset_x, component_offset_y, { - zpl2.ARG_DIAMETER: component.width, - zpl2.ARG_THICKNESS: component.thickness, - zpl2.ARG_COLOR: component.color, - }) - elif component.component_type == 'sublabel': - component_offset_x += component.sublabel_id.origin_x - component_offset_y += component.sublabel_id.origin_y - component.sublabel_id._generate_zpl2_components_data( - label_data, data, - label_offset_x=component_offset_x, - label_offset_y=component_offset_y) - else: - if component.component_type == zpl2.BARCODE_QR_CODE: - # Adding Control Arguments to QRCode data Label - data = '{}A,{}'.format(component.error_correction, data) - - barcode_arguments = dict([ - (field_name, component[field_name]) - for field_name in [ - zpl2.ARG_ORIENTATION, - zpl2.ARG_CHECK_DIGITS, - zpl2.ARG_HEIGHT, - zpl2.ARG_INTERPRETATION_LINE, - zpl2.ARG_INTERPRETATION_LINE_ABOVE, - zpl2.ARG_SECURITY_LEVEL, - zpl2.ARG_COLUMNS_COUNT, - zpl2.ARG_ROWS_COUNT, - zpl2.ARG_TRUNCATE, - zpl2.ARG_MODULE_WIDTH, - zpl2.ARG_BAR_WIDTH_RATIO, - zpl2.ARG_MODEL, - zpl2.ARG_MAGNIFICATION_FACTOR, - zpl2.ARG_ERROR_CORRECTION, - zpl2.ARG_MASK_VALUE, - ] - ]) - label_data.barcode_data( - component.origin_x + offset_x, - component.origin_y + offset_y, - component.component_type, barcode_arguments, data) + self._component_type_selector( + component, + label_data, + component_offset_x, + component_offset_y, + offset_x, + offset_y, + data, + ) def _generate_zpl2_data(self, record, page_count=1, **extra): self.ensure_one() label_data = zpl2.Zpl2() - labelary_emul = extra.get('labelary_emul', False) + labelary_emul = extra.get("labelary_emul", False) for page_number in range(page_count): # Initialize printer's configuration label_data.label_start() @@ -241,8 +312,12 @@ class PrintingLabelZpl2(models.Model): label_data.label_home(self.origin_x, self.origin_y) self._generate_zpl2_components_data( - label_data, record, page_number=page_number, - page_count=page_count, **extra) + label_data, + record, + page_number=page_number, + page_count=page_count, + **extra + ) # Restore printer's configuration and end the label if self.restore_saved_config: @@ -255,51 +330,53 @@ class PrintingLabelZpl2(models.Model): for label in self: if record._name != label.model_id.model: raise exceptions.UserError( - _('This label cannot be used on {model}').format( - model=record._name)) + _("This label cannot be used on {model}").format(model=record._name) + ) # Send the label to printer label_contents = label._generate_zpl2_data( - record, page_count=page_count, **extra) + record, page_count=page_count, **extra + ) printer.print_document( - report=None, content=label_contents, doc_format='raw') + report=None, content=label_contents, doc_format="raw" + ) return True def create_action(self): for label in self.filtered(lambda record: not record.action_window_id): - label.action_window_id = self.env['ir.actions.act_window'].create({ - 'name': _('Print Label'), - 'src_model': label.model_id.model, - 'binding_model_id': label.model_id.id, - 'res_model': 'wizard.print.record.label', - 'view_mode': 'form', - 'target': 'new', - 'binding_type': 'action', - }) + label.action_window_id = self.env["ir.actions.act_window"].create( + { + "name": _("Print Label"), + "binding_model_id": label.model_id.id, + "res_model": "wizard.print.record.label", + "view_mode": "form", + "target": "new", + "binding_type": "action", + } + ) return True def unlink_action(self): - self.mapped('action_window_id').unlink() + self.mapped("action_window_id").unlink() def import_zpl2(self): self.ensure_one() return { - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'wizard.import.zpl2', - 'type': 'ir.actions.act_window', - 'target': 'new', - 'context': {'default_label_id': self.id}, + "view_mode": "form", + "res_model": "wizard.import.zpl2", + "type": "ir.actions.act_window", + "target": "new", + "context": {"default_label_id": self.id}, } def _get_record(self): self.ensure_one() Obj = self.env[self.model_id.model] - record = Obj.search([('id', '=', self.record_id)], limit=1) + record = Obj.search([("id", "=", self.record_id)], limit=1) if not record: - record = Obj.search([], limit=1, order='id desc') + record = Obj.search([], limit=1, order="id desc") self.record_id = record.id return record @@ -308,58 +385,66 @@ class PrintingLabelZpl2(models.Model): for label in self: if label.test_print_mode and label.record_id and label.printer_id: record = label._get_record() - extra = safe_eval(label.extra, {'env': self.env}) + extra = safe_eval(label.extra, {"env": self.env}) if record: label.print_label(label.printer_id, record, **extra) @api.onchange( - 'record_id', 'labelary_dpmm', 'labelary_width', 'labelary_height', - 'component_ids', 'origin_x', 'origin_y') + "record_id", + "labelary_dpmm", + "labelary_width", + "labelary_height", + "component_ids", + "origin_x", + "origin_y", + ) def _on_change_labelary(self): self.ensure_one() - if not(self.test_labelary_mode and self.record_id and - self.labelary_width and self.labelary_height and - self.labelary_dpmm and self.component_ids): + if not ( + self.test_labelary_mode + and self.record_id + and self.labelary_width + and self.labelary_height + and self.labelary_dpmm + and self.component_ids + ): return record = self._get_record() if record: # If case there an error (in the data field with the safe_eval # for exemple) the new component or the update is not lost. try: - url = 'http://api.labelary.com/v1/printers/' \ - '{dpmm}/labels/{width}x{height}/0/' + url = ( + "http://api.labelary.com/v1/printers/" + "{dpmm}/labels/{width}x{height}/0/" + ) width = round(self.labelary_width / 25.4, 2) height = round(self.labelary_height / 25.4, 2) - url = url.format( - dpmm=self.labelary_dpmm, width=width, height=height) - extra = safe_eval(self.extra, {'env': self.env}) - zpl_file = self._generate_zpl2_data( - record, labelary_emul=True, **extra) - files = {'file': zpl_file} - headers = {'Accept': 'image/png'} - response = requests.post( - url, headers=headers, files=files, stream=True) + url = url.format(dpmm=self.labelary_dpmm, width=width, height=height) + extra = safe_eval(self.extra, {"env": self.env}) + zpl_file = self._generate_zpl2_data(record, labelary_emul=True, **extra) + files = {"file": zpl_file} + headers = {"Accept": "image/png"} + response = requests.post(url, headers=headers, files=files, stream=True) if response.status_code == 200: # Add a padd im = Image.open(io.BytesIO(response.content)) im_size = im.size new_im = Image.new( - 'RGB', (im_size[0] + 2, im_size[1] + 2), - (164, 164, 164)) + "RGB", (im_size[0] + 2, im_size[1] + 2), (164, 164, 164) + ) new_im.paste(im, (1, 1)) imgByteArr = io.BytesIO() - new_im.save(imgByteArr, format='PNG') - self.labelary_image = base64.b64encode( - imgByteArr.getvalue()) + new_im.save(imgByteArr, format="PNG") + self.labelary_image = base64.b64encode(imgByteArr.getvalue()) else: - return {'warning': { - 'title': _('Error with Labelary API.'), - 'message': response.status_code, - }} + return { + "warning": { + "title": _("Error with Labelary API."), + "message": response.status_code, + } + } except Exception as e: self.labelary_image = False - return {'warning': { - 'title': _('Some thing is wrong.'), - 'message': e, - }} + return {"warning": {"title": _("Some thing is wrong."), "message": e}} diff --git a/printer_zpl2/models/printing_label_zpl2_component.py b/printer_zpl2/models/printing_label_zpl2_component.py index c2fde3b..c6489a5 100644 --- a/printer_zpl2/models/printing_label_zpl2_component.py +++ b/printer_zpl2/models/printing_label_zpl2_component.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging + from odoo import fields, models _logger = logging.getLogger(__name__) @@ -9,7 +10,7 @@ _logger = logging.getLogger(__name__) try: import zpl2 except ImportError: - _logger.debug('Cannot `import zpl2`.') + _logger.debug("Cannot `import zpl2`.") DEFAULT_PYTHON_CODE = """# Python One-Liners # - object: record on which the action is triggered; may be be void @@ -25,162 +26,208 @@ DEFAULT_PYTHON_CODE = """# Python One-Liners class PrintingLabelZpl2Component(models.Model): - _name = 'printing.label.zpl2.component' - _description = 'ZPL II Label Component' - _order = 'sequence, id' + _name = "printing.label.zpl2.component" + _description = "ZPL II Label Component" + _order = "sequence, id" label_id = fields.Many2one( - comodel_name='printing.label.zpl2', string='Label', - required=True, ondelete='cascade', help='Label using this component.') - sequence = fields.Integer(help='Order used to print the elements.') - name = fields.Char(required=True, help='Name of the component.') + comodel_name="printing.label.zpl2", + string="Label", + required=True, + ondelete="cascade", + help="Label using this component.", + ) + sequence = fields.Integer(help="Order used to print the elements.") + name = fields.Char(required=True, help="Name of the component.") origin_x = fields.Integer( - required=True, default=10, - help='Origin point of the component in the label, X coordinate.') + required=True, + default=10, + help="Origin point of the component in the label, X coordinate.", + ) origin_y = fields.Integer( - required=True, default=10, - help='Origin point of the component in the label, Y coordinate.') + required=True, + default=10, + help="Origin point of the component in the label, Y coordinate.", + ) component_type = fields.Selection( selection=[ - ('text', 'Text'), - ('rectangle', 'Rectangle / Line'), - ('diagonal', 'Diagonal Line'), - ('circle', 'Circle'), - ('graphic', 'Graphic'), - (zpl2.BARCODE_CODE_11, 'Code 11'), - (zpl2.BARCODE_INTERLEAVED_2_OF_5, 'Interleaved 2 of 5'), - (zpl2.BARCODE_CODE_39, 'Code 39'), - (zpl2.BARCODE_CODE_49, 'Code 49'), - (zpl2.BARCODE_PDF417, 'PDF417'), - (zpl2.BARCODE_EAN_8, 'EAN-8'), - (zpl2.BARCODE_UPC_E, 'UPC-E'), - (zpl2.BARCODE_CODE_128, 'Code 128'), - (zpl2.BARCODE_EAN_13, 'EAN-13'), - (zpl2.BARCODE_QR_CODE, 'QR Code'), - ('sublabel', 'Sublabel'), - ('zpl2_raw', 'ZPL2'), - ], string='Type', required=True, default='text', oldname='type', - help='Type of content, simple text or barcode.') + ("text", "Text"), + ("rectangle", "Rectangle / Line"), + ("diagonal", "Diagonal Line"), + ("circle", "Circle"), + ("graphic", "Graphic"), + (zpl2.BARCODE_CODE_11, "Code 11"), + (zpl2.BARCODE_INTERLEAVED_2_OF_5, "Interleaved 2 of 5"), + (zpl2.BARCODE_CODE_39, "Code 39"), + (zpl2.BARCODE_CODE_49, "Code 49"), + (zpl2.BARCODE_PDF417, "PDF417"), + (zpl2.BARCODE_EAN_8, "EAN-8"), + (zpl2.BARCODE_UPC_E, "UPC-E"), + (zpl2.BARCODE_CODE_128, "Code 128"), + (zpl2.BARCODE_EAN_13, "EAN-13"), + (zpl2.BARCODE_QR_CODE, "QR Code"), + ("sublabel", "Sublabel"), + ("zpl2_raw", "ZPL2"), + ], + string="Type", + required=True, + default="text", + help="Type of content, simple text or barcode.", + ) font = fields.Selection( selection=[ - (zpl2.FONT_DEFAULT, 'Default'), - (zpl2.FONT_9X5, '9x5'), - (zpl2.FONT_11X7, '11x7'), - (zpl2.FONT_18X10, '18x10'), - (zpl2.FONT_28X15, '28x15'), - (zpl2.FONT_26X13, '26x13'), - (zpl2.FONT_60X40, '60x40'), - (zpl2.FONT_21X13, '21x13'), - ], required=True, default=zpl2.FONT_DEFAULT, - help='Font to use, for text only.') - thickness = fields.Integer(help='Thickness of the line to draw.') + (zpl2.FONT_DEFAULT, "Default"), + (zpl2.FONT_9X5, "9x5"), + (zpl2.FONT_11X7, "11x7"), + (zpl2.FONT_18X10, "18x10"), + (zpl2.FONT_28X15, "28x15"), + (zpl2.FONT_26X13, "26x13"), + (zpl2.FONT_60X40, "60x40"), + (zpl2.FONT_21X13, "21x13"), + ], + required=True, + default=zpl2.FONT_DEFAULT, + help="Font to use, for text only.", + ) + thickness = fields.Integer(help="Thickness of the line to draw.") color = fields.Selection( - selection=[ - (zpl2.COLOR_BLACK, 'Black'), - (zpl2.COLOR_WHITE, 'White'), - ], default=zpl2.COLOR_BLACK, - help='Color of the line to draw.') + selection=[(zpl2.COLOR_BLACK, "Black"), (zpl2.COLOR_WHITE, "White")], + default=zpl2.COLOR_BLACK, + help="Color of the line to draw.", + ) orientation = fields.Selection( selection=[ - (zpl2.ORIENTATION_NORMAL, 'Normal'), - (zpl2.ORIENTATION_ROTATED, 'Rotated'), - (zpl2.ORIENTATION_INVERTED, 'Inverted'), - (zpl2.ORIENTATION_BOTTOM_UP, 'Read from Bottom up'), - ], required=True, default=zpl2.ORIENTATION_NORMAL, - help='Orientation of the barcode.') + (zpl2.ORIENTATION_NORMAL, "Normal"), + (zpl2.ORIENTATION_ROTATED, "Rotated"), + (zpl2.ORIENTATION_INVERTED, "Inverted"), + (zpl2.ORIENTATION_BOTTOM_UP, "Read from Bottom up"), + ], + required=True, + default=zpl2.ORIENTATION_NORMAL, + help="Orientation of the barcode.", + ) diagonal_orientation = fields.Selection( selection=[ - (zpl2.DIAGONAL_ORIENTATION_LEFT, 'Left (\\)'), - (zpl2.DIAGONAL_ORIENTATION_RIGHT, 'Right (/)'), - ], default=zpl2.DIAGONAL_ORIENTATION_LEFT, - help='Orientation of the diagonal line.') + (zpl2.DIAGONAL_ORIENTATION_LEFT, "Left (\\)"), + (zpl2.DIAGONAL_ORIENTATION_RIGHT, "Right (/)"), + ], + default=zpl2.DIAGONAL_ORIENTATION_LEFT, + help="Orientation of the diagonal line.", + ) check_digits = fields.Boolean( - help='Check if you want to compute and print the check digit.') + help="Check if you want to compute and print the check digit." + ) height = fields.Integer( - help='Height of the printed component. For a text component, height ' - 'of a single character.') + help="Height of the printed component. For a text component, height " + "of a single character." + ) width = fields.Integer( - help='Width of the printed component. For a text component, width of ' - 'a single character.') - rounding = fields.Integer( - help='Rounding of the printed rectangle corners.') + help="Width of the printed component. For a text component, width of " + "a single character." + ) + rounding = fields.Integer(help="Rounding of the printed rectangle corners.") interpretation_line = fields.Boolean( - help='Check if you want the interpretation line to be printed.') + help="Check if you want the interpretation line to be printed." + ) interpretation_line_above = fields.Boolean( - help='Check if you want the interpretation line to be printed above ' - 'the barcode.') - module_width = fields.Integer( - default=2, help='Module width for the barcode.') + help="Check if you want the interpretation line to be printed above " + "the barcode." + ) + module_width = fields.Integer(default=2, help="Module width for the barcode.") bar_width_ratio = fields.Float( - default=3.0, help='Ratio between wide bar and narrow bar.') - security_level = fields.Integer(help='Security level for error detection.') - columns_count = fields.Integer(help='Number of data columns to encode.') - rows_count = fields.Integer(help='Number of rows to encode.') - truncate = fields.Boolean( - help='Check if you want to truncate the barcode.') + default=3.0, help="Ratio between wide bar and narrow bar." + ) + security_level = fields.Integer(help="Security level for error detection.") + columns_count = fields.Integer(help="Number of data columns to encode.") + rows_count = fields.Integer(help="Number of rows to encode.") + truncate = fields.Boolean(help="Check if you want to truncate the barcode.") model = fields.Selection( selection=[ - (zpl2.MODEL_ORIGINAL, 'Original'), - (zpl2.MODEL_ENHANCED, 'Enhanced'), - ], default=zpl2.MODEL_ENHANCED, - help='Barcode model, used by some barcode types like QR Code.') + (str(zpl2.MODEL_ORIGINAL), "Original"), + (str(zpl2.MODEL_ENHANCED), "Enhanced"), + ], + default=str(zpl2.MODEL_ENHANCED), + help="Barcode model, used by some barcode types like QR Code.", + ) magnification_factor = fields.Integer( - default=1, help='Magnification Factor, from 1 to 10.') + default=1, help="Magnification Factor, from 1 to 10." + ) error_correction = fields.Selection( selection=[ - (zpl2.ERROR_CORRECTION_ULTRA_HIGH, 'Ultra-high Reliability Level'), - (zpl2.ERROR_CORRECTION_HIGH, 'High Reliability Level'), - (zpl2.ERROR_CORRECTION_STANDARD, 'Standard Level'), - (zpl2.ERROR_CORRECTION_HIGH_DENSITY, 'High Density Level'), - ], required=True, default=zpl2.ERROR_CORRECTION_HIGH, - help='Error correction for some barcode types like QR Code.') - mask_value = fields.Integer(default=7, help='Mask Value, from 0 to 7.') + (zpl2.ERROR_CORRECTION_ULTRA_HIGH, "Ultra-high Reliability Level"), + (zpl2.ERROR_CORRECTION_HIGH, "High Reliability Level"), + (zpl2.ERROR_CORRECTION_STANDARD, "Standard Level"), + (zpl2.ERROR_CORRECTION_HIGH_DENSITY, "High Density Level"), + ], + required=True, + default=zpl2.ERROR_CORRECTION_HIGH, + help="Error correction for some barcode types like QR Code.", + ) + mask_value = fields.Integer(default=7, help="Mask Value, from 0 to 7.") data = fields.Text( - default=DEFAULT_PYTHON_CODE, required=True, - help='Data to print on this component. Resource values can be ' - 'inserted with %(object.field_name)s.') + default=DEFAULT_PYTHON_CODE, + required=True, + help="Data to print on this component. Resource values can be " + "inserted with %(object.field_name)s.", + ) sublabel_id = fields.Many2one( - comodel_name='printing.label.zpl2', string='Sublabel', - help='Another label to include into this one as a component. ' - 'This allows to define reusable labels parts.') + comodel_name="printing.label.zpl2", + string="Sublabel", + help="Another label to include into this one as a component. " + "This allows to define reusable labels parts.", + ) repeat = fields.Boolean( - string='Repeatable', - help='Check this box to repeat this component on the label.') + string="Repeatable", + help="Check this box to repeat this component on the label.", + ) repeat_offset = fields.Integer( - default=0, - help='Number of elements to skip when reading a list of elements.') + default=0, help="Number of elements to skip when reading a list of elements." + ) repeat_count = fields.Integer( - default=1, - help='Maximum count of repeats of the component.') + default=1, help="Maximum count of repeats of the component." + ) repeat_offset_x = fields.Integer( - help='X coordinate offset between each occurence of this component on ' - 'the label.') + help="X coordinate offset between each occurence of this component on " + "the label." + ) repeat_offset_y = fields.Integer( - help='Y coordinate offset between each occurence of this component on ' - 'the label.') + help="Y coordinate offset between each occurence of this component on " + "the label." + ) reverse_print = fields.Boolean( - help='If checked, the data will be printed in the inverse color of ' - 'the background.') + help="If checked, the data will be printed in the inverse color of " + "the background." + ) in_block = fields.Boolean( - help='If checked, the data will be restrected in a ' - 'defined block on the label.') - block_width = fields.Integer(help='Width of the block.') + help="If checked, the data will be restrected in a " + "defined block on the label." + ) + block_width = fields.Integer(help="Width of the block.") block_lines = fields.Integer( - default=1, help='Maximum number of lines to print in the block.') + default=1, help="Maximum number of lines to print in the block." + ) block_spaces = fields.Integer( - help='Number of spaces added between lines in the block.') + help="Number of spaces added between lines in the block." + ) block_justify = fields.Selection( selection=[ - (zpl2.JUSTIFY_LEFT, 'Left'), - (zpl2.JUSTIFY_CENTER, 'Center'), - (zpl2.JUSTIFY_JUSTIFIED, 'Justified'), - (zpl2.JUSTIFY_RIGHT, 'Right'), - ], string='Justify', required=True, default='L', - help='Choose how the text will be justified in the block.') + (zpl2.JUSTIFY_LEFT, "Left"), + (zpl2.JUSTIFY_CENTER, "Center"), + (zpl2.JUSTIFY_JUSTIFIED, "Justified"), + (zpl2.JUSTIFY_RIGHT, "Right"), + ], + string="Justify", + required=True, + default="L", + help="Choose how the text will be justified in the block.", + ) block_left_margin = fields.Integer( - string='Left Margin', - help='Left margin for the second and other lines in the block.') + string="Left Margin", + help="Left margin for the second and other lines in the block.", + ) graphic_image = fields.Binary( - string='Image', attachment=True, - help='This field holds a static image to print. ' - 'If not set, the data field is evaluated.') + string="Image", + attachment=True, + help="This field holds a static image to print. " + "If not set, the data field is evaluated.", + ) diff --git a/printer_zpl2/readme/CONFIGURE.rst b/printer_zpl2/readme/CONFIGURE.rst new file mode 100644 index 0000000..2a3036e --- /dev/null +++ b/printer_zpl2/readme/CONFIGURE.rst @@ -0,0 +1,17 @@ +To configure this module, you need to: + +#. Go to *Settings > Printing > Labels > ZPL II* +#. Create new labels +#. Import ZPL2 code +#. Use the Test Mode tab during the creation + +It's also possible to add a label printing wizard on any model by creating a new *ir.actions.act_window* record. +For example, to add the printing wizard on the *product.product* model :: + + diff --git a/printer_zpl2/readme/CONTRIBUTORS.rst b/printer_zpl2/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..6ef4003 --- /dev/null +++ b/printer_zpl2/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Sylvain Garancher +* Florent de Labarre +* Jos De Graeve +* Rod Schouteden diff --git a/printer_zpl2/readme/DESCRIPTION.rst b/printer_zpl2/readme/DESCRIPTION.rst new file mode 100644 index 0000000..3dbd004 --- /dev/null +++ b/printer_zpl2/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This module extends the **Report to printer** (``base_report_to_printer``) +module to add a ZPL II label printing feature. + +This module is meant to be used as a base for module development, and does not provide a GUI on its own. +See below for more details. diff --git a/printer_zpl2/readme/HISTORY.rst b/printer_zpl2/readme/HISTORY.rst new file mode 100644 index 0000000..7067915 --- /dev/null +++ b/printer_zpl2/readme/HISTORY.rst @@ -0,0 +1,8 @@ +13.0.1.0.0 (2019-09-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [RELEASE] Port from V12. +* Selection lists do not support integers any longer +* Binary field now returns False when empty instead of none, + change tests to reflect this +* work around an appels vs oranges warning diff --git a/printer_zpl2/readme/INSTALL.rst b/printer_zpl2/readme/INSTALL.rst new file mode 100644 index 0000000..5ffe8fa --- /dev/null +++ b/printer_zpl2/readme/INSTALL.rst @@ -0,0 +1 @@ +Nothing special, just install the module. diff --git a/printer_zpl2/readme/USAGE.rst b/printer_zpl2/readme/USAGE.rst new file mode 100644 index 0000000..cfbe9a9 --- /dev/null +++ b/printer_zpl2/readme/USAGE.rst @@ -0,0 +1,13 @@ +To print a label, you need to call use the label printing method from anywhere (other modules, server actions, etc.). + +Example : Print the label of a product :: + + self.env['printing.label.zpl2'].browse(label_id).print_label( + self.env['printing.printer'].browse(printer_id), + self.env['product.product'].browse(product_id)) + +You can also use the generic label printing wizard, if added on some models. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/144/12.0 diff --git a/printer_zpl2/static/description/index.html b/printer_zpl2/static/description/index.html new file mode 100644 index 0000000..96eb729 --- /dev/null +++ b/printer_zpl2/static/description/index.html @@ -0,0 +1,484 @@ + + + + + + +Printer ZPL II + + + +
+

Printer ZPL II

+ + +

Beta License: AGPL-3 OCA/report-print-send Translate me on Weblate Try me on Runbot

+

This module extends the Report to printer (base_report_to_printer) +module to add a ZPL II label printing feature.

+

This module is meant to be used as a base for module development, and does not provide a GUI on its own. +See below for more details.

+

Table of contents

+ +
+

Installation

+

Nothing special, just install the module.

+
+
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Settings > Printing > Labels > ZPL II
  2. +
  3. Create new labels
  4. +
  5. Import ZPL2 code
  6. +
  7. Use the Test Mode tab during the creation
  8. +
+

It’s also possible to add a label printing wizard on any model by creating a new ir.actions.act_window record. +For example, to add the printing wizard on the product.product model

+
+<act_window id="action_wizard_purchase"
+  name="Print Label"
+  src_model="product.product"
+  res_model="wizard.print.record.label"
+  view_mode="form"
+  target="new"
+  key2="client_action_multi"/>
+
+
+
+

Usage

+

To print a label, you need to call use the label printing method from anywhere (other modules, server actions, etc.).

+

Example : Print the label of a product

+
+self.env['printing.label.zpl2'].browse(label_id).print_label(
+    self.env['printing.printer'].browse(printer_id),
+    self.env['product.product'].browse(product_id))
+
+

You can also use the generic label printing wizard, if added on some models.

+Try me on Runbot +
+
+

Changelog

+
+

13.0.1.0.0 (2019-09-30)

+
    +
  • [RELEASE] Port from V12.
  • +
  • Selection lists do not support integers any longer
  • +
  • Binary field now returns False when empty instead of none, +change tests to reflect this
  • +
  • work around an appels vs oranges warning
  • +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • SUBTENO-IT
  • +
  • FLorent de Labarre
  • +
  • Apertoso NV
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/report-print-send project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/printer_zpl2/tests/test_generate_action.py b/printer_zpl2/tests/test_generate_action.py index 0669bd2..6b0769a 100644 --- a/printer_zpl2/tests/test_generate_action.py +++ b/printer_zpl2/tests/test_generate_action.py @@ -3,30 +3,35 @@ from odoo.tests.common import TransactionCase -model = 'odoo.addons.base_report_to_printer.models.printing_server' +model = "odoo.addons.base_report_to_printer.models.printing_server" class TestWizardPrintRecordLabel(TransactionCase): def setUp(self): super(TestWizardPrintRecordLabel, self).setUp() - self.Model = self.env['wizard.print.record.label'] - self.server = self.env['printing.server'].create({}) - self.printer = self.env['printing.printer'].create({ - 'name': 'Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) - self.label = self.env['printing.label.zpl2'].create({ - 'name': 'ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - }) + self.Model = self.env["wizard.print.record.label"] + self.server = self.env["printing.server"].create({}) + self.printer = self.env["printing.printer"].create( + { + "name": "Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) + self.label = self.env["printing.label.zpl2"].create( + { + "name": "ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, + } + ) def test_create_action(self): """ Check the creation of action """ diff --git a/printer_zpl2/tests/test_printing_label_zpl2.py b/printer_zpl2/tests/test_printing_label_zpl2.py index b944696..d2b32c1 100644 --- a/printer_zpl2/tests/test_printing_label_zpl2.py +++ b/printer_zpl2/tests/test_printing_label_zpl2.py @@ -1,9 +1,10 @@ # Copyright 2016 LasLabs Inc. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import mock import logging +import mock + from odoo import exceptions from odoo.tests.common import TransactionCase @@ -12,36 +13,37 @@ _logger = logging.getLogger(__name__) try: import zpl2 except ImportError: - _logger.debug('Cannot `import zpl2`.') + _logger.debug("Cannot `import zpl2`.") -model = 'odoo.addons.base_report_to_printer.models.printing_server' +model = "odoo.addons.base_report_to_printer.models.printing_server" class TestPrintingLabelZpl2(TransactionCase): def setUp(self): super(TestPrintingLabelZpl2, self).setUp() - self.Model = self.env['printing.label.zpl2'] - self.ComponentModel = self.env['printing.label.zpl2.component'] - self.server = self.env['printing.server'].create({}) - self.printer = self.env['printing.printer'].create({ - 'name': 'Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) + self.Model = self.env["printing.label.zpl2"] + self.ComponentModel = self.env["printing.label.zpl2.component"] + self.server = self.env["printing.server"].create({}) + self.printer = self.env["printing.printer"].create( + { + "name": "Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) self.label_vals = { - 'name': 'ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - } - self.component_vals = { - 'name': 'ZPL II Label Component', + "name": "ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, } + self.component_vals = {"name": "ZPL II Label Component"} def new_label(self, vals=None): values = self.label_vals.copy() @@ -61,7 +63,7 @@ class TestPrintingLabelZpl2(TransactionCase): with self.assertRaises(exceptions.UserError): label.print_label(self.printer, label) - @mock.patch('%s.cups' % model) + @mock.patch("%s.cups" % model) def test_print_empty_label(self, cups): """ Check that printing an empty label works """ label = self.new_label() @@ -71,123 +73,124 @@ class TestPrintingLabelZpl2(TransactionCase): def test_empty_label_contents(self): """ Check contents of an empty label """ label = self.new_label() - contents = label._generate_zpl2_data(self.printer).decode('utf-8') + contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ') + "^XZ", + ) def test_sublabel_label_contents(self): """ Check contents of a sublabel label component """ - sublabel = self.new_label({ - 'name': 'Sublabel', - }) - data = 'Some text' - self.new_component({ - 'label_id': sublabel.id, - 'data': '"' + data + '"', - }) + sublabel = self.new_label({"name": "Sublabel"}) + data = "Some text" + self.new_component({"label_id": sublabel.id, "data": '"' + data + '"'}) label = self.new_label() - self.new_component({ - 'label_id': label.id, - 'name': 'Sublabel contents', - 'component_type': 'sublabel', - 'sublabel_id': sublabel.id, - }) - contents = label._generate_zpl2_data(self.printer).decode('utf-8') + self.new_component( + { + "label_id": label.id, + "name": "Sublabel contents", + "component_type": "sublabel", + "sublabel_id": sublabel.id, + } + ) + contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Sublabel component position # Position 30x30 because the default values are : # - 10x10 for the sublabel component in the main label # - 10x10 for the sublabel in the sublabel component # - 10x10 for the component in the sublabel - '^FO30,30' + "^FO30,30" # Sublabel component format - '^A0N,10,10' + "^A0N,10,10" # Sublabel component contents - '^FD{contents}' + "^FD{contents}" # Sublabel component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_repeatable_component_label_fixed_contents(self): """ Check contents of a repeatable label component Check that a fixed value is repeated each time """ - label = self.new_label({ - 'model_id': self.env.ref( - 'printer_zpl2.model_printing_label_zpl2').id, - }) - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'data': '"' + data + '"', - 'repeat': True, - 'repeat_count': 3, - 'repeat_offset_y': 15, - }) + label = self.new_label( + {"model_id": self.env.ref("printer_zpl2.model_printing_label_zpl2").id} + ) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "data": '"' + data + '"', + "repeat": True, + "repeat_count": 3, + "repeat_offset_y": 15, + } + ) contents = label._generate_zpl2_data(label).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # First component position - '^FO10,10' + "^FO10,10" # First component format - '^A0N,10,10' + "^A0N,10,10" # First component contents - '^FD{contents}' + "^FD{contents}" # First component end - '^FS\n' + "^FS\n" # Second component position - '^FO10,25' + "^FO10,25" # Second component format - '^A0N,10,10' + "^A0N,10,10" # Second component contents - '^FD{contents}' + "^FD{contents}" # Second component end - '^FS\n' + "^FS\n" # Third component position - '^FO10,40' + "^FO10,40" # Third component format - '^A0N,10,10' + "^A0N,10,10" # Third component contents - '^FD{contents}' + "^FD{contents}" # Third component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_repeatable_component_label_iterable_contents(self): """ Check contents of a repeatable label component @@ -196,50 +199,52 @@ class TestPrintingLabelZpl2(TransactionCase): If the repeat_count is higher than the value length, all values are displayed """ - label = self.new_label({ - 'model_id': self.env.ref( - 'printer_zpl2.model_printing_label_zpl2').id, - }) - data = ['First text', 'Second text', 'Third text'] - self.new_component({ - 'label_id': label.id, - 'data': str(data), - 'repeat': True, - 'repeat_offset': 1, - 'repeat_count': 3, - 'repeat_offset_y': 15, - }) - contents = label._generate_zpl2_data(label).decode('utf-8') + label = self.new_label( + {"model_id": self.env.ref("printer_zpl2.model_printing_label_zpl2").id} + ) + data = ["First text", "Second text", "Third text"] + self.new_component( + { + "label_id": label.id, + "data": str(data), + "repeat": True, + "repeat_offset": 1, + "repeat_count": 3, + "repeat_offset_y": 15, + } + ) + contents = label._generate_zpl2_data(label).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # First component position - '^FO10,10' + "^FO10,10" # First component format - '^A0N,10,10' + "^A0N,10,10" # First component contents - '^FD{contents[1]}' + "^FD{contents[1]}" # First component end - '^FS\n' + "^FS\n" # Second component position - '^FO10,25' + "^FO10,25" # Second component format - '^A0N,10,10' + "^A0N,10,10" # Second component contents - '^FD{contents[2]}' + "^FD{contents[2]}" # Second component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_repeatable_component_label_iterable_offset(self): """ Check contents of a repeatable label component with an offset @@ -248,777 +253,794 @@ class TestPrintingLabelZpl2(TransactionCase): If the repeat_count is higher than the value length, all values are displayed """ - label = self.new_label({ - 'model_id': self.env.ref( - 'printer_zpl2.model_printing_label_zpl2').id, - }) - data = ['Text {value}'.format(value=ind) for ind in range(20)] - self.new_component({ - 'label_id': label.id, - 'data': str(data), - 'repeat': True, - 'repeat_offset': 10, - 'repeat_count': 3, - 'repeat_offset_y': 15, - }) - contents = label._generate_zpl2_data(label).decode('utf-8') - self.assertEqual( - contents, - # Label start - '^XA\n' - # Print width - '^PW480\n' - # UTF-8 encoding - '^CI28\n' - # Label position - '^LH10,10\n' - # First component position - '^FO10,10' - # First component format - '^A0N,10,10' - # First component contents - '^FD{contents[10]}' - # First component end - '^FS\n' - # Second component position - '^FO10,25' - # Second component format - '^A0N,10,10' - # Second component contents - '^FD{contents[11]}' - # Second component end - '^FS\n' - # Third component position - '^FO10,40' - # Third component format - '^A0N,10,10' - # Third component contents - '^FD{contents[12]}' - # Third component end - '^FS\n' - # Recall last saved parameters - '^JUR\n' - # Label end - '^XZ'.format(contents=data)) - - def test_repeatable_sublabel_contents(self): - """ Check contents of a repeatable sublabel label component """ - sublabel = self.new_label({ - 'name': 'Sublabel', - 'model_id': self.env.ref( - 'printer_zpl2.model_printing_label_zpl2_component').id, - }) - self.new_component({ - 'label_id': sublabel.id, - 'name': 'Components name', - 'data': 'object.name', - }) - self.new_component({ - 'label_id': sublabel.id, - 'name': 'Components data', - 'data': 'object.data', - 'origin_x': 50, - }) - label = self.new_label({ - 'model_id': self.env.ref( - 'printer_zpl2.model_printing_label_zpl2').id, - }) - self.new_component({ - 'label_id': label.id, - 'name': 'Label name', - 'data': 'object.name', - }) - self.new_component({ - 'label_id': label.id, - 'name': 'Label components', - 'component_type': 'sublabel', - 'origin_x': 15, - 'origin_y': 30, - 'data': 'object.component_ids', - 'sublabel_id': sublabel.id, - 'repeat': True, - 'repeat_count': 3, - 'repeat_offset_y': 15, - }) + label = self.new_label( + {"model_id": self.env.ref("printer_zpl2.model_printing_label_zpl2").id} + ) + data = ["Text {value}".format(value=ind) for ind in range(20)] + self.new_component( + { + "label_id": label.id, + "data": str(data), + "repeat": True, + "repeat_offset": 10, + "repeat_count": 3, + "repeat_offset_y": 15, + } + ) contents = label._generate_zpl2_data(label).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' - # Label name component position - '^FO10,10' - # Label name component format - '^A0N,10,10' - # Label name component contents - '^FD{label.name}' - # Label name component end - '^FS\n' - # First component name component position - '^FO35,50' - # First component name component format - '^A0N,10,10' - # First component name component contents - '^FD{label.component_ids[0].name}' - # First component name component end - '^FS\n' - # First component data component position - '^FO75,50' - # First component data component format - '^A0N,10,10' - # First component data component contents - '^FD{label.component_ids[0].data}' - # First component data component end - '^FS\n' - # Second component name component position - '^FO35,65' - # Second component name component format - '^A0N,10,10' - # Second component name component contents - '^FD{label.component_ids[1].name}' - # Second component name component end - '^FS\n' - # Second component data component position - '^FO75,65' - # Second component data component format - '^A0N,10,10' - # Second component data component contents - '^FD{label.component_ids[1].data}' - # Second component data component end - '^FS\n' + "^LH10,10\n" + # First component position + "^FO10,10" + # First component format + "^A0N,10,10" + # First component contents + "^FD{contents[10]}" + # First component end + "^FS\n" + # Second component position + "^FO10,25" + # Second component format + "^A0N,10,10" + # Second component contents + "^FD{contents[11]}" + # Second component end + "^FS\n" + # Third component position + "^FO10,40" + # Third component format + "^A0N,10,10" + # Third component contents + "^FD{contents[12]}" + # Third component end + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(label=label)) + "^XZ".format(contents=data), + ) + + def test_repeatable_sublabel_contents(self): + """ Check contents of a repeatable sublabel label component """ + sublabel = self.new_label( + { + "name": "Sublabel", + "model_id": self.env.ref( + "printer_zpl2.model_printing_label_zpl2_component" + ).id, + } + ) + self.new_component( + {"label_id": sublabel.id, "name": "Components name", "data": "object.name"} + ) + self.new_component( + { + "label_id": sublabel.id, + "name": "Components data", + "data": "object.data", + "origin_x": 50, + } + ) + label = self.new_label( + {"model_id": self.env.ref("printer_zpl2.model_printing_label_zpl2").id} + ) + self.new_component( + {"label_id": label.id, "name": "Label name", "data": "object.name"} + ) + self.new_component( + { + "label_id": label.id, + "name": "Label components", + "component_type": "sublabel", + "origin_x": 15, + "origin_y": 30, + "data": "object.component_ids", + "sublabel_id": sublabel.id, + "repeat": True, + "repeat_count": 3, + "repeat_offset_y": 15, + } + ) + contents = label._generate_zpl2_data(label).decode("utf-8") + self.assertEqual( + contents, + # Label start + "^XA\n" + # Print width + "^PW480\n" + # UTF-8 encoding + "^CI28\n" + # Label position + "^LH10,10\n" + # Label name component position + "^FO10,10" + # Label name component format + "^A0N,10,10" + # Label name component contents + "^FD{label.name}" + # Label name component end + "^FS\n" + # First component name component position + "^FO35,50" + # First component name component format + "^A0N,10,10" + # First component name component contents + "^FD{label.component_ids[0].name}" + # First component name component end + "^FS\n" + # First component data component position + "^FO75,50" + # First component data component format + "^A0N,10,10" + # First component data component contents + "^FD{label.component_ids[0].data}" + # First component data component end + "^FS\n" + # Second component name component position + "^FO35,65" + # Second component name component format + "^A0N,10,10" + # Second component name component contents + "^FD{label.component_ids[1].name}" + # Second component name component end + "^FS\n" + # Second component data component position + "^FO75,65" + # Second component data component format + "^A0N,10,10" + # Second component data component contents + "^FD{label.component_ids[1].data}" + # Second component data component end + "^FS\n" + # Recall last saved parameters + "^JUR\n" + # Label end + "^XZ".format(label=label), + ) def test_text_label_contents(self): """ Check contents of a text label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'data': '"%s"' % data, - }) + data = "Some text" + self.new_component({"label_id": label.id, "data": '"%s"' % data}) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^A0N,10,10' + "^A0N,10,10" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_reversed_text_label_contents(self): """ Check contents of a text label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'data': '"' + data + '"', - 'reverse_print': True, - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "data": '"' + data + '"', "reverse_print": True} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^A0N,10,10' + "^A0N,10,10" # Reverse print argument - '^FR' + "^FR" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_block_text_label_contents(self): """ Check contents of a text label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'data': '"' + data + '"', - 'in_block': True, - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "data": '"' + data + '"', "in_block": True} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^A0N,10,10' + "^A0N,10,10" # Block definition - '^FB0,1,0,L,0' + "^FB0,1,0,L,0" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_rectangle_label_contents(self): """ Check contents of a rectangle label """ label = self.new_label() - self.new_component({ - 'label_id': label.id, - 'component_type': 'rectangle', - }) + self.new_component({"label_id": label.id, "component_type": "rectangle"}) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^GB1,1,1,B,0' + "^GB1,1,1,B,0" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ') + "^XZ", + ) def test_diagonal_line_label_contents(self): """ Check contents of a diagonal line label """ label = self.new_label() - self.new_component({ - 'label_id': label.id, - 'component_type': 'diagonal', - }) + self.new_component({"label_id": label.id, "component_type": "diagonal"}) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^GD3,3,1,B,L' + "^GD3,3,1,B,L" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ') + "^XZ", + ) def test_circle_label_contents(self): """ Check contents of a circle label """ label = self.new_label() - self.new_component({ - 'label_id': label.id, - 'component_type': 'circle', - }) + self.new_component({"label_id": label.id, "component_type": "circle"}) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^GC3,2,B' + "^GC3,2,B" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ') + "^XZ", + ) def test_code11_barcode_label_contents(self): """ Check contents of a code 11 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_11', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_11", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B1N,N,0,N,N' + "^B1N,N,0,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_2of5_barcode_label_contents(self): """ Check contents of a interleaved 2 of 5 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'interleaved_2_of_5', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "interleaved_2_of_5", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B2N,0,N,N,N' + "^B2N,0,N,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_code39_barcode_label_contents(self): """ Check contents of a code 39 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_39', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_39", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B3N,N,0,N,N' + "^B3N,N,0,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_code49_barcode_label_contents(self): """ Check contents of a code 49 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_49', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_49", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B4N,0,N' + "^B4N,0,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_code49_barcode_label_contents_line(self): """ Check contents of a code 49 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_49', - 'data': '"' + data + '"', - 'interpretation_line': True, - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_49", + "data": '"' + data + '"', + "interpretation_line": True, + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B4N,0,B' + "^B4N,0,B" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_code49_barcode_label_contents_with_above(self): """ Check contents of a code 49 barconde label with interpretation line above """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_49', - 'data': '"' + data + '"', - 'interpretation_line': True, - 'interpretation_line_above': True, - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_49", + "data": '"' + data + '"', + "interpretation_line": True, + "interpretation_line_above": True, + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B4N,0,A' + "^B4N,0,A" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_pdf417_barcode_label_contents(self): """ Check contents of a pdf417 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'pdf417', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "component_type": "pdf417", "data": '"' + data + '"'} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B7N,0,0,0,0,N' + "^B7N,0,0,0,0,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_ean8_barcode_label_contents(self): """ Check contents of a ean-8 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'ean-8', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "component_type": "ean-8", "data": '"' + data + '"'} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B8N,0,N,N' + "^B8N,0,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_upce_barcode_label_contents(self): """ Check contents of a upc-e barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'upc-e', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "component_type": "upc-e", "data": '"' + data + '"'} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^B9N,0,N,N,N' + "^B9N,0,N,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_code128_barcode_label_contents(self): """ Check contents of a code 128 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'code_128', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "code_128", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^BCN,0,N,N,N' + "^BCN,0,N,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_ean13_barcode_label_contents(self): """ Check contents of a ean-13 barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'ean-13', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + {"label_id": label.id, "component_type": "ean-13", "data": '"' + data + '"'} + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^BEN,0,N,N' + "^BEN,0,N,N" # Component contents - '^FD{contents}' + "^FD{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_qrcode_barcode_label_contents(self): """ Check contents of a qr code barcode label """ label = self.new_label() - data = 'Some text' - self.new_component({ - 'label_id': label.id, - 'component_type': 'qr_code', - 'data': '"' + data + '"', - }) + data = "Some text" + self.new_component( + { + "label_id": label.id, + "component_type": "qr_code", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, # Label start - '^XA\n' + "^XA\n" # Print width - '^PW480\n' + "^PW480\n" # UTF-8 encoding - '^CI28\n' + "^CI28\n" # Label position - '^LH10,10\n' + "^LH10,10\n" # Barcode default format - '^BY2,3.0' + "^BY2,3.0" # Component position - '^FO10,10' + "^FO10,10" # Component format - '^BQN,2,1,Q,7' + "^BQN,2,1,Q,7" # Component contents - '^FDQA,{contents}' + "^FDQA,{contents}" # Component end - '^FS\n' + "^FS\n" # Recall last saved parameters - '^JUR\n' + "^JUR\n" # Label end - '^XZ'.format(contents=data)) + "^XZ".format(contents=data), + ) def test_graphic_label_contents_blank(self): """ Check contents of a image label """ label = self.new_label() - data = 'R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==' - self.new_component({ - 'label_id': label.id, - 'component_type': 'graphic', - 'data': '"' + data + '"', - }) + data = "R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" + self.new_component( + { + "label_id": label.id, + "component_type": "graphic", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, @@ -1028,21 +1050,24 @@ class TestPrintingLabelZpl2(TransactionCase): "^LH10,10\n" "^FO10,10^GFA,1.0,1.0,1.0,b'00'^FS\n" "^JUR\n" - "^XZ") + "^XZ", + ) def test_graphic_label_contents_blank_rotated(self): """ Check contents of image rotated label """ label = self.new_label() - data = 'R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==' - self.new_component({ - 'label_id': label.id, - 'component_type': 'graphic', - 'data': '"' + data + '"', - 'height': 10, - 'width': 10, - 'reverse_print': 1, - 'orientation': zpl2.ORIENTATION_ROTATED, - }) + data = "R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" + self.new_component( + { + "label_id": label.id, + "component_type": "graphic", + "data": '"' + data + '"', + "height": 10, + "width": 10, + "reverse_print": 1, + "orientation": zpl2.ORIENTATION_ROTATED, + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, @@ -1053,18 +1078,21 @@ class TestPrintingLabelZpl2(TransactionCase): "^FO10,10^GFA,20.0,20.0,2.0," "b'FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0'^FS\n" "^JUR\n" - "^XZ") + "^XZ", + ) def test_graphic_label_contents_blank_inverted(self): """ Check contents of a image inverted label """ label = self.new_label() - data = 'R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==' - self.new_component({ - 'label_id': label.id, - 'component_type': 'graphic', - 'data': '"' + data + '"', - 'orientation': zpl2.ORIENTATION_INVERTED, - }) + data = "R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" + self.new_component( + { + "label_id": label.id, + "component_type": "graphic", + "data": '"' + data + '"', + "orientation": zpl2.ORIENTATION_INVERTED, + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, @@ -1074,18 +1102,21 @@ class TestPrintingLabelZpl2(TransactionCase): "^LH10,10\n" "^FO10,10^GFA,1.0,1.0,1.0,b'00'^FS\n" "^JUR\n" - "^XZ") + "^XZ", + ) def test_graphic_label_contents_blank_bottom(self): """ Check contents of a image bottom label """ label = self.new_label() - data = 'R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==' - self.new_component({ - 'label_id': label.id, - 'component_type': 'graphic', - 'data': '"' + data + '"', - 'orientation': zpl2.ORIENTATION_BOTTOM_UP, - }) + data = "R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" + self.new_component( + { + "label_id": label.id, + "component_type": "graphic", + "data": '"' + data + '"', + "orientation": zpl2.ORIENTATION_BOTTOM_UP, + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, @@ -1095,43 +1126,44 @@ class TestPrintingLabelZpl2(TransactionCase): "^LH10,10\n" "^FO10,10^GFA,1.0,1.0,1.0,b'00'^FS\n" "^JUR\n" - "^XZ") + "^XZ", + ) def test_zpl2_raw_contents_blank(self): """ Check contents of a image label """ label = self.new_label() - data = '^FO50,50^GB100,100,100^FS' - self.new_component({ - 'label_id': label.id, - 'component_type': 'zpl2_raw', - 'data': '"' + data + '"', - }) + data = "^FO50,50^GB100,100,100^FS" + self.new_component( + { + "label_id": label.id, + "component_type": "zpl2_raw", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( contents, - '^XA\n' - '^PW480\n' - '^CI28\n' - '^LH10,10\n' - '^FO50,50^GB100,100,100^FS\n' - '^JUR\n' - '^XZ') + "^XA\n" + "^PW480\n" + "^CI28\n" + "^LH10,10\n" + "^FO50,50^GB100,100,100^FS\n" + "^JUR\n" + "^XZ", + ) def test_zpl2_component_not_show(self): """ Check to don't show no things """ label = self.new_label() - data = 'component_not_show' - self.new_component({ - 'label_id': label.id, - 'component_type': 'zpl2_raw', - 'data': '"' + data + '"', - }) + data = "component_not_show" + self.new_component( + { + "label_id": label.id, + "component_type": "zpl2_raw", + "data": '"' + data + '"', + } + ) contents = label._generate_zpl2_data(self.printer).decode("utf-8") self.assertEqual( - contents, - '^XA\n' - '^PW480\n' - '^CI28\n' - '^LH10,10\n' - '^JUR\n' - '^XZ') + contents, "^XA\n" "^PW480\n" "^CI28\n" "^LH10,10\n" "^JUR\n" "^XZ" + ) diff --git a/printer_zpl2/tests/test_test_mode.py b/printer_zpl2/tests/test_test_mode.py index 7fada83..5b7b5d4 100644 --- a/printer_zpl2/tests/test_test_mode.py +++ b/printer_zpl2/tests/test_test_mode.py @@ -4,30 +4,35 @@ import mock from odoo.tests.common import TransactionCase -model = 'odoo.addons.base_report_to_printer.models.printing_server' +model = "odoo.addons.base_report_to_printer.models.printing_server" class TestWizardPrintRecordLabel(TransactionCase): def setUp(self): super(TestWizardPrintRecordLabel, self).setUp() - self.Model = self.env['wizard.print.record.label'] - self.server = self.env['printing.server'].create({}) - self.printer = self.env['printing.printer'].create({ - 'name': 'Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) - self.label = self.env['printing.label.zpl2'].create({ - 'name': 'ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - }) + self.Model = self.env["wizard.print.record.label"] + self.server = self.env["printing.server"].create({}) + self.printer = self.env["printing.printer"].create( + { + "name": "Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) + self.label = self.env["printing.label.zpl2"].create( + { + "name": "ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, + } + ) def test_get_record(self): """ Check if return a record """ @@ -35,12 +40,12 @@ class TestWizardPrintRecordLabel(TransactionCase): res = self.label._get_record() Obj = self.env[self.label.model_id.model] - record = Obj.search([('id', '=', self.label.record_id)], limit=1) + record = Obj.search([("id", "=", self.label.record_id)], limit=1) if not record: - record = Obj.search([], limit=1, order='id desc') + record = Obj.search([], limit=1, order="id desc") self.assertEqual(res, record) - @mock.patch('%s.cups' % model) + @mock.patch("%s.cups" % model) def test_print_label_test(self, cups): """ Check if print test """ self.label.test_print_mode = True @@ -53,18 +58,17 @@ class TestWizardPrintRecordLabel(TransactionCase): """ Check if not execute next if not in this mode """ self.label.test_labelary_mode = False self.label._on_change_labelary() - self.assertIs(self.label.labelary_image, None) + self.assertIs(self.label.labelary_image, False) def test_emulation_with_bad_header(self): """ Check if bad header """ self.label.test_labelary_mode = True self.label.labelary_width = 80 - self.label.labelary_dpmm = '8dpmm' + self.label.labelary_dpmm = "8dpmm" self.label.labelary_height = 10000000 - self.env['printing.label.zpl2.component'].create({ - 'name': 'ZPL II Label', - 'label_id': self.label.id, - 'data': '"Test"'}) + self.env["printing.label.zpl2.component"].create( + {"name": "ZPL II Label", "label_id": self.label.id, "data": '"Test"'} + ) self.label._on_change_labelary() self.assertFalse(self.label.labelary_image) @@ -73,24 +77,22 @@ class TestWizardPrintRecordLabel(TransactionCase): self.label.test_labelary_mode = True self.label.labelary_width = 80 self.label.labelary_height = 30 - self.label.labelary_dpmm = '8dpmm' - component = self.env['printing.label.zpl2.component'].create({ - 'name': 'ZPL II Label', - 'label_id': self.label.id, - 'data': 'wrong_data'}) + self.label.labelary_dpmm = "8dpmm" + component = self.env["printing.label.zpl2.component"].create( + {"name": "ZPL II Label", "label_id": self.label.id, "data": "wrong_data"} + ) self.label._on_change_labelary() component.unlink() - self.assertIs(self.label.labelary_image, None) + self.assertIs(self.label.labelary_image, False) def test_emulation_with_good_data(self): """ Check if ok """ self.label.test_labelary_mode = True self.label.labelary_width = 80 self.label.labelary_height = 30 - self.label.labelary_dpmm = '8dpmm' - self.env['printing.label.zpl2.component'].create({ - 'name': 'ZPL II Label', - 'label_id': self.label.id, - 'data': '"good_data"', }) + self.label.labelary_dpmm = "8dpmm" + self.env["printing.label.zpl2.component"].create( + {"name": "ZPL II Label", "label_id": self.label.id, "data": '"good_data"'} + ) self.label._on_change_labelary() self.assertTrue(self.label.labelary_image) diff --git a/printer_zpl2/tests/test_wizard_import_zpl2.py b/printer_zpl2/tests/test_wizard_import_zpl2.py index cbe1673..41f2d5e 100644 --- a/printer_zpl2/tests/test_wizard_import_zpl2.py +++ b/printer_zpl2/tests/test_wizard_import_zpl2.py @@ -7,92 +7,89 @@ from odoo.tests.common import TransactionCase class TestWizardImportZpl2(TransactionCase): def setUp(self): super(TestWizardImportZpl2, self).setUp() - self.Model = self.env['wizard.print.record.label'] - self.server = self.env['printing.server'].create({}) - self.printer = self.env['printing.printer'].create({ - 'name': 'Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) - self.label = self.env['printing.label.zpl2'].create({ - 'name': 'ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - }) + self.Model = self.env["wizard.print.record.label"] + self.server = self.env["printing.server"].create({}) + self.printer = self.env["printing.printer"].create( + { + "name": "Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) + self.label = self.env["printing.label.zpl2"].create( + { + "name": "ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, + } + ) def test_open_wizard(self): """ open wizard from label""" res = self.label.import_zpl2() - self.assertEqual( - res.get('context').get('default_label_id'), - self.label.id) + self.assertEqual(res.get("context").get("default_label_id"), self.label.id) def test_wizard_import_zpl2(self): """ Import ZPL2 from wizard """ - zpl_data = ("^XA\n" - "^CI28\n" - "^LH0,0\n" - "^CF0\n" - "^CFA,10\n" - "^CFB,10,10\n" - "^FO10,10^A0N,30,30^FDTEXT^FS\n" - "^BY2,3.0^FO600,60^BCN,30,N,N,N" - "^FDAJFGJAGJVJVHK^FS\n" - "^FO10,40^A0N,20,40^FB150,2,1,J,0^FDTEXT BLOCK^FS\n" - "^FO300,10^GC100,3,B^FS\n" - "^FO10,200^GB200,200,100,B,0^FS\n" - "^FO10,60^GFA,16.0,16.0,2.0," - "b'FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0'^FS\n" - "^FO10,200^GB300,100,6,W,0^FS\n" - "^BY2,3.0^FO300,10^B1N,N,30,N,N^FD678987656789^FS\n" - "^BY2,3.0^FO300,70^B2N,30,Y,Y,N^FD567890987768^FS\n" - "^BY2,3.0^FO300,120^B3N,N,30,N,N^FD98765456787656^FS\n" - "^BY2,3.0^FO300,200^BQN,2,5,Q,7" - "^FDMM,A876567897656787658654645678^FS\n" - "^BY2,3.0^FO400,250^BER,40,Y,Y^FD9876789987654567^FS\n" - "^BY2,3.0^FO350,250^B7N,20,0,0,0,N^FD8765678987656789^FS\n" - "^BY2,3.0^FO700,10^B9N,20,N,N,N^FD87657890987654^FS\n" - "^BY2,3.0^FO600,200^B4N,50,N^FD7654567898765678^FS\n" - "^BY2,3.0^FO600,300^BEN,50,Y,Y^FD987654567890876567^FS\n" - "^FO300,300^AGI,50,50^FR^FDINVERTED^FS\n" - "^BY2,3.0^FO700,200^B8,50,N,N^FD987609876567^FS\n" - "^JUR\n" - "^XZ") + zpl_data = ( + "^XA\n" + "^CI28\n" + "^LH0,0\n" + "^CF0\n" + "^CFA,10\n" + "^CFB,10,10\n" + "^FO10,10^A0N,30,30^FDTEXT^FS\n" + "^BY2,3.0^FO600,60^BCN,30,N,N,N" + "^FDAJFGJAGJVJVHK^FS\n" + "^FO10,40^A0N,20,40^FB150,2,1,J,0^FDTEXT BLOCK^FS\n" + "^FO300,10^GC100,3,B^FS\n" + "^FO10,200^GB200,200,100,B,0^FS\n" + "^FO10,60^GFA,16.0,16.0,2.0," + "b'FFC0FFC0FFC0FFC0FFC0FFC0FFC0FFC0'^FS\n" + "^FO10,200^GB300,100,6,W,0^FS\n" + "^BY2,3.0^FO300,10^B1N,N,30,N,N^FD678987656789^FS\n" + "^BY2,3.0^FO300,70^B2N,30,Y,Y,N^FD567890987768^FS\n" + "^BY2,3.0^FO300,120^B3N,N,30,N,N^FD98765456787656^FS\n" + "^BY2,3.0^FO300,200^BQN,2,5,Q,7" + "^FDMM,A876567897656787658654645678^FS\n" + "^BY2,3.0^FO400,250^BER,40,Y,Y^FD9876789987654567^FS\n" + "^BY2,3.0^FO350,250^B7N,20,0,0,0,N^FD8765678987656789^FS\n" + "^BY2,3.0^FO700,10^B9N,20,N,N,N^FD87657890987654^FS\n" + "^BY2,3.0^FO600,200^B4N,50,N^FD7654567898765678^FS\n" + "^BY2,3.0^FO600,300^BEN,50,Y,Y^FD987654567890876567^FS\n" + "^FO300,300^AGI,50,50^FR^FDINVERTED^FS\n" + "^BY2,3.0^FO700,200^B8,50,N,N^FD987609876567^FS\n" + "^JUR\n" + "^XZ" + ) - vals = {'label_id': self.label.id, - 'delete_component': True, - 'data': zpl_data} - wizard = self.env['wizard.import.zpl2'].create(vals) + vals = {"label_id": self.label.id, "delete_component": True, "data": zpl_data} + wizard = self.env["wizard.import.zpl2"].create(vals) wizard.import_zpl2() - self.assertEqual( - 18, - len(self.label.component_ids)) + self.assertEqual(18, len(self.label.component_ids)) def test_wizard_import_zpl2_add(self): """ Import ZPL2 from wizard ADD""" - self.env['printing.label.zpl2.component'].create({ - 'name': 'ZPL II Label', - 'label_id': self.label.id, - 'data': '"data"', - 'sequence': 10}) - zpl_data = ("^XA\n" - "^CI28\n" - "^LH0,0\n" - "^FO10,10^A0N,30,30^FDTEXT^FS\n" - "^JUR\n" - "^XZ") + self.env["printing.label.zpl2.component"].create( + { + "name": "ZPL II Label", + "label_id": self.label.id, + "data": '"data"', + "sequence": 10, + } + ) + zpl_data = ( + "^XA\n" "^CI28\n" "^LH0,0\n" "^FO10,10^A0N,30,30^FDTEXT^FS\n" "^JUR\n" "^XZ" + ) - vals = {'label_id': self.label.id, - 'delete_component': False, - 'data': zpl_data} - wizard = self.env['wizard.import.zpl2'].create(vals) + vals = {"label_id": self.label.id, "delete_component": False, "data": zpl_data} + wizard = self.env["wizard.import.zpl2"].create(vals) wizard.import_zpl2() - self.assertEqual( - 2, - len(self.label.component_ids)) + self.assertEqual(2, len(self.label.component_ids)) diff --git a/printer_zpl2/tests/test_wizard_print_record_label.py b/printer_zpl2/tests/test_wizard_print_record_label.py index a2aa6d6..1babfaa 100644 --- a/printer_zpl2/tests/test_wizard_print_record_label.py +++ b/printer_zpl2/tests/test_wizard_print_record_label.py @@ -5,37 +5,41 @@ import mock from odoo.tests.common import TransactionCase - -model = 'odoo.addons.base_report_to_printer.models.printing_server' +model = "odoo.addons.base_report_to_printer.models.printing_server" class TestWizardPrintRecordLabel(TransactionCase): def setUp(self): super(TestWizardPrintRecordLabel, self).setUp() - self.Model = self.env['wizard.print.record.label'] - self.server = self.env['printing.server'].create({}) - self.printer = self.env['printing.printer'].create({ - 'name': 'Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) - self.label = self.env['printing.label.zpl2'].create({ - 'name': 'ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - }) + self.Model = self.env["wizard.print.record.label"] + self.server = self.env["printing.server"].create({}) + self.printer = self.env["printing.printer"].create( + { + "name": "Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) + self.label = self.env["printing.label.zpl2"].create( + { + "name": "ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, + } + ) - @mock.patch('%s.cups' % model) + @mock.patch("%s.cups" % model) def test_print_record_label(self, cups): """ Check that printing a label using the generic wizard works """ wizard_obj = self.Model.with_context( - active_model='printing.printer', + active_model="printing.printer", active_id=self.printer.id, active_ids=[self.printer.id], printer_zpl2_id=self.printer.id, @@ -50,41 +54,48 @@ class TestWizardPrintRecordLabel(TransactionCase): """ Check that printer_id and label_id are not automatically filled when there are multiple possible values """ - self.env['printing.printer'].create({ - 'name': 'Other_Printer', - 'server_id': self.server.id, - 'system_name': 'Sys Name', - 'default': True, - 'status': 'unknown', - 'status_message': 'Msg', - 'model': 'res.users', - 'location': 'Location', - 'uri': 'URI', - }) - self.env['printing.label.zpl2'].create({ - 'name': 'Other ZPL II Label', - 'model_id': self.env.ref( - 'base_report_to_printer.model_printing_printer').id, - }) + self.env["printing.printer"].create( + { + "name": "Other_Printer", + "server_id": self.server.id, + "system_name": "Sys Name", + "default": True, + "status": "unknown", + "status_message": "Msg", + "model": "res.users", + "location": "Location", + "uri": "URI", + } + ) + self.env["printing.label.zpl2"].create( + { + "name": "Other ZPL II Label", + "model_id": self.env.ref( + "base_report_to_printer.model_printing_printer" + ).id, + } + ) wizard_obj = self.Model.with_context( - active_model='printing.printer', + active_model="printing.printer", active_id=self.printer.id, active_ids=[self.printer.id], ) - values = wizard_obj.default_get(['printer_id', 'label_id']) - self.assertEqual(values.get('printer_id', False), False) - self.assertEqual(values.get('label_id', False), False) + values = wizard_obj.default_get(["printer_id", "label_id"]) + self.assertEqual(values.get("printer_id", False), False) + self.assertEqual(values.get("label_id", False), False) def test_wizard_multiple_labels_but_on_different_models(self): """ Check that label_id is automatically filled when there are multiple labels, but only one on the right model """ - self.env['printing.label.zpl2'].create({ - 'name': 'Other ZPL II Label', - 'model_id': self.env.ref('base.model_res_users').id, - }) + self.env["printing.label.zpl2"].create( + { + "name": "Other ZPL II Label", + "model_id": self.env.ref("base.model_res_users").id, + } + ) wizard_obj = self.Model.with_context( - active_model='printing.printer', + active_model="printing.printer", active_id=self.printer.id, active_ids=[self.printer.id], printer_zpl2_id=self.printer.id, diff --git a/printer_zpl2/views/printing_label_zpl2.xml b/printer_zpl2/views/printing_label_zpl2.xml index 69008ba..235bd03 100644 --- a/printer_zpl2/views/printing_label_zpl2.xml +++ b/printer_zpl2/views/printing_label_zpl2.xml @@ -7,7 +7,7 @@ printing.label.zpl2 - + @@ -44,7 +44,7 @@ - + @@ -178,7 +178,6 @@ ZPL II Labels ir.actions.act_window printing.label.zpl2 - form tree,form [] diff --git a/printer_zpl2/wizard/print_record_label.py b/printer_zpl2/wizard/print_record_label.py index 1944960..ebd93e0 100644 --- a/printer_zpl2/wizard/print_record_label.py +++ b/printer_zpl2/wizard/print_record_label.py @@ -1,45 +1,53 @@ # Copyright (C) 2016 SYLEAM () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models, api, fields +from odoo import api, fields, models class PrintRecordLabel(models.TransientModel): - _name = 'wizard.print.record.label' - _description = 'Print Record Label' + _name = "wizard.print.record.label" + _description = "Print Record Label" printer_id = fields.Many2one( - comodel_name='printing.printer', string='Printer', required=True, - help='Printer used to print the labels.') + comodel_name="printing.printer", + string="Printer", + required=True, + help="Printer used to print the labels.", + ) label_id = fields.Many2one( - comodel_name='printing.label.zpl2', string='Label', required=True, + comodel_name="printing.label.zpl2", + string="Label", + required=True, domain=lambda self: [ - ('model_id.model', '=', self.env.context.get('active_model'))], - help='Label to print.') + ("model_id.model", "=", self.env.context.get("active_model")) + ], + help="Label to print.", + ) @api.model def default_get(self, fields_list): values = super(PrintRecordLabel, self).default_get(fields_list) # Automatically select the printer and label, if only one is available - printers = self.env['printing.printer'].search( - [('id', '=', self.env.context.get('printer_zpl2_id'))]) + printers = self.env["printing.printer"].search( + [("id", "=", self.env.context.get("printer_zpl2_id"))] + ) if not printers: - printers = self.env['printing.printer'].search([]) + printers = self.env["printing.printer"].search([]) if len(printers) == 1: - values['printer_id'] = printers.id + values["printer_id"] = printers.id - labels = self.env['printing.label.zpl2'].search([ - ('model_id.model', '=', self.env.context.get('active_model')), - ]) + labels = self.env["printing.label.zpl2"].search( + [("model_id.model", "=", self.env.context.get("active_model"))] + ) if len(labels) == 1: - values['label_id'] = labels.id + values["label_id"] = labels.id return values def print_label(self): """ Prints a label per selected record """ - record_model = self.env.context['active_model'] - for record_id in self.env.context['active_ids']: + record_model = self.env.context["active_model"] + for record_id in self.env.context["active_ids"]: record = self.env[record_model].browse(record_id) self.label_id.print_label(self.printer_id, record) diff --git a/printer_zpl2/wizard/print_record_label.xml b/printer_zpl2/wizard/print_record_label.xml index bba539e..f111f2c 100644 --- a/printer_zpl2/wizard/print_record_label.xml +++ b/printer_zpl2/wizard/print_record_label.xml @@ -24,7 +24,6 @@ Print Label ir.actions.act_window wizard.print.record.label - form form [] {} diff --git a/printer_zpl2/wizard/wizard_import_zpl2.py b/printer_zpl2/wizard/wizard_import_zpl2.py index 451affa..7c647dd 100644 --- a/printer_zpl2/wizard/wizard_import_zpl2.py +++ b/printer_zpl2/wizard/wizard_import_zpl2.py @@ -1,42 +1,42 @@ # Copyright (C) 2018 Florent de Labarre () # 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 diff --git a/requirements.txt b/requirements.txt index 2706d74..66bff96 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ pycups==1.9.74 +zpl2==1.2 diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 59e0308..9859b88 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -1,18 +1,12 @@ import setuptools -with open('VERSION.txt', 'r') as f: +with open("VERSION.txt", "r") as f: version = f.read().strip() setuptools.setup( name="odoo13-addons-oca-report-print-send", description="Meta package for oca-report-print-send Odoo addons", version=version, - install_requires=[ - 'odoo13-addon-base_report_to_printer', - 'odoo13-addon-stock_picking_auto_print', - ], - classifiers=[ - 'Programming Language :: Python', - 'Framework :: Odoo', - ] + install_requires=["odoo13-addon-base_report_to_printer"], + classifiers=["Programming Language :: Python", "Framework :: Odoo"], ) diff --git a/setup/base_report_to_printer/setup.py b/setup/base_report_to_printer/setup.py index 28c57bb..6c7278d 100644 --- a/setup/base_report_to_printer/setup.py +++ b/setup/base_report_to_printer/setup.py @@ -1,6 +1,3 @@ import setuptools -setuptools.setup( - setup_requires=['setuptools-odoo'], - odoo_addon=True, -) +setuptools.setup(setup_requires=["setuptools-odoo"], odoo_addon=True)