diff --git a/erpnext/controllers/tests/test_subcontracting_controller.py b/erpnext/controllers/tests/test_subcontracting_controller.py
new file mode 100644
index 0000000..ff588be
--- /dev/null
+++ b/erpnext/controllers/tests/test_subcontracting_controller.py
@@ -0,0 +1,1024 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import copy
+from collections import defaultdict
+
+import frappe
+from frappe.tests.utils import FrappeTestCase
+from frappe.utils import cint
+
+from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
+from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+from erpnext.stock.doctype.item.test_item import make_item
+from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
+	get_materials_from_supplier,
+	make_rm_stock_entry,
+	make_subcontracting_receipt,
+)
+
+
+class TestSubcontractingController(FrappeTestCase):
+	def setUp(self):
+		make_subcontracted_items()
+		make_raw_materials()
+		make_service_items()
+		make_bom_for_subcontracted_items()
+
+	def test_remove_empty_rows(self):
+		sco = get_subcontracting_order()
+		len_before = len(sco.service_items)
+		sco.service_items[0].item_code = None
+		sco.remove_empty_rows()
+		self.assertEqual((len_before - 1), len(sco.service_items))
+
+	def test_create_raw_materials_supplied(self):
+		sco = get_subcontracting_order()
+		sco.supplied_items = None
+		sco.create_raw_materials_supplied()
+		self.assertIsNotNone(sco.supplied_items)
+
+	def test_sco_with_bom(self):
+		"""
+		- Set backflush based on BOM.
+		- Create SCO for the item Subcontracted Item SA1 and add same item two times.
+		- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
+		- Create SCR against the SCO and check serial nos and batch no.
+		"""
+
+		set_backflush_based_on("BOM")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA1",
+				"fg_item_qty": 5,
+			},
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 6,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA1",
+				"fg_item_qty": 6,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name if item.get("qty") == 5 else sco.items[1].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+		scr = make_subcontracting_receipt(sco.name)
+		scr.save()
+		scr.submit()
+
+		for key, value in get_supplied_items(scr).items():
+			transferred_detais = itemwise_details.get(key)
+
+			for field in ["qty", "serial_no", "batch_no"]:
+				if value.get(field):
+					transfer, consumed = (transferred_detais.get(field), value.get(field))
+					if field == "serial_no":
+						transfer, consumed = (sorted(transfer), sorted(consumed))
+
+					self.assertEqual(transfer, consumed)
+
+	def test_sco_with_material_transfer(self):
+		"""
+		- Set backflush based on Material Transfer.
+		- Create SCO for the item Subcontracted Item SA1 and Subcontracted Item SA5.
+		- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
+		- Transfer extra item Subcontracted SRM Item 4 for the subcontract item Subcontracted Item SA5.
+		- Create partial SCR against the SCO and check serial nos and batch no.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 1",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA1",
+				"fg_item_qty": 5,
+			},
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 5",
+				"qty": 6,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA5",
+				"fg_item_qty": 6,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		rm_items.append(
+			{
+				"main_item_code": "Subcontracted Item SA5",
+				"item_code": "Subcontracted SRM Item 4",
+				"qty": 6,
+			}
+		)
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name if item.get("qty") == 5 else sco.items[1].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.remove(scr1.items[1])
+		scr1.save()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			transferred_detais = itemwise_details.get(key)
+
+			for field in ["qty", "serial_no", "batch_no"]:
+				if value.get(field):
+					self.assertEqual(value.get(field), transferred_detais.get(field))
+
+		scr2 = make_subcontracting_receipt(sco.name)
+		scr2.save()
+		scr2.submit()
+
+		for key, value in get_supplied_items(scr2).items():
+			transferred_detais = itemwise_details.get(key)
+
+			for field in ["qty", "serial_no", "batch_no"]:
+				if value.get(field):
+					self.assertEqual(value.get(field), transferred_detais.get(field))
+
+	def test_subcontracting_with_same_components_different_fg(self):
+		"""
+		- Set backflush based on Material Transfer.
+		- Create SCO for the item Subcontracted Item SA2 and Subcontracted Item SA3.
+		- Transfer the components from Stores to Supplier warehouse with serial nos.
+		- Transfer extra qty of components for the item Subcontracted Item SA2.
+		- Create partial SCR against the SCO and check serial nos.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 2",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA2",
+				"fg_item_qty": 5,
+			},
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 3",
+				"qty": 6,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA3",
+				"fg_item_qty": 6,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		rm_items[0]["qty"] += 1
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name if item.get("qty") == 5 else sco.items[1].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.items[0].qty = 3
+		scr1.remove(scr1.items[1])
+		scr1.save()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			transferred_detais = itemwise_details.get(key)
+
+			self.assertEqual(value.qty, 4)
+			self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get("serial_no")[0:4]))
+
+		scr2 = make_subcontracting_receipt(sco.name)
+		scr2.items[0].qty = 2
+		scr2.remove(scr2.items[1])
+		scr2.save()
+		scr2.submit()
+
+		for key, value in get_supplied_items(scr2).items():
+			transferred_detais = itemwise_details.get(key)
+
+			self.assertEqual(value.qty, 2)
+			self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get("serial_no")[4:6]))
+
+		scr3 = make_subcontracting_receipt(sco.name)
+		scr3.save()
+		scr3.submit()
+
+		for key, value in get_supplied_items(scr3).items():
+			transferred_detais = itemwise_details.get(key)
+
+			self.assertEqual(value.qty, 6)
+			self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get("serial_no")[6:12]))
+
+	def test_return_non_consumed_materials(self):
+		"""
+		- Set backflush based on Material Transfer.
+		- Create SCO for item Subcontracted Item SA2.
+		- Transfer the components from Stores to Supplier warehouse with serial nos.
+		- Transfer extra qty of component for the subcontracted item Subcontracted Item SA2.
+		- Create SCR for full qty against the SCO and change the qty of raw material.
+		- After that return the non consumed material back to the store from supplier's warehouse.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 2",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA2",
+				"fg_item_qty": 5,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		rm_items[0]["qty"] += 1
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.save()
+		scr1.supplied_items[0].consumed_qty = 5
+		scr1.supplied_items[0].serial_no = "\n".join(
+			sorted(itemwise_details.get("Subcontracted SRM Item 2").get("serial_no")[0:5])
+		)
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			transferred_detais = itemwise_details.get(key)
+			self.assertEqual(value.qty, 5)
+			self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get("serial_no")[0:5]))
+
+		sco.load_from_db()
+		self.assertEqual(sco.supplied_items[0].consumed_qty, 5)
+		doc = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items])
+		self.assertEqual(doc.items[0].qty, 1)
+		self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC")
+		self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC")
+		self.assertEqual(
+			get_serial_nos(doc.items[0].serial_no),
+			itemwise_details.get(doc.items[0].item_code)["serial_no"][5:6],
+		)
+
+	def test_item_with_batch_based_on_bom(self):
+		"""
+		- Set backflush based on BOM.
+		- Create SCO for item Subcontracted Item SA4 (has batch no).
+		- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
+		- Transfer the components in multiple batches.
+		- Create the 3 SCR against the SCO and split Subcontracted Items into two batches.
+		- Keep the qty as 2 for Subcontracted Item in the SCR.
+		"""
+
+		set_backflush_based_on("BOM")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 4",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA4",
+				"fg_item_qty": 10,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = [
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 1",
+				"qty": 10.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 2",
+				"qty": 10.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 1.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+		]
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.items[0].qty = 2
+		add_second_row_in_scr(scr1)
+		scr1.flags.ignore_mandatory = True
+		scr1.save()
+		scr1.set_missing_values()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			self.assertEqual(value.qty, 4)
+
+		scr2 = make_subcontracting_receipt(sco.name)
+		scr2.items[0].qty = 2
+		add_second_row_in_scr(scr2)
+		scr2.flags.ignore_mandatory = True
+		scr2.save()
+		scr2.set_missing_values()
+		scr2.submit()
+
+		for key, value in get_supplied_items(scr2).items():
+			self.assertEqual(value.qty, 4)
+
+		scr3 = make_subcontracting_receipt(sco.name)
+		scr3.items[0].qty = 2
+		scr3.flags.ignore_mandatory = True
+		scr3.save()
+		scr3.set_missing_values()
+		scr3.submit()
+
+		for key, value in get_supplied_items(scr3).items():
+			self.assertEqual(value.qty, 2)
+
+	def test_item_with_batch_based_on_material_transfer(self):
+		"""
+		- Set backflush based on Material Transferred for Subcontract.
+		- Create SCO for item Subcontracted Item SA4 (has batch no).
+		- Transfer the components from Stores to Supplier warehouse with batch no and serial nos.
+		- Transfer the components in multiple batches with extra 2 qty for the batched item.
+		- Create the 3 SCR against the SCO and split Subcontracted Items into two batches.
+		- Keep the qty as 2 for Subcontracted Item in the SCR.
+		- In the first SCR the batched raw materials will be consumed 2 extra qty.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 4",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA4",
+				"fg_item_qty": 10,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = [
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 1",
+				"qty": 10.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 2",
+				"qty": 10.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+			{
+				"main_item_code": "Subcontracted Item SA4",
+				"item_code": "Subcontracted SRM Item 3",
+				"qty": 3.0,
+				"rate": 100.0,
+				"stock_uom": "Nos",
+				"warehouse": "_Test Warehouse - _TC",
+			},
+		]
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.items[0].qty = 2
+		add_second_row_in_scr(scr1)
+		scr1.flags.ignore_mandatory = True
+		scr1.save()
+		scr1.set_missing_values()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			qty = 4 if key != "Subcontracted SRM Item 3" else 6
+			self.assertEqual(value.qty, qty)
+
+		scr2 = make_subcontracting_receipt(sco.name)
+		scr2.items[0].qty = 2
+		add_second_row_in_scr(scr2)
+		scr2.flags.ignore_mandatory = True
+		scr2.save()
+		scr2.set_missing_values()
+		scr2.submit()
+
+		for key, value in get_supplied_items(scr2).items():
+			self.assertEqual(value.qty, 4)
+
+		scr3 = make_subcontracting_receipt(sco.name)
+		scr3.items[0].qty = 2
+		scr3.flags.ignore_mandatory = True
+		scr3.save()
+		scr3.set_missing_values()
+		scr3.submit()
+
+		for key, value in get_supplied_items(scr3).items():
+			self.assertEqual(value.qty, 1)
+
+	def test_partial_transfer_serial_no_components_based_on_material_transfer(self):
+		"""
+		- Set backflush based on Material Transferred for Subcontract.
+		- Create SCO for the item Subcontracted Item SA2.
+		- Transfer the partial components from Stores to Supplier warehouse with serial nos.
+		- Create partial SCR against the SCO and change the qty manually.
+		- Transfer the remaining components from Stores to Supplier warehouse with serial nos.
+		- Create SCR for remaining qty against the SCO and change the qty manually.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 2",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA2",
+				"fg_item_qty": 10,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		rm_items[0]["qty"] = 5
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.items[0].qty = 5
+		scr1.flags.ignore_mandatory = True
+		scr1.save()
+		scr1.set_missing_values()
+
+		for key, value in get_supplied_items(scr1).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, 3)
+			self.assertEqual(sorted(value.serial_no), sorted(details.serial_no[0:3]))
+
+		scr1.load_from_db()
+		scr1.supplied_items[0].consumed_qty = 5
+		scr1.supplied_items[0].serial_no = "\n".join(
+			itemwise_details[scr1.supplied_items[0].rm_item_code]["serial_no"]
+		)
+		scr1.save()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, details.qty)
+			self.assertEqual(sorted(value.serial_no), sorted(details.serial_no))
+
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr2 = make_subcontracting_receipt(sco.name)
+		scr2.submit()
+
+		for key, value in get_supplied_items(scr2).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, details.qty)
+			self.assertEqual(sorted(value.serial_no), sorted(details.serial_no))
+
+	def test_incorrect_serial_no_components_based_on_material_transfer(self):
+		"""
+		- Set backflush based on Material Transferred for Subcontract.
+		- Create SCO for the item Subcontracted Item SA2.
+		- Transfer the serialized componenets to the supplier.
+		- Create SCR and change the serial no which is not transferred.
+		- System should throw the error and not allowed to save the SCR.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 2",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA2",
+				"fg_item_qty": 10,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.save()
+		scr1.supplied_items[0].serial_no = "ABCD"
+		self.assertRaises(frappe.ValidationError, scr1.save)
+		scr1.delete()
+
+	def test_partial_transfer_batch_based_on_material_transfer(self):
+		"""
+		- Set backflush based on Material Transferred for Subcontract.
+		- Create SCO for the item Subcontracted Item SA6.
+		- Transfer the partial components from Stores to Supplier warehouse with batch.
+		- Create partial SCR against the SCO and change the qty manually.
+		- Transfer the remaining components from Stores to Supplier warehouse with batch.
+		- Create SCR for remaining qty against the SCO and change the qty manually.
+		"""
+
+		set_backflush_based_on("Material Transferred for Subcontract")
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 6",
+				"qty": 10,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA6",
+				"fg_item_qty": 10,
+			},
+		]
+		sco = get_subcontracting_order(service_items=service_items)
+		rm_items = get_rm_items(sco.supplied_items)
+		rm_items[0]["qty"] = 5
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.items[0].qty = 5
+		scr1.save()
+
+		transferred_batch_no = ""
+		for key, value in get_supplied_items(scr1).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, 3)
+			transferred_batch_no = details.batch_no
+			self.assertEqual(value.batch_no, details.batch_no)
+
+		scr1.load_from_db()
+		scr1.supplied_items[0].consumed_qty = 5
+		scr1.supplied_items[0].batch_no = list(transferred_batch_no.keys())[0]
+		scr1.save()
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, details.qty)
+			self.assertEqual(value.batch_no, details.batch_no)
+
+		itemwise_details = make_stock_in_entry(rm_items=rm_items)
+		for item in rm_items:
+			item["sco_rm_detail"] = sco.items[0].name
+
+		make_stock_transfer_entry(
+			sco_no=sco.name,
+			rm_items=rm_items,
+			itemwise_details=copy.deepcopy(itemwise_details),
+		)
+
+		scr1 = make_subcontracting_receipt(sco.name)
+		scr1.submit()
+
+		for key, value in get_supplied_items(scr1).items():
+			details = itemwise_details.get(key)
+			self.assertEqual(value.qty, details.qty)
+			self.assertEqual(value.batch_no, details.batch_no)
+
+
+def add_second_row_in_scr(scr):
+	item_dict = {}
+	for column in [
+		"item_code",
+		"item_name",
+		"qty",
+		"uom",
+		"warehouse",
+		"stock_uom",
+		"subcontracting_order",
+		"subcontracting_order_finished_good_item",
+		"conversion_factor",
+		"rate",
+		"expense_account",
+		"sco_rm_detail",
+	]:
+		item_dict[column] = scr.items[0].get(column)
+
+	scr.append("items", item_dict)
+
+
+def get_supplied_items(scr_doc):
+	supplied_items = {}
+	for row in scr_doc.get("supplied_items"):
+		if row.rm_item_code not in supplied_items:
+			supplied_items.setdefault(
+				row.rm_item_code, frappe._dict({"qty": 0, "serial_no": [], "batch_no": defaultdict(float)})
+			)
+
+		details = supplied_items[row.rm_item_code]
+		update_item_details(row, details)
+
+	return supplied_items
+
+
+def make_stock_in_entry(**args):
+	args = frappe._dict(args)
+
+	items = {}
+	for row in args.rm_items:
+		row = frappe._dict(row)
+
+		doc = make_stock_entry(
+			target=row.warehouse or "_Test Warehouse - _TC",
+			item_code=row.item_code,
+			qty=row.qty or 1,
+			basic_rate=row.rate or 100,
+		)
+
+		if row.item_code not in items:
+			items.setdefault(
+				row.item_code, frappe._dict({"qty": 0, "serial_no": [], "batch_no": defaultdict(float)})
+			)
+
+		child_row = doc.items[0]
+		details = items[child_row.item_code]
+		update_item_details(child_row, details)
+
+	return items
+
+
+def update_item_details(child_row, details):
+	details.qty += (
+		child_row.get("qty")
+		if child_row.doctype == "Stock Entry Detail"
+		else child_row.get("consumed_qty")
+	)
+
+	if child_row.serial_no:
+		details.serial_no.extend(get_serial_nos(child_row.serial_no))
+
+	if child_row.batch_no:
+		details.batch_no[child_row.batch_no] += child_row.get("qty") or child_row.get("consumed_qty")
+
+
+def make_stock_transfer_entry(**args):
+	args = frappe._dict(args)
+
+	items = []
+	for row in args.rm_items:
+		row = frappe._dict(row)
+
+		item = {
+			"item_code": row.main_item_code or args.main_item_code,
+			"rm_item_code": row.item_code,
+			"qty": row.qty or 1,
+			"item_name": row.item_code,
+			"rate": row.rate or 100,
+			"stock_uom": row.stock_uom or "Nos",
+			"warehouse": row.warehuose or "_Test Warehouse - _TC",
+		}
+
+		item_details = args.itemwise_details.get(row.item_code)
+
+		if item_details and item_details.serial_no:
+			serial_nos = item_details.serial_no[0 : cint(row.qty)]
+			item["serial_no"] = "\n".join(serial_nos)
+			item_details.serial_no = list(set(item_details.serial_no) - set(serial_nos))
+
+		if item_details and item_details.batch_no:
+			for batch_no, batch_qty in item_details.batch_no.items():
+				if batch_qty >= row.qty:
+					item["batch_no"] = batch_no
+					item_details.batch_no[batch_no] -= row.qty
+					break
+
+		items.append(item)
+
+	ste_dict = make_rm_stock_entry(args.sco_no, items)
+	doc = frappe.get_doc(ste_dict)
+	doc.insert()
+	doc.submit()
+
+	return doc
+
+
+def make_subcontracted_items():
+	sub_contracted_items = {
+		"Subcontracted Item SA1": {},
+		"Subcontracted Item SA2": {},
+		"Subcontracted Item SA3": {},
+		"Subcontracted Item SA4": {
+			"has_batch_no": 1,
+			"create_new_batch": 1,
+			"batch_number_series": "SBAT.####",
+		},
+		"Subcontracted Item SA5": {},
+		"Subcontracted Item SA6": {},
+		"Subcontracted Item SA7": {},
+	}
+
+	for item, properties in sub_contracted_items.items():
+		if not frappe.db.exists("Item", item):
+			properties.update({"is_stock_item": 1, "is_sub_contracted_item": 1})
+			make_item(item, properties)
+
+
+def make_raw_materials():
+	raw_materials = {
+		"Subcontracted SRM Item 1": {},
+		"Subcontracted SRM Item 2": {"has_serial_no": 1, "serial_no_series": "SRI.####"},
+		"Subcontracted SRM Item 3": {
+			"has_batch_no": 1,
+			"create_new_batch": 1,
+			"batch_number_series": "BAT.####",
+		},
+		"Subcontracted SRM Item 4": {"has_serial_no": 1, "serial_no_series": "SRII.####"},
+		"Subcontracted SRM Item 5": {"has_serial_no": 1, "serial_no_series": "SRII.####"},
+	}
+
+	for item, properties in raw_materials.items():
+		if not frappe.db.exists("Item", item):
+			properties.update({"is_stock_item": 1})
+			make_item(item, properties)
+
+
+def make_service_item(item, properties={}):
+	if not frappe.db.exists("Item", item):
+		properties.update({"is_stock_item": 0})
+		make_item(item, properties)
+
+
+def make_service_items():
+	service_items = {
+		"Subcontracted Service Item 1": {},
+		"Subcontracted Service Item 2": {},
+		"Subcontracted Service Item 3": {},
+		"Subcontracted Service Item 4": {},
+		"Subcontracted Service Item 5": {},
+		"Subcontracted Service Item 6": {},
+		"Subcontracted Service Item 7": {},
+	}
+
+	for item, properties in service_items.items():
+		make_service_item(item, properties)
+
+
+def make_bom_for_subcontracted_items():
+	boms = {
+		"Subcontracted Item SA1": [
+			"Subcontracted SRM Item 1",
+			"Subcontracted SRM Item 2",
+			"Subcontracted SRM Item 3",
+		],
+		"Subcontracted Item SA2": ["Subcontracted SRM Item 2"],
+		"Subcontracted Item SA3": ["Subcontracted SRM Item 2"],
+		"Subcontracted Item SA4": [
+			"Subcontracted SRM Item 1",
+			"Subcontracted SRM Item 2",
+			"Subcontracted SRM Item 3",
+		],
+		"Subcontracted Item SA5": ["Subcontracted SRM Item 5"],
+		"Subcontracted Item SA6": ["Subcontracted SRM Item 3"],
+		"Subcontracted Item SA7": ["Subcontracted SRM Item 1"],
+	}
+
+	for item_code, raw_materials in boms.items():
+		if not frappe.db.exists("BOM", {"item": item_code}):
+			make_bom(item=item_code, raw_materials=raw_materials, rate=100)
+
+
+def set_backflush_based_on(based_on):
+	frappe.db.set_value(
+		"Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", based_on
+	)
+
+
+def get_subcontracting_order(**args):
+	from erpnext.subcontracting.doctype.subcontracting_order.test_subcontracting_order import (
+		create_subcontracting_order,
+	)
+
+	args = frappe._dict(args)
+
+	if args.get("po_name"):
+		po = frappe.get_doc("Purchase Order", args.get("po_name"))
+
+		if po.is_subcontracted:
+			return create_subcontracting_order(po_name=po.name, **args)
+
+	if not args.service_items:
+		service_items = [
+			{
+				"warehouse": "_Test Warehouse - _TC",
+				"item_code": "Subcontracted Service Item 7",
+				"qty": 5,
+				"rate": 100,
+				"fg_item": "Subcontracted Item SA7",
+				"fg_item_qty": 10,
+			},
+		]
+	else:
+		service_items = args.service_items
+
+	po = create_purchase_order(
+		rm_items=service_items,
+		is_subcontracted=1,
+		supplier_warehouse=args.supplier_warehouse or "_Test Warehouse 1 - _TC",
+	)
+
+	return create_subcontracting_order(po_name=po.name, **args)
+
+
+def get_rm_items(supplied_items):
+	rm_items = []
+
+	for item in supplied_items:
+		rm_items.append(
+			{
+				"main_item_code": item.main_item_code,
+				"item_code": item.rm_item_code,
+				"qty": item.required_qty,
+				"rate": item.rate,
+				"stock_uom": item.stock_uom,
+				"warehouse": item.reserve_warehouse,
+			}
+		)
+
+	return rm_items
+
+
+def make_subcontracted_item(**args):
+	from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+
+	args = frappe._dict(args)
+
+	if not frappe.db.exists("Item", args.item_code):
+		make_item(
+			args.item_code,
+			{
+				"is_stock_item": 1,
+				"is_sub_contracted_item": 1,
+				"has_batch_no": args.get("has_batch_no") or 0,
+			},
+		)
+
+	if not args.raw_materials:
+		if not frappe.db.exists("Item", "Test Extra Item 1"):
+			make_item(
+				"Test Extra Item 1",
+				{
+					"is_stock_item": 1,
+				},
+			)
+
+		if not frappe.db.exists("Item", "Test Extra Item 2"):
+			make_item(
+				"Test Extra Item 2",
+				{
+					"is_stock_item": 1,
+				},
+			)
+
+		args.raw_materials = ["_Test FG Item", "Test Extra Item 1"]
+
+	if not frappe.db.get_value("BOM", {"item": args.item_code}, "name"):
+		make_bom(item=args.item_code, raw_materials=args.get("raw_materials"))
\ No newline at end of file
