Production Order Enhancements (#9432)

* Production Order Enhancements
  - Show required items child table
  - Source warehouse for each raw materials, in Pro Order Item and BOM Item table
  - Group warehouse allowed for source and wip warehouse
  - Patch to populate required items, to fix status and reserved qty for stopped pro order
  - Cleaned up existing codes
  - Test cases

* Set available qty in source and wip warehouse

* minor fix in bom query naming

* Minor Fixes

* Reload BOM doctypes in patch
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 87dd565..347314b 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -5,12 +5,24 @@
 
 frappe.ui.form.on("BOM", {
 	setup: function(frm) {
-		frm.add_fetch('buying_price_list', 'currency', 'currency');
-		frm.fields_dict["items"].grid.get_field("bom_no").get_query = function(doc, cdt, cdn){
+		frm.add_fetch('buying_price_list', 'currency', 'currency')
+
+		frm.set_query("bom_no", "items", function() {
 			return {
-				filters: {'currency': frm.doc.currency}
+				filters: {
+					'currency': frm.doc.currency,
+					'company': frm.doc.company
+				}
 			}
-		}
+		});
+		
+		frm.set_query("source_warehouse", "items", function() {
+			return {
+				filters: {
+					'company': frm.doc.company,
+				}
+			}
+		});
 	},
 
 	onload_post_render: function(frm) {
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 41eec8d..7aef4fc 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -408,6 +408,7 @@
 				self.add_to_cur_exploded_items(frappe._dict({
 					'item_code'		: d.item_code,
 					'item_name'		: d.item_name,
+					'source_warehouse': d.source_warehouse,
 					'description'	: d.description,
 					'image'			: d.image,
 					'stock_uom'		: d.stock_uom,
@@ -427,7 +428,8 @@
 	def get_child_exploded_items(self, bom_no, stock_qty):
 		""" Add all items from Flat BOM of child BOM"""
 		# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
-		child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name, bom_item.description,
+		child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
+			bom_item.description, bom_item.source_warehouse,
 			bom_item.stock_uom, bom_item.stock_qty, bom_item.rate,
 			bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
 			from `tabBOM Explosion Item` bom_item, tabBOM bom
@@ -437,9 +439,10 @@
 			self.add_to_cur_exploded_items(frappe._dict({
 				'item_code'				: d['item_code'],
 				'item_name'				: d['item_name'],
+				'source_warehouse'		: d['source_warehouse'],
 				'description'			: d['description'],
 				'stock_uom'				: d['stock_uom'],
-				'stock_qty'					: d['qty_consumed_per_unit']*stock_qty,
+				'stock_qty'				: d['qty_consumed_per_unit'] * stock_qty,
 				'rate'					: flt(d['rate']),
 			}))
 
@@ -493,6 +496,7 @@
 				item.default_warehouse,
 				item.expense_account as expense_account,
 				item.buying_cost_center as cost_center
+				{select_columns}
 			from
 				`tab{table}` bom_item, `tabBOM` bom, `tabItem` item
 			where
@@ -501,18 +505,20 @@
 				and bom_item.parent = bom.name
 				and item.name = bom_item.item_code
 				and is_stock_item = 1
-				{conditions}
-			group by item_code, stock_uom"""
+				{where_conditions}
+				group by item_code, stock_uom"""
 
 	if fetch_exploded:
 		query = query.format(table="BOM Explosion Item",
-			conditions="""and item.is_sub_contracted_item = 0""")
+			where_conditions="""and item.is_sub_contracted_item = 0""",
+			select_columns = ", bom_item.source_warehouse")
 		items = frappe.db.sql(query, { "qty": qty,	"bom": bom }, as_dict=True)
 	elif fetch_scrap_items:
-		query = query.format(table="BOM Scrap Item", conditions="")
+		query = query.format(table="BOM Scrap Item", where_conditions="", select_columns="")
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
 	else:
-		query = query.format(table="BOM Item", conditions="")
+		query = query.format(table="BOM Item", where_conditions="",
+			select_columns = ", bom_item.source_warehouse")
 		items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
 
 	for item in items:
diff --git a/erpnext/manufacturing/doctype/bom/test_records.json b/erpnext/manufacturing/doctype/bom/test_records.json
index 0f1143e..6c24871 100644
--- a/erpnext/manufacturing/doctype/bom/test_records.json
+++ b/erpnext/manufacturing/doctype/bom/test_records.json
@@ -8,7 +8,8 @@
     "parentfield": "items",
     "stock_qty": 1.0,
     "rate": 5000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    },
    {
     "amount": 2000.0,
@@ -17,7 +18,8 @@
     "parentfield": "items",
     "stock_qty": 2.0,
     "rate": 1000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    }
   ],
   "docstatus": 1,
@@ -48,7 +50,8 @@
     "parentfield": "items",
     "stock_qty": 1.0,
     "rate": 5000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    },
    {
     "amount": 2000.0,
@@ -57,7 +60,8 @@
     "parentfield": "items",
     "stock_qty": 2.0,
     "rate": 1000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    }
   ],
   "docstatus": 1,
@@ -86,7 +90,8 @@
     "parentfield": "items",
     "stock_qty": 1.0,
     "rate": 5000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    },
    {
     "amount": 2000.0,
@@ -96,7 +101,8 @@
     "parentfield": "items",
     "stock_qty": 3.0,
     "rate": 1000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    }
   ],
   "docstatus": 1,
@@ -126,7 +132,8 @@
     "parentfield": "items",
     "stock_qty": 2.0,
     "rate": 3000.0,
-    "stock_uom": "_Test UOM"
+    "stock_uom": "_Test UOM",
+	"source_warehouse": "_Test Warehouse - _TC"
    }
   ],
   "docstatus": 1,
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
index e1a3d4d..19fc37f 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -7,9 +7,9 @@
  "beta": 0, 
  "creation": "2013-03-07 11:42:57", 
  "custom": 0, 
- "default_print_format": "Standard", 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "document_type": "Setup", 
  "editable_grid": 1, 
  "engine": "InnoDB", 
  "fields": [
@@ -110,6 +110,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_3", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -481,7 +512,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-06-02 19:29:34.498719", 
+ "modified": "2017-05-29 17:51:18.151002", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Explosion Item", 
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index 966b89b..d259dd5 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -22,7 +22,7 @@
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
-   "in_filter": 0, 
+   "in_filter": 1, 
    "in_global_search": 0, 
    "in_list_view": 1, 
    "in_standard_filter": 0, 
@@ -113,7 +113,7 @@
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
-   "in_filter": 0, 
+   "in_filter": 1, 
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
@@ -142,6 +142,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_5", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -729,7 +760,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-05-23 15:59:37.946963", 
+ "modified": "2017-05-29 17:42:37.216408", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM Item", 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 6465cec..283ebcd 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -7,7 +7,63 @@
 			'Timesheet': 'Make Timesheet',
 			'Stock Entry': 'Make Stock Entry',
 		}
+		
+		// Set query for warehouses
+		frm.set_query("wip_warehouse", function(doc) {
+			return {
+				filters: {
+					'company': frm.doc.company,
+				}
+			}
+		});
+		
+		frm.set_query("source_warehouse", "required_items", function() {
+			return {
+				filters: {
+					'company': frm.doc.company,
+				}
+			}
+		});
+		
+		frm.set_query("fg_warehouse", function() {
+			return {
+				filters: {
+					'company': frm.doc.company,
+					'is_group': 0
+				}
+			}
+		});
+		
+		// Set query for BOM
+		frm.set_query("bom_no", function() {
+			if (frm.doc.production_item) {
+				return{
+					query: "erpnext.controllers.queries.bom",
+					filters: {item: cstr(frm.doc.production_item)}
+				}
+			} else msgprint(__("Please enter Production Item first"));
+		});
+		
+		// Set query for FG Item
+		frm.set_query("production_item", function() {
+			return {
+				query: "erpnext.controllers.queries.item_query",
+				filters:{
+					'is_stock_item': 1,
+				}
+			}
+		});
+
+		// Set query for FG Item
+		frm.set_query("project", function() {
+			return{
+				filters:[
+					['Project', 'status', 'not in', 'Completed, Cancelled']
+				]
+			}
+		});
 	},
+	
 	onload: function(frm) {
 		if (!frm.doc.status)
 			frm.doc.status = 'Draft';
@@ -28,9 +84,8 @@
 			function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" })
 
 		erpnext.production_order.set_custom_buttons(frm);
-		erpnext.production_order.setup_company_filter(frm);
-		erpnext.production_order.setup_bom_filter(frm);
 	},
+	
 	refresh: function(frm) {
 		erpnext.toggle_naming_series();
 		erpnext.production_order.set_custom_buttons(frm);
@@ -53,6 +108,7 @@
 			})
 		}
 	},
+	
 	show_progress: function(frm) {
 		var bars = [];
 		var message = '';
@@ -85,10 +141,83 @@
 			}
 		}
 		frm.dashboard.add_progress(__('Status'), bars, message);
+	},
+	
+	production_item: function(frm) {
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
+			args: {
+				item: frm.doc.production_item,
+				project: frm.doc.project
+			},
+			callback: function(r) {
+				if(r.message) {
+					erpnext.in_production_item_onchange = true;
+					$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
+						frm.set_value(field, r.message[field]);
+					});
+
+					if(r.message["set_scrap_wh_mandatory"]){
+						frm.toggle_reqd("scrap_warehouse", true);
+					}
+					erpnext.in_production_item_onchange = false;
+				}
+			}
+		});
+	},
+	
+	project: function(frm) {
+		if(!erpnext.in_production_item_onchange) {
+			frm.trigger("production_item");
+		}
+	},
+	
+	bom_no: function(frm) {
+		return frm.call({
+			doc: frm.doc,
+			method: "get_items_and_operations_from_bom",
+			callback: function(r) {
+				if(r.message["set_scrap_wh_mandatory"]){
+					frm.toggle_reqd("scrap_warehouse", true);
+				}
+			}
+		});
+	},
+	
+	use_multi_level_bom: function(frm) {
+		if(frm.doc.bom_no) {
+			frm.trigger("bom_no");
+		}
+	},
+
+	qty: function(frm) {
+		frm.trigger('bom_no');
+	},
+	
+	before_submit: function(frm) {
+		frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
+		frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
 	}
 });
 
-
+frappe.ui.form.on("Production Order Item", {
+	source_warehouse: function(frm, cdt, cdn) {
+		var row = locals[cdt][cdn];
+		if(row.source_warehouse) {
+			frappe.call({
+				"method": "erpnext.stock.utils.get_latest_stock_qty",
+				args: {
+					item_code: row.item_code,
+					warehouse: row.source_warehouse
+				},
+				callback: function (r) {			
+					frappe.model.set_value(row.doctype, row.name,
+						"available_qty_at_source_warehouse", r.message);
+				}
+			})
+		}
+	}
+})
 
 frappe.ui.form.on("Production Order Operation", {
 	workstation: function(frm, cdt, cdn) {
@@ -119,38 +248,45 @@
 		var doc = frm.doc;
 		if (doc.docstatus === 1) {
 			if (doc.status != 'Stopped' && doc.status != 'Completed') {
-				frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Production Order'], __("Status"));
+				frm.add_custom_button(__('Stop'), function() {
+					erpnext.production_order.stop_production_order(frm, "Stopped");
+				}, __("Status"));
 			} else if (doc.status == 'Stopped') {
-				frm.add_custom_button(__('Re-open'), cur_frm.cscript['Unstop Production Order'], __("Status"));
+				frm.add_custom_button(__('Re-open'), function() {
+					erpnext.production_order.stop_production_order(frm, "Resumed");
+				}, __("Status"));
 			}
-
+			
 			if(!frm.doc.skip_transfer){
-				if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty)) && frm.doc.status != 'Stopped') {
+				if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))
+					&& frm.doc.status != 'Stopped') {
 					frm.has_start_btn = true;
-					var btn = frm.add_custom_button(__('Start'),
-						cur_frm.cscript['Transfer Raw Materials']);
-					btn.addClass('btn-primary');
-				}
+					var start_btn = frm.add_custom_button(__('Start'), function() {
+						erpnext.production_order.make_se(frm, 'Material Transfer for Manufacture');
+					});
+					start_btn.addClass('btn-primary');
+					}
 			}
 
 			if(!frm.doc.skip_transfer){
-				if ((flt(doc.produced_qty) < flt(doc.material_transferred_for_manufacturing)) && frm.doc.status != 'Stopped') {
+				if ((flt(doc.produced_qty) < flt(doc.material_transferred_for_manufacturing))
+						&& frm.doc.status != 'Stopped') {
 					frm.has_finish_btn = true;
-					var btn = frm.add_custom_button(__('Finish'),
-						cur_frm.cscript['Update Finished Goods']);
+					var finish_btn = frm.add_custom_button(__('Finish'), function() {
+						erpnext.production_order.make_se(frm, 'Manufacture');
+					});
 
 					if(doc.material_transferred_for_manufacturing==doc.qty) {
-						// all materials transferred for manufacturing,
-						// make this primary
-						btn.addClass('btn-primary');
+						// all materials transferred for manufacturing, make this primary
+						finish_btn.addClass('btn-primary');
 					}
 				}
 			} else {
 				if ((flt(doc.produced_qty) < flt(doc.qty)) && frm.doc.status != 'Stopped') {
 					frm.has_finish_btn = true;
-					var btn = frm.add_custom_button(__('Finish'),
+					var finish_btn = frm.add_custom_button(__('Finish'),
 						cur_frm.cscript['Update Finished Goods']);
-					btn.addClass('btn-primary');
+					finish_btn.addClass('btn-primary');
 				}
 			}
 		}
@@ -162,8 +298,8 @@
 			doc.planned_operating_cost = 0.0;
 			for(var i=0;i<op.length;i++) {
 				var planned_operating_cost = flt(flt(op[i].hour_rate) * flt(op[i].time_in_mins) / 60, 2);
-				frappe.model.set_value('Production Order Operation',op[i].name, "planned_operating_cost", planned_operating_cost);
-
+				frappe.model.set_value('Production Order Operation', op[i].name,
+					"planned_operating_cost", planned_operating_cost);
 				doc.planned_operating_cost += planned_operating_cost;
 			}
 			refresh_field('planned_operating_cost');
@@ -176,37 +312,10 @@
 		frm.set_value("total_operating_cost", (flt(frm.doc.additional_operating_cost) + variable_cost))
 	},
 
-	setup_company_filter: function(frm) {
-		var company_filter = function(doc) {
-			return {
-				filters: {
-					'company': frm.doc.company,
-					'is_group': 0
-				}
-			}
-		}
-
-		frm.fields_dict.source_warehouse.get_query = company_filter;
-		frm.fields_dict.fg_warehouse.get_query = company_filter;
-		frm.fields_dict.wip_warehouse.get_query = company_filter;
-	},
-
-	setup_bom_filter: function(frm) {
-		frm.set_query("bom_no", function(doc) {
-			if (doc.production_item) {
-				return{
-					query: "erpnext.controllers.queries.bom",
-					filters: {item: cstr(doc.production_item)}
-				}
-			} else frappe.msgprint(__("Please enter Production Item first"));
-		});
-	},
-
 	set_default_warehouse: function(frm) {
 		if (!(frm.doc.wip_warehouse || frm.doc.fg_warehouse)) {
 			frappe.call({
 				method: "erpnext.manufacturing.doctype.production_order.production_order.get_default_warehouse",
-
 				callback: function(r) {
 					if(!r.exe) {
 						frm.set_value("wip_warehouse", r.message.wip_warehouse);
@@ -215,45 +324,15 @@
 				}
 			});
 		}
-	}
-}
-
-$.extend(cur_frm.cscript, {
-	before_submit: function() {
-		cur_frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
 	},
-
-	production_item: function(doc) {
-		frappe.call({
-			method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
-			args: {
-				item: doc.production_item,
-				project: doc.project
-			},
-			callback: function(r) {
-				$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
-					cur_frm.set_value(field, r.message[field]);
-				});
-
-				if(r.message["set_scrap_wh_mandatory"]){
-					cur_frm.toggle_reqd("scrap_warehouse", true);
-				}
-			}
-		});
-	},
-
-	project: function(doc) {
-		cur_frm.cscript.production_item(doc)
-	},
-
-	make_se: function(purpose) {
-		var me = this;
-		if(!this.frm.doc.skip_transfer){
+	
+	make_se: function(frm, purpose) {
+		if(!frm.doc.skip_transfer){
 			var max = (purpose === "Manufacture") ?
-				flt(this.frm.doc.material_transferred_for_manufacturing) - flt(this.frm.doc.produced_qty) :
-				flt(this.frm.doc.qty) - flt(this.frm.doc.material_transferred_for_manufacturing);
+				flt(frm.doc.material_transferred_for_manufacturing) - flt(frm.doc.produced_qty) :
+				flt(frm.doc.qty) - flt(frm.doc.material_transferred_for_manufacturing);
 		} else {
-			var max = flt(this.frm.doc.qty) - flt(this.frm.doc.produced_qty);
+			var max = flt(frm.doc.qty) - flt(frm.doc.produced_qty);
 		}
 
 		frappe.prompt({fieldtype:"Float", label: __("Qty for {0}", [purpose]), fieldname:"qty",
@@ -266,7 +345,7 @@
 				frappe.call({
 					method:"erpnext.manufacturing.doctype.production_order.production_order.make_stock_entry",
 					args: {
-						"production_order_id": me.frm.doc.name,
+						"production_order_id": frm.doc.name,
 						"purpose": purpose,
 						"qty": data.qty
 					},
@@ -277,59 +356,20 @@
 				});
 			}, __("Select Quantity"), __("Make"));
 	},
-
-	bom_no: function() {
-		return this.frm.call({
-			doc: this.frm.doc,
-			method: "set_production_order_operations",
+	
+	stop_production_order: function(frm, status) {
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.production_order.production_order.stop_unstop",
+			args: {
+				production_order: frm.doc.name,
+				status: status
+			},
 			callback: function(r) {
-				if(r.message["set_scrap_wh_mandatory"]){
-					cur_frm.toggle_reqd("scrap_warehouse", true);
+				if(r.message) {
+					frm.set_value("status", r.message);
+					frm.reload_doc();
 				}
 			}
-		});
-	},
-	
-	use_multi_level_bom: function() {
-		if(this.frm.doc.bom_no) {
-			this.frm.trigger("bom_no");
-		}
-	},
-
-	qty: function() {
-		frappe.ui.form.trigger("Production Order", 'bom_no')
-	},
-});
-
-cur_frm.cscript['Stop Production Order'] = function() {
-	$c_obj(cur_frm.doc, 'stop_unstop', 'Stopped', function(r, rt) {cur_frm.refresh();});
-}
-
-cur_frm.cscript['Unstop Production Order'] = function() {
-	$c_obj(cur_frm.doc, 'stop_unstop', 'Unstopped', function(r, rt) {cur_frm.refresh();});
-}
-
-cur_frm.cscript['Transfer Raw Materials'] = function() {
-	cur_frm.cscript.make_se('Material Transfer for Manufacture');
-}
-
-cur_frm.cscript['Update Finished Goods'] = function() {
-	cur_frm.cscript.make_se('Manufacture');
-}
-
-cur_frm.fields_dict['production_item'].get_query = function(doc) {
-	return {
-		query: "erpnext.controllers.queries.item_query",
-		filters:{
-			'is_stock_item': 1,
-		}
-	}
-}
-
-cur_frm.fields_dict['project'].get_query = function(doc, dt, dn) {
-	return{
-		filters:[
-			['Project', 'status', 'not in', 'Completed, Cancelled']
-		]
+		})
 	}
 }
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 94b6b95..ee033c4 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -95,7 +95,7 @@
    "no_copy": 1, 
    "oldfieldname": "status", 
    "oldfieldtype": "Select", 
-   "options": "\nDraft\nSubmitted\nNot Started\nStopped\nUnstopped\nIn Process\nCompleted\nCancelled", 
+   "options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -145,38 +145,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "project", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Project", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "project", 
-   "oldfieldtype": "Link", 
-   "options": "Project", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "depends_on": "", 
    "description": "", 
    "fieldname": "bom_no", 
@@ -272,37 +240,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "description": "", 
-   "fieldname": "sales_order", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 1, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Sales Order", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Sales Order", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "depends_on": "", 
    "fieldname": "qty", 
    "fieldtype": "Float", 
@@ -335,37 +272,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "description": "Check if material transfer entry is not required", 
-   "fieldname": "skip_transfer", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Skip Material Transfer", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "default": "0", 
    "depends_on": "eval:doc.docstatus==1 && doc.skip_transfer==0", 
    "description": "", 
@@ -433,6 +339,100 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "description": "", 
+   "fieldname": "sales_order", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 1, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Sales Order", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Sales Order", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Project", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "project", 
+   "oldfieldtype": "Link", 
+   "options": "Project", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "description": "Check if material transfer entry is not required", 
+   "fieldname": "skip_transfer", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Skip Material Transfer", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "warehouses", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -463,38 +463,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "description": "", 
-   "fieldname": "source_warehouse", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Source Warehouse (for reserving Items)", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Warehouse", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "wip_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -525,34 +493,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "column_break_12", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "depends_on": "", 
    "description": "", 
    "fieldname": "fg_warehouse", 
@@ -585,6 +525,34 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "column_break_12", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "scrap_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -616,7 +584,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "time", 
+   "fieldname": "required_items_section", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -625,10 +593,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Time", 
+   "label": "Required Items", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "fa fa-time", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -647,9 +614,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "depends_on": "", 
-   "fieldname": "expected_delivery_date", 
-   "fieldtype": "Date", 
+   "fieldname": "required_items", 
+   "fieldtype": "Table", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -657,10 +623,43 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Expected Delivery Date", 
+   "label": "Required Items", 
+   "length": 0, 
+   "no_copy": 1, 
+   "options": "Production Order Item", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "time", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Time", 
    "length": 0, 
    "no_copy": 0, 
+   "options": "fa fa-time", 
    "permlevel": 0, 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -708,7 +707,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "planned_end_date", 
+   "fieldname": "actual_start_date", 
    "fieldtype": "Datetime", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -717,9 +716,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Planned End Date", 
+   "label": "Actual Start Date", 
    "length": 0, 
-   "no_copy": 1, 
+   "no_copy": 0, 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -767,7 +766,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "actual_start_date", 
+   "fieldname": "planned_end_date", 
    "fieldtype": "Datetime", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
@@ -776,9 +775,9 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Actual Start Date", 
+   "label": "Planned End Date", 
    "length": 0, 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -828,6 +827,36 @@
    "collapsible": 0, 
    "columns": 0, 
    "depends_on": "", 
+   "fieldname": "expected_delivery_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Expected Delivery Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "", 
    "fieldname": "operations_section", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -1076,67 +1105,6 @@
    "bold": 0, 
    "collapsible": 1, 
    "columns": 0, 
-   "fieldname": "required_items_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Required Items", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "required_items", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Required Items", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Production Order Item", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "columns": 0, 
    "fieldname": "more_info", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 68da336..040a559 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -3,24 +3,21 @@
 
 from __future__ import unicode_literals
 import frappe
-
 import json
-from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
 from frappe import _
-from frappe.utils import time_diff_in_seconds
+from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
 from frappe.model.document import Document
-from frappe.model.mapper import get_mapped_doc
-from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
+from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_bom_items_as_dict
 from dateutil.relativedelta import relativedelta
 from erpnext.stock.doctype.item.item import validate_end_of_life
-from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
+from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
 from erpnext.projects.doctype.timesheet.timesheet import OverlapError
 from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
 from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
 from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
-from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
-from erpnext.stock.utils import get_bin
 from frappe.utils.csvutils import getlink
+from erpnext.stock.utils import get_bin, validate_warehouse_company, get_latest_stock_qty
+from erpnext.utilities.transaction_base import validate_uom_is_integer
 
 class OverProductionError(frappe.ValidationError): pass
 class StockOverProductionError(frappe.ValidationError): pass
@@ -38,15 +35,19 @@
 			validate_bom_no(self.production_item, self.bom_no)
 
 		self.validate_sales_order()
-		self.validate_warehouse()
+		self.validate_warehouse_belongs_to_company()
 		self.calculate_operating_cost()
 		self.validate_qty()
 		self.validate_operation_time()
 		self.status = self.get_status()
 
-		from erpnext.utilities.transaction_base import validate_uom_is_integer
 		validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
 
+		if not self.get("required_items"):
+			self.set_required_items()
+		else:
+			self.set_available_qty()
+
 	def validate_sales_order(self):
 		if self.sales_order:
 			so = frappe.db.sql("""select name, delivery_date, project from `tabSales Order`
@@ -64,11 +65,14 @@
 			else:
 				frappe.throw(_("Sales Order {0} is not valid").format(self.sales_order))
 
-	def validate_warehouse(self):
-		from erpnext.stock.utils import validate_warehouse_company
+	def validate_warehouse_belongs_to_company(self):
+		warehouses = [self.fg_warehouse, self.wip_warehouse]
+		for d in self.get("required_items"):
+			if d.source_warehouse not in warehouses:
+				warehouses.append(d.source_warehouse)
 
-		for w in [self.source_warehouse, self.fg_warehouse, self.wip_warehouse]:
-			validate_warehouse_company(w, self.company)
+		for wh in warehouses:
+			validate_warehouse_company(wh, self.company)
 
 	def calculate_operating_cost(self):
 		self.planned_operating_cost, self.actual_operating_cost = 0.0, 0.0
@@ -79,7 +83,8 @@
 			self.planned_operating_cost += flt(d.planned_operating_cost)
 			self.actual_operating_cost += flt(d.actual_operating_cost)
 
-		variable_cost = self.actual_operating_cost if self.actual_operating_cost else self.planned_operating_cost
+		variable_cost = self.actual_operating_cost if self.actual_operating_cost \
+			else self.planned_operating_cost
 		self.total_operating_cost = flt(self.additional_operating_cost) + flt(variable_cost)
 
 	def validate_production_order_against_so(self):
@@ -101,22 +106,16 @@
 		# total qty in SO
 		so_qty = flt(so_item_qty) + flt(dnpi_qty)
 
-		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings", "over_production_allowance_percentage"))
+		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
+			"over_production_allowance_percentage"))
+			
 		if total_qty > so_qty + (allowance_percentage/100 * so_qty):
-			frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}").format(self.production_item,
-				so_qty), OverProductionError)
-
-	def stop_unstop(self, status):
-		""" Called from client side on Stop/Unstop event"""
-		status = self.update_status(status)
-		self.update_planned_qty()
-		frappe.msgprint(_("Production Order status is {0}").format(status))
-		self.notify_update()
-
+			frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
+				.format(self.production_item, so_qty), OverProductionError)
 
 	def update_status(self, status=None):
 		'''Update status of production order if unknown'''
-		if not status:
+		if status != "Stopped":
 			status = self.get_status(status)
 
 		if status != self.status:
@@ -167,7 +166,6 @@
 			self.db_set(fieldname, qty)
 
 	def before_submit(self):
-		self.set_required_items()
 		self.make_time_logs()
 
 	def on_submit(self):
@@ -184,10 +182,10 @@
 		self.validate_cancel()
 
 		frappe.db.set(self,'status', 'Cancelled')
-		self.clear_required_items()
 		self.delete_timesheet()
 		self.update_completed_qty_in_material_request()
 		self.update_planned_qty()
+		self.update_reserved_qty_for_production()
 
 	def validate_cancel(self):
 		if self.status == "Stopped":
@@ -214,12 +212,11 @@
 
 	def set_production_order_operations(self):
 		"""Fetch operations from BOM and set in 'Production Order'"""
+		self.set('operations', [])
 		
 		if not self.bom_no \
 			or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")):
 				return
-			
-		self.set('operations', [])
 		
 		if self.use_multi_level_bom:
 			bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
@@ -240,8 +237,6 @@
 		self.set('operations', operations)
 		self.calculate_time()
 
-		return check_if_scrap_warehouse_mandatory(self.bom_no)
-
 	def calculate_time(self):
 		bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
 
@@ -403,62 +398,60 @@
 		update bin reserved_qty_for_production
 		called from Stock Entry for production, after submit, cancel
 		'''
-		if self.docstatus==1 and self.source_warehouse:
-			if self.material_transferred_for_manufacturing == self.produced_qty:
-				# clear required items table and save document
-				self.clear_required_items()
-			else:
-				# calculate transferred qty based on submitted
-				# stock entries
-				self.update_transaferred_qty_for_required_items()
+		if self.docstatus==1:
+			# calculate transferred qty based on submitted stock entries
+			self.update_transaferred_qty_for_required_items()
 
-				# update in bin
-				self.update_reserved_qty_for_production()
-
-	def clear_required_items(self):
-		'''Remove the required_items table and update the bins'''
-		items = [d.item_code for d in self.required_items]
-		self.required_items = []
-
-		self.update_child_table('required_items')
-
-		# completed, update reserved qty in bin
-		self.update_reserved_qty_for_production(items)
+			# update in bin
+			self.update_reserved_qty_for_production()
 
 	def update_reserved_qty_for_production(self, items=None):
 		'''update reserved_qty_for_production in bins'''
-		if not self.source_warehouse:
-			return
-
-		if not items:
-			items = [d.item_code for d in self.required_items]
-
-		for item in items:
-			stock_bin = get_bin(item, self.source_warehouse)
-			stock_bin.update_reserved_qty_for_production()
+		for d in self.required_items:
+			if d.source_warehouse:
+				stock_bin = get_bin(d.item_code, d.source_warehouse)
+				stock_bin.update_reserved_qty_for_production()
+			
+	def get_items_and_operations_from_bom(self):
+		self.set_required_items()
+		self.set_production_order_operations()
+		
+		return check_if_scrap_warehouse_mandatory(self.bom_no)
+		
+	def set_available_qty(self):
+		for d in self.get("required_items"):
+			if d.source_warehouse:
+				d.available_qty_at_source_warehouse = get_latest_stock_qty(d.item_code, d.source_warehouse)
+				
+			if self.wip_warehouse:
+				d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
 
 	def set_required_items(self):
 		'''set required_items for production to keep track of reserved qty'''
-		if self.source_warehouse:
+		self.required_items = []
+		if self.bom_no and self.qty:
 			item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
 				fetch_exploded = self.use_multi_level_bom)
 
 			for item in item_dict.values():
-				self.append('required_items', {'item_code': item.item_code,
-					'required_qty': item.qty})
-
-			#print frappe.as_json(self.required_items)
+				self.append('required_items', {
+					'item_code': item.item_code,
+					'required_qty': item.qty,
+					'source_warehouse': item.source_warehouse or item.default_warehouse
+				})
+			
+			self.set_available_qty()
 
 	def update_transaferred_qty_for_required_items(self):
 		'''update transferred qty from submitted stock entries for that item against
 			the production order'''
 
 		for d in self.required_items:
-			transferred_qty = frappe.db.sql('''select count(qty)
+			transferred_qty = frappe.db.sql('''select sum(qty)
 				from `tabStock Entry` entry, `tabStock Entry Detail` detail
 				where
 					entry.production_order = %s
-					entry.purpose = "Material Transfer for Manufacture"
+					and entry.purpose = "Material Transfer for Manufacture"
 					and entry.docstatus = 1
 					and detail.parent = entry.name
 					and detail.item_code = %s''', (self.name, d.item_code))[0][0]
@@ -496,10 +489,12 @@
 
 	if not res["bom_no"]:
 		if project:
-			frappe.throw(_("Default BOM for {0} not found for Project {1}").format(item, project))
-		frappe.throw(_("Default BOM for {0} not found").format(item))
+			res = get_item_details(item)
+			frappe.msgprint(_("Default BOM not found for Item {0} and Project {1}").format(item, project))
+		else:
+			frappe.throw(_("Default BOM for {0} not found").format(item))
 
-	res['project'] = frappe.db.get_value('BOM', res['bom_no'], 'project')
+	res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
 	res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
 
 	return res
@@ -507,16 +502,21 @@
 @frappe.whitelist()
 def check_if_scrap_warehouse_mandatory(bom_no):
 	res = {"set_scrap_wh_mandatory": False }
-	bom = frappe.get_doc("BOM", bom_no)
+	if bom_no:
+		bom = frappe.get_doc("BOM", bom_no)
 
-	if len(bom.scrap_items) > 0:
-		res["set_scrap_wh_mandatory"] = True
+		if len(bom.scrap_items) > 0:
+			res["set_scrap_wh_mandatory"] = True
 
 	return res
 
 @frappe.whitelist()
 def make_stock_entry(production_order_id, purpose, qty=None):
 	production_order = frappe.get_doc("Production Order", production_order_id)
+	if not frappe.db.get_value("Warehouse", production_order.wip_warehouse, "is_group"):
+		wip_warehouse = production_order.wip_warehouse
+	else:
+		wip_warehouse = None
 
 	stock_entry = frappe.new_doc("Stock Entry")
 	stock_entry.purpose = purpose
@@ -528,12 +528,10 @@
 	stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
 
 	if purpose=="Material Transfer for Manufacture":
-		if production_order.source_warehouse:
-			stock_entry.from_warehouse = production_order.source_warehouse
-		stock_entry.to_warehouse = production_order.wip_warehouse
+		stock_entry.to_warehouse = wip_warehouse
 		stock_entry.project = production_order.project
 	else:
-		stock_entry.from_warehouse = production_order.wip_warehouse
+		stock_entry.from_warehouse = wip_warehouse
 		stock_entry.to_warehouse = production_order.fg_warehouse
 		additional_costs = get_additional_costs(production_order, fg_qty=stock_entry.fg_completed_qty)
 		stock_entry.project = production_order.project
@@ -601,3 +599,18 @@
 		frappe.throw(_("Already completed"))
 
 	return ts
+
+@frappe.whitelist()
+def stop_unstop(production_order, status):
+	""" Called from client side on Stop/Unstop event"""
+	
+	if not frappe.has_permission("Production Order", "write"):
+		frappe.throw(_("Not permitted"), frappe.PermissionError)
+		
+	pro_order = frappe.get_doc("Production Order", production_order)
+	pro_order.update_status(status)
+	pro_order.update_planned_qty()
+	frappe.msgprint(_("Production Order has been {0}").format(status))
+	pro_order.notify_update()
+	
+	return pro_order.status
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index cdadba4..18aa51d 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -8,7 +8,7 @@
 from frappe.utils import flt, time_diff_in_hours, now, add_days, cint
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
 from erpnext.manufacturing.doctype.production_order.production_order \
-	import make_stock_entry, ItemHasVariantError
+	import make_stock_entry, ItemHasVariantError, stop_unstop
 from erpnext.stock.doctype.stock_entry import test_stock_entry
 from erpnext.stock.doctype.item.test_item import get_total_projected_qty
 from erpnext.stock.utils import get_bin
@@ -228,10 +228,46 @@
 			cint(bin1_on_start_production.reserved_qty_for_production))
 		self.assertEqual(cint(bin1_on_end_production.projected_qty),
 			cint(bin1_on_end_production.projected_qty))
+			
+	def test_reserved_qty_for_stopped_production(self):
+		test_stock_entry.make_stock_entry(item_code="_Test Item",
+			target= self.warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
+			target= self.warehouse, qty=100, basic_rate=100)
 
-		# required_items removed
-		self.pro_order.reload()
-		self.assertEqual(len(self.pro_order.required_items), 0)
+		# 	0 0 0
+		
+		self.test_reserved_qty_for_production_submit()
+		
+		#2 0 -2
+
+		s = frappe.get_doc(make_stock_entry(self.pro_order.name,
+			"Material Transfer for Manufacture", 1))
+
+		s.submit()
+		
+		#1 -1 0
+		
+		bin1_on_start_production = get_bin(self.item, self.warehouse)
+
+		# reserved_qty_for_producion updated
+		self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production) + 1,
+			cint(bin1_on_start_production.reserved_qty_for_production))
+
+		# projected qty will now be 2 less (becuase of item movement)
+		self.assertEqual(cint(self.bin1_at_start.projected_qty),
+			cint(bin1_on_start_production.projected_qty) + 2)
+			
+		# STOP
+		stop_unstop(self.pro_order.name, "Stopped")
+		
+		bin1_on_stop_production = get_bin(self.item, self.warehouse)
+
+		# no change in reserved / projected
+		self.assertEqual(cint(bin1_on_stop_production.reserved_qty_for_production),
+			cint(self.bin1_at_start.reserved_qty_for_production))
+		self.assertEqual(cint(bin1_on_stop_production.projected_qty) + 1,
+			cint(self.bin1_at_start.projected_qty))
 
 	def test_scrap_material_qty(self):
 		prod_order = make_prod_order_test_record(planned_start_date=now(), qty=2)
@@ -286,10 +322,11 @@
 	pro_order.company = args.company or "_Test Company"
 	pro_order.stock_uom = args.stock_uom or "_Test UOM"
 	pro_order.use_multi_level_bom=0
-	pro_order.set_production_order_operations()
-	
+	pro_order.get_items_and_operations_from_bom()
+
 	if args.source_warehouse:
-		pro_order.source_warehouse = args.source_warehouse
+		for item in pro_order.get("required_items"):
+			item.source_warehouse = args.source_warehouse
 
 	if args.planned_start_date:
 		pro_order.planned_start_date = args.planned_start_date
diff --git a/erpnext/manufacturing/doctype/production_order_item/production_order_item.json b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
index a0fe7ab..06a7876 100644
--- a/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
+++ b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
@@ -13,6 +13,7 @@
  "engine": "InnoDB", 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -43,6 +44,157 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "source_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 1, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_3", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "item_name", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Item Name", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "description", 
+   "fieldtype": "Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Description", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "qty_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Qty", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -72,6 +224,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -99,6 +252,95 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_9", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "available_qty_at_source_warehouse", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Available Qty at Source Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "available_qty_at_wip_warehouse", 
+   "fieldtype": "Float", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Available Qty at WIP Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
   }
  ], 
  "has_web_view": 0, 
@@ -111,7 +353,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-03-28 14:18:36.342161", 
+ "modified": "2017-05-15 17:37:20.212361", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order Item", 
diff --git a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
index 618235f..89306c4 100644
--- a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
+++ b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
@@ -13,6 +13,7 @@
  "engine": "InnoDB", 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -42,6 +43,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -74,6 +76,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -85,7 +88,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "BOM", 
    "length": 0, 
@@ -104,6 +107,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -135,6 +139,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -163,6 +168,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -193,6 +199,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -224,6 +231,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -256,6 +264,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -285,6 +294,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -314,6 +324,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -343,6 +354,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -371,6 +383,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -403,6 +416,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -434,6 +448,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -464,6 +479,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -493,6 +509,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -522,6 +539,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -552,6 +570,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -580,6 +599,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -610,6 +630,7 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -651,7 +672,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-03-27 15:56:29.010336", 
+ "modified": "2017-05-29 18:02:04.252419", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order Operation", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index e7cf5f2..4f5c238 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -412,3 +412,4 @@
 execute:frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
 erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
 erpnext.patches.v8_1.gst_fixes
+erpnext.patches.v8_0.update_production_orders
diff --git a/erpnext/patches/v8_0/update_production_orders.py b/erpnext/patches/v8_0/update_production_orders.py
new file mode 100644
index 0000000..317aed5
--- /dev/null
+++ b/erpnext/patches/v8_0/update_production_orders.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	# reload schema
+	for doctype in ("Production Order", "Production Order Item", "Production Order Operation", 
+		"BOM Item", "BOM Explosion Item", "BOM"):
+			frappe.reload_doctype(doctype)
+
+	# fetch all draft and submitted production orders
+	fields = ["name"]
+	if "source_warehouse" in frappe.db.get_table_columns("Production Order"):
+		fields.append("source_warehouse")
+		
+	pro_orders = frappe.get_all("Production Order", filters={"docstatus": ["!=", 2]}, fields=fields)
+	
+	for p in pro_orders:
+		pro_order = frappe.get_doc("Production Order", p.name)
+		
+		# set required items table
+		pro_order.set_required_items()
+		
+		for item in pro_order.get("required_items"):
+			# set source warehouse based on parent
+			if not item.source_warehouse and "source_warehouse" in fields:
+				item.source_warehouse = pro_order.get("source_warehouse")
+			item.db_update()
+		
+		if pro_order.docstatus == 1:
+			# update transferred qty based on Stock Entry, it also updates db
+			pro_order.update_transaferred_qty_for_required_items()
+			
+			# Set status where it was 'Unstopped', as it is deprecated
+			if pro_order.status == "Unstopped":
+				status = pro_order.get_status()
+				pro_order.db_set("status", status)
+			elif pro_order.status == "Stopped":
+				pro_order.update_reserved_qty_for_production()
+			
+			
+			
\ No newline at end of file
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 75510de..9b49b69 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -3,7 +3,6 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _
 from frappe.utils import flt, nowdate
 import frappe.defaults
 from frappe.model.document import Document
@@ -15,7 +14,6 @@
 
 		self.validate_mandatory()
 		self.set_projected_qty()
-		self.block_transactions_against_group_warehouse()
 
 	def on_update(self):
 		update_item_projected_qty(self.item_code)
@@ -26,10 +24,6 @@
 			if (not getattr(self, f, None)) or (not self.get(f)):
 				self.set(f, 0.0)
 
-	def block_transactions_against_group_warehouse(self):
-		from erpnext.stock.utils import is_group_warehouse
-		is_group_warehouse(self.warehouse)
-
 	def update_stock(self, args, allow_negative_stock=False, via_landed_cost_voucher=False):
 		'''Called from erpnext.stock.utils.update_bin'''
 		self.update_qty(args)
@@ -91,7 +85,8 @@
 				item.item_code = %s
 				and item.parent = pro.name
 				and pro.docstatus = 1
-				and pro.source_warehouse = %s''', (self.item_code, self.warehouse))[0][0]
+				and item.source_warehouse = %s
+				and pro.status not in ("Stopped", "Completed")''', (self.item_code, self.warehouse))[0][0]
 
 		self.set_projected_qty()
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index b74be39..7c7e630 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -708,13 +708,11 @@
 			issue (item quantity) that is pending to issue or desire to transfer,
 			whichever is less
 		"""
-		item_dict = self.get_bom_raw_materials(1)
-		issued_item_qty = self.get_issued_qty()
-
+		item_dict = self.get_pro_order_required_items()
 		max_qty = flt(self.pro_doc.qty)
-		for item in item_dict:
-			pending_to_issue = (max_qty * item_dict[item]["qty"]) - issued_item_qty.get(item, 0)
-			desire_to_transfer = flt(self.fg_completed_qty) * item_dict[item]["qty"]
+		for item, item_details in item_dict.items():
+			pending_to_issue = flt(item_details.required_qty) - flt(item_details.transferred_qty)
+			desire_to_transfer = flt(self.fg_completed_qty) * flt(item_details.required_qty) / max_qty
 
 			if desire_to_transfer <= pending_to_issue:
 				item_dict[item]["qty"] = desire_to_transfer
@@ -734,34 +732,43 @@
 
 		return item_dict
 
-	def get_issued_qty(self):
-		issued_item_qty = {}
-		result = frappe.db.sql("""select t1.item_code, sum(t1.qty)
-			from `tabStock Entry Detail` t1, `tabStock Entry` t2
-			where t1.parent = t2.name and t2.production_order = %s and t2.docstatus = 1
-			and t2.purpose = 'Material Transfer for Manufacture'
-			group by t1.item_code""", self.production_order)
-		for t in result:
-			issued_item_qty[t[0]] = flt(t[1])
-
-		return issued_item_qty
+	def get_pro_order_required_items(self):
+		item_dict = frappe._dict()
+		pro_order = frappe.get_doc("Production Order", self.production_order)
+		if not frappe.db.get_value("Warehouse", pro_order.wip_warehouse, "is_group"):
+			wip_warehouse = pro_order.wip_warehouse
+		else:
+			wip_warehouse = None
+			
+		for d in pro_order.get("required_items"):
+			if flt(d.required_qty) > flt(d.transferred_qty):
+				item_row = d.as_dict()
+				if d.source_warehouse and not frappe.db.get_value("Warehouse", d.source_warehouse, "is_group"):
+					item_row["from_warehouse"] = d.source_warehouse
+				
+				item_row["to_warehouse"] = wip_warehouse
+				item_dict.setdefault(d.item_code, item_row)
+			
+		return item_dict
 
 	def add_to_stock_entry_detail(self, item_dict, bom_no=None):
 		expense_account, cost_center = frappe.db.get_values("Company", self.company, \
 			["default_expense_account", "cost_center"])[0]
-
+				
 		for d in item_dict:
+			stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom")
+			
 			se_child = self.append('items')
 			se_child.s_warehouse = item_dict[d].get("from_warehouse")
 			se_child.t_warehouse = item_dict[d].get("to_warehouse")
 			se_child.item_code = cstr(d)
 			se_child.item_name = item_dict[d]["item_name"]
 			se_child.description = item_dict[d]["description"]
-			se_child.uom = item_dict[d]["stock_uom"]
-			se_child.stock_uom = item_dict[d]["stock_uom"]
+			se_child.uom = stock_uom
+			se_child.stock_uom = stock_uom
 			se_child.qty = flt(item_dict[d]["qty"])
-			se_child.expense_account = item_dict[d]["expense_account"] or expense_account
-			se_child.cost_center = item_dict[d]["cost_center"] or cost_center
+			se_child.expense_account = item_dict[d].get("expense_account") or expense_account
+			se_child.cost_center = item_dict[d].get("cost_center") or cost_center
 
 			if se_child.s_warehouse==None:
 				se_child.s_warehouse = self.from_warehouse
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index a9d0522..403d5cb 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -132,7 +132,7 @@
 def get_planned_qty(item_code, warehouse):
 	planned_qty = frappe.db.sql("""
 		select sum(qty - produced_qty) from `tabProduction Order`
-		where production_item = %s and fg_warehouse = %s and status != "Stopped"
+		where production_item = %s and fg_warehouse = %s and status not in ("Stopped", "Completed")
 		and docstatus=1 and qty > produced_qty""", (item_code, warehouse))
 
 	return flt(planned_qty[0][0]) if planned_qty else 0
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 2b9def3..01a18b9 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -41,7 +41,8 @@
 
 	sle_map = {}
 	for sle in stock_ledger_entries:
-		sle_map[sle.item_code] = sle_map.get(sle.item_code, 0.0) + flt(sle.stock_value)
+		if not sle_map.has_key((sle.item_code, sle.warehouse)):
+			sle_map[(sle.item_code, sle.warehouse)] = flt(sle.stock_value)
 		
 	return sum(sle_map.values())
 
@@ -67,6 +68,28 @@
 	else:
 		return last_entry.qty_after_transaction if last_entry else 0.0
 
+@frappe.whitelist()
+def get_latest_stock_qty(item_code, warehouse=None):
+	values, condition = [item_code], ""
+	if warehouse:
+		lft, rgt, is_group = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt", "is_group"])
+	
+		if is_group:
+			values.extend([lft, rgt])
+			condition += "and exists (\
+				select name from `tabWarehouse` wh where wh.name = tabBin.warehouse\
+				and wh.lft >= %s and wh.rgt <= %s)"
+	
+		else:
+			values.append(warehouse)
+			condition += " AND warehouse = %s"
+	
+	actual_qty = frappe.db.sql("""select sum(actual_qty) from tabBin
+		where item_code=%s {0}""".format(condition), values)[0][0]
+
+	return actual_qty
+
+
 def get_latest_stock_balance():
 	bin_map = {}
 	for d in frappe.db.sql("""SELECT item_code, warehouse, stock_value as stock_value