feat: Added unit testing for Item Barcodes in item.py
Adds three different barcodes and barcodes types to a test item and
checks that they are added correctly.
Adds a barcode that already exists, and checks a DuplicateEntryError
is raised.
Adds an invalid EAN barcode and checks InvalidBarcode (a subclass of
ValidationError) is raised.
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 294e26d..566b638 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -32,6 +32,10 @@
pass
+class InvalidBarcode(frappe.ValidationError):
+ pass
+
+
class Item(WebsiteGenerator):
website = frappe._dict(
page_title_field="item_name",
@@ -508,13 +512,13 @@
"""select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name))
if duplicate:
frappe.throw(_("Barcode {0} already used in Item {1}").format(
- item_barcode.barcode, duplicate[0][0]))
+ item_barcode.barcode, duplicate[0][0]), frappe.DuplicateEntryError)
item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type
if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'):
if not ean.is_valid(item_barcode.barcode):
frappe.throw(_("Barcode {0} is not a valid {1} code").format(
- item_barcode.barcode, item_barcode.barcode_type))
+ item_barcode.barcode, item_barcode.barcode_type), InvalidBarcode)
def validate_warehouse_for_reorder(self):
'''Validate Reorder level table for duplicate and conditional mandatory'''
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 7ef4f8c..24292f7 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -8,7 +8,7 @@
from frappe.test_runner import make_test_objects
from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError,
InvalidItemAttributeValueError, get_variant)
-from erpnext.stock.doctype.item.item import StockExistsForTemplate
+from erpnext.stock.doctype.item.item import StockExistsForTemplate, InvalidBarcode
from erpnext.stock.doctype.item.item import get_uom_conv_factor
from frappe.model.rename_doc import rename_doc
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -305,6 +305,65 @@
item_doc.has_variants = 1
self.assertRaises(StockExistsForTemplate, item_doc.save)
+ def test_add_item_barcode(self):
+ # Clean up
+ frappe.db.sql("""delete from `tabItem Barcode`""")
+ item_code = "Test Item Barcode"
+ if frappe.db.exists("Item", item_code):
+ frappe.delete_doc("Item", item_code)
+
+ # Create new item and add barcodes
+ barcode_properties_list = [
+ {
+ "barcode": "0012345678905",
+ "barcode_type": "EAN"
+ },
+ {
+ "barcode": "012345678905",
+ "barcode_type": "UAN"
+ },
+ {
+ "barcode": "ARBITRARY_TEXT",
+ }
+ ]
+ create_item(item_code)
+ for barcode_properties in barcode_properties_list:
+ item_doc = frappe.get_doc('Item', item_code)
+ new_barcode = item_doc.append('barcodes')
+ new_barcode.update(barcode_properties)
+ item_doc.save()
+
+ # Check values saved correctly
+ barcodes = frappe.get_list(
+ 'Item Barcode',
+ fields=['barcode', 'barcode_type'],
+ filters={'parent': item_code})
+
+ for barcode_properties in barcode_properties_list:
+ barcode_to_find = barcode_properties['barcode']
+ matching_barcodes = [
+ x for x in barcodes
+ if x['barcode'] == barcode_to_find
+ ]
+ self.assertEqual(len(matching_barcodes), 1)
+ details = matching_barcodes[0]
+
+ for key, value in iteritems(barcode_properties):
+ self.assertEqual(value, details.get(key))
+
+ # Add barcode again - should cause DuplicateEntryError
+ item_doc = frappe.get_doc('Item', item_code)
+ new_barcode = item_doc.append('barcodes')
+ new_barcode.update(barcode_properties_list[0])
+ self.assertRaises(frappe.DuplicateEntryError, item_doc.save)
+
+ # Add invalid barcode - should cause InvalidBarcode
+ item_doc = frappe.get_doc('Item', item_code)
+ new_barcode = item_doc.append('barcodes')
+ new_barcode.barcode = '9999999999999'
+ new_barcode.barcode_type = 'EAN'
+ self.assertRaises(InvalidBarcode, item_doc.save)
+
def set_item_variant_settings(fields):
doc = frappe.get_doc('Item Variant Settings')
doc.set('fields', fields)