test_barcode_nomenclature.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. # -*- coding: utf-8 -*-
  2. from odoo.exceptions import ValidationError
  3. from odoo.tests import common
  4. class TestBarcodeNomenclature(common.TransactionCase):
  5. @classmethod
  6. def setUpClass(cls):
  7. super().setUpClass()
  8. # Creates an empty nomenclature (rules will be added in the tests).
  9. cls.nomenclature = cls.env['barcode.nomenclature'].create({
  10. 'name': 'Barcode Nomenclature Test',
  11. })
  12. def test_barcode_nomenclature_parse_barcode_ean8_01(self):
  13. """ Parses some barcodes with a simple EAN-8 barcode rule and checks the result.
  14. """
  15. self.env['barcode.rule'].create({
  16. 'name': 'Rule Test #1',
  17. 'barcode_nomenclature_id': self.nomenclature.id,
  18. 'encoding': 'ean8',
  19. 'pattern': '........',
  20. })
  21. # Must fail because too short.
  22. res = self.nomenclature.parse_barcode('0002')
  23. self.assertEqual(res['code'], '0002')
  24. self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
  25. self.assertEqual(res['encoding'], '')
  26. self.assertEqual(res['base_code'], '0002')
  27. self.assertEqual(res['value'], 0)
  28. # Must fail because wrong checksum (last digit).
  29. res = self.nomenclature.parse_barcode('12345678')
  30. self.assertEqual(res['code'], '12345678')
  31. self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
  32. self.assertEqual(res['encoding'], '')
  33. self.assertEqual(res['base_code'], '12345678')
  34. self.assertEqual(res['value'], 0)
  35. # Must pass (right number of digits, right checksum).
  36. res = self.nomenclature.parse_barcode('12345670')
  37. self.assertEqual(res['code'], '12345670')
  38. self.assertEqual(res['type'], 'product')
  39. self.assertEqual(res['encoding'], 'ean8')
  40. self.assertEqual(res['base_code'], '12345670')
  41. self.assertEqual(res['value'], 0, "No value must be located into the barcode")
  42. # Must pass (right number of digits, right checksum).
  43. res = self.nomenclature.parse_barcode('02003405')
  44. self.assertEqual(res['code'], '02003405')
  45. self.assertEqual(res['type'], 'product')
  46. self.assertEqual(res['encoding'], 'ean8')
  47. self.assertEqual(res['base_code'], '02003405')
  48. self.assertEqual(res['value'], 0, "No value must be located into the barcode")
  49. def test_barcode_nomenclature_parse_barcode_ean8_02_validation_error(self):
  50. """ Try to parse a barcode with a wrong barcode rule.
  51. """
  52. barcode_rule = self.env['barcode.rule'].create({
  53. 'name': 'Rule Test #1',
  54. 'barcode_nomenclature_id': self.nomenclature.id,
  55. 'encoding': 'ean8',
  56. })
  57. with self.assertRaises(ValidationError), self.cr.savepoint():
  58. # Must fail because empty braces.
  59. barcode_rule.pattern = '......{}..'
  60. with self.assertRaises(ValidationError), self.cr.savepoint():
  61. # Must fail because decimal can't be before integer.
  62. barcode_rule.pattern = '......{DN}'
  63. with self.assertRaises(ValidationError), self.cr.savepoint():
  64. # Must fail because a pattern can't have multiple braces group.
  65. barcode_rule.pattern = '....{NN}{DD}'
  66. with self.assertRaises(ValidationError), self.cr.savepoint():
  67. # Must fail because '*' isn't accepted (should be '.*' instead).
  68. barcode_rule.pattern = '*'
  69. def test_barcode_nomenclature_parse_barcode_ean8_03_value(self):
  70. """ Parses some barcodes with a EAN-8 barcode rule who convert the
  71. barcode into value and checks the result.
  72. """
  73. self.env['barcode.rule'].create({
  74. 'name': 'Rule Test #2',
  75. 'barcode_nomenclature_id': self.nomenclature.id,
  76. 'encoding': 'ean8',
  77. 'pattern': '{NNNNNNNN}',
  78. })
  79. res = self.nomenclature.parse_barcode('0002')
  80. self.assertEqual(res['code'], '0002')
  81. self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
  82. self.assertEqual(res['encoding'], '')
  83. self.assertEqual(res['base_code'], '0002')
  84. self.assertEqual(res['value'], 0)
  85. res = self.nomenclature.parse_barcode('12345678')
  86. self.assertEqual(res['code'], '12345678')
  87. self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
  88. self.assertEqual(res['encoding'], '')
  89. self.assertEqual(res['base_code'], '12345678')
  90. self.assertEqual(res['value'], 0)
  91. # Must pass (right number of digits, right checksum).
  92. res = self.nomenclature.parse_barcode('12345670')
  93. self.assertEqual(res['code'], '12345670')
  94. self.assertEqual(res['type'], 'product')
  95. self.assertEqual(res['encoding'], 'ean8')
  96. self.assertEqual(res['base_code'], '00000000',
  97. "All the barcode should be consumed into the value")
  98. self.assertEqual(res['value'], 12345670.0, "The barcode must be converted into value")
  99. # Must pass (right number of digits, right checksum).
  100. res = self.nomenclature.parse_barcode('02003405')
  101. self.assertEqual(res['code'], '02003405')
  102. self.assertEqual(res['type'], 'product')
  103. self.assertEqual(res['encoding'], 'ean8')
  104. self.assertEqual(res['base_code'], '00000000',
  105. "All the barcode should be consumed into the value")
  106. self.assertEqual(res['value'], 2003405.0, "The barcode must be converted into value")
  107. def test_barcode_nomenclature_parse_barcode_ean8_04_multiple_rules(self):
  108. """ Parses some barcodes with a nomenclature containing multiple EAN-8
  109. barcode rule and checks the right one is took depending of the pattern.
  110. """
  111. self.env['barcode.rule'].create({
  112. 'name': 'Rule Test #1',
  113. 'barcode_nomenclature_id': self.nomenclature.id,
  114. 'encoding': 'ean8',
  115. 'pattern': '11.....{N}',
  116. })
  117. self.env['barcode.rule'].create({
  118. 'name': 'Rule Test #1',
  119. 'barcode_nomenclature_id': self.nomenclature.id,
  120. 'encoding': 'ean8',
  121. 'pattern': '66{NN}....',
  122. })
  123. # Only fits the second barcode rule.
  124. res = self.nomenclature.parse_barcode('11012344')
  125. self.assertEqual(res['code'], '11012344')
  126. self.assertEqual(res['type'], 'product')
  127. self.assertEqual(res['encoding'], 'ean8')
  128. self.assertEqual(res['base_code'], '11012340')
  129. self.assertEqual(res['value'], 4)
  130. # Only fits the second barcode rule.
  131. res = self.nomenclature.parse_barcode('66012344')
  132. self.assertEqual(res['code'], '66012344')
  133. self.assertEqual(res['type'], 'product')
  134. self.assertEqual(res['encoding'], 'ean8')
  135. self.assertEqual(res['base_code'], '66002344')
  136. self.assertEqual(res['value'], 1)
  137. # Doesn't fit any barcode rule.
  138. res = self.nomenclature.parse_barcode('16012344')
  139. self.assertEqual(res['code'], '16012344')
  140. self.assertEqual(res['type'], 'error')
  141. self.assertEqual(res['encoding'], '')
  142. self.assertEqual(res['base_code'], '16012344')
  143. self.assertEqual(res['value'], 0)
  144. def test_barcode_nomenclature_parse_barcode_ean13_01(self):
  145. """ Parses some barcodes with a EAN-13 barcode rule who contains a value
  146. and checks the result.
  147. """
  148. self.env['barcode.rule'].create({
  149. 'name': 'Rule Test #3',
  150. 'barcode_nomenclature_id': self.nomenclature.id,
  151. 'encoding': 'ean13',
  152. 'pattern': '1........{NND}.',
  153. })
  154. # Must fail because too short.
  155. res = self.nomenclature.parse_barcode('0002')
  156. self.assertEqual(res['code'], '0002')
  157. self.assertEqual(res['type'], 'error', "Must fail because the barcode is too short")
  158. self.assertEqual(res['encoding'], '')
  159. self.assertEqual(res['base_code'], '0002')
  160. self.assertEqual(res['value'], 0)
  161. # Must fail because wrong checksum (last digit).
  162. res = self.nomenclature.parse_barcode('12345678')
  163. self.assertEqual(res['code'], '12345678')
  164. self.assertEqual(res['type'], 'error', "Must fail because the checksum digit is wrong")
  165. self.assertEqual(res['encoding'], '')
  166. self.assertEqual(res['base_code'], '12345678')
  167. self.assertEqual(res['value'], 0)
  168. # Must pass (right number of digits, right checksum).
  169. res = self.nomenclature.parse_barcode('1020034051259')
  170. self.assertEqual(res['code'], '1020034051259')
  171. self.assertEqual(res['type'], 'product')
  172. self.assertEqual(res['encoding'], 'ean13')
  173. self.assertEqual(res['base_code'], '1020034050009')
  174. self.assertEqual(res['value'], 12.5, "Should taken only the value part (NND)")
  175. def test_barcode_nomenclature_parse_barcode_ean13_02_sequence(self):
  176. """ Parses some barcodes with a nomenclature containing two EAN-13
  177. barcode rule and checks the good one is took depending of its sequence.
  178. """
  179. first_created_rule = self.env['barcode.rule'].create({
  180. 'name': 'Rule Test #1',
  181. 'barcode_nomenclature_id': self.nomenclature.id,
  182. 'encoding': 'ean13',
  183. 'pattern': '.....{NNNDDDD}.',
  184. 'sequence': 3,
  185. })
  186. self.env['barcode.rule'].create({
  187. 'name': 'Rule Test #2',
  188. 'barcode_nomenclature_id': self.nomenclature.id,
  189. 'encoding': 'ean13',
  190. 'pattern': '22......{NNDD}.',
  191. 'sequence': 2,
  192. })
  193. # Invalids the cache to reset the nomenclature barcode rules' order.
  194. self.nomenclature.invalidate_recordset(['rule_ids'])
  195. # Only fits the second barcode rule.
  196. res = self.nomenclature.parse_barcode('2012345610255')
  197. self.assertEqual(res['code'], '2012345610255')
  198. self.assertEqual(res['type'], 'product')
  199. self.assertEqual(res['encoding'], 'ean13')
  200. self.assertEqual(res['base_code'], '2012300000008')
  201. self.assertEqual(res['value'], 456.1025)
  202. # Fits the two barcode rules, but should take the second one (lower sequence).
  203. res = self.nomenclature.parse_barcode('2212345610259')
  204. self.assertEqual(res['code'], '2212345610259')
  205. self.assertEqual(res['type'], 'product')
  206. self.assertEqual(res['encoding'], 'ean13')
  207. self.assertEqual(res['base_code'], '2212345600007')
  208. self.assertEqual(res['value'], 10.25)
  209. first_created_rule.sequence = 1
  210. # Invalids the cache to reset the nomenclature barcode rules' order.
  211. self.nomenclature.invalidate_recordset(['rule_ids'])
  212. # Should take the first one now (lower sequence).
  213. res = self.nomenclature.parse_barcode('2212345610259')
  214. self.assertEqual(res['code'], '2212345610259')
  215. self.assertEqual(res['type'], 'product')
  216. self.assertEqual(res['encoding'], 'ean13')
  217. self.assertEqual(res['base_code'], '2212300000002')
  218. self.assertEqual(res['value'], 456.1025)