Requested qty calculation logic
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 25be39d..2d7d4e5 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -47,8 +47,8 @@
 		"on_update": "erpnext.home.make_comment_feed"
 	},
 	"Stock Entry": {
-		"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_qty",
-		"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_qty"
+		"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
+		"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty"
 	},
 	"User": {
 		"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index eeda2ce..cb9552d 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -79,30 +79,9 @@
 		# NOTE: Since Item BOM and FG quantities are combined, using current data, it cannot be validated
 		# Though the creation of Material Request from a Production Plan can be rethought to fix this
 
-	def update_bin(self, is_submit, is_stopped):
-		""" Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'"""
-
-		from erpnext.stock.utils import update_bin
-		for d in self.get('indent_details'):
-			if frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes":
-				if not d.warehouse:
-					frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
-
-				qty =flt(d.qty)
-				if is_stopped:
-					qty = (d.qty > d.ordered_qty) and flt(flt(d.qty) - flt(d.ordered_qty)) or 0
-
-				args = {
-					"item_code": d.item_code,
-					"warehouse": d.warehouse,
-					"indented_qty": (is_submit and 1 or -1) * flt(qty),
-					"posting_date": self.transaction_date
-				}
-				update_bin(args)
-
 	def on_submit(self):
 		frappe.db.set(self, 'status', 'Submitted')
-		self.update_bin(is_submit = 1, is_stopped = 0)
+		self.update_requested_qty()
 
 	def check_modified_date(self):
 		mod_db = frappe.db.sql("""select modified from `tabMaterial Request` where name = %s""",
@@ -115,23 +94,18 @@
 
 	def update_status(self, status):
 		self.check_modified_date()
-		self.update_bin(is_submit = (status == 'Submitted') and 1 or 0, is_stopped = 1)
+		self.update_requested_qty()
 		frappe.db.set(self, 'status', cstr(status))
 		frappe.msgprint(_("Status updated to {0}").format(_(status)))
 
 	def on_cancel(self):
-		# Step 1:=> Get Purchase Common Obj
 		pc_obj = frappe.get_doc('Purchase Common')
 
-		# Step 2:=> Check for stopped status
 		pc_obj.check_for_stopped_status(self.doctype, self.name)
-
-		# Step 3:=> Check if Purchase Order has been submitted against current Material Request
 		pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Order', docname = self.name, detail_doctype = 'Purchase Order Item')
-		# Step 4:=> Update Bin
-		self.update_bin(is_submit = 0, is_stopped = (cstr(self.status) == 'Stopped') and 1 or 0)
 
-		# Step 5:=> Set Status
+		self.update_requested_qty()
+
 		frappe.db.set(self,'status','Cancelled')
 
 	def update_completed_qty(self, mr_items=None):
@@ -162,56 +136,47 @@
 		self.per_ordered = flt((per_ordered / flt(len(item_doclist))) * 100.0, 2)
 		frappe.db.set_value(self.doctype, self.name, "per_ordered", self.per_ordered)
 
-def update_completed_qty(doc, method):
-	if doc.doctype == "Stock Entry":
+	def update_requested_qty(self, mr_item_rows=None):
+		"""update requested qty (before ordered_qty is updated)"""
+		from erpnext.stock.utils import get_bin
+
+		def _update_requested_qty(item_code, warehouse):
+			requested_qty = frappe.db.sql("""select sum(mr_item.qty - ifnull(mr_item.ordered_qty, 0))
+				from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
+				where mr_item.item_code=%s and mr_item.warehouse=%s
+				and mr_item.qty > ifnull(mr_item.ordered_qty, 0) and mr_item.parent=mr.name
+				and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
+
+			bin_doc = get_bin(item_code, warehouse)
+			bin_doc.indented_qty = flt(requested_qty[0][0]) if requested_qty else 0
+			bin_doc.save()
+
+		item_wh_list = []
+		for d in self.get("indent_details"):
+			if (not mr_item_rows or d.name in mr_item_rows) and [d.item_code, d.warehouse] not in item_wh_list \
+					and frappe.db.get_value("Item", d.item_code, "is_stock_item") == "Yes" and d.warehouse:
+				item_wh_list.append([d.item_code, d.warehouse])
+
+		for item_code, warehouse in item_wh_list:
+			_update_requested_qty(item_code, warehouse)
+
+def update_completed_and_requested_qty(stock_entry, method):
+	if stock_entry.doctype == "Stock Entry":
 		material_request_map = {}
 
-		for d in doc.get("mtn_details"):
+		for d in stock_entry.get("mtn_details"):
 			if d.material_request:
 				material_request_map.setdefault(d.material_request, []).append(d.material_request_item)
 
-		for mr_name, mr_items in material_request_map.items():
-			mr_obj = frappe.get_doc("Material Request", mr_name)
+		for mr, mr_item_rows in material_request_map.items():
+			if mr and mr_item_rows:
+				mr_obj = frappe.get_doc("Material Request", mr)
 
-			if mr_obj.status in ["Stopped", "Cancelled"]:
-				frappe.throw(_("Material Request {0} is cancelled or stopped").format(mr_obj.name),
-					frappe.InvalidStatusError)
+				if mr_obj.status in ["Stopped", "Cancelled"]:
+					frappe.throw(_("Material Request {0} is cancelled or stopped").format(mr), frappe.InvalidStatusError)
 
-			_update_requested_qty(doc, mr_obj, mr_items)
-
-			# update ordered percentage and qty
-			mr_obj.update_completed_qty(mr_items)
-
-def _update_requested_qty(doc, mr_obj, mr_items):
-	"""update requested qty (before ordered_qty is updated)"""
-	from erpnext.stock.utils import update_bin
-	for mr_item_name in mr_items:
-		mr_item = mr_obj.get("indent_details", {"name": mr_item_name})
-		se_detail = doc.get("mtn_details", {"material_request": mr_obj.name,
-			"material_request_item": mr_item_name})
-
-		if mr_item and se_detail:
-			mr_item = mr_item[0]
-			se_detail = se_detail[0]
-			mr_item.ordered_qty = flt(mr_item.ordered_qty)
-			mr_item.qty = flt(mr_item.qty)
-			se_detail.transfer_qty = flt(se_detail.transfer_qty)
-
-			if se_detail.docstatus == 2 and mr_item.ordered_qty > mr_item.qty \
-					and se_detail.transfer_qty == mr_item.ordered_qty:
-				add_indented_qty = mr_item.qty
-			elif se_detail.docstatus == 1 and \
-					mr_item.ordered_qty + se_detail.transfer_qty > mr_item.qty:
-				add_indented_qty = mr_item.qty - mr_item.ordered_qty
-			else:
-				add_indented_qty = se_detail.transfer_qty
-
-			update_bin({
-				"item_code": se_detail.item_code,
-				"warehouse": se_detail.t_warehouse,
-				"indented_qty": (se_detail.docstatus==2 and 1 or -1) * add_indented_qty,
-				"posting_date": doc.posting_date,
-			})
+				mr_obj.update_completed_qty(mr_item_rows)
+				mr_obj.update_requested_qty(mr_item_rows)
 
 def set_missing_values(source, target_doc):
 	target_doc.run_method("set_missing_values")
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index 04b7793..ab1d3cc 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -58,12 +58,6 @@
 		self.assertEquals(se.doctype, "Stock Entry")
 		self.assertEquals(len(se.get("mtn_details")), len(mr.get("indent_details")))
 
-	def _test_requested_qty(self, qty1, qty2):
-		self.assertEqual(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item Home Desktop 100",
-			"warehouse": "_Test Warehouse - _TC"}, "indented_qty")), qty1)
-		self.assertEqual(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item Home Desktop 200",
-			"warehouse": "_Test Warehouse - _TC"}, "indented_qty")), qty2)
-
 	def _insert_stock_entry(self, qty1, qty2):
 		se = frappe.get_doc({
 				"company": "_Test Company",
@@ -103,7 +97,8 @@
 		se.submit()
 
 	def test_completed_qty_for_purchase(self):
-		frappe.db.sql("""delete from `tabBin`""")
+		existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		existing_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
 		# submit material request of type Purchase
 		mr = frappe.copy_doc(test_records[0])
@@ -115,8 +110,6 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 0)
 
-		self._test_requested_qty(54.0, 3.0)
-
 		# map a purchase order
 		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
 		po_doc = make_purchase_order(mr.name)
@@ -149,7 +142,12 @@
 		self.assertEquals(mr.per_ordered, 50)
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 27.0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 1.5)
-		self._test_requested_qty(27.0, 1.5)
+
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 27.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 1.5)
 
 		po.cancel()
 		# check if per complete is as expected
@@ -158,11 +156,15 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, None)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, None)
 
-		self._test_requested_qty(54.0, 3.0)
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 	def test_completed_qty_for_transfer(self):
-		frappe.db.sql("""delete from `tabBin`""")
-		frappe.db.sql("""delete from `tabStock Ledger Entry`""")
+		existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		existing_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
 		# submit material request of type Purchase
 		mr = frappe.copy_doc(test_records[0])
@@ -175,7 +177,11 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 0)
 
-		self._test_requested_qty(54.0, 3.0)
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
 
@@ -226,7 +232,11 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 27.0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 1.5)
 
-		self._test_requested_qty(27.0, 1.5)
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 27.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 1.5)
 
 		# check if per complete is as expected for Stock Entry cancelled
 		se.cancel()
@@ -235,11 +245,15 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 0)
 
-		self._test_requested_qty(54.0, 3.0)
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 	def test_completed_qty_for_over_transfer(self):
-		frappe.db.sql("""delete from `tabBin`""")
-		frappe.db.sql("""delete from `tabStock Ledger Entry`""")
+		existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		existing_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
 		# submit material request of type Purchase
 		mr = frappe.copy_doc(test_records[0])
@@ -252,8 +266,6 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 0)
 
-		self._test_requested_qty(54.0, 3.0)
-
 		# map a stock entry
 		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
 
@@ -297,7 +309,12 @@
 		self.assertEquals(mr.per_ordered, 100)
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 60.0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 3.0)
-		self._test_requested_qty(0.0, 0.0)
+
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2)
 
 		# check if per complete is as expected for Stock Entry cancelled
 		se.cancel()
@@ -306,7 +323,11 @@
 		self.assertEquals(mr.get("indent_details")[0].ordered_qty, 0)
 		self.assertEquals(mr.get("indent_details")[1].ordered_qty, 0)
 
-		self._test_requested_qty(54.0, 3.0)
+		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
+		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
+
+		self.assertEquals(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEquals(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 	def test_incorrect_mapping_of_stock_entry(self):
 		# submit material request of type Purchase
@@ -348,5 +369,9 @@
 		mr.company = "_Test Company 1"
 		self.assertRaises(InvalidWarehouseCompany, mr.insert)
 
+	def _get_requested_qty(self, item_code, warehouse):
+		return flt(frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, "indented_qty"))
+
+
 test_dependencies = ["Currency Exchange"]
 test_records = frappe.get_test_records('Material Request')
diff --git a/erpnext/utilities/repost_stock.py b/erpnext/utilities/repost_stock.py
index f1ba179..b63493e 100644
--- a/erpnext/utilities/repost_stock.py
+++ b/erpnext/utilities/repost_stock.py
@@ -93,11 +93,11 @@
 	return flt(reserved_qty[0][0]) if reserved_qty else 0
 
 def get_indented_qty(item_code, warehouse):
-	indented_qty = frappe.db.sql("""select sum(pr_item.qty - ifnull(pr_item.ordered_qty, 0))
-		from `tabMaterial Request Item` pr_item, `tabMaterial Request` pr
-		where pr_item.item_code=%s and pr_item.warehouse=%s
-		and pr_item.qty > ifnull(pr_item.ordered_qty, 0) and pr_item.parent=pr.name
-		and pr.status!='Stopped' and pr.docstatus=1""", (item_code, warehouse))
+	indented_qty = frappe.db.sql("""select sum(mr_item.qty - ifnull(mr_item.ordered_qty, 0))
+		from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
+		where mr_item.item_code=%s and mr_item.warehouse=%s
+		and mr_item.qty > ifnull(mr_item.ordered_qty, 0) and mr_item.parent=mr.name
+		and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
 
 	return flt(indented_qty[0][0]) if indented_qty else 0