Merge pull request #4015 from anandpdoshi/use-add-fetch

Use add_fetch in Product Bundle, Maintenance Visit and Maintenance Schedule instead of redundant get_item_details method
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index a2bb10c..7b5c6c1 100644
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -158,8 +158,13 @@
 	import datetime
 	ret = {}
 	if date_of_birth:
-		dt = getdate(date_of_birth) + datetime.timedelta(21915)
-		ret = {'date_of_retirement': dt.strftime('%Y-%m-%d')}
+		try:
+			dt = getdate(date_of_birth) + datetime.timedelta(21915)
+			ret = {'date_of_retirement': dt.strftime('%Y-%m-%d')}
+		except ValueError:
+			# invalid date
+			ret = {}
+
 	return ret
 
 @frappe.whitelist()
diff --git a/erpnext/patches/v6_0/default_activity_rate.py b/erpnext/patches/v6_0/default_activity_rate.py
index 90a7a8c..44fda34 100644
--- a/erpnext/patches/v6_0/default_activity_rate.py
+++ b/erpnext/patches/v6_0/default_activity_rate.py
@@ -1,6 +1,8 @@
 import frappe
 
 def execute():
+	frappe.reload_doc("projects", "doctype", "activity_cost")
+
 	for cost in frappe.db.get_list("Activity Cost", filters = {"employee": ""},
 		fields = ("name", "activity_type", "costing_rate", "billing_rate")):
 		activity_type = frappe.get_doc("Activity Type", cost.activity_type)
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.js b/erpnext/selling/doctype/product_bundle/product_bundle.js
index 2849be5..7a04c6a 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.js
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.js
@@ -12,9 +12,8 @@
 }
 cur_frm.fields_dict.new_item_code.query_description = __('Please select Item where "Is Stock Item" is "No" and "Is Sales Item" is "Yes" and there is no other Product Bundle');
 
-cur_frm.cscript.item_code = function(doc, dt, dn) {
-	var d = locals[dt][dn];
-	if (d.item_code){
-		return get_server_fields('get_item_details', d.item_code, 'items', doc ,dt, dn, 1);
-	}
+cur_frm.cscript.onload = function() {
+	// set add fetch for item_code's item_name and description
+	cur_frm.add_fetch('item_code', 'stock_uom', 'uom');
+	cur_frm.add_fetch('item_code', 'description', 'description');
 }
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.py b/erpnext/selling/doctype/product_bundle/product_bundle.py
index 2949c5c..363d334 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.py
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.py
@@ -22,14 +22,6 @@
 		if frappe.db.get_value("Item", self.new_item_code, "is_stock_item"):
 			frappe.throw(_("Parent Item {0} must not be a Stock Item").format(self.new_item_code))
 
-	def get_item_details(self, name):
-		det = frappe.db.sql("""select description, stock_uom from `tabItem`
-			where name = %s""", name)
-		return {
-			'description' : det and det[0][0] or '',
-			'uom': det and det[0][1] or ''
-		}
-
 def get_new_item_code(doctype, txt, searchfield, start, page_len, filters):
 	from erpnext.controllers.queries import get_match_cond
 
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index e178f28..a275de5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -171,7 +171,7 @@
 			if row.qty and not row.valuation_rate:
 				frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
 
-			if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction") 
+			if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction")
 				and row.valuation_rate == previous_sle.get("valuation_rate"))
 				or (not previous_sle and not row.qty)):
 					continue
@@ -243,7 +243,7 @@
 @frappe.whitelist()
 def get_items(warehouse, posting_date, posting_time):
 	items = frappe.get_list("Item", fields=["name"], filters=
-		{"is_stock_item": 1, "has_serial_no": 0, "has_batch_no": 0})
+		{"is_stock_item": 1, "has_serial_no": 0, "has_batch_no": 0, "has_variants": 0})
 	for item in items:
 		item.item_code = item.name
 		item.warehouse = warehouse
diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js
index d84dc17..023ef6c 100644
--- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js
+++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js
@@ -80,11 +80,16 @@
 $.extend(cur_frm.cscript, new erpnext.support.MaintenanceSchedule({frm: cur_frm}));
 
 cur_frm.cscript.onload = function(doc, dt, dn) {
-  if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
+	if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
 
-  if(doc.__islocal){
-    set_multiple(dt,dn,{transaction_date:get_today()});
-  }
+	if(doc.__islocal){
+		set_multiple(dt,dn,{transaction_date:get_today()});
+	}
+
+	// set add fetch for item_code's item_name and description
+	cur_frm.add_fetch('item_code', 'item_name', 'item_name');
+	cur_frm.add_fetch('item_code', 'description', 'description');
+
 }
 
 cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
@@ -106,14 +111,6 @@
 	}
 }
 
-cur_frm.cscript.item_code = function(doc, cdt, cdn) {
-	var d = locals[cdt][cdn];
-	if (d.item_code) {
-		return get_server_fields('get_item_details', d.item_code, 'items',
-			doc, cdt, cdn, 1);
-	}
-}
-
 cur_frm.cscript.generate_schedule = function(doc, cdt, cdn) {
 	if (!doc.__islocal) {
 		return $c('runserverobj', args={'method':'generate_schedule', 'docs':doc},
diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
index 0ecc9c0..9ac1133 100644
--- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
@@ -11,16 +11,6 @@
 from erpnext.stock.utils import get_valid_serial_nos
 
 class MaintenanceSchedule(TransactionBase):
-
-	def get_item_details(self, item_code):
-		item = frappe.db.sql("""select item_name, description from `tabItem`
-			where name=%s""", (item_code), as_dict=1)
-		ret = {
-			'item_name': item and item[0]['item_name'] or '',
-			'description' : item and item[0]['description'] or ''
-		}
-		return ret
-
 	def generate_schedule(self):
 		self.set('schedules', [])
 		frappe.db.sql("""delete from `tabMaintenance Schedule Detail`
diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
index c917918..7a803fb 100644
--- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
@@ -61,6 +61,10 @@
 cur_frm.cscript.onload = function(doc, dt, dn) {
 	if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
 	if(doc.__islocal) set_multiple(dt,dn,{mntc_date:get_today()});
+
+	// set add fetch for item_code's item_name and description
+	cur_frm.add_fetch('item_code', 'item_name', 'item_name');
+	cur_frm.add_fetch('item_code', 'description', 'description');
 }
 
 cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
@@ -81,14 +85,6 @@
   	}
 }
 
-cur_frm.cscript.item_code = function(doc, cdt, cdn) {
-	var d = locals[cdt][cdn];
-	if (d.item_code) {
-		return get_server_fields('get_item_details',d.item_code, 'purposes',doc,cdt,cdn,1);
-	}
-}
-
-
 cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) {
 	return {query: "erpnext.controllers.queries.customer_query" }
 }
diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
index b17685f..6d082bd 100644
--- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
+++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
@@ -11,9 +11,6 @@
 	def get_feed(self):
 		return _("To {0}").format(self.customer_name)
 
-	def get_item_details(self, item_code):
-		return frappe.db.get_value("Item", item_code, ["item_name", "description"], as_dict=1)
-
 	def validate_serial_no(self):
 		for d in self.get('purposes'):
 			if d.serial_no and not frappe.db.exists("Serial No", d.serial_no):