Compare commits
1 Commits
14-product
...
14-formatL
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a7475a761 |
@@ -6,3 +6,4 @@ from . import res_company
|
||||
from . import ir_mail_server
|
||||
from . import ir_actions_report
|
||||
from . import ir_model
|
||||
from . import misc
|
||||
|
||||
39
base_usability/models/misc.py
Normal file
39
base_usability/models/misc.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# Copyright 2025 Akretion France (https://www.akretion.com/)
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models, api
|
||||
from odoo.tools import misc
|
||||
from openerp.tools import float_compare
|
||||
|
||||
|
||||
class BaseUsabilityInstalled(models.AbstractModel):
|
||||
_name = "base.usability.installed"
|
||||
_description = "Base Usability Installed"
|
||||
|
||||
|
||||
formatLang_original = misc.formatLang
|
||||
|
||||
|
||||
def formatLang(
|
||||
self, value, digits=None, grouping=True,
|
||||
monetary=False, dp=False, currency_obj=False, int_no_digits=True):
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(self.cr, self.uid, {})
|
||||
if (
|
||||
'base.usability.installed' in env and
|
||||
int_no_digits and
|
||||
not monetary and
|
||||
isinstance(value, float) and
|
||||
dp):
|
||||
prec = env['decimal.precision'].precision_get(dp)
|
||||
if not float_compare(value, int(value), precision_digits=prec):
|
||||
digits = 0
|
||||
dp = False
|
||||
res = formatLang_original(
|
||||
self, value, digits=digits, grouping=grouping,
|
||||
monetary=monetary, dp=dp, currency_obj=currency_obj)
|
||||
return res
|
||||
|
||||
|
||||
misc.formatLang = formatLang
|
||||
@@ -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',
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
from . import product_print_zpl_barcode
|
||||
from . import res_config_settings
|
||||
|
||||
@@ -8,12 +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
|
||||
|
||||
PRINTER_PORT = 9100
|
||||
PRINTER_TIMEOUT = 10
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -40,8 +36,7 @@ class ProductPrintZplBarcode(models.TransientModel):
|
||||
raise UserError(_(
|
||||
"There are no pricelist in company '%s'.") % company.name)
|
||||
|
||||
printer_ip = self.env['ir.config_parameter'].sudo().get_param(
|
||||
'product_print_zpl_barcode.printer_ip')
|
||||
printer = self.env['printing.printer'].get_default()
|
||||
|
||||
line_ids = []
|
||||
if self._context.get('active_model') == 'product.product':
|
||||
@@ -76,7 +71,7 @@ class ProductPrintZplBarcode(models.TransientModel):
|
||||
'company_id': company.id,
|
||||
'nomenclature_id': nomenclature.id,
|
||||
'pricelist_id': pricelist.id,
|
||||
'zpl_printer_ip': printer_ip,
|
||||
'zpl_printer_id': printer and printer.id or False,
|
||||
'line_ids': line_ids,
|
||||
})
|
||||
return res
|
||||
@@ -113,7 +108,8 @@ 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_ip = fields.Char(string='ZPL Printer IP Address')
|
||||
zpl_printer_id = fields.Many2one(
|
||||
'printing.printer', string='ZPL Printer')
|
||||
line_ids = fields.One2many(
|
||||
'product.print.zpl.barcode.line', 'parent_id',
|
||||
string='Lines', states={'step2': [('readonly', True)]})
|
||||
@@ -172,21 +168,11 @@ class ProductPrintZplBarcode(models.TransientModel):
|
||||
return action
|
||||
|
||||
def print_zpl(self):
|
||||
if not self.zpl_printer_ip:
|
||||
if not self.zpl_printer_id:
|
||||
raise UserError(_(
|
||||
"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,
|
||||
))
|
||||
"You must select a ZPL Printer."))
|
||||
self.zpl_printer_id.print_document(
|
||||
self.zpl_filename, base64.decodebytes(self.zpl_file), format='raw')
|
||||
|
||||
|
||||
class ProductPrintZplBarcodeLine(models.TransientModel):
|
||||
|
||||
@@ -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_ip" attrs="{'required': [('state', '=', 'step2')]}"/>
|
||||
<field name="zpl_printer_id" attrs="{'required': [('state', '=', 'step2')]}"/>
|
||||
</group>
|
||||
<group name="lines">
|
||||
<field name="line_ids" colspan="2" nolabel="1">
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# 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))
|
||||
@@ -1,30 +0,0 @@
|
||||
<?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>
|
||||
Reference in New Issue
Block a user