Odoo18-Base/addons/barcodes/tests/test_barcode_nomenclature.py
2025-01-06 10:57:38 +07:00

291 lines
13 KiB
Python

from odoo.exceptions import ValidationError
from odoo.tests import common
class TestBarcodeNomenclature(common.TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Creates an empty nomenclature (rules will be added in the tests).
cls.nomenclature = cls.env['barcode.nomenclature'].create({
'name': 'Barcode Nomenclature Test',
})
def test_barcode_nomenclature_parse_barcode_ean8_01(self):
""" Parses some barcodes with a simple EAN-8 barcode rule and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '........',
})
# Must fail because too short.
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
# Must fail because wrong checksum (last digit).
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('12345670')
self.assertEqual(res['code'], '12345670')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '12345670')
self.assertEqual(res['value'], 0, "No value must be located into the barcode")
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('02003405')
self.assertEqual(res['code'], '02003405')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '02003405')
self.assertEqual(res['value'], 0, "No value must be located into the barcode")
def test_barcode_nomenclature_parse_barcode_ean8_02_validation_error(self):
""" Try to parse a barcode with a wrong barcode rule.
"""
barcode_rule = self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
})
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because empty braces.
barcode_rule.pattern = '......{}..'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because decimal can't be before integer.
barcode_rule.pattern = '......{DN}'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because a pattern can't have multiple braces group.
barcode_rule.pattern = '....{NN}{DD}'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because '*' isn't accepted (should be '.*' instead).
barcode_rule.pattern = '*'
with self.assertRaises(ValidationError), self.cr.savepoint():
# Must fail because '**' isn't even a valid regular expression.
barcode_rule.pattern = '**>>>{ND}'
# Allowed since it leads to a valid regular expression.
barcode_rule.pattern = '..>>>{ND}'
def test_barcode_nomenclature_parse_barcode_ean8_03_value(self):
""" Parses some barcodes with a EAN-8 barcode rule who convert the
barcode into value and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #2',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '{NNNNNNNN}',
})
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('12345670')
self.assertEqual(res['code'], '12345670')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '00000000',
"All the barcode should be consumed into the value")
self.assertEqual(res['value'], 12345670.0, "The barcode must be converted into value")
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('02003405')
self.assertEqual(res['code'], '02003405')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '00000000',
"All the barcode should be consumed into the value")
self.assertEqual(res['value'], 2003405.0, "The barcode must be converted into value")
def test_barcode_nomenclature_parse_barcode_ean8_04_multiple_rules(self):
""" Parses some barcodes with a nomenclature containing multiple EAN-8
barcode rule and checks the right one is took depending of the pattern.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '11.....{N}',
})
self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean8',
'pattern': '66{NN}....',
})
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('11012344')
self.assertEqual(res['code'], '11012344')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '11012340')
self.assertEqual(res['value'], 4)
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('66012344')
self.assertEqual(res['code'], '66012344')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean8')
self.assertEqual(res['base_code'], '66002344')
self.assertEqual(res['value'], 1)
# Doesn't fit any barcode rule.
res = self.nomenclature.parse_barcode('16012344')
self.assertEqual(res['code'], '16012344')
self.assertEqual(res['type'], 'error')
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '16012344')
self.assertEqual(res['value'], 0)
def test_barcode_nomenclature_parse_barcode_ean13_01(self):
""" Parses some barcodes with a EAN-13 barcode rule who contains a value
and checks the result.
"""
self.env['barcode.rule'].create({
'name': 'Rule Test #3',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '1........{NND}.',
})
# Must fail because too short.
res = self.nomenclature.parse_barcode('0002')
self.assertEqual(res['code'], '0002')
self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '0002')
self.assertEqual(res['value'], 0)
# Must fail because wrong checksum (last digit).
res = self.nomenclature.parse_barcode('12345678')
self.assertEqual(res['code'], '12345678')
self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
self.assertEqual(res['encoding'], '')
self.assertEqual(res['base_code'], '12345678')
self.assertEqual(res['value'], 0)
# Must pass (right number of digits, right checksum).
res = self.nomenclature.parse_barcode('1020034051259')
self.assertEqual(res['code'], '1020034051259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '1020034050009')
self.assertEqual(res['value'], 12.5, "Should taken only the value part (NND)")
def test_barcode_nomenclature_parse_barcode_ean13_02_sequence(self):
""" Parses some barcodes with a nomenclature containing two EAN-13
barcode rule and checks the good one is took depending of its sequence.
"""
first_created_rule = self.env['barcode.rule'].create({
'name': 'Rule Test #1',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '.....{NNNDDDD}.',
'sequence': 3,
})
self.env['barcode.rule'].create({
'name': 'Rule Test #2',
'barcode_nomenclature_id': self.nomenclature.id,
'encoding': 'ean13',
'pattern': '22......{NNDD}.',
'sequence': 2,
})
# Invalids the cache to reset the nomenclature barcode rules' order.
self.nomenclature.invalidate_recordset(['rule_ids'])
# Only fits the second barcode rule.
res = self.nomenclature.parse_barcode('2012345610255')
self.assertEqual(res['code'], '2012345610255')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2012300000008')
self.assertEqual(res['value'], 456.1025)
# Fits the two barcode rules, but should take the second one (lower sequence).
res = self.nomenclature.parse_barcode('2212345610259')
self.assertEqual(res['code'], '2212345610259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2212345600007')
self.assertEqual(res['value'], 10.25)
first_created_rule.sequence = 1
# Invalids the cache to reset the nomenclature barcode rules' order.
self.nomenclature.invalidate_recordset(['rule_ids'])
# Should take the first one now (lower sequence).
res = self.nomenclature.parse_barcode('2212345610259')
self.assertEqual(res['code'], '2212345610259')
self.assertEqual(res['type'], 'product')
self.assertEqual(res['encoding'], 'ean13')
self.assertEqual(res['base_code'], '2212300000002')
self.assertEqual(res['value'], 456.1025)
def test_barcode_uri_conversion(self):
""" This test ensures URIs are correctly converted into barcode data."""
uri = 'urn:epc:class:lgtin : 4012345.012345.998877'
barcode_data = self.nomenclature.parse_barcode(uri)
self.assertEqual(len(barcode_data), 2)
product_part, lot_part = barcode_data
self.assertEqual(product_part['type'], 'product')
self.assertEqual(product_part['value'], '04012345123456')
self.assertEqual(lot_part['type'], 'lot')
self.assertEqual(lot_part['value'], '998877')
uri = 'urn:epc:id:sgtin:9521141.012345.4711'
barcode_data = self.nomenclature.parse_barcode(uri)
self.assertEqual(len(barcode_data), 2)
product_part, serial_part = barcode_data
self.assertEqual(product_part['type'], 'product')
self.assertEqual(product_part['value'], '09521141123454')
self.assertEqual(serial_part['type'], 'lot')
self.assertEqual(serial_part['value'], '4711')
uri = 'urn:epc:tag:sgtin-96 : 1.358378.0728089.620776'
barcode_data = self.nomenclature.parse_barcode(uri)
self.assertEqual(len(barcode_data), 2)
product_part, serial_part = barcode_data
self.assertEqual(product_part['type'], 'product')
self.assertEqual(product_part['value'], '03583787280898')
self.assertEqual(serial_part['type'], 'lot')
self.assertEqual(serial_part['value'], '620776')
uri = 'urn:epc:id:sscc:952656789012.03456'
barcode_data = self.nomenclature.parse_barcode(uri)
self.assertEqual(len(barcode_data), 1)
self.assertEqual(barcode_data[0]['type'], 'package')
self.assertEqual(barcode_data[0]['value'], '095265678901234568')