Merge pull request #21639 from deepeshgarg007/loan_unpledge_uutility_fix

fix: Loan Security Unpledge fixes
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index fb1a4f4..bfe35ab 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -297,7 +297,8 @@
 			fields = ["*"],
 			filters = {
 				"voucher_type": voucher_type,
-				"voucher_no": voucher_no
+				"voucher_no": voucher_no,
+				"is_cancelled": 0
 			})
 
 	if gl_entries:
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
index f75bb41..61faea1 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
@@ -145,7 +145,7 @@
 
 	def remove_holidays(rows):
 		rows = [ row for row in rows if row[4] != "Holiday"]
-		return
+		return rows
 
 	from frappe.modules import scrub
 
diff --git a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
index d98ed1b..82ed277 100644
--- a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
+++ b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
@@ -215,7 +215,7 @@
 def get_employee_details(group_by, company):
 	emp_map = {}
 	query = """select name, employee_name, designation, department, branch, company,
-		holiday_list from `tabEmployee` where company = '%s' """ % frappe.db.escape(company)
+		holiday_list from `tabEmployee` where company = %s """ % frappe.db.escape(company)
 
 	if group_by:
 		group_by = group_by.lower()
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ba17b67..ce0e4ac 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -495,6 +495,7 @@
 execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True)
 erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group # 24-12-2018
 erpnext.patches.v10_0.add_default_cash_flow_mappers
+erpnext.patches.v11_0.rename_duplicate_item_code_values
 erpnext.patches.v11_0.make_quality_inspection_template
 erpnext.patches.v10_0.update_status_for_multiple_source_in_po
 erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
diff --git a/erpnext/patches/v11_0/rename_duplicate_item_code_values.py b/erpnext/patches/v11_0/rename_duplicate_item_code_values.py
new file mode 100644
index 0000000..00ab562
--- /dev/null
+++ b/erpnext/patches/v11_0/rename_duplicate_item_code_values.py
@@ -0,0 +1,8 @@
+import frappe
+
+def execute():
+	items = []
+	items = frappe.db.sql("""select item_code from `tabItem` group by item_code having count(*) > 1""", as_dict=True)
+	if items:
+		for item in items:
+			frappe.db.sql("""update `tabItem` set item_code=name where item_code = %s""", (item.item_code))
diff --git a/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py b/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
index f5bd8c3..6f843cd 100644
--- a/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
+++ b/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
@@ -3,6 +3,10 @@
 from collections import defaultdict
 
 def execute():
+
+	frappe.reload_doc('stock', 'doctype', 'delivery_note_item', force=True)
+	frappe.reload_doc('stock', 'doctype', 'purchase_receipt_item', force=True)
+
 	def map_rows(doc_row, return_doc_row, detail_field, doctype):
 		"""Map rows after identifying similar ones."""
 
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 9b7249e..a091ac7 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -7,7 +7,7 @@
 from frappe import _
 from frappe.model.document import Document
 from frappe.model.naming import make_autoname, revert_series_if_last
-from frappe.utils import flt, cint
+from frappe.utils import flt, cint, get_link_to_form
 from frappe.utils.jinja import render_template
 from frappe.utils.data import add_days
 from six import string_types
@@ -124,7 +124,7 @@
 		if has_expiry_date and not self.expiry_date:
 			frappe.throw(msg=_("Please set {0} for Batched Item {1}, which is used to set {2} on Submit.") \
 				.format(frappe.bold("Shelf Life in Days"),
-					frappe.utils.get_link_to_form("Item", self.item),
+					get_link_to_form("Item", self.item),
 					frappe.bold("Batch Expiry Date")),
 				title=_("Expiry Date Mandatory"))
 
@@ -264,16 +264,20 @@
 def get_batches(item_code, warehouse, qty=1, throw=False, serial_no=None):
 	from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 	cond = ''
-	if serial_no:
+	if serial_no and frappe.get_cached_value('Item', item_code, 'has_batch_no'):
+		serial_nos = get_serial_nos(serial_no)
 		batch = frappe.get_all("Serial No",
 			fields = ["distinct batch_no"],
 			filters= {
 				"item_code": item_code,
 				"warehouse": warehouse,
-				"name": ("in", get_serial_nos(serial_no))
+				"name": ("in", serial_nos)
 			}
 		)
 
+		if not batch:
+			validate_serial_no_with_batch(serial_nos, item_code)
+
 		if batch and len(batch) > 1:
 			return []
 
@@ -288,4 +292,15 @@
 			and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL) {0}
 		group by batch_id
 		order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC
-	""".format(cond), (item_code, warehouse), as_dict=True)
\ No newline at end of file
+	""".format(cond), (item_code, warehouse), as_dict=True)
+
+def validate_serial_no_with_batch(serial_nos, item_code):
+	if frappe.get_cached_value("Serial No", serial_nos[0], "item_code") != item_code:
+		frappe.throw(_("The serial no {0} does not belong to item {1}")
+			.format(get_link_to_form("Serial No", serial_nos[0]), get_link_to_form("Item", item_code)))
+
+	serial_no_link = ','.join([get_link_to_form("Serial No", sn) for sn in serial_nos])
+
+	message = "Serial Nos" if len(serial_nos) > 1 else "Serial No"
+	frappe.throw(_("There is no batch found against the {0}: {1}")
+		.format(message, serial_no_link))
\ No newline at end of file