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/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