[IMP] product_print_zpl_barcode: remove dep on base_report_to_printer. Use direct print.

This commit is contained in:
Alexis de Lattre
2025-03-24 22:34:44 +00:00
parent ce7a3a382a
commit 819b1370e7
6 changed files with 80 additions and 11 deletions

View File

@@ -39,12 +39,12 @@ This module has been written by Alexis de Lattre from Akretion
'depends': [ 'depends': [
'point_of_sale', 'point_of_sale',
'barcodes', 'barcodes',
'base_report_to_printer',
], ],
'external_dependencies': {'python': ['python-barcode>=0.14.0']}, 'external_dependencies': {'python': ['python-barcode>=0.14.0']},
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'wizard/product_print_zpl_barcode_view.xml', 'wizard/product_print_zpl_barcode_view.xml',
'wizard/res_config_settings_view.xml',
'views/product.xml', 'views/product.xml',
'views/stock_picking.xml', 'views/stock_picking.xml',
'data/barcode_sequence.xml', 'data/barcode_sequence.xml',

View File

@@ -1 +1,2 @@
from . import product_print_zpl_barcode from . import product_print_zpl_barcode
from . import res_config_settings

View File

@@ -8,8 +8,12 @@ from odoo.tools import float_compare, float_is_zero
from stdnum.ean import is_valid, calc_check_digit from stdnum.ean import is_valid, calc_check_digit
import base64 import base64
import re import re
import socket
import ipaddress
import logging import logging
PRINTER_PORT = 9100
PRINTER_TIMEOUT = 10
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -36,7 +40,8 @@ class ProductPrintZplBarcode(models.TransientModel):
raise UserError(_( raise UserError(_(
"There are no pricelist in company '%s'.") % company.name) "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 = [] line_ids = []
if self._context.get('active_model') == 'product.product': if self._context.get('active_model') == 'product.product':
@@ -71,7 +76,7 @@ class ProductPrintZplBarcode(models.TransientModel):
'company_id': company.id, 'company_id': company.id,
'nomenclature_id': nomenclature.id, 'nomenclature_id': nomenclature.id,
'pricelist_id': pricelist.id, 'pricelist_id': pricelist.id,
'zpl_printer_id': printer and printer.id or False, 'zpl_printer_ip': printer_ip,
'line_ids': line_ids, 'line_ids': line_ids,
}) })
return res return res
@@ -108,8 +113,7 @@ class ProductPrintZplBarcode(models.TransientModel):
], default='step1', readonly=True) ], default='step1', readonly=True)
zpl_file = fields.Binary(string='ZPL File', readonly=True) zpl_file = fields.Binary(string='ZPL File', readonly=True)
zpl_filename = fields.Char('ZPL Filename') zpl_filename = fields.Char('ZPL Filename')
zpl_printer_id = fields.Many2one( zpl_printer_ip = fields.Char(string='ZPL Printer IP Address')
'printing.printer', string='ZPL Printer')
line_ids = fields.One2many( line_ids = fields.One2many(
'product.print.zpl.barcode.line', 'parent_id', 'product.print.zpl.barcode.line', 'parent_id',
string='Lines', states={'step2': [('readonly', True)]}) string='Lines', states={'step2': [('readonly', True)]})
@@ -168,11 +172,21 @@ class ProductPrintZplBarcode(models.TransientModel):
return action return action
def print_zpl(self): def print_zpl(self):
if not self.zpl_printer_id: if not self.zpl_printer_ip:
raise UserError(_( raise UserError(_(
"You must select a ZPL Printer.")) "You must configure the IP address of the ZPL Printer."))
self.zpl_printer_id.print_document( zpl_file_bytes = base64.decodebytes(self.zpl_file)
self.zpl_filename, base64.decodebytes(self.zpl_file), format='raw') 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): class ProductPrintZplBarcodeLine(models.TransientModel):

View File

@@ -23,7 +23,7 @@
<group name="step2" states="step2"> <group name="step2" states="step2">
<field name="zpl_file" filename="zpl_filename" /> <field name="zpl_file" filename="zpl_filename" />
<field name="zpl_filename" invisible="1"/> <field name="zpl_filename" invisible="1"/>
<field name="zpl_printer_id" attrs="{'required': [('state', '=', 'step2')]}"/> <field name="zpl_printer_ip" attrs="{'required': [('state', '=', 'step2')]}"/>
</group> </group>
<group name="lines"> <group name="lines">
<field name="line_ids" colspan="2" nolabel="1"> <field name="line_ids" colspan="2" nolabel="1">

View File

@@ -0,0 +1,24 @@
# Copyright 2023 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# 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))

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base_setup.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='companies']" position='after'>
<h2>Barcode printing</h2>
<div class="row mt16 o_settings_container" name="zpl_printer">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_right_pane" id="zpl_printer_ip">
<div class="row">
<label for="zpl_printer_ip" class="col-md-5" />
<field name="zpl_printer_ip" />
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>