diff --git a/product_print_zpl_barcode/__manifest__.py b/product_print_zpl_barcode/__manifest__.py index b574b77..c3d2a9d 100644 --- a/product_print_zpl_barcode/__manifest__.py +++ b/product_print_zpl_barcode/__manifest__.py @@ -41,6 +41,7 @@ This module has been written by Alexis de Lattre from Akretion 'barcodes', 'base_report_to_printer', ], + 'external_dependencies': {'python': ['python-barcode>=0.14.0']}, 'data': [ 'security/ir.model.access.csv', 'wizard/product_print_zpl_barcode_view.xml', diff --git a/product_print_zpl_barcode/models/product.py b/product_print_zpl_barcode/models/product.py index 6853de6..761a791 100644 --- a/product_print_zpl_barcode/models/product.py +++ b/product_print_zpl_barcode/models/product.py @@ -1,11 +1,14 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Akretion France (http://www.akretion.com/) +# Copyright 2020-2023 Akretion France (http://www.akretion.com/) # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import api, fields, models, _ from odoo.exceptions import UserError -from stdnum.ean import calc_check_digit +from stdnum.ean import calc_check_digit, is_valid +from barcode import EAN13, EAN8 +from barcode.writer import ImageWriter +import base64 +import io class ProductTemplate(models.Model): @@ -34,8 +37,8 @@ class ProductTemplate(models.Model): "print_zpl_barcode_from_product_template on product '%s' " "because it has %d variants and not just one.") % (self.display_name, self.product_variant_count)) - action = self.env.ref( - 'product_print_zpl_barcode.product_print_zpl_barcode_action').sudo().read()[0] + action = self.env["ir.actions.actions"]._for_xml_id( + 'product_print_zpl_barcode.product_print_zpl_barcode_action') action['context'] = { 'active_id': self.product_variant_ids[0].id, 'active_model': 'product.product', @@ -46,6 +49,30 @@ class ProductTemplate(models.Model): class ProductProduct(models.Model): _inherit = 'product.product' + # Not useful for ZPL, but it is often useful to have a barcode image field + barcode_image = fields.Binary( + compute='_compute_barcode_image', + string='Barcode Image') + + @api.depends('barcode') + def _compute_barcode_image(self): + for product in self: + barcode = product.barcode + barcode_image = False + if barcode: + barcode_obj = False + if len(barcode) == 13 and is_valid(barcode): + barcode_obj = EAN13(barcode, writer=ImageWriter(), guardbar=True) + elif len(barcode) == 8 and is_valid(barcode): + barcode_obj = EAN8(barcode, writer=ImageWriter(), guardbar=True) + if barcode_obj: + barcode_file = io.BytesIO() + barcode_obj.write(barcode_file) # generate PNG + barcode_file.seek(0) + barcode_img = barcode_file.read() + barcode_image = base64.b64encode(barcode_img) + product.barcode_image = barcode_image + def generate_barcode_from_product_product(self): self.ensure_one() if self.barcode: diff --git a/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py b/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py index 45a05b1..7554f80 100644 --- a/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py +++ b/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py @@ -270,7 +270,8 @@ class ProductPrintZplBarcode(models.TransientModel): 'zpl_filename': 'barcode_%s.zpl' % vals['barcode'], }) self.write(vals) - action = self.env.ref('product_print_zpl_barcode.product_print_zpl_barcode_action').sudo().read()[0] + action = self.env["ir.actions.actions"]._for_xml_id( + 'product_print_zpl_barcode.product_print_zpl_barcode_action') action.update({ 'res_id': self.id, 'context': self._context, @@ -285,7 +286,8 @@ class ProductPrintZplBarcode(models.TransientModel): self.zpl_filename, base64.decodebytes(self.zpl_file), format='raw') action = True if self._context.get('print_and_new'): - action = self.env.ref('product_print_zpl_barcode.product_print_zpl_barcode_action').sudo().read()[0] + action = self.env["ir.actions.actions"]._for_xml_id( + 'product_print_zpl_barcode.product_print_zpl_barcode_action') action.update({ 'views': False, 'context': self._context,