fix: reserved qty for production issue for partial completion of work order
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 0a8f41f..2260bef 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -14,6 +14,7 @@
 from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
 from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
 
 class TestWorkOrder(unittest.TestCase):
 	def setUp(self):
@@ -82,6 +83,37 @@
 		wo_order.set_work_order_operations()
 		self.assertEqual(wo_order.planned_operating_cost, cost*2)
 
+	def test_resered_qty_for_partial_completion(self):
+		item = "_Test Item"
+		warehouse = create_warehouse("Test Warehouse for reserved_qty - _TC")
+
+		bin1_at_start = get_bin(item, warehouse)
+
+		# reset to correct value
+		bin1_at_start.update_reserved_qty_for_production()
+
+		wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2,
+			source_warehouse=warehouse, skip_transfer=1)
+
+		bin1_on_submit = get_bin(item, warehouse)
+
+		# reserved qty for production is updated
+		self.assertEqual(cint(bin1_at_start.reserved_qty_for_production) + 2,
+			cint(bin1_on_submit.reserved_qty_for_production))
+
+		test_stock_entry.make_stock_entry(item_code="_Test Item",
+			target=warehouse, qty=100, basic_rate=100)
+		test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100",
+			target=warehouse, qty=100, basic_rate=100)
+
+		s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1))
+		s.submit()
+
+		bin1_at_completion = get_bin(item, warehouse)
+
+		self.assertEqual(cint(bin1_at_completion.reserved_qty_for_production),
+			cint(bin1_on_submit.reserved_qty_for_production) - 1)
+
 	def test_production_item(self):
 		wo_order = make_wo_order_test_record(item="_Test FG Item", qty=1, do_not_save=True)
 		frappe.db.set_value("Item", "_Test FG Item", "end_of_life", "2000-1-1")
@@ -404,7 +436,7 @@
 	wo_order.company = args.company or "_Test Company"
 	wo_order.stock_uom = args.stock_uom or "_Test UOM"
 	wo_order.use_multi_level_bom=0
-	wo_order.skip_transfer=1
+	wo_order.skip_transfer=args.skip_transfer or 0
 	wo_order.get_items_and_operations_from_bom()
 	wo_order.sales_order = args.sales_order or None
 	wo_order.planned_start_date = args.planned_start_date or now()
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 1df5b3b..98149ae 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -468,6 +468,9 @@
 		update bin reserved_qty_for_production
 		called from Stock Entry for production, after submit, cancel
 		'''
+		# calculate consumed qty based on submitted stock entries
+		self.update_consumed_qty_for_required_items()
+
 		if self.docstatus==1:
 			# calculate transferred qty based on submitted stock entries
 			self.update_transaferred_qty_for_required_items()
@@ -475,9 +478,6 @@
 			# update in bin
 			self.update_reserved_qty_for_production()
 
-		# calculate consumed qty based on submitted stock entries
-		self.update_consumed_qty_for_required_items()
-
 	def update_reserved_qty_for_production(self, items=None):
 		'''update reserved_qty_for_production in bins'''
 		for d in self.required_items:
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 97a8472..73b36e3 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -69,15 +69,21 @@
 		'''Update qty reserved for production from Production Item tables
 			in open work orders'''
 		self.reserved_qty_for_production = frappe.db.sql('''
-			select sum(item.required_qty - item.transferred_qty)
-			from `tabWork Order` pro, `tabWork Order Item` item
-			where
+			SELECT
+				CASE WHEN ifnull(skip_transfer, 0) = 0 THEN
+					SUM(item.required_qty - item.transferred_qty)
+				ELSE
+					SUM(item.required_qty - item.consumed_qty)
+				END
+			FROM `tabWork Order` pro, `tabWork Order Item` item
+			WHERE
 				item.item_code = %s
 				and item.parent = pro.name
 				and pro.docstatus = 1
 				and item.source_warehouse = %s
 				and pro.status not in ("Stopped", "Completed")
-				and item.required_qty > item.transferred_qty''', (self.item_code, self.warehouse))[0][0]
+				and (item.required_qty > item.transferred_qty or item.required_qty > item.consumed_qty)
+		''', (self.item_code, self.warehouse))[0][0]
 
 		self.set_projected_qty()