[MIG][11.0] printer_zpl2

This commit is contained in:
Florent de Labarre
2018-01-23 01:24:26 +01:00
committed by Lois Rilo
parent be2f132892
commit a297ab11b8
13 changed files with 150 additions and 149 deletions

View File

@@ -25,18 +25,18 @@ To configure this module, you need to:
#. Go to *Settings > Printing > Labels > ZPL II* #. Go to *Settings > Printing > Labels > ZPL II*
#. Create new labels #. Create new labels
It's also possible to add a label printing wizard on any model by creating a new *ir.values* record. 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 : For example, to add the printing wizard on the *product.product* model :
.. code-block:: xml .. code-block:: xml
<record model="ir.values" id="wizard_wizard_print_product_label"> <act_window id="action_wizard_purchase"
<field name="name">Print Product Label</field> name="Print Label"
<field name="key">action</field> src_model="product.product"
<field name="key2">client_action_multi</field> res_model="wizard.print.record.label"
<field name="model">product.product</field> view_mode="form"
<field name="value" eval="'ir.actions.act_window,' + str(ref('printer_zpl2.action_wizard_print_record_label_view'))"/> target="new"
</record> key2="client_action_multi"/>
Usage Usage
===== =====
@@ -54,7 +54,7 @@ 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 .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/144/10.0 :target: https://runbot.odoo-community.org/runbot/144/11.0
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@@ -82,6 +82,7 @@ Contributors
------------ ------------
* Sylvain Garancher <sylvain.garancher@syleam.fr> * Sylvain Garancher <sylvain.garancher@syleam.fr>
* Florent de Labarre
* Jos De Graeve <Jos.DeGraeve@apertoso.be> * Jos De Graeve <Jos.DeGraeve@apertoso.be>
Maintainer Maintainer

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'Printer ZPL II', 'name': 'Printer ZPL II',
'version': '10.0.1.1.1', 'version': '11.0.1.0.0',
'category': 'Printer', 'category': 'Printer',
'author': 'SYLEAM, Apertoso NV, Odoo Community Association (OCA)', 'author': 'SYLEAM, Apertoso NV, Odoo Community Association (OCA)',
'website': 'http://www.syleam.fr/', 'website': 'http://www.syleam.fr/',

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -8,8 +7,7 @@ import datetime
import io import io
import logging import logging
from PIL import Image, ImageOps from PIL import Image, ImageOps
from odoo import api, exceptions, fields, models from odoo import exceptions, fields, models, _
from odoo.tools.translate import _
from odoo.tools.safe_eval import safe_eval from odoo.tools.safe_eval import safe_eval
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -23,8 +21,10 @@ except ImportError:
class PrintingLabelZpl2(models.Model): class PrintingLabelZpl2(models.Model):
_name = 'printing.label.zpl2' _name = 'printing.label.zpl2'
_description = 'ZPL II Label' _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( model_id = fields.Many2one(
comodel_name='ir.model', string='Model', required=True, comodel_name='ir.model', string='Model', required=True,
@@ -47,7 +47,6 @@ class PrintingLabelZpl2(models.Model):
help="Restore printer's saved configuration and end of each label ", help="Restore printer's saved configuration and end of each label ",
default=True) default=True)
@api.multi
def _generate_zpl2_components_data( def _generate_zpl2_components_data(
self, label_data, record, page_number=1, page_count=1, self, label_data, record, page_number=1, page_count=1,
label_offset_x=0, label_offset_y=0, **extra): label_offset_x=0, label_offset_y=0, **extra):
@@ -123,7 +122,7 @@ class PrintingLabelZpl2(models.Model):
elif component.component_type == 'graphic': elif component.component_type == 'graphic':
image = component.graphic_image or data image = component.graphic_image or data
pil_image = Image.open(io.BytesIO( pil_image = Image.open(io.BytesIO(
base64.b64decode(image))) base64.b64decode(image))).convert('RGB')
if component.width and component.height: if component.width and component.height:
pil_image = pil_image.resize( pil_image = pil_image.resize(
(component.width, component.height)) (component.width, component.height))
@@ -188,7 +187,6 @@ class PrintingLabelZpl2(models.Model):
component.origin_y + offset_y, component.origin_y + offset_y,
component.component_type, barcode_arguments, data) component.component_type, barcode_arguments, data)
@api.multi
def _generate_zpl2_data(self, record, page_count=1, **extra): def _generate_zpl2_data(self, record, page_count=1, **extra):
self.ensure_one() self.ensure_one()
label_data = zpl2.Zpl2() label_data = zpl2.Zpl2()
@@ -212,7 +210,6 @@ class PrintingLabelZpl2(models.Model):
return label_data.output() return label_data.output()
@api.multi
def print_label(self, printer, record, page_count=1, **extra): def print_label(self, printer, record, page_count=1, **extra):
for label in self: for label in self:
if record._name != label.model_id.model: if record._name != label.model_id.model:
@@ -223,6 +220,7 @@ class PrintingLabelZpl2(models.Model):
# Send the label to printer # Send the label to printer
label_contents = label._generate_zpl2_data( label_contents = label._generate_zpl2_data(
record, page_count=page_count, **extra) record, page_count=page_count, **extra)
printer.print_document(None, label_contents, 'raw') printer.print_document(
report=None, content=label_contents, doc_format='raw')
return True return True

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -16,7 +15,7 @@ except ImportError:
class PrintingLabelZpl2Component(models.Model): class PrintingLabelZpl2Component(models.Model):
_name = 'printing.label.zpl2.component' _name = 'printing.label.zpl2.component'
_description = 'ZPL II Label Component' _description = 'ZPL II Label Component'
_order = 'sequence' _order = 'sequence, id'
label_id = fields.Many2one( label_id = fields.Many2one(
comodel_name='printing.label.zpl2', string='Label', comodel_name='printing.label.zpl2', string='Label',

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 LasLabs Inc. # Copyright 2016 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
@@ -72,7 +71,7 @@ class TestPrintingLabelZpl2(TransactionCase):
def test_empty_label_contents(self): def test_empty_label_contents(self):
""" Check contents of an empty label """ """ Check contents of an empty label """
label = self.new_label() label = self.new_label()
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode('utf-8')
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -105,7 +104,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'sublabel', 'component_type': 'sublabel',
'sublabel_id': sublabel.id, 'sublabel_id': sublabel.id,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode('utf-8')
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -150,7 +149,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'repeat_count': 3, 'repeat_count': 3,
'repeat_offset_y': 15, 'repeat_offset_y': 15,
}) })
contents = label._generate_zpl2_data(label) contents = label._generate_zpl2_data(label).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -210,7 +209,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'repeat_count': 3, 'repeat_count': 3,
'repeat_offset_y': 15, 'repeat_offset_y': 15,
}) })
contents = label._generate_zpl2_data(label) contents = label._generate_zpl2_data(label).decode('utf-8')
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -262,7 +261,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'repeat_count': 3, 'repeat_count': 3,
'repeat_offset_y': 15, 'repeat_offset_y': 15,
}) })
contents = label._generate_zpl2_data(label) contents = label._generate_zpl2_data(label).decode('utf-8')
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -341,7 +340,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'repeat_count': 3, 'repeat_count': 3,
'repeat_offset_y': 15, 'repeat_offset_y': 15,
}) })
contents = label._generate_zpl2_data(label) contents = label._generate_zpl2_data(label).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -403,9 +402,9 @@ class TestPrintingLabelZpl2(TransactionCase):
data = 'Some text' data = 'Some text'
self.new_component({ self.new_component({
'label_id': label.id, 'label_id': label.id,
'data': '"' + data + '"', 'data': '"%s"' % data,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -438,7 +437,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'data': '"' + data + '"', 'data': '"' + data + '"',
'reverse_print': True, 'reverse_print': True,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -473,7 +472,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'data': '"' + data + '"', 'data': '"' + data + '"',
'in_block': True, 'in_block': True,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -506,7 +505,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'label_id': label.id, 'label_id': label.id,
'component_type': 'rectangle', 'component_type': 'rectangle',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -535,7 +534,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'label_id': label.id, 'label_id': label.id,
'component_type': 'circle', 'component_type': 'circle',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -566,7 +565,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'code_11', 'component_type': 'code_11',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -601,7 +600,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'interleaved_2_of_5', 'component_type': 'interleaved_2_of_5',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -636,7 +635,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'code_39', 'component_type': 'code_39',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -671,7 +670,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'code_49', 'component_type': 'code_49',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -707,7 +706,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'data': '"' + data + '"', 'data': '"' + data + '"',
'interpretation_line': True, 'interpretation_line': True,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -746,7 +745,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'interpretation_line': True, 'interpretation_line': True,
'interpretation_line_above': True, 'interpretation_line_above': True,
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -781,7 +780,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'pdf417', 'component_type': 'pdf417',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -816,7 +815,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'ean-8', 'component_type': 'ean-8',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -851,7 +850,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'upc-e', 'component_type': 'upc-e',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -886,7 +885,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'code_128', 'component_type': 'code_128',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -921,7 +920,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'ean-13', 'component_type': 'ean-13',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start
@@ -956,7 +955,7 @@ class TestPrintingLabelZpl2(TransactionCase):
'component_type': 'qr_code', 'component_type': 'qr_code',
'data': '"' + data + '"', 'data': '"' + data + '"',
}) })
contents = label._generate_zpl2_data(self.printer) contents = label._generate_zpl2_data(self.printer).decode("utf-8")
self.assertEqual( self.assertEqual(
contents, contents,
# Label start # Label start

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 LasLabs Inc. # Copyright 2016 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

View File

@@ -5,7 +5,6 @@
--> -->
<odoo> <odoo>
<record id="view_printing_label_zpl2_tree" model="ir.ui.view"> <record id="view_printing_label_zpl2_tree" model="ir.ui.view">
<field name="name">printing.label.zpl2.tree</field>
<field name="model">printing.label.zpl2</field> <field name="model">printing.label.zpl2</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="ZPL II Label"> <tree string="ZPL II Label">
@@ -15,10 +14,15 @@
</field> </field>
</record> </record>
<record id="view_printing_label_zpl2_form" model="ir.ui.view"> <record id="view_printing_label_zpl2_form" model="ir.ui.view">
<field name="name">printing.label.zpl2.form</field>
<field name="model">printing.label.zpl2</field> <field name="model">printing.label.zpl2</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="ZPL II Label"> <form string="ZPL II Label">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
</button>
</div>
<group col="4"> <group col="4">
<field name="name"/> <field name="name"/>
<field name="model_id"/> <field name="model_id"/>
@@ -28,6 +32,8 @@
<field name="origin_y"/> <field name="origin_y"/>
<field name="restore_saved_config"/> <field name="restore_saved_config"/>
</group> </group>
<notebook>
<page string="Composents">
<field name="component_ids" nolabel="1" colspan="4"> <field name="component_ids" nolabel="1" colspan="4">
<tree string="Label Component"> <tree string="Label Component">
<field name="sequence"/> <field name="sequence"/>
@@ -114,16 +120,19 @@
</notebook> </notebook>
</form> </form>
</field> </field>
</page>
</notebook>
</sheet>
</form> </form>
</field> </field>
</record> </record>
<record id="view_printing_label_zpl2_search" model="ir.ui.view"> <record id="view_printing_label_zpl2_search" model="ir.ui.view">
<field name="name">printing.label.zpl2.search</field>
<field name="model">printing.label.zpl2</field> <field name="model">printing.label.zpl2</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="ZPL II Label"> <search string="ZPL II Label">
<field name="name"/> <field name="name"/>
<field name="model_id"/> <field name="model_id"/>
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
</search> </search>
</field> </field>
</record> </record>

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>) # Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -38,7 +37,6 @@ class PrintRecordLabel(models.TransientModel):
return values return values
@api.multi
def print_label(self): def print_label(self):
""" Prints a label per selected record """ """ Prints a label per selected record """
record_model = self.env.context['active_model'] record_model = self.env.context['active_model']

View File

@@ -13,7 +13,10 @@
<field name="printer_id"/> <field name="printer_id"/>
<field name="label_id"/> <field name="label_id"/>
</group> </group>
<button string="Print Label" type="object" name="print_label"/> <footer>
<button type="special" special="cancel" string="Cancel"/>
<button string="Print label" type="object" name="print_label" class="oe_highlight"/>
</footer>
</form> </form>
</field> </field>
</record> </record>