feat: allow manually entry for scrap items in SCR
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index b396b27..b1ce539 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -436,24 +436,6 @@
 
 			# validate rate with ref PR
 
-	def validate_rejected_warehouse(self):
-		for item in self.get("items"):
-			if flt(item.rejected_qty) and not item.rejected_warehouse:
-				if self.rejected_warehouse:
-					item.rejected_warehouse = self.rejected_warehouse
-
-				if not item.rejected_warehouse:
-					frappe.throw(
-						_("Row #{0}: Rejected Warehouse is mandatory for the rejected Item {1}").format(
-							item.idx, item.item_code
-						)
-					)
-
-			if item.get("rejected_warehouse") and (item.get("rejected_warehouse") == item.get("warehouse")):
-				frappe.throw(
-					_("Row #{0}: Accepted Warehouse and Rejected Warehouse cannot be same").format(item.idx)
-				)
-
 	# validate accepted and rejected qty
 	def validate_accepted_rejected_qty(self):
 		for d in self.get("items"):
diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py
index 6633f4f..8379697 100644
--- a/erpnext/controllers/subcontracting_controller.py
+++ b/erpnext/controllers/subcontracting_controller.py
@@ -55,6 +55,23 @@
 		else:
 			super(SubcontractingController, self).validate()
 
+	def validate_rejected_warehouse(self):
+		for item in self.get("items"):
+			if flt(item.rejected_qty) and not item.rejected_warehouse:
+				if self.rejected_warehouse:
+					item.rejected_warehouse = self.rejected_warehouse
+				else:
+					frappe.throw(
+						_("Row #{0}: Rejected Warehouse is mandatory for the rejected Item {1}").format(
+							item.idx, item.item_code
+						)
+					)
+
+			if item.get("rejected_warehouse") and (item.get("rejected_warehouse") == item.get("warehouse")):
+				frappe.throw(
+					_("Row #{0}: Accepted Warehouse and Rejected Warehouse cannot be same").format(item.idx)
+				)
+
 	def remove_empty_rows(self):
 		for key in ["service_items", "items", "supplied_items"]:
 			if self.get(key):
@@ -80,23 +97,27 @@
 			if not is_stock_item:
 				frappe.throw(_("Row {0}: Item {1} must be a stock item.").format(item.idx, item.item_name))
 
-			if not is_sub_contracted_item:
-				frappe.throw(
-					_("Row {0}: Item {1} must be a subcontracted item.").format(item.idx, item.item_name)
-				)
+			if not item.is_scrap_item:
+				if not is_sub_contracted_item:
+					frappe.throw(
+						_("Row {0}: Item {1} must be a subcontracted item.").format(item.idx, item.item_name)
+					)
 
-			if item.bom:
-				bom = frappe.get_doc("BOM", item.bom)
-				if not bom.is_active:
-					frappe.throw(
-						_("Row {0}: Please select an active BOM for Item {1}.").format(item.idx, item.item_name)
-					)
-				if bom.item != item.item_code:
-					frappe.throw(
-						_("Row {0}: Please select an valid BOM for Item {1}.").format(item.idx, item.item_name)
-					)
+				if item.bom:
+					is_active, bom_item = frappe.get_value("BOM", item.bom, ["is_active", "item"])
+
+					if not is_active:
+						frappe.throw(
+							_("Row {0}: Please select an active BOM for Item {1}.").format(item.idx, item.item_name)
+						)
+					if bom_item != item.item_code:
+						frappe.throw(
+							_("Row {0}: Please select an valid BOM for Item {1}.").format(item.idx, item.item_name)
+						)
+				else:
+					frappe.throw(_("Row {0}: Please select a BOM for Item {1}.").format(item.idx, item.item_name))
 			else:
-				frappe.throw(_("Row {0}: Please select a BOM for Item {1}.").format(item.idx, item.item_name))
+				item.bom = None
 
 	def __get_data_before_save(self):
 		item_dict = {}
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
index 53c567a..b1a585d 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
@@ -79,6 +79,7 @@
 		super(SubcontractingReceipt, self).validate()
 		self.set_missing_values()
 		self.validate_posting_time()
+		self.validate_accepted_warehouse()
 		self.validate_rejected_warehouse()
 
 		if getdate(self.posting_date) > getdate(nowdate()):
@@ -127,6 +128,23 @@
 		self.calculate_supplied_items_qty_and_amount()
 		self.calculate_items_qty_and_amount()
 
+	def validate_accepted_warehouse(self):
+		for item in self.get("items"):
+			if flt(item.qty) and not item.warehouse:
+				if self.set_warehouse:
+					item.warehouse = self.set_warehouse
+				else:
+					frappe.throw(
+						_("Row #{0}: Accepted Warehouse is mandatory for the accepted Item {1}").format(
+							item.idx, item.item_code
+						)
+					)
+
+			if item.get("warehouse") and (item.get("warehouse") == item.get("rejected_warehouse")):
+				frappe.throw(
+					_("Row #{0}: Accepted Warehouse and Rejected Warehouse cannot be same").format(item.idx)
+				)
+
 	def set_available_qty_for_consumption(self):
 		supplied_items_details = {}
 
@@ -191,24 +209,6 @@
 			self.total_qty = total_qty
 			self.total = total_amount
 
-	def validate_rejected_warehouse(self):
-		for item in self.items:
-			if flt(item.rejected_qty) and not item.rejected_warehouse:
-				if self.rejected_warehouse:
-					item.rejected_warehouse = self.rejected_warehouse
-
-				if not item.rejected_warehouse:
-					frappe.throw(
-						_("Row #{0}: Rejected Warehouse is mandatory for the rejected Item {1}").format(
-							item.idx, item.item_code
-						)
-					)
-
-			if item.get("rejected_warehouse") and (item.get("rejected_warehouse") == item.get("warehouse")):
-				frappe.throw(
-					_("Row #{0}: Accepted Warehouse and Rejected Warehouse cannot be same").format(item.idx)
-				)
-
 	def validate_available_qty_for_consumption(self):
 		for item in self.get("supplied_items"):
 			precision = item.precision("consumed_qty")