test: test cases for process loss
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 31f7396..53af28d 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -193,6 +193,7 @@
 		self.update_exploded_items(save=False)
 		self.update_stock_qty()
 		self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
+		self.set_process_loss_qty()
 		self.validate_scrap_items()
 
 	def get_context(self, context):
@@ -877,6 +878,10 @@
 		"""Get a complete tree representation preserving order of child items."""
 		return BOMTree(self.name)
 
+	def set_process_loss_qty(self):
+		if self.process_loss_percentage:
+			self.process_loss_qty = flt(self.quantity) * flt(self.process_loss_percentage) / 100
+
 	def validate_scrap_items(self):
 		must_be_whole_number = frappe.get_value("UOM", self.uom, "must_be_whole_number")
 
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 9898617..16f5c79 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -384,36 +384,16 @@
 	def test_bom_with_process_loss_item(self):
 		fg_item_non_whole, fg_item_whole, bom_item = create_process_loss_bom_items()
 
-		if not frappe.db.exists("BOM", f"BOM-{fg_item_non_whole.item_code}-001"):
-			bom_doc = create_bom_with_process_loss_item(
-				fg_item_non_whole, bom_item, scrap_qty=0.25, scrap_rate=0, fg_qty=1
-			)
-			bom_doc.submit()
-
 		bom_doc = create_bom_with_process_loss_item(
-			fg_item_non_whole, bom_item, scrap_qty=2, scrap_rate=0
+			fg_item_non_whole, bom_item, scrap_qty=2, scrap_rate=0, process_loss_percentage=110
 		)
-		#  PL Item qty can't be >= FG Item qty
+		#  PL can't be > 100
 		self.assertRaises(frappe.ValidationError, bom_doc.submit)
 
-		bom_doc = create_bom_with_process_loss_item(
-			fg_item_non_whole, bom_item, scrap_qty=1, scrap_rate=100
-		)
-		# PL Item rate has to be 0
-		self.assertRaises(frappe.ValidationError, bom_doc.submit)
-
-		bom_doc = create_bom_with_process_loss_item(
-			fg_item_whole, bom_item, scrap_qty=0.25, scrap_rate=0
-		)
+		bom_doc = create_bom_with_process_loss_item(fg_item_whole, bom_item, process_loss_percentage=20)
 		#  Items with whole UOMs can't be PL Items
 		self.assertRaises(frappe.ValidationError, bom_doc.submit)
 
-		bom_doc = create_bom_with_process_loss_item(
-			fg_item_non_whole, bom_item, scrap_qty=0.25, scrap_rate=0
-		)
-		# FG Items in Scrap/Loss Table should have Is Process Loss set
-		self.assertRaises(frappe.ValidationError, bom_doc.submit)
-
 	def test_bom_item_query(self):
 		query = partial(
 			item_query,
@@ -743,7 +723,9 @@
 		create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty=qty, rate=rate)
 
 
-def create_bom_with_process_loss_item(fg_item, bom_item, scrap_qty, scrap_rate, fg_qty=2):
+def create_bom_with_process_loss_item(
+	fg_item, bom_item, scrap_qty=0, scrap_rate=0, fg_qty=2, process_loss_percentage=0
+):
 	bom_doc = frappe.new_doc("BOM")
 	bom_doc.item = fg_item.item_code
 	bom_doc.quantity = fg_qty
@@ -757,18 +739,22 @@
 			"rate": 100.0,
 		},
 	)
-	bom_doc.append(
-		"scrap_items",
-		{
-			"item_code": fg_item.item_code,
-			"qty": scrap_qty,
-			"stock_qty": scrap_qty,
-			"uom": fg_item.stock_uom,
-			"stock_uom": fg_item.stock_uom,
-			"rate": scrap_rate,
-		},
-	)
+
+	if scrap_qty:
+		bom_doc.append(
+			"scrap_items",
+			{
+				"item_code": fg_item.item_code,
+				"qty": scrap_qty,
+				"stock_qty": scrap_qty,
+				"uom": fg_item.stock_uom,
+				"stock_uom": fg_item.stock_uom,
+				"rate": scrap_rate,
+			},
+		)
+
 	bom_doc.currency = "INR"
+	bom_doc.process_loss_percentage = process_loss_percentage
 	return bom_doc
 
 
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 6c7483c..76040b2 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -846,20 +846,20 @@
 			create_process_loss_bom_items,
 		)
 
-		qty = 4
+		qty = 10
 		scrap_qty = 0.25  # bom item qty = 1, consider as 25% of FG
 		source_warehouse = "Stores - _TC"
 		wip_warehouse = "_Test Warehouse - _TC"
 		fg_item_non_whole, _, bom_item = create_process_loss_bom_items()
 
 		test_stock_entry.make_stock_entry(
-			item_code=bom_item.item_code, target=source_warehouse, qty=4, basic_rate=100
+			item_code=bom_item.item_code, target=source_warehouse, qty=qty, basic_rate=100
 		)
 
 		bom_no = f"BOM-{fg_item_non_whole.item_code}-001"
 		if not frappe.db.exists("BOM", bom_no):
 			bom_doc = create_bom_with_process_loss_item(
-				fg_item_non_whole, bom_item, scrap_qty=scrap_qty, scrap_rate=0, fg_qty=1
+				fg_item_non_whole, bom_item, fg_qty=1, process_loss_percentage=10
 			)
 			bom_doc.submit()
 
@@ -883,19 +883,12 @@
 
 		# Testing stock entry values
 		items = se.get("items")
-		self.assertEqual(len(items), 3, "There should be 3 items including process loss.")
+		self.assertEqual(len(items), 2, "There should be 3 items including process loss.")
+		fg_item = items[1]
 
-		source_item, fg_item, pl_item = items
-
-		total_pl_qty = qty * scrap_qty
-		actual_fg_qty = qty - total_pl_qty
-
-		self.assertEqual(pl_item.qty, total_pl_qty)
-		self.assertEqual(fg_item.qty, actual_fg_qty)
-
-		# Testing Work Order values
-		self.assertEqual(frappe.db.get_value("Work Order", wo.name, "produced_qty"), qty)
-		self.assertEqual(frappe.db.get_value("Work Order", wo.name, "process_loss_qty"), total_pl_qty)
+		self.assertEqual(fg_item.qty, qty - 1)
+		self.assertEqual(se.process_loss_percentage, 10)
+		self.assertEqual(se.process_loss_qty, 1)
 
 	@timeout(seconds=60)
 	def test_job_card_scrap_item(self):