[production] update planned and produced ty
diff --git a/manufacturing/doctype/production_order/production_order.py b/manufacturing/doctype/production_order/production_order.py
index 719d149..b29b0f1 100644
--- a/manufacturing/doctype/production_order/production_order.py
+++ b/manufacturing/doctype/production_order/production_order.py
@@ -18,6 +18,9 @@
 		self.doclist = doclist
 
 	def validate(self):
+		if self.doc.docstatus == 0:
+			self.doc.status = "Draft"
+			
 		import utilities
 		utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", 
 			"In Process", "Completed", "Cancelled"])
@@ -149,12 +152,6 @@
 @webnotes.whitelist()
 def make_stock_entry(production_order_id, purpose):
 	production_order = webnotes.bean("Production Order", production_order_id)
-	
-	# validate already existing
-	ste = webnotes.conn.get_value("Stock Entry",  {
-		"production_order":production_order_id,
-		"purpose": purpose
-	}, "name")
 		
 	stock_entry = webnotes.new_bean("Stock Entry")
 	stock_entry.doc.purpose = purpose
@@ -171,4 +168,4 @@
 		stock_entry.doc.to_warehouse = production_order.doc.fg_warehouse
 		
 	stock_entry.run_method("get_items")
-	return [d.fields for d in stock_entry.doclist]
+	return [d.fields for d in stock_entry.doclist]
\ No newline at end of file
diff --git a/manufacturing/doctype/production_order/test_production_order.py b/manufacturing/doctype/production_order/test_production_order.py
new file mode 100644
index 0000000..9a75762
--- /dev/null
+++ b/manufacturing/doctype/production_order/test_production_order.py
@@ -0,0 +1,75 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+
+from __future__ import unicode_literals
+import unittest
+import webnotes
+from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
+from manufacturing.doctype.production_order.production_order import make_stock_entry
+
+
+class TestProductionOrder(unittest.TestCase):
+	def test_planned_qty(self):
+		set_perpetual_inventory(0)
+		webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+		webnotes.conn.sql("""delete from `tabBin`""")
+		webnotes.conn.sql("""delete from `tabGL Entry`""")
+		
+		pro_bean = webnotes.bean(copy = test_records[0])
+		pro_bean.insert()
+		pro_bean.submit()
+		
+		from stock.doctype.stock_entry.test_stock_entry import test_records as se_test_records
+		mr1 = webnotes.bean(copy = se_test_records[0])
+		mr1.insert()
+		mr1.submit()
+		
+		mr2 = webnotes.bean(copy = se_test_records[0])
+		mr2.doclist[1].item_code = "_Test Item Home Desktop 100"
+		mr2.insert()
+		mr2.submit()
+		
+		stock_entry = make_stock_entry(pro_bean.doc.name, "Manufacture/Repack")
+		stock_entry = webnotes.bean(stock_entry)
+		
+		stock_entry.doc.fg_completed_qty = 4
+		stock_entry.run_method("get_items")
+		stock_entry.submit()
+		
+		self.assertEqual(webnotes.conn.get_value("Production Order", pro_bean.doc.name, 
+			"produced_qty"), 4)
+		self.assertEqual(webnotes.conn.get_value("Bin", {"item_code": "_Test FG Item", 
+			"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"), 6)
+			
+		return pro_bean.doc.name
+			
+	def test_over_production(self):
+		from stock.doctype.stock_entry.stock_entry import StockOverProductionError
+		pro_order = self.test_planned_qty()
+		
+		stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
+		stock_entry = webnotes.bean(stock_entry)
+		
+		stock_entry.doc.fg_completed_qty = 15
+		stock_entry.run_method("get_items")
+		stock_entry.insert()
+		
+		self.assertRaises(StockOverProductionError, stock_entry.submit)
+			
+		
+
+test_records = [
+	[
+		{
+			"bom_no": "BOM/_Test FG Item/001", 
+			"company": "_Test Company", 
+			"doctype": "Production Order", 
+			"production_item": "_Test FG Item", 
+			"qty": 10.0, 
+			"fg_warehouse": "_Test Warehouse 1 - _TC",
+			"wip_warehouse": "_Test Warehouse - _TC",
+			"stock_uom": "Nos"
+		}
+	]
+]
\ No newline at end of file
diff --git a/patches/december_2012/repost_ordered_qty.py b/patches/december_2012/repost_ordered_qty.py
index e73b726..4c1d11d 100644
--- a/patches/december_2012/repost_ordered_qty.py
+++ b/patches/december_2012/repost_ordered_qty.py
@@ -3,19 +3,9 @@
 
 def execute():
 	import webnotes
-	from webnotes.utils import flt
-
-	for d in webnotes.conn.sql("select name, item_code, warehouse, ordered_qty from tabBin", 
-			as_dict=1):
-		ordered_qty = webnotes.conn.sql("""
-			select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
-			from `tabPurchase Order Item` po_item, `tabPurchase Order` po
-			where po_item.item_code=%s and po_item.warehouse=%s 
-			and po_item.qty > po_item.received_qty and po_item.parent=po.name 
-			and po.status!='Stopped' and po.docstatus=1""", (d.item_code, d.warehouse))
+	from utilities.repost_stock import get_ordered_qty, update_bin
 			
-		if flt(d.ordered_qty) != flt(ordered_qty[0][0]):
-			webnotes.conn.set_value("Bin", d.name, "ordered_qty", flt(ordered_qty[0][0]))
-			
-			webnotes.conn.sql("""update tabBin set projected_qty = actual_qty + planned_qty + 
-				indented_qty + ordered_qty - reserved_qty where name = %s""", d.name)
\ No newline at end of file
+	for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+		update_bin(d[0], d[1], {
+			"ordered_qty": get_ordered_qty(d[0], d[1])
+		})
\ No newline at end of file
diff --git a/patches/february_2013/repost_reserved_qty.py b/patches/february_2013/repost_reserved_qty.py
index 3a3353f..5c41266 100644
--- a/patches/february_2013/repost_reserved_qty.py
+++ b/patches/february_2013/repost_reserved_qty.py
@@ -4,54 +4,10 @@
 import webnotes
 def execute():
 	webnotes.conn.auto_commit_on_many_writes = 1
-	repost_reserved_qty()
-	webnotes.conn.auto_commit_on_many_writes = 0
+	from utilities.repost_stock import get_reserved_qty, update_bin
 	
-def repost_reserved_qty():
-	from webnotes.utils import flt
-	bins = webnotes.conn.sql("select item_code, warehouse, name, reserved_qty from `tabBin`")
-	i = 0
-	for d in bins:
-		i += 1
-		reserved_qty = webnotes.conn.sql("""
-			select 
-				sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
-			from 
-				(
-					(select
-						qty as dnpi_qty,
-						(
-							select qty from `tabSales Order Item`
-							where name = dnpi.parent_detail_docname
-						) as so_item_qty,
-						(
-							select ifnull(delivered_qty, 0) from `tabSales Order Item`
-							where name = dnpi.parent_detail_docname
-						) as so_item_delivered_qty, 
-						parent, name
-					from 
-					(
-						select qty, parent_detail_docname, parent, name
-						from `tabDelivery Note Packing Item` dnpi_in
-						where item_code = %s and warehouse = %s
-						and parenttype="Sales Order"
-					and item_code != parent_item
-						and exists (select * from `tabSales Order` so
-						where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
-					) dnpi)
-				union
-					(select qty as dnpi_qty, qty as so_item_qty,
-						ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
-					from `tabSales Order Item` so_item
-					where item_code = %s and reserved_warehouse = %s 
-					and exists(select * from `tabSales Order` so
-						where so.name = so_item.parent and so.docstatus = 1 
-						and so.status != 'Stopped'))
-				) tab
-			where 
-				so_item_qty >= so_item_delivered_qty
-		""", (d[0], d[1], d[0], d[1]))
-		
-		if flt(d[3]) != flt(reserved_qty[0][0]):
-			webnotes.conn.sql("""update `tabBin` set reserved_qty = %s where name = %s""",
-				(reserved_qty and reserved_qty[0][0] or 0, d[2]))
\ No newline at end of file
+	for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+		update_bin(d[0], d[1], {
+			"reserved_qty": get_reserved_qty(d[0], d[1])
+		})
+	webnotes.conn.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/patches/october_2013/repost_planned_qty.py b/patches/october_2013/repost_planned_qty.py
new file mode 100644
index 0000000..cfe47ca
--- /dev/null
+++ b/patches/october_2013/repost_planned_qty.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+def execute():
+	import webnotes
+	from utilities.repost_stock import get_planned_qty, update_bin
+	
+	for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+		update_bin(d[0], d[1], {
+			"planned_qty": get_planned_qty(d[0], d[1])
+		})
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index 6a5d0f4..59e0b0c 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -221,4 +221,5 @@
 	"patches.september_2013.p05_fix_customer_in_pos",
 	"patches.october_2013.fix_is_cancelled_in_sle",
 	"patches.october_2013.repost_ordered_qty",
+	"patches.october_2013.repost_planned_qty",
 ]
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 8d2e764..7d8130c 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -6,7 +6,7 @@
 import webnotes.defaults
 
 from webnotes.utils import cstr, cint, flt, comma_or, nowdate
-from webnotes.model.doc import Document, addchild
+from webnotes.model.doc import addchild
 from webnotes.model.bean import getlist
 from webnotes.model.code import get_obj
 from webnotes import msgprint, _
@@ -21,6 +21,7 @@
 class StockOverReturnError(webnotes.ValidationError): pass
 class IncorrectValuationRateError(webnotes.ValidationError): pass
 class DuplicateEntryForProductionOrderError(webnotes.ValidationError): pass
+class StockOverProductionError(webnotes.ValidationError): pass
 	
 from controllers.stock_controller import StockController
 
@@ -56,12 +57,12 @@
 		from stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
 		update_serial_nos_after_submit(self, "Stock Entry", "mtn_details")
 		
-		self.update_production_order(1)
+		self.update_production_order()
 		self.make_gl_entries()
 
 	def on_cancel(self):
 		self.update_stock_ledger()
-		self.update_production_order(0)
+		self.update_production_order()
 		self.make_cancel_gl_entries()
 		
 	def validate_fiscal_year(self):
@@ -326,37 +327,44 @@
 				
 		self.make_sl_entries(sl_entries, self.doc.amended_from and 'Yes' or 'No')
 
-	def update_production_order(self, is_submit):
+	def update_production_order(self):
+		def _validate_production_order(pro_bean):
+			if flt(pro_bean.doc.docstatus) != 1:
+				webnotes.throw(_("Production Order must be submitted") + ": " + 
+					self.doc.production_order)
+					
+			if pro_bean.doc.status == 'Stopped':
+				msgprint(_("Transaction not allowed against stopped Production Order") + ": " + 
+					self.doc.production_order)
+		
 		if self.doc.production_order:
-			# first perform some validations
-			# (they are here coz this fn is also called during on_cancel)
-			pro_obj = get_obj("Production Order", self.doc.production_order)
-			if flt(pro_obj.doc.docstatus) != 1:
-				msgprint("""You cannot do any transaction against 
-					Production Order : %s, as it's not submitted"""
-					% (pro_obj.doc.name), raise_exception=1)
-					
-			if pro_obj.doc.status == 'Stopped':
-				msgprint("""You cannot do any transaction against Production Order : %s, 
-					as it's status is 'Stopped'"""% (pro_obj.doc.name), raise_exception=1)
-					
-			# update bin
-			if self.doc.purpose == "Manufacture/Repack":
-				from stock.utils import update_bin
-				pro_obj.doc.produced_qty = flt(pro_obj.doc.produced_qty) + \
-					(is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty)
-				args = {
-					"item_code": pro_obj.doc.production_item,
-					"warehouse": pro_obj.doc.fg_warehouse,
-					"posting_date": self.doc.posting_date,
-					"planned_qty": (is_submit and -1 or 1 ) * flt(self.doc.fg_completed_qty)
-				}
-				update_bin(args)
+			pro_bean = webnotes.bean("Production Order", self.doc.production_order)
+			_validate_production_order(pro_bean)
+			self.update_produced_qty(pro_bean)
+			self.update_planned_qty(pro_bean)
 			
-			# update production order status
-			pro_obj.doc.status = (flt(pro_obj.doc.qty)==flt(pro_obj.doc.produced_qty)) \
-				and 'Completed' or 'In Process'
-			pro_obj.doc.save()
+	def update_produced_qty(self, pro_bean):
+		if self.doc.purpose == "Manufacture/Repack":
+			produced_qty = flt(pro_bean.doc.produced_qty) + \
+				(self.doc.docstatus==1 and 1 or -1 ) * flt(self.doc.fg_completed_qty)
+				
+			if produced_qty > flt(pro_bean.doc.qty):
+				webnotes.throw(_("Production Order") + ": " + self.doc.production_order + "\n" +
+					_("Total Manufactured Qty can not be greater than Planned qty to manufacture") 
+					+ "(%s/%s)" % (produced_qty, flt(pro_bean.doc.qty)), StockOverProductionError)
+					
+			status = 'Completed' if flt(produced_qty) >= flt(pro_bean.doc.qty) else 'In Process'
+			webnotes.conn.sql("""update `tabProduction Order` set status=%s, produced_qty=%s 
+				where name=%s""", (status, produced_qty, self.doc.production_order))
+			
+	def update_planned_qty(self, pro_bean):
+		from stock.utils import update_bin
+		update_bin({
+			"item_code": pro_bean.doc.production_item,
+			"warehouse": pro_bean.doc.fg_warehouse,
+			"posting_date": self.doc.posting_date,
+			"planned_qty": (self.doc.docstatus==1 and -1 or 1 ) * flt(self.doc.fg_completed_qty)
+		})
 					
 	def get_item_details(self, arg):
 		arg = json.loads(arg)
@@ -415,7 +423,8 @@
 		return ret
 		
 	def get_items(self):
-		self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
+		self.doclist = filter(lambda d: d.parentfield!="mtn_details", self.doclist)
+		# self.doclist = self.doc.clear_table(self.doclist, 'mtn_details')
 		
 		pro_obj = None
 		if self.doc.production_order:
@@ -454,7 +463,7 @@
 						"stock_uom": pro_obj.doc.stock_uom
 					}
 				}, bom_no=pro_obj.doc.bom_no)
-				
+								
 			elif self.doc.purpose in ["Material Receipt", "Manufacture/Repack"]:
 				if self.doc.purpose=="Material Receipt":
 					self.doc.from_warehouse = ""
@@ -471,6 +480,7 @@
 				}, bom_no=self.doc.bom_no)
 		
 		self.get_stock_and_rate()
+		
 	
 	def get_bom_raw_materials(self, qty):
 		""" 
diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py
index 58cf11b..476a6f6 100644
--- a/stock/doctype/warehouse/warehouse.py
+++ b/stock/doctype/warehouse/warehouse.py
@@ -5,7 +5,6 @@
 import webnotes
 
 from webnotes.utils import cint, flt, validate_email_add
-from webnotes.model.code import get_obj
 from webnotes import msgprint, _
 
 sql = webnotes.conn.sql
@@ -83,103 +82,15 @@
 			
 		webnotes.conn.delete_doc("Account", old_warehouse_account)
 		
+		from utilities.repost_stock import repost
 		for item_code in items:
-			self.repost(item_code[0], self.doc.merge_with)
+			repost(item_code[0], self.doc.merge_with)
 			
 		webnotes.conn.auto_commit_on_many_writes = 0
 		
 		msgprint("Warehouse %s merged into %s. Now you can delete warehouse: %s" 
 			% (self.doc.name, self.doc.merge_with, self.doc.name))
 		
-
-	def repost(self, item_code, warehouse=None):
-		from stock.utils import get_bin
-		self.repost_actual_qty(item_code, warehouse)
-		
-		bin = get_bin(item_code, warehouse)
-		self.repost_reserved_qty(bin)
-		self.repost_indented_qty(bin)
-		self.repost_ordered_qty(bin)
-		self.repost_planned_qty(bin)
-		bin.doc.projected_qty = flt(bin.doc.actual_qty) + flt(bin.doc.planned_qty) \
-			+ flt(bin.doc.indented_qty) + flt(bin.doc.ordered_qty) - flt(bin.doc.reserved_qty)
-		bin.doc.save()
-			
-
-	def repost_actual_qty(self, item_code, warehouse=None):
-		from stock.stock_ledger import update_entries_after
-		if not warehouse:
-			warehouse = self.doc.name
-		
-		update_entries_after({ "item_code": item_code, "warehouse": warehouse })
-
-	def repost_reserved_qty(self, bin):
-		reserved_qty = webnotes.conn.sql("""
-			select 
-				sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
-			from 
-				(
-					select
-						qty as dnpi_qty,
-						(
-							select qty from `tabSales Order Item`
-							where name = dnpi.parent_detail_docname
-						) as so_item_qty,
-						(
-							select ifnull(delivered_qty, 0) from `tabSales Order Item`
-							where name = dnpi.parent_detail_docname
-						) as so_item_delivered_qty
-					from 
-					(
-						select qty, parent_detail_docname
-						from `tabDelivery Note Packing Item` dnpi_in
-						where item_code = %s and warehouse = %s
-						and parenttype="Sales Order"
-						and exists (select * from `tabSales Order` so
-						where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
-					) dnpi
-				) tab 
-			where 
-				so_item_qty >= so_item_delivered_qty
-		""", (bin.doc.item_code, bin.doc.warehouse))
-
-		if flt(bin.doc.reserved_qty) != flt(reserved_qty[0][0]):
-			webnotes.conn.set_value("Bin", bin.doc.name, "reserved_qty", flt(reserved_qty[0][0]))
-
-
-	def repost_indented_qty(self, bin):
-		indented_qty = webnotes.conn.sql("""select sum(pr_item.qty - pr_item.ordered_qty)
-			from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr
-			where pr_item.item_code=%s and pr_item.warehouse=%s 
-			and pr_item.qty > pr_item.ordered_qty and pr_item.parent=pr.name 
-			and pr.status!='Stopped' and pr.docstatus=1"""
-			, (bin.doc.item_code, bin.doc.warehouse))
-			
-		if flt(bin.doc.indented_qty) != flt(indented_qty[0][0]):
-			webnotes.conn.set_value("Bin", bin.doc.name, "indented_qty", flt(indented_qty[0][0]))
-		
-	
-	def repost_ordered_qty(self, bin):
-		ordered_qty = webnotes.conn.sql("""
-			select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
-			from `tabPurchase Order Item` po_item, `tabPurchase Order` po
-			where po_item.item_code=%s and po_item.warehouse=%s 
-			and po_item.qty > po_item.received_qty and po_item.parent=po.name 
-			and po.status!='Stopped' and po.docstatus=1"""
-			, (bin.doc.item_code, bin.doc.warehouse))
-			
-		if flt(bin.doc.ordered_qty) != flt(ordered_qty[0][0]):
-			webnotes.conn.set_value("Bin", bin.doc.name, "ordered_qty", flt(ordered_qty[0][0]))
-
-	def repost_planned_qty(self, bin):
-		planned_qty = webnotes.conn.sql("""
-			select sum(qty - produced_qty) from `tabProduction Order` 
-			where production_item = %s and fg_warehouse = %s and status != "Stopped"
-			and docstatus=1""", (bin.doc.item_code, bin.doc.warehouse))
-
-		if flt(bin.doc.planned_qty) != flt(planned_qty[0][0]):
-			webnotes.conn.set_value("Bin", bin.doc.name, "planned_qty", flt(planned_qty[0][0]))
-
 	def on_trash(self):
 		# delete bin
 		bins = sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1)
diff --git a/stock/utils.py b/stock/utils.py
index 983ee72..0f801c7 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -393,13 +393,4 @@
 		Administrator""" % ("\n\n".join(["\n".join(msg) for msg in exceptions_list]),)
 
 	from webnotes.profile import get_system_managers
-	sendmail(get_system_managers(), subject=subject, msg=msg)
-
-
-def repost():
-	"""
-	Repost everything!
-	"""
-	from webnotes.model.code import get_obj
-	for wh in webnotes.conn.sql("select name from tabWarehouse"):
-		get_obj('Warehouse', wh[0]).repost_stock()
+	sendmail(get_system_managers(), subject=subject, msg=msg)
\ No newline at end of file
diff --git a/utilities/repost_stock.py b/utilities/repost_stock.py
new file mode 100644
index 0000000..b46aae6
--- /dev/null
+++ b/utilities/repost_stock.py
@@ -0,0 +1,119 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+from webnotes.utils import flt
+
+
+def repost():
+	"""
+	Repost everything!
+	"""
+	webnotes.conn.auto_commit_on_many_writes = 1
+	
+	for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
+		repost_stock(d[0], d[1])
+		
+	webnotes.conn.auto_commit_on_many_writes = 0
+
+def repost_stock(item_code, warehouse):
+	repost_actual_qty(item_code, warehouse)
+	
+	if item_code and warehouse:
+		update_bin(item_code, warehouse, {
+			"reserved_qty": get_reserved_qty(item_code, warehouse),
+			"indented_qty": get_indented_qty(item_code, warehouse),
+			"ordered_qty": get_ordered_qty(item_code, warehouse),
+			"planned_qty": get_planned_qty(item_code, warehouse)
+		})
+
+def repost_actual_qty(item_code, warehouse):
+	from stock.stock_ledger import update_entries_after
+	update_entries_after({ "item_code": item_code, "warehouse": warehouse })
+
+def get_reserved_qty(item_code, warehouse):
+	reserved_qty = webnotes.conn.sql("""
+		select 
+			sum((dnpi_qty / so_item_qty) * (so_item_qty - so_item_delivered_qty))
+		from 
+			(
+				(select
+					qty as dnpi_qty,
+					(
+						select qty from `tabSales Order Item`
+						where name = dnpi.parent_detail_docname
+					) as so_item_qty,
+					(
+						select ifnull(delivered_qty, 0) from `tabSales Order Item`
+						where name = dnpi.parent_detail_docname
+					) as so_item_delivered_qty, 
+					parent, name
+				from 
+				(
+					select qty, parent_detail_docname, parent, name
+					from `tabDelivery Note Packing Item` dnpi_in
+					where item_code = %s and warehouse = %s
+					and parenttype="Sales Order"
+				and item_code != parent_item
+					and exists (select * from `tabSales Order` so
+					where name = dnpi_in.parent and docstatus = 1 and status != 'Stopped')
+				) dnpi)
+			union
+				(select qty as dnpi_qty, qty as so_item_qty,
+					ifnull(delivered_qty, 0) as so_item_delivered_qty, parent, name
+				from `tabSales Order Item` so_item
+				where item_code = %s and reserved_warehouse = %s 
+				and exists(select * from `tabSales Order` so
+					where so.name = so_item.parent and so.docstatus = 1 
+					and so.status != 'Stopped'))
+			) tab
+		where 
+			so_item_qty >= so_item_delivered_qty
+	""", (item_code, warehouse, item_code, warehouse))
+
+	return flt(reserved_qty[0][0]) if reserved_qty else 0
+	
+def get_indented_qty(item_code, warehouse):
+	indented_qty = webnotes.conn.sql("""select sum(pr_item.qty - pr_item.ordered_qty)
+		from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr
+		where pr_item.item_code=%s and pr_item.warehouse=%s 
+		and pr_item.qty > pr_item.ordered_qty and pr_item.parent=pr.name 
+		and pr.status!='Stopped' and pr.docstatus=1""", (item_code, warehouse))
+		
+	return flt(indented_qty[0][0]) if indented_qty else 0
+
+def get_ordered_qty(item_code, warehouse):
+	ordered_qty = webnotes.conn.sql("""
+		select sum((po_item.qty - po_item.received_qty)*po_item.conversion_factor)
+		from `tabPurchase Order Item` po_item, `tabPurchase Order` po
+		where po_item.item_code=%s and po_item.warehouse=%s 
+		and po_item.qty > po_item.received_qty and po_item.parent=po.name 
+		and po.status!='Stopped' and po.docstatus=1""", (item_code, warehouse))
+		
+	return flt(ordered_qty[0][0]) if ordered_qty else 0
+			
+def get_planned_qty(item_code, warehouse):
+	planned_qty = webnotes.conn.sql("""
+		select sum(qty - produced_qty) from `tabProduction Order` 
+		where production_item = %s and fg_warehouse = %s and status != "Stopped"
+		and docstatus=1 and qty > produced_qty""", (item_code, warehouse))
+
+	return flt(planned_qty[0][0]) if planned_qty else 0
+	
+	
+def update_bin(item_code, warehouse, qty_dict=None):
+	from stock.utils import get_bin
+	bin = get_bin(item_code, warehouse)
+	mismatch = False
+	for fld, val in qty_dict.items():
+		if flt(bin.doc.fields.get(fld)) != flt(val):
+			bin.doc.fields[fld] = flt(val)
+			mismatch = True
+			
+	if mismatch:
+		bin.doc.projected_qty = flt(bin.doc.actual_qty) + flt(bin.doc.ordered_qty) + \
+			flt(bin.doc.indented_qty) + flt(bin.doc.planned_qty) - flt(bin.doc.reserved_qty)
+	
+		bin.doc.save()
\ No newline at end of file