product_usability: add field barcode_type

Remove field barcode_code128, which was buggy
This commit is contained in:
Alexis de Lattre
2022-05-16 19:30:48 +02:00
parent a89f1a9ae7
commit 9507d1fbd8
5 changed files with 53 additions and 28 deletions

View File

@@ -21,11 +21,14 @@ The usability enhancements include:
* hide description field on product (description_sale must be use instead of description) * hide description field on product (description_sale must be use instead of description)
* add a field barcode_type in product form view
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>. This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""", """,
'author': 'Akretion', 'author': 'Akretion',
'website': 'http://www.akretion.com', 'website': 'http://www.akretion.com',
'depends': ['product'], 'depends': ['product'],
"external_dependencies": {"python": ["stdnum"]},
'data': [ 'data': [
'views/product_supplierinfo_view.xml', 'views/product_supplierinfo_view.xml',
'views/product_pricelist_view.xml', 'views/product_pricelist_view.xml',

View File

@@ -4,6 +4,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields from odoo import api, models, fields
from stdnum.ean import is_valid
class ProductProduct(models.Model): class ProductProduct(models.Model):
@@ -13,9 +14,7 @@ class ProductProduct(models.Model):
barcode = fields.Char(tracking=20) barcode = fields.Char(tracking=20)
weight = fields.Float(tracking=30) weight = fields.Float(tracking=30)
active = fields.Boolean(tracking=40) active = fields.Boolean(tracking=40)
barcode_code128 = fields.Char( barcode_type = fields.Char(compute='_compute_barcode_type')
compute='_compute_barcode_code128',
help="Barcode in Code128-B with start char, checksum and stop char")
_sql_constraints = [( _sql_constraints = [(
# Maybe it could be better to have a constrain per company # Maybe it could be better to have a constrain per company
@@ -28,30 +27,17 @@ class ProductProduct(models.Model):
'This internal reference already exists!')] 'This internal reference already exists!')]
@api.model @api.model
def _compute_code128_checksum(self, code): def _get_barcode_type(self, barcode):
# This is NOT a full implementation of code128 checksum barcode_type = False
csum = 104 # Start B if barcode:
i = 0 size = len(barcode)
for char in code: if size == 13 and is_valid(barcode):
i += 1 barcode_type = 'EAN13'
char_val = ord(char) - 32 elif size == 8 and is_valid(barcode):
csum += char_val * i barcode_type = 'EAN8'
remainder = csum % 103 return barcode_type
checksum = chr(remainder + 32)
return checksum
@api.depends('barcode') @api.depends('barcode')
def _compute_barcode_code128(self): def _compute_barcode_type(self):
# We use Code128-B. Useful info on code128:
# https://boowiki.info/art/codes-a-barres/code-128.html
# Use code128.ttf and copy it in /usr/local/share/fonts/
startb = chr(209)
stop = chr(211)
for product in self: for product in self:
code128 = False product.barcode_type = self._get_barcode_type(product.barcode)
barcode = product.barcode
if barcode and all([32 <= ord(x) <= 127 for x in barcode]):
checksum = self._compute_code128_checksum(barcode)
if checksum:
code128 = startb + barcode + checksum + stop
product.barcode_code128 = code128

View File

@@ -3,7 +3,7 @@
# @author Raphaël Valyi <rvalyi@akretion.com> # @author Raphaël Valyi <rvalyi@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields from odoo import api, models, fields
class ProductTemplate(models.Model): class ProductTemplate(models.Model):
@@ -31,3 +31,14 @@ class ProductTemplate(models.Model):
purchase_ok = fields.Boolean(tracking=90) purchase_ok = fields.Boolean(tracking=90)
active = fields.Boolean(tracking=100) active = fields.Boolean(tracking=100)
company_id = fields.Many2one(tracking=110) company_id = fields.Many2one(tracking=110)
barcode_type = fields.Char(compute='_compute_template_barcode_type')
@api.depends('product_variant_ids.barcode')
def _compute_template_barcode_type(self):
ppo = self.env['product.product']
for template in self:
barcode_type = False
if len(template.product_variant_ids) == 1:
barcode = template.product_variant_ids.barcode
barcode_type = ppo._get_barcode_type(barcode)
template.barcode_type = barcode_type

View File

@@ -21,4 +21,16 @@
</field> </field>
</record> </record>
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">usability.product.product.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="barcode" position="after">
<field name="barcode_type" attrs="{'invisible': [('barcode', '=', False)]}"/>
</field>
</field>
</record>
</odoo> </odoo>

View File

@@ -19,4 +19,17 @@
</field> </field>
</record> </record>
<!-- product template ONLY form view -->
<record id="product_template_only_form_view" model="ir.ui.view">
<field name="name">usability.product.template.ONLY.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<field name="barcode" position="after">
<!-- barcode is False when the template has several variants anyway -->
<field name="barcode_type" attrs="{'invisible': [('barcode', '=', False)]}"/>
</field>
</field>
</record>
</odoo> </odoo>