Merge pull request #3215 from neilLasrado/prod-order

Production Order - Fixed cost not considering qty issue
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 60ecd03..3781450 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -189,6 +189,10 @@
 			method: "set_production_order_operations"
 		});
 	},
+	
+	qty: function() {
+		frappe.ui.form.trigger("Production Order", 'bom_no')
+	},
 
 	show_time_logs: function(doc, cdt, cdn) {
 		var child = locals[cdt][cdn]
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 9d17cf6..62eb400 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -63,6 +63,7 @@
 	def calculate_operating_cost(self):
 		self.planned_operating_cost, self.actual_operating_cost = 0.0, 0.0
 		for d in self.get("operations"):
+			d.planned_operating_cost = flt(d.hour_rate) * (flt(d.time_in_mins) / 60.0)
 			d.actual_operating_cost = flt(d.hour_rate) * (flt(d.actual_operation_time) / 60.0)
 
 			self.planned_operating_cost += flt(d.planned_operating_cost)
@@ -175,14 +176,20 @@
 		self.set('operations', [])
 
 		operations = frappe.db.sql("""select operation, description, workstation, idx,
-			hour_rate, time_in_mins, operating_cost as "planned_operating_cost", "Pending" as status
-			from `tabBOM Operation` where parent = %s order by idx""", self.bom_no, as_dict=1)
+			hour_rate, time_in_mins, "Pending" as status from `tabBOM Operation` 
+			where parent = %s order by idx""", self.bom_no, as_dict=1)
 
 		self.set('operations', operations)
-
+		self.calculate_time()
+		
+	def calculate_time(self):
+		bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
+		
+		for d in self.get("operations"):
+			d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * flt(self.qty)
+			
 		self.calculate_operating_cost()
 
-
 	def get_holidays(self, workstation):
 		holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
 
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index db00754..7b6425e 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -125,7 +125,17 @@
 			"docstatus": 0
 		})
 		self.assertRaises(OverProductionLoggedError, time_log2.save)
-
+		
+	def test_planned_operating_cost(self):
+		prod_order = make_prod_order_test_record(item="_Test FG Item 2",
+			planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)
+		prod_order.set_production_order_operations()
+		prod_order.save()
+		cost = prod_order.planned_operating_cost
+		prod_order.qty = 2
+		prod_order.save()
+		self.assertEqual(prod_order.planned_operating_cost, cost*2)
+		
 def make_prod_order_test_record(**args):
 	args = frappe._dict(args)
 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index d857c59..593a2b4 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -150,4 +150,5 @@
 erpnext.patches.v5_0.link_warehouse_with_account
 erpnext.patches.v5_0.rename_taxes_and_charges_master
 execute:frappe.delete_doc("Page", "stock-ledger")
-execute:frappe.delete_doc("Page", "stock-level")
\ No newline at end of file
+execute:frappe.delete_doc("Page", "stock-level")
+erpnext.patches.v5_0.reclculate_planned_operating_cost_in_production_order
diff --git a/erpnext/patches/v5_0/reclculate_planned_operating_cost_in_production_order.py b/erpnext/patches/v5_0/reclculate_planned_operating_cost_in_production_order.py
new file mode 100644
index 0000000..a943c06
--- /dev/null
+++ b/erpnext/patches/v5_0/reclculate_planned_operating_cost_in_production_order.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():					
+	for po in frappe.db.sql("""select name from `tabProduction Order` where docstatus < 2""", as_dict=1):
+		prod_order = frappe.get_doc("Production Order", po.name)
+		if prod_order.operations:
+			prod_order.flags.ignore_validate_update_after_submit = True
+			prod_order.calculate_time()
+			prod_order.save()
\ No newline at end of file