fixes #8941: Better error message for duplicate items (#8968)
* fixes #8941: Better error message for duplicate items
* gathers all non unique items instead of first encountered non unique item
* renders errored items with `br` instead of `li`
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index b8a8ae8..2cf2f40 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -244,6 +244,14 @@
def validate_materials(self):
""" Validate raw material entries """
+
+ def get_duplicates(lst):
+ seen = set()
+ seen_add = seen.add
+ for item in lst:
+ if item.item_code in seen or seen_add(item.item_code):
+ yield item
+
if not self.get('items'):
frappe.throw(_("Raw Materials cannot be blank."))
check_list = []
@@ -252,10 +260,16 @@
validate_bom_no(m.item_code, m.bom_no)
if flt(m.qty) <= 0:
frappe.throw(_("Quantity required for Item {0} in row {1}").format(m.item_code, m.idx))
- check_list.append(cstr(m.item_code))
- unique_chk_list = set(check_list)
- if len(unique_chk_list) != len(check_list):
- frappe.throw(_("Same item has been entered multiple times."))
+ check_list.append(m)
+
+ duplicate_items = list(get_duplicates(check_list))
+ if duplicate_items:
+ li = []
+ for i in duplicate_items:
+ li.append("{0} on row {1}".format(i.item_code, i.idx))
+ duplicate_list = '<br>' + '<br>'.join(li)
+
+ frappe.throw(_("Same item has been entered multiple times. {list}").format(list=duplicate_list))
def check_recursion(self):
""" Check whether recursion occurs in any bom"""