From 819b1370e700f15ceb484caccb5890f16959caec Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 24 Mar 2025 22:34:44 +0000 Subject: [PATCH] [IMP] product_print_zpl_barcode: remove dep on base_report_to_printer. Use direct print. --- product_print_zpl_barcode/__manifest__.py | 2 +- product_print_zpl_barcode/wizard/__init__.py | 1 + .../wizard/product_print_zpl_barcode.py | 32 +++++++++++++------ .../wizard/product_print_zpl_barcode_view.xml | 2 +- .../wizard/res_config_settings.py | 24 ++++++++++++++ .../wizard/res_config_settings_view.xml | 30 +++++++++++++++++ 6 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 product_print_zpl_barcode/wizard/res_config_settings.py create mode 100644 product_print_zpl_barcode/wizard/res_config_settings_view.xml diff --git a/product_print_zpl_barcode/__manifest__.py b/product_print_zpl_barcode/__manifest__.py index 28823b1..39e2aaf 100644 --- a/product_print_zpl_barcode/__manifest__.py +++ b/product_print_zpl_barcode/__manifest__.py @@ -39,12 +39,12 @@ This module has been written by Alexis de Lattre from Akretion 'depends': [ 'point_of_sale', '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', + 'wizard/res_config_settings_view.xml', 'views/product.xml', 'views/stock_picking.xml', 'data/barcode_sequence.xml', diff --git a/product_print_zpl_barcode/wizard/__init__.py b/product_print_zpl_barcode/wizard/__init__.py index 71c6c20..3d74426 100644 --- a/product_print_zpl_barcode/wizard/__init__.py +++ b/product_print_zpl_barcode/wizard/__init__.py @@ -1 +1,2 @@ from . import product_print_zpl_barcode +from . import res_config_settings 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 236709c..b83844c 100644 --- a/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py +++ b/product_print_zpl_barcode/wizard/product_print_zpl_barcode.py @@ -8,8 +8,12 @@ from odoo.tools import float_compare, float_is_zero from stdnum.ean import is_valid, calc_check_digit import base64 import re - +import socket +import ipaddress import logging + +PRINTER_PORT = 9100 +PRINTER_TIMEOUT = 10 logger = logging.getLogger(__name__) @@ -36,7 +40,8 @@ class ProductPrintZplBarcode(models.TransientModel): raise UserError(_( "There are no pricelist in company '%s'.") % company.name) - printer = self.env['printing.printer'].get_default() + printer_ip = self.env['ir.config_parameter'].sudo().get_param( + 'product_print_zpl_barcode.printer_ip') line_ids = [] if self._context.get('active_model') == 'product.product': @@ -71,7 +76,7 @@ class ProductPrintZplBarcode(models.TransientModel): 'company_id': company.id, 'nomenclature_id': nomenclature.id, 'pricelist_id': pricelist.id, - 'zpl_printer_id': printer and printer.id or False, + 'zpl_printer_ip': printer_ip, 'line_ids': line_ids, }) return res @@ -108,8 +113,7 @@ class ProductPrintZplBarcode(models.TransientModel): ], default='step1', readonly=True) zpl_file = fields.Binary(string='ZPL File', readonly=True) zpl_filename = fields.Char('ZPL Filename') - zpl_printer_id = fields.Many2one( - 'printing.printer', string='ZPL Printer') + zpl_printer_ip = fields.Char(string='ZPL Printer IP Address') line_ids = fields.One2many( 'product.print.zpl.barcode.line', 'parent_id', string='Lines', states={'step2': [('readonly', True)]}) @@ -168,11 +172,21 @@ class ProductPrintZplBarcode(models.TransientModel): return action def print_zpl(self): - if not self.zpl_printer_id: + if not self.zpl_printer_ip: raise UserError(_( - "You must select a ZPL Printer.")) - self.zpl_printer_id.print_document( - self.zpl_filename, base64.decodebytes(self.zpl_file), format='raw') + "You must configure the IP address of the ZPL Printer.")) + zpl_file_bytes = base64.decodebytes(self.zpl_file) + try: + with socket.create_connection((self.zpl_printer_ip, PRINTER_PORT), timeout=PRINTER_TIMEOUT) as sock: + sock.send(zpl_file_bytes) + except Exception as e: + raise UserError(_( + "Failure in the connection to the ZPL printer " + "on %(ip_addr)s port %(port)s: %(error)s.", + ip_addr=self.zpl_printer_ip, + port=PRINTER_PORT, + error=e, + )) class ProductPrintZplBarcodeLine(models.TransientModel): diff --git a/product_print_zpl_barcode/wizard/product_print_zpl_barcode_view.xml b/product_print_zpl_barcode/wizard/product_print_zpl_barcode_view.xml index 9866982..d6d860c 100644 --- a/product_print_zpl_barcode/wizard/product_print_zpl_barcode_view.xml +++ b/product_print_zpl_barcode/wizard/product_print_zpl_barcode_view.xml @@ -23,7 +23,7 @@ - + diff --git a/product_print_zpl_barcode/wizard/res_config_settings.py b/product_print_zpl_barcode/wizard/res_config_settings.py new file mode 100644 index 0000000..7a860c8 --- /dev/null +++ b/product_print_zpl_barcode/wizard/res_config_settings.py @@ -0,0 +1,24 @@ +# Copyright 2023 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models +from odoo.exceptions import ValidationError +import ipaddress + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + zpl_printer_ip = fields.Char( + config_parameter="product_print_zpl_barcode.printer_ip", + string="ZPL Printer IP Address") + + @api.constrains('zpl_printer_ip') + def _check_zpl_printer_ip(self): + for wiz in self: + if wiz.zpl_printer_ip: + try: + ipaddress.ip_address(wiz.zpl_printer_ip) + except Exception as e: + raise ValidationError(str(e)) diff --git a/product_print_zpl_barcode/wizard/res_config_settings_view.xml b/product_print_zpl_barcode/wizard/res_config_settings_view.xml new file mode 100644 index 0000000..584cb5c --- /dev/null +++ b/product_print_zpl_barcode/wizard/res_config_settings_view.xml @@ -0,0 +1,30 @@ + + + + + + + res.config.settings + + + +

Barcode printing

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