product_print_zpl_barcode: remove dependency on base_report_to_printer

We now print directly on the ZPL printer, without going through CUPS
This commit is contained in:
Alexis de Lattre
2024-01-30 17:00:56 +01:00
parent 0756beb8f5
commit a61d1458d8
8 changed files with 89 additions and 11 deletions

View File

@@ -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',

View File

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

View File

@@ -8,6 +8,8 @@ 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
logger = logging.getLogger(__name__)
@@ -36,7 +38,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 +74,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 +111,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 +170,27 @@ 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."))
try:
ip = ipaddress.ip_address(self.zpl_printer_ip)
except Exception as e:
raise UserError(str(e))
version = ip.version
# TODO works with DNS ?
if version == 6: # IPv6
socket_inet = socket.AF_INET6
else: # IPv4
socket_inet = socket.AF_INET
with socket.socket(socket_inet, socket.SOCK_STREAM) as s:
try:
s.connect((str(ip), 9100))
except Exception as e:
raise UserError(str(e))
zpl_file_bytes = base64.decodebytes(self.zpl_file)
s.send(zpl_file_bytes)
s.close()
class ProductPrintZplBarcodeLine(models.TransientModel):

View File

@@ -23,7 +23,7 @@
<group name="step2" states="step2">
<field name="zpl_file" filename="zpl_filename" />
<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 name="lines">
<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>

View File

@@ -16,7 +16,7 @@ This module has been written by Alexis de Lattre from Akretion
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['sale_stock'],
'depends': ['sale_stock', 'base_view_inheritance_extension'],
'data': ['views/sale_order.xml'],
'installable': True,
}

View File

@@ -15,6 +15,11 @@
<field name="partner_shipping_id" position="after">
<field name="route_id" options="{'no_create_edit': True}"/>
</field>
<!-- propagate route_id to lines: it's important when you add an order line AFTER
order confirmation -->
<field name="order_line" position="attributes">
<attribute name="context" operation="python_dict" key="default_route_id">route_id</attribute>
</field>
</field>
</record>