168 lines
6.5 KiB
Python
168 lines
6.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.fields import Command
|
|
from odoo.tests import TransactionCase, tagged
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestProductBarcode(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.env['product.product'].create([
|
|
{'name': 'BC1', 'barcode': '1'},
|
|
{'name': 'BC2', 'barcode': '2'},
|
|
])
|
|
|
|
cls.size_attribute = cls.env['product.attribute'].create({
|
|
'name': 'Size',
|
|
'value_ids': [
|
|
Command.create({'name': 'SMALL'}),
|
|
Command.create({'name': 'LARGE'}),
|
|
]
|
|
})
|
|
cls.size_attribute_s, cls.size_attribute_l = cls.size_attribute.value_ids
|
|
|
|
cls.template = cls.env['product.template'].create({'name': 'template'})
|
|
cls.template.write({
|
|
'attribute_line_ids': [Command.create({
|
|
'attribute_id': cls.size_attribute.id,
|
|
'value_ids': [
|
|
Command.link(cls.size_attribute_s.id),
|
|
Command.link(cls.size_attribute_l.id),
|
|
],
|
|
})]
|
|
})
|
|
|
|
def test_blank_barcodes_allowed(self):
|
|
"""Makes sure duplicated blank barcodes are allowed."""
|
|
for i in range(2):
|
|
self.env['product.product'].create({'name': f'BC_{i}'})
|
|
|
|
def test_false_barcodes_allowed(self):
|
|
"""Makes sure duplicated False barcodes are allowed."""
|
|
for i in range(2):
|
|
self.env['product.product'].create({'name': f'BC_{i}', 'barcode': False})
|
|
|
|
def test_duplicated_barcode(self):
|
|
"""Tests for simple duplication."""
|
|
with self.assertRaises(ValidationError):
|
|
self.env['product.product'].create({'name': 'BC3', 'barcode': '1'})
|
|
|
|
def test_duplicated_barcode_in_batch_edit(self):
|
|
"""Tests for duplication in batch edits."""
|
|
batch = [
|
|
{'name': 'BC3', 'barcode': '3'},
|
|
{'name': 'BC4', 'barcode': '4'},
|
|
]
|
|
self.env['product.product'].create(batch)
|
|
batch.append({'name': 'BC5', 'barcode': '1'})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['product.product'].create(batch)
|
|
|
|
def test_test_duplicated_barcode_error_msg_content(self):
|
|
"""Validates the error message shown when duplicated barcodes are found."""
|
|
batch = [
|
|
{'name': 'BC3', 'barcode': '3'},
|
|
{'name': 'BC4', 'barcode': '3'},
|
|
{'name': 'BC5', 'barcode': '4'},
|
|
{'name': 'BC6', 'barcode': '4'},
|
|
{'name': 'BC7', 'barcode': '1'},
|
|
]
|
|
try:
|
|
self.env['product.product'].create(batch)
|
|
except ValidationError as exc:
|
|
assert 'Barcode "3" already assigned to product(s): BC3, BC4' in exc.args[0]
|
|
assert 'Barcode "4" already assigned to product(s): BC5, BC6' in exc.args[0]
|
|
assert 'Barcode "1" already assigned to product(s): BC1' in exc.args[0]
|
|
|
|
def test_delete_package_and_use_its_barcode_in_product(self):
|
|
""" Test that the barcode of the package can be used when the package is removed from the product."""
|
|
product = self.env['product.product'].create({
|
|
'name': 'product',
|
|
'packaging_ids': [(0, 0, {
|
|
'name': 'packing',
|
|
'barcode': '1234',
|
|
})]
|
|
})
|
|
package = product.packaging_ids
|
|
self.assertTrue(package.exists())
|
|
self.assertEqual(package.barcode, '1234')
|
|
product.packaging_ids = False
|
|
self.assertFalse(package.exists())
|
|
product.barcode = '1234'
|
|
|
|
def test_duplicated_barcodes_are_allowed_for_different_companies(self):
|
|
"""Barcode needs to be unique only withing the same company"""
|
|
company_a = self.env.company
|
|
company_b = self.env['res.company'].create({'name': 'CB'})
|
|
|
|
allowed_products = [
|
|
# Allowed, barcode doesn't exist yet
|
|
{'name': 'A1', 'barcode': '3', 'company_id': company_a.id},
|
|
# Allowed, barcode exists (A1), but for a different company
|
|
{'name': 'A2', 'barcode': '3', 'company_id': company_b.id},
|
|
]
|
|
|
|
forbidden_products = [
|
|
# Forbidden, collides with BC1
|
|
{'name': 'F1', 'barcode': '1', 'company_id': False},
|
|
# Forbidden, collides with BC1
|
|
{'name': 'F2', 'barcode': '1', 'company_id': company_a.id},
|
|
# Forbidden, collides with BC2
|
|
{'name': 'F3', 'barcode': '2', 'company_id': company_b.id},
|
|
# Forbidden, collides with A1
|
|
{'name': 'F4', 'barcode': '3', 'company_id': company_a.id},
|
|
# Forbidden, collides with A2
|
|
{'name': 'F5', 'barcode': '3', 'company_id': company_b.id},
|
|
# Forbidden, collides with A1 and A2
|
|
{'name': 'F6', 'barcode': '3', 'company_id': False},
|
|
]
|
|
|
|
for product in allowed_products:
|
|
self.env['product.product'].create(product)
|
|
|
|
for product in forbidden_products:
|
|
with self.assertRaises(ValidationError):
|
|
self.env['product.product'].create(product)
|
|
|
|
def test_duplicated_barcodes_in_product_variants(self):
|
|
"""
|
|
Create 2 variants with different barcodes and same company.
|
|
Assign a duplicated barcode to one of them while changing the company.
|
|
Barcode validation should be triggered and a duplicated barcode should be detected.
|
|
"""
|
|
company_a = self.env.company
|
|
company_b = self.env['res.company'].create({'name': 'CB'})
|
|
|
|
variant_1 = self.template.product_variant_ids[0]
|
|
variant_2 = self.template.product_variant_ids[1]
|
|
|
|
variant_1.barcode = 'barcode_1'
|
|
variant_1.company_id = company_a
|
|
variant_2.barcode = 'barcode_2'
|
|
variant_2.company_id = company_a
|
|
|
|
with self.assertRaises(ValidationError):
|
|
variant_2.write({
|
|
'barcode': 'barcode_1',
|
|
'company_id': company_b
|
|
})
|
|
|
|
# Variant 1 was not updated
|
|
self.assertEqual(variant_2.barcode, 'barcode_2')
|
|
self.assertEqual(variant_2.company_id, company_a)
|
|
|
|
variant_2.write({
|
|
'barcode': 'barcode_3',
|
|
'company_id': company_b
|
|
})
|
|
|
|
self.assertEqual(variant_1.barcode, 'barcode_1')
|
|
self.assertEqual(variant_1.company_id, company_b)
|
|
self.assertEqual(variant_2.barcode, 'barcode_3')
|
|
self.assertEqual(variant_2.company_id, company_b)
|