From 4911a26d2c242a999e1901ffc007a50449d03eac Mon Sep 17 00:00:00 2001 From: Adrien Widart Date: Thu, 20 Jan 2022 11:55:46 +0000 Subject: [PATCH] [IMP] product: check barcode uniqueness With GS1 nomenclature, products and packagins use the same pattern. Therefore, we need to ensure the uniqueness between products' barcodes and packagings' ones. closes odoo/odoo#82883 Related: odoo/enterprise#23550 Related: odoo/upgrade#3180 Signed-off-by: Arnold Moyaux --- addons/product/models/product.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/addons/product/models/product.py b/addons/product/models/product.py index 444825d94f0..55aee61e490 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -231,6 +231,14 @@ class ProductProduct(models.Model): ('barcode_uniq', 'unique(barcode)', "A barcode can only be assigned to one product !"), ] + @api.constrains('barcode') + def _check_barcode_uniqueness(self): + """ With GS1 nomenclature, products and packagins use the same pattern. Therefore, we need + to ensure the uniqueness between products' barcodes and packagings' ones""" + condition = expression.OR([[('barcode', '=', b)] for b in self.mapped('barcode') if b]) + if self.env['product.packaging'].search(condition, limit=1): + raise ValidationError(_("A packaging already uses the barcode")) + def _get_invoice_policy(self): return False @@ -754,9 +762,18 @@ class ProductPackaging(models.Model): company_id = fields.Many2one('res.company', 'Company', index=True) _sql_constraints = [ - ('positive_qty', 'CHECK(qty > 0)', 'Contained Quantity should be positive.') + ('positive_qty', 'CHECK(qty > 0)', 'Contained Quantity should be positive.'), + ('barcode_uniq', 'unique(barcode)', 'A barcode can only be assigned to one packaging.'), ] + @api.constrains('barcode') + def _check_barcode_uniqueness(self): + """ With GS1 nomenclature, products and packagins use the same pattern. Therefore, we need + to ensure the uniqueness between products' barcodes and packagings' ones""" + condition = expression.OR([[('barcode', '=', b)] for b in self.mapped('barcode') if b]) + if self.env['product.product'].search(condition, limit=1): + raise ValidationError(_("A product already uses the barcode")) + def _check_qty(self, product_qty, uom_id, rounding_method="HALF-UP"): """Check if product_qty in given uom is a multiple of the packaging qty. If not, rounding the product_qty to closest multiple of the packaging qty