Planned Qty logic fixed and reposted for existing
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 19746fc..3e380a5 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -2,9 +2,9 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import frappe
 
-from frappe.utils import flt, nowdate, get_datetime, getdate, date_diff, cint
+from frappe.utils import flt, get_datetime, getdate, date_diff, cint
 from frappe import _
 from frappe.model.document import Document
 from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
@@ -14,6 +14,7 @@
 from erpnext.projects.doctype.time_log.time_log 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
 
 class OverProductionError(frappe.ValidationError): pass
 class StockOverProductionError(frappe.ValidationError): pass
@@ -106,8 +107,7 @@
 	def stop_unstop(self, status):
 		""" Called from client side on Stop/Unstop event"""
 		self.update_status(status)
-		qty = (flt(self.qty)-flt(self.produced_qty)) * ((status == 'Stopped') and -1 or 1)
-		self.update_planned_qty(qty)
+		self.update_planned_qty()
 		frappe.msgprint(_("Production Order status is {0}").format(status))
 		self.notify_modified()
 
@@ -154,30 +154,30 @@
 			frappe.throw(_("For Warehouse is required before Submit"))
 		frappe.db.set(self,'status', 'Submitted')
 		self.make_time_logs()
-		self.update_planned_qty(self.qty)
+		self.update_planned_qty()
 
 
 	def on_cancel(self):
+		self.validate_cancel()
+		
+		frappe.db.set(self,'status', 'Cancelled')
+		self.update_planned_qty()
+		self.delete_time_logs()
+		
+	def validate_cancel(self):
+		if self.status == "Stopped":
+			frappe.throw(_("Stopped Production Order cannot be cancelled, Unstop it first to cancel"))
+		
 		# Check whether any stock entry exists against this Production Order
 		stock_entry = frappe.db.sql("""select name from `tabStock Entry`
 			where production_order = %s and docstatus = 1""", self.name)
 		if stock_entry:
 			frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(stock_entry[0][0]))
 
-		frappe.db.set(self,'status', 'Cancelled')
-		self.update_planned_qty(-self.qty)
-		self.delete_time_logs()
-
-	def update_planned_qty(self, qty):
-		"""update planned qty in bin"""
-		args = {
-			"item_code": self.production_item,
-			"warehouse": self.fg_warehouse,
-			"posting_date": nowdate(),
-			"planned_qty": flt(qty)
-		}
-		from erpnext.stock.utils import update_bin
-		update_bin(args)
+	def update_planned_qty(self):		
+		update_bin_qty(self.production_item, self.fg_warehouse, {
+			"planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)
+		})
 
 	def set_production_order_operations(self):
 		"""Fetch operations from BOM and set in 'Production Order'"""
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b5fa71b..2b4a017 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -205,3 +205,4 @@
 execute:frappe.db.set_value("Stock Settings", None, "automatically_set_serial_nos_based_on_fifo", 1)
 execute:frappe.db.sql("""update `tabProject` set percent_complete=round(percent_complete, 2) where percent_complete is not null""")
 erpnext.patches.v6_0.fix_outstanding_amount
+erpnext.patches.v6_0.fix_planned_qty
\ No newline at end of file
diff --git a/erpnext/patches/v6_0/fix_planned_qty.py b/erpnext/patches/v6_0/fix_planned_qty.py
new file mode 100644
index 0000000..b523350
--- /dev/null
+++ b/erpnext/patches/v6_0/fix_planned_qty.py
@@ -0,0 +1,13 @@
+# 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
+from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
+
+def execute():
+	for item_code, warehouse in frappe.db.sql("""select distinct production_item, fg_warehouse 
+		from `tabProduction Order`"""):
+			update_bin_qty(item_code, warehouse, {
+				"planned_qty": get_planned_qty(item_code, warehouse)
+			})
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index cdfdc78..5f85ef9 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -441,16 +441,7 @@
 			if self.fg_completed_qty:
 				pro_doc.run_method("update_production_order_qty")
 				if self.purpose == "Manufacture":
-					self.update_planned_qty(pro_doc)
-
-	def update_planned_qty(self, pro_doc):
-		from erpnext.stock.utils import update_bin
-		update_bin({
-			"item_code": pro_doc.production_item,
-			"warehouse": pro_doc.fg_warehouse,
-			"posting_date": self.posting_date,
-			"planned_qty": (self.docstatus==1 and -1 or 1 ) * flt(self.fg_completed_qty)
-		})
+					pro_doc.run_method("update_planned_qty")
 
 	def get_item_details(self, args=None, for_update=False):
 		item = frappe.db.sql("""select stock_uom, description, image, item_name,