refactor code in Production Planning Tool
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
index 6596e23..6138435 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
@@ -120,6 +120,54 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "column_break_6", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse", 
+   "fieldname": "warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "fieldname": "sales_order", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -160,7 +208,7 @@
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -198,31 +246,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse", 
-   "fieldname": "warehouse", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Warehouse", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Warehouse", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "fieldname": "stock_uom", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -308,7 +331,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-02-10 07:08:38.461787", 
+ "modified": "2016-02-11 05:08:19.492712", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Plan Item", 
diff --git a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
index 0522e7a..1a7c894 100644
--- a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
+++ b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
@@ -66,7 +66,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "fieldname": "material_request_date", 
-   "fieldtype": "Date", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
@@ -76,6 +76,7 @@
    "no_copy": 0, 
    "oldfieldname": "document_date", 
    "oldfieldtype": "Date", 
+   "options": "material_request.transaction_date", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -99,7 +100,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-02-10 05:13:07.529068", 
+ "modified": "2016-02-11 04:21:34.372317", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Plan Material Request", 
diff --git a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
index bed893f..85bf7d6 100644
--- a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
+++ b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
@@ -41,7 +41,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "fieldname": "sales_order_date", 
-   "fieldtype": "Date", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
@@ -51,11 +51,12 @@
    "no_copy": 0, 
    "oldfieldname": "document_date", 
    "oldfieldtype": "Date", 
+   "options": "sales_order.transaction_date", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "print_width": "120px", 
-   "read_only": 1, 
+   "read_only": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -91,7 +92,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "fieldname": "customer", 
-   "fieldtype": "Link", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
@@ -99,7 +100,7 @@
    "label": "Customer", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Customer", 
+   "options": "sales_order.customer", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -116,8 +117,9 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "default": "", 
    "fieldname": "grand_total", 
-   "fieldtype": "Currency", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "in_filter": 0, 
@@ -125,7 +127,7 @@
    "label": "Grand Total", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Company:company:default_currency", 
+   "options": "sales_order.base_grand_total", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -148,7 +150,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-02-10 05:13:30.301297", 
+ "modified": "2016-02-11 04:17:42.849873", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Plan Sales Order", 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
index 15c4245..3fa1160 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
@@ -5,24 +5,25 @@
 
 cur_frm.cscript.onload = function(doc, cdt, cdn) {
 	cur_frm.set_value("company", frappe.defaults.get_user_default("Company"))
-	cur_frm.set_value("use_multi_level_bom", 1)
 }
 
 cur_frm.cscript.refresh = function(doc) {
 	cur_frm.disable_save();
 }
 
-cur_frm.cscript.sales_order = function(doc,cdt,cdn) {
-	var d = locals[cdt][cdn];
-	if (d.sales_order) {
-		return get_server_fields('get_so_details', d.sales_order, 'sales_orders', doc, cdt, cdn, 1);
-	}
-}
-
 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);
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
+			args: {
+				"item" : d.item_code
+			},
+			callback: function(r) {
+				$.extend(d, r.message);
+				refresh_field("items");
+			}
+		});
 	}
 }
 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
index 3f04713..19b5fd9 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
@@ -510,7 +510,7 @@
    "label": "Create Production Orders", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "raise_production_order", 
+   "options": "raise_production_orders", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -629,7 +629,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-02-10 07:28:50.298538", 
+ "modified": "2016-02-11 06:18:45.077263", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Planning Tool", 
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index 4be22e4..bec97d1 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -16,28 +16,8 @@
 		super(ProductionPlanningTool, self).__init__(arg1, arg2)
 		self.item_dict = {}
 
-	def get_so_details(self, so):
-		"""Pull other details from so"""
-		so = frappe.db.sql("""select transaction_date, customer, base_grand_total
-			from `tabSales Order` where name = %s""", so, as_dict = 1)
-		ret = {
-			'sales_order_date': so and so[0]['transaction_date'] or '',
-			'customer' : so[0]['customer'] or '',
-			'grand_total': so[0]['base_grand_total']
-		}
-		return ret
-
-	def get_item_details(self, item_code):
-		return get_item_details(item_code)
-
-	def clear_so_table(self):
-		self.set('sales_orders', [])
-
-	def clear_mr_table(self):
-		self.set('material_requests', [])
-	
-	def clear_item_table(self):
-		self.set('items', [])
+	def clear_table(self, table_name):
+		self.set(table_name, [])
 
 	def validate_company(self):
 		if not self.company:
@@ -81,7 +61,7 @@
 
 	def add_so_in_table(self, open_so):
 		""" Add sales orders in the table"""
-		self.clear_so_table()
+		self.clear_table("sales_orders")
 
 		so_list = [d.sales_order for d in self.get('sales_orders')]
 		for r in open_so:
@@ -125,7 +105,7 @@
 		
 	def add_mr_in_table(self, pending_mr):
 		""" Add Material Requests in the table"""
-		self.clear_mr_table()
+		self.clear_table("material_requests")
 
 		mr_list = [d.material_request for d in self.get('material_requests')]
 		for r in pending_mr:
@@ -199,7 +179,7 @@
 		
 
 	def add_items(self, items):
-		self.clear_item_table()
+		self.clear_table("items")
 		for p in items:
 			item_details = get_item_details(p['item_code'])
 			pi = self.append('items', {})
@@ -220,97 +200,108 @@
 	def validate_data(self):
 		self.validate_company()
 		for d in self.get('items'):
-			validate_bom_no(d.item_code, d.bom_no)
+			if not d.bom_no:
+				frappe.throw(_("Please select BOM for Item in Row {0}".format(d.idx)))
+			else:
+				validate_bom_no(d.item_code, d.bom_no)
+	
 			if not flt(d.planned_qty):
 				frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx))
 
-	def raise_production_order(self):
+	def raise_production_orders(self):
 		"""It will raise production order (Draft) for all distinct FG items"""
 		self.validate_data()
 
 		from erpnext.utilities.transaction_base import validate_uom_is_integer
 		validate_uom_is_integer(self, "stock_uom", "planned_qty")
 
-		items = self.get_distinct_items_and_boms()[1]
-		pro = self.create_production_order(items)
-		if pro:
-			pro = ["""<a href="#Form/Production Order/%s" target="_blank">%s</a>""" % \
-				(p, p) for p in pro]
-			msgprint(_("{0} created").format(comma_and(pro)))
+		items = self.get_production_items()
+		
+		pro_list = []
+		frappe.flags.mute_messages = True
+		
+		for key in items:
+			production_order = self.create_production_order(items[key])
+			if production_order:
+				pro_list.append(production_order)
+		
+		frappe.flags.mute_messages = False
+		
+		if pro_list:
+			pro_list = ["""<a href="#Form/Production Order/%s" target="_blank">%s</a>""" % \
+				(p, p) for p in pro_list]
+			msgprint(_("{0} created").format(comma_and(pro_list)))
 		else :
 			msgprint(_("No Production Orders created"))
 
-	def get_distinct_items_and_boms(self):
-		""" Club similar BOM and item for processing
+	def get_production_items(self):
+		item_dict = {}
+		for d in self.get("items"):
+			item_details= {
+				"production_item"		: d.item_code,
+				"sales_order"			: d.sales_order,
+				"material_request"		: d.material_request,
+				"material_request_item"	: d.material_request_item,
+				"bom_no"				: d.bom_no,
+				"description"			: d.description,
+				"stock_uom"				: d.stock_uom,
+				"company"				: self.company,
+				"wip_warehouse"			: "",
+				"fg_warehouse"			: d.warehouse,
+				"status"				: "Draft",
+			}
+			
+			""" Club similar BOM and item for processing in case of Sales Orders """
+			if self.plan_using == "Sales Order":
+				item_details.update({
+					"qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
+						.get("qty")) + flt(d.planned_qty)
+				})
+				item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
+			
+			elif self.plan_using == "Material Request":
+				item_details.update({
+					"qty": d.planned_qty
+				})
+				item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
+
+		return item_dict
+
+	def create_production_order(self, item_dict):
+		"""Create production order. Called from Production Planning Tool"""
+		from erpnext.manufacturing.doctype.production_order.production_order import OverProductionError, get_default_warehouse
+		warehouse = get_default_warehouse()
+		pro = frappe.new_doc("Production Order")
+		pro.update(item_dict)
+		pro.set_production_order_operations()
+		if warehouse:
+			pro.wip_warehouse = warehouse.get('wip_warehouse')
+		if not pro.fg_warehouse:
+			pro.fg_warehouse = warehouse.get('fg_warehouse')
+		
+		try:
+			pro.insert()
+			return pro.name
+		except OverProductionError:
+			pass
+
+	def get_so_wise_planned_qty(self):
+		"""	
 			bom_dict {
 				bom_no: ['sales_order', 'qty']
 			}
 		"""
-		item_dict, bom_dict = {}, {}
+		bom_dict = {}
 		for d in self.get("items"):
-			if d.bom_no:
-				if self.plan_using == "Sales Order":
-					bom_dict.setdefault(d.bom_no, []).append([d.sales_order, flt(d.planned_qty)])
-					if frappe.db.get_value("Item", d.item_code, "is_pro_applicable"):
-						item_dict[(d.item_code, d.sales_order, d.warehouse)] = {
-							"production_item"		: d.item_code,
-							"sales_order"			: d.sales_order,
-							"qty" 					: flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),
-														{}).get("qty")) + flt(d.planned_qty),
-							"bom_no"				: d.bom_no,
-							"description"			: d.description,
-							"stock_uom"				: d.stock_uom,
-							"company"				: self.company,
-							"wip_warehouse"			: "",
-							"fg_warehouse"			: d.warehouse,
-							"status"				: "Draft",
-						}
-				elif self.plan_using == "Material Request":
-					bom_dict.setdefault(d.bom_no, []).append([d.material_request_item, flt(d.planned_qty)])
-					if frappe.db.get_value("Item", d.item_code, "is_pro_applicable"):
-						item_dict[(d.item_code, d.material_request_item, d.warehouse)] = {
-							"production_item"		: d.item_code,
-							"material_request"		: d.material_request,
-							"material_request_item"	: d.material_request_item,
-							"qty" 					: d.planned_qty,
-							"bom_no"				: d.bom_no,
-							"description"			: d.description,
-							"stock_uom"				: d.stock_uom,
-							"company"				: self.company,
-							"wip_warehouse"			: "",
-							"fg_warehouse"			: d.warehouse,
-							"status"				: "Draft",
-						}
-		return bom_dict, item_dict
-
-	def create_production_order(self, items):
-		"""Create production order. Called from Production Planning Tool"""
-		from erpnext.manufacturing.doctype.production_order.production_order import OverProductionError, get_default_warehouse
-		warehouse = get_default_warehouse()
-		pro_list = []
-		for key in items:
-			pro = frappe.new_doc("Production Order")
-			pro.update(items[key])
-			pro.set_production_order_operations()
-			if warehouse:
-				pro.wip_warehouse = warehouse.get('wip_warehouse')
-				if not pro.fg_warehouse:
-					pro.fg_warehouse = warehouse.get('fg_warehouse')
-			frappe.flags.mute_messages = True
-
-			try:
-				pro.insert()
-				pro_list.append(pro.name)
-			except OverProductionError:
-				pass
-
-			frappe.flags.mute_messages = False
-		return pro_list
-
+			if self.plan_using == "Sales Order":
+				bom_dict.setdefault(d.bom_no, []).append({d.sales_order: flt(d.planned_qty)})
+			elif self.plan_using == "Material Request":
+				bom_dict.setdefault(d.bom_no, []).append({d.material_request_item: flt(d.planned_qty)})
+	
 	def download_raw_materials(self):
 		""" Create csv data for required raw material to produce finished goods"""
 		self.validate_data()
-		bom_dict = self.get_distinct_items_and_boms()[0]
+		bom_dict = self.get_so_wise_planned_qty()
 		self.get_raw_materials(bom_dict)
 		return self.get_csv()
 
@@ -389,7 +380,7 @@
 		if not self.purchase_request_for_warehouse:
 			frappe.throw(_("Please enter Warehouse for which Material Request will be raised"))
 
-		bom_dict = self.get_distinct_items_and_boms()[0]
+		bom_dict = self.get_so_wise_planned_qty()
 		self.get_raw_materials(bom_dict)
 
 		if self.item_dict:
@@ -445,12 +436,12 @@
 	def insert_purchase_request(self):
 		items_to_be_requested = self.get_requested_items()
 
-		purchase_request_list = []
+		material_request_list = []
 		if items_to_be_requested:
 			for item in items_to_be_requested:
 				item_wrapper = frappe.get_doc("Item", item)
-				pr_doc = frappe.new_doc("Material Request")
-				pr_doc.update({
+				material_request = frappe.new_doc("Material Request")
+				material_request.update({
 					"transaction_date": nowdate(),
 					"status": "Draft",
 					"company": self.company,
@@ -458,7 +449,7 @@
 					"material_request_type": "Purchase"
 				})
 				for sales_order, requested_qty in items_to_be_requested[item].items():
-					pr_doc.append("items", {
+					material_request.append("items", {
 						"doctype": "Material Request Item",
 						"__islocal": 1,
 						"item_code": item,
@@ -473,13 +464,13 @@
 						"sales_order": sales_order if sales_order!="No Sales Order" else None
 					})
 
-				pr_doc.flags.ignore_permissions = 1
-				pr_doc.submit()
-				purchase_request_list.append(pr_doc.name)
+				material_request.flags.ignore_permissions = 1
+				material_request.submit()
+				material_request_list.append(material_request.name)
 
-			if purchase_request_list:
-				pur_req = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
-					(p, p) for p in purchase_request_list]
-				msgprint(_("Material Requests {0} created").format(comma_and(pur_req)))
+			if material_request_list:
+				message = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
+					(p, p) for p in material_request_list]
+				msgprint(_("Material Requests {0} created").format(comma_and(message)))
 		else:
 			msgprint(_("Nothing to request"))