From 72bf940b6e83a961a09ba1b2e2476121e2eadadb Mon Sep 17 00:00:00 2001 From: Florent de Labarre Date: Tue, 23 Jan 2018 00:28:50 +0100 Subject: [PATCH] [IMP] Add a preview on the label using labelary.com --- printer_zpl2/models/printing_label_zpl2.py | 82 ++++++++++++++++++++- printer_zpl2/tests/__init__.py | 1 + printer_zpl2/tests/test_test_mode.py | 85 ++++++++++++++++++++++ printer_zpl2/views/printing_label_zpl2.xml | 24 ++++++ 4 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 printer_zpl2/tests/test_test_mode.py diff --git a/printer_zpl2/models/printing_label_zpl2.py b/printer_zpl2/models/printing_label_zpl2.py index e8bf697..a12cd17 100644 --- a/printer_zpl2/models/printing_label_zpl2.py +++ b/printer_zpl2/models/printing_label_zpl2.py @@ -6,8 +6,9 @@ import base64 import datetime import io import logging +import requests from PIL import Image, ImageOps -from odoo import exceptions, fields, models, _ +from odoo import api, exceptions, fields, models, _ from odoo.tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) @@ -48,6 +49,19 @@ class PrintingLabelZpl2(models.Model): default=True) action_window_id = fields.Many2one( comodel_name='ir.actions.act_window', string='Action', readonly=True) + test_labelary_mode = fields.Boolean(string='Mode Labelary') + record_id = fields.Integer(string='Record ID', default=1) + extra = fields.Text(string="Extra", default='{}') + 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) def _generate_zpl2_components_data( self, label_data, record, page_number=1, page_count=1, @@ -205,10 +219,12 @@ class PrintingLabelZpl2(models.Model): self.ensure_one() label_data = zpl2.Zpl2() + labelary_emul = extra.get('labelary_emul', False) for page_number in range(page_count): # Initialize printer's configuration label_data.label_start() - label_data.print_width(self.width) + if not labelary_emul: + label_data.print_width(self.width) label_data.label_encoding() label_data.label_home(self.origin_x, self.origin_y) @@ -255,3 +271,65 @@ class PrintingLabelZpl2(models.Model): def unlink_action(self): self.mapped('action_window_id').unlink() + + def _get_record(self): + self.ensure_one() + Obj = self.env[self.model_id.model] + record = Obj.search([('id', '=', self.record_id)], limit=1) + if not record: + record = Obj.search([], limit=1, order='id desc') + self.record_id = record.id + + return record + + @api.onchange( + '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): + 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/' + 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) + 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)) + new_im.paste(im, (1, 1)) + imgByteArr = io.BytesIO() + 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, + }} + + except Exception as e: + self.labelary_image = False + return {'warning': { + 'title': _('Some thing is wrong.'), + 'message': e, + }} diff --git a/printer_zpl2/tests/__init__.py b/printer_zpl2/tests/__init__.py index cc4e18f..03aa9ce 100644 --- a/printer_zpl2/tests/__init__.py +++ b/printer_zpl2/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_printing_label_zpl2 from . import test_wizard_print_record_label from . import test_generate_action +from . import test_test_mode diff --git a/printer_zpl2/tests/test_test_mode.py b/printer_zpl2/tests/test_test_mode.py new file mode 100644 index 0000000..20abdb5 --- /dev/null +++ b/printer_zpl2/tests/test_test_mode.py @@ -0,0 +1,85 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests.common import TransactionCase + +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, + }) + + def test_get_record(self): + """ Check if return a record """ + self.label.record_id = 10 + res = self.label._get_record() + + Obj = self.env[self.label.model_id.model] + record = Obj.search([('id', '=', self.label.record_id)], limit=1) + if not record: + record = Obj.search([], limit=1, order='id desc') + self.assertEqual(res, record) + + def test_emulation_without_params(self): + """ 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) + + 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_height = 10000000 + 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) + + def test_emulation_with_bad_data_compute(self): + """ Check if bad data compute """ + 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._on_change_labelary() + component.unlink() + self.assertIs(self.label.labelary_image, None) + + 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._on_change_labelary() + self.assertTrue(self.label.labelary_image) diff --git a/printer_zpl2/views/printing_label_zpl2.xml b/printer_zpl2/views/printing_label_zpl2.xml index 9dd679e..2263e06 100644 --- a/printer_zpl2/views/printing_label_zpl2.xml +++ b/printer_zpl2/views/printing_label_zpl2.xml @@ -126,6 +126,30 @@ + + +

+ Note : It is an emulation from http://labelary.com/, the result on printer can be diffrent. +

+
+ + + + + + + + + + + + + + + + + +