Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/startup/report_data_map.py b/startup/report_data_map.py
index c2e4023..93995a9 100644
--- a/startup/report_data_map.py
+++ b/startup/report_data_map.py
@@ -117,8 +117,7 @@
 			"(ifnull(qty, 0) - ifnull(ordered_qty, 0)) as qty"],
 		"from": "`tabMaterial Request Item` item, `tabMaterial Request` main",
 		"conditions": ["item.parent = main.name", "main.docstatus=1", "main.status != 'Stopped'",
-			"material_request_type = 'Purchase'", "ifnull(warehouse, '')!=''", 
-			"ifnull(qty, 0) > ifnull(ordered_qty, 0)"],
+			"ifnull(warehouse, '')!=''", "ifnull(qty, 0) > ifnull(ordered_qty, 0)"],
 		"links": {
 			"item_code": ["Item", "name"],
 			"warehouse": ["Warehouse", "name"]
diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py
index 56d1160..37ecf85 100644
--- a/stock/doctype/bin/bin.py
+++ b/stock/doctype/bin/bin.py
@@ -87,7 +87,7 @@
 		if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
 				and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
 			self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
-	
+			
 	def get_first_sle(self):
 		sle = sql("""
 			select * from `tabStock Ledger Entry`
@@ -122,7 +122,8 @@
 				self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty,
 					material_request_type)
 
-	def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, material_request_type):
+	def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty,
+			material_request_type):
 		"""	Create indent on reaching reorder level	"""
 		defaults = webnotes.defaults.get_defaults()
 		item = webnotes.doc("Item", self.doc.item_code)
@@ -175,4 +176,5 @@
 				formatdate(), doc_type, doc_name, bean.doc.doctype, 
 				get_url_to_form(bean.doc.doctype, bean.doc.name))
 		
-		sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg)	
+		sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg)
+		
diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py
index e476aa4..708700d 100644
--- a/stock/doctype/material_request/material_request.py
+++ b/stock/doctype/material_request/material_request.py
@@ -7,7 +7,7 @@
 from webnotes.utils import cstr, flt
 from webnotes.model.bean import getlist
 from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes import msgprint, _
 
 from controllers.buying_controller import BuyingController
 class DocType(BuyingController):
@@ -119,23 +119,22 @@
 	
 	def update_bin(self, is_submit, is_stopped):
 		""" Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'"""
-		if self.doc.material_request_type == "Purchase":
-			for d in getlist(self.doclist, 'indent_details'):
-				if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
-					if not d.warehouse:
-						msgprint("Please Enter Warehouse for Item %s as it is stock item" 
-							% cstr(d.item_code), raise_exception=1)
-						
-					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,
-						"indented_qty": (is_submit and 1 or -1) * flt(qty),
-						"posting_date": self.doc.transaction_date
-					}
-					get_obj('Warehouse', d.warehouse).update_bin(args)		
+		for d in getlist(self.doclist, 'indent_details'):
+			if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+				if not d.warehouse:
+					msgprint("Please Enter Warehouse for Item %s as it is stock item" 
+						% cstr(d.item_code), raise_exception=1)
+					
+				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,
+					"indented_qty": (is_submit and 1 or -1) * flt(qty),
+					"posting_date": self.doc.transaction_date
+				}
+				get_obj('Warehouse', d.warehouse).update_bin(args)		
 		
 	def on_submit(self):
 		purchase_controller = webnotes.get_obj("Purchase Common")
@@ -196,7 +195,7 @@
 					and material_request_item = %s and docstatus = 1""", 
 					(self.doc.name, d.name))[0][0])
 				webnotes.conn.set_value(d.doctype, d.name, "ordered_qty", d.ordered_qty)
-
+				
 			# note: if qty is 0, its row is still counted in len(item_doclist)
 			# hence adding 1 to per_ordered
 			if (d.ordered_qty > d.qty) or not d.qty:
@@ -204,11 +203,9 @@
 			elif d.qty > 0:
 				per_ordered += flt(d.ordered_qty / flt(d.qty))
 		
-		if per_ordered:
-			self.doc.per_ordered = flt((per_ordered / flt(len(item_doclist))) * 100.0, 2)
-			webnotes.conn.set_value(self.doc.doctype, self.doc.name, "per_ordered", self.doc.per_ordered)
-
-
+		self.doc.per_ordered = flt((per_ordered / flt(len(item_doclist))) * 100.0, 2)
+		webnotes.conn.set_value(self.doc.doctype, self.doc.name, "per_ordered", self.doc.per_ordered)
+			
 def update_completed_qty(controller, caller_method):
 	if controller.doc.doctype == "Stock Entry":
 		material_request_map = {}
@@ -218,7 +215,18 @@
 				if d.material_request not in material_request_map:
 					material_request_map[d.material_request] = []
 				material_request_map[d.material_request].append(d.material_request_item)
-
+				webnotes.get_obj("Warehouse", d.t_warehouse).update_bin({
+					"item_code": d.item_code,
+					"indented_qty": (d.docstatus==2 and 1 or -1) * d.transfer_qty,
+					"posting_date": controller.doc.posting_date,
+				})
+			
 		for mr_name, mr_items in material_request_map.items():
-			webnotes.get_obj("Material Request", mr_name, with_children=1).update_completed_qty(mr_items)
-	
\ No newline at end of file
+			mr_obj = webnotes.get_obj("Material Request", mr_name, with_children=1)
+			mr_doctype = webnotes.get_doctype("Material Request")
+			if mr_obj.doc.status in ["Stopped", "Cancelled"]:
+				msgprint(_("Material Request") + ": %s, " % mr_obj.doc.name 
+					+ _(mr_doctype.get_label("status")) + " = %s. " % _(mr_obj.doc.status)
+					+ _("Cannot continue."), raise_exception=True)
+				
+			mr_obj.update_completed_qty(mr_items)
\ No newline at end of file
diff --git a/stock/doctype/material_request/test_material_request.py b/stock/doctype/material_request/test_material_request.py
index 1fa1a9f..3c2f421 100644
--- a/stock/doctype/material_request/test_material_request.py
+++ b/stock/doctype/material_request/test_material_request.py
@@ -10,7 +10,15 @@
 			for fieldname, val in expected.items():
 				self.assertEquals(val, doclist[i].fields.get(fieldname))
 				
+	def _test_requested_qty(self, qty1, qty2):
+		self.assertEqual(webnotes.conn.get_value("Bin", {"item_code": "_Test Item Home Desktop 100",
+			"warehouse": "_Test Warehouse"}, "indented_qty"), qty1)
+		self.assertEqual(webnotes.conn.get_value("Bin", {"item_code": "_Test Item Home Desktop 200",
+			"warehouse": "_Test Warehouse"}, "indented_qty"), qty2)
+				
 	def test_completed_qty_for_purchase(self):
+		webnotes.conn.sql("""delete from `tabBin`""")
+		
 		# submit material request of type Purchase
 		mr = webnotes.bean(copy=test_records[0])
 		mr.insert()
@@ -19,11 +27,12 @@
 		# check if per complete is None
 		self._test_expected(mr.doclist, [{"per_ordered": None}, {"ordered_qty": None}, {"ordered_qty": None}])
 		
+		self._test_requested_qty(54.0, 3.0)
+		
 		# map a purchase order
-		po = webnotes.map_doclist([["Material Request", "Purchase Order"], 
+		po_doclist = webnotes.map_doclist([["Material Request", "Purchase Order"], 
 			["Material Request Item", "Purchase Order Item"]], mr.doc.name)
-		po = webnotes.bean(po)
-		po.doc.fields.update({
+		po_doclist[0].fields.update({
 			"supplier": "_Test Supplier",
 			"supplier_name": "_Test Supplier",
 			"transaction_date": mr.doc.transaction_date,
@@ -32,21 +41,35 @@
 			"conversion_rate": 1.0,
 			"grand_total_import": 0.0
 		})
-		po.doclist[1].qty = 27.0
-		po.doclist[2].qty = 1.5
+		po_doclist[1].qty = 27.0
+		po_doclist[2].qty = 1.5
+		
+		# check for stopped status of Material Request
+		po = webnotes.bean(copy=po_doclist)
+		po.insert()
+		mr.obj.update_status('Stopped')
+		self.assertRaises(webnotes.ValidationError, po.submit)
+		self.assertRaises(webnotes.ValidationError, po.cancel)
+
+		mr.obj.update_status('Submitted')
+		po = webnotes.bean(copy=po_doclist)
 		po.insert()
 		po.submit()
 		
 		# check if per complete is as expected
 		mr.load_from_db()
 		self._test_expected(mr.doclist, [{"per_ordered": 50}, {"ordered_qty": 27.0}, {"ordered_qty": 1.5}])
+		self._test_requested_qty(27.0, 1.5)
 		
 		po.cancel()
 		# check if per complete is as expected
 		mr.load_from_db()
 		self._test_expected(mr.doclist, [{"per_ordered": 0}, {"ordered_qty": 0}, {"ordered_qty": 0}])
+		self._test_requested_qty(54.0, 3.0)
 		
 	def test_completed_qty_for_transfer(self):
+		webnotes.conn.sql("""delete from `tabBin`""")
+		
 		# submit material request of type Purchase
 		mr = webnotes.bean(copy=test_records[0])
 		mr.doc.material_request_type = "Transfer"
@@ -56,33 +79,51 @@
 		# check if per complete is None
 		self._test_expected(mr.doclist, [{"per_ordered": None}, {"ordered_qty": None}, {"ordered_qty": None}])
 		
+		self._test_requested_qty(54.0, 3.0)
+		
 		# map a stock entry
-		se = webnotes.map_doclist([["Material Request", "Stock Entry"], 
+		se_doclist = webnotes.map_doclist([["Material Request", "Stock Entry"], 
 			["Material Request Item", "Stock Entry Detail"]], mr.doc.name)
-		se = webnotes.bean(se)
-		se.doc.fields.update({
+		se_doclist[0].fields.update({
 			"posting_date": "2013-03-01",
 			"posting_time": "00:00"
 		})
-		se.doclist[1].fields.update({
+		se_doclist[1].fields.update({
 			"qty": 27.0,
 			"transfer_qty": 27.0,
 			"s_warehouse": "_Test Warehouse 1",
 			"incoming_rate": 1.0
 		})
-		se.doclist[2].fields.update({
+		se_doclist[2].fields.update({
 			"qty": 1.5,
 			"transfer_qty": 1.5,
 			"s_warehouse": "_Test Warehouse 1",
 			"incoming_rate": 1.0
 		})
+		
+		# check for stopped status of Material Request
+		se = webnotes.bean(copy=se_doclist)
+		se.insert()
+		mr.obj.update_status('Stopped')
+		self.assertRaises(webnotes.ValidationError, se.submit)
+		self.assertRaises(webnotes.ValidationError, se.cancel)
+		
+		mr.obj.update_status('Submitted')
+		se = webnotes.bean(copy=se_doclist)
 		se.insert()
 		se.submit()
 		
 		# check if per complete is as expected
 		mr.load_from_db()
 		self._test_expected(mr.doclist, [{"per_ordered": 50}, {"ordered_qty": 27.0}, {"ordered_qty": 1.5}])
-
+		self._test_requested_qty(27.0, 1.5)
+		
+		# check if per complete is as expected for Stock Entry cancelled
+		se.cancel()
+		mr.load_from_db()
+		self._test_expected(mr.doclist, [{"per_ordered": 0}, {"ordered_qty": 0}, {"ordered_qty": 0}])
+		self._test_requested_qty(54.0, 3.0)
+		
 test_records = [
 	[
 		{
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 342cd6b..78d06ce 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -63,7 +63,7 @@
 		self.update_stock_ledger(1)
 		# update Production Order
 		self.update_production_order(0)
-
+		
 	def validate_purpose(self):
 		valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", 
 			"Manufacture/Repack", "Subcontract", "Sales Return", "Purchase Return"]
diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py
index a7fc185..dc8bfea 100644
--- a/stock/doctype/warehouse/warehouse.py
+++ b/stock/doctype/warehouse/warehouse.py
@@ -207,3 +207,4 @@
 				exists for this warehouse.""", raise_exception=1)
 		else:
 			sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
+