refactor: serial no ledger and batchwise balance history report
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 80275de..71fee9f 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -323,8 +323,6 @@
 def make_return_doc(doctype: str, source_name: str, target_doc=None):
 	from frappe.model.mapper import get_mapped_doc
 
-	from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
-
 	company = frappe.db.get_value("Delivery Note", source_name, "company")
 	default_warehouse_for_sales_return = frappe.get_cached_value(
 		"Company", company, "default_warehouse_for_sales_return"
@@ -392,23 +390,51 @@
 			doc.run_method("calculate_taxes_and_totals")
 
 	def update_item(source_doc, target_doc, source_parent):
+		from erpnext.stock.serial_batch_bundle import SerialBatchCreation
+
 		target_doc.qty = -1 * source_doc.qty
 
-		if source_doc.serial_no:
-			returned_serial_nos = get_returned_serial_nos(source_doc, source_parent)
-			serial_nos = list(set(get_serial_nos(source_doc.serial_no)) - set(returned_serial_nos))
-			if serial_nos:
-				target_doc.serial_no = "\n".join(serial_nos)
+		if source_doc.get("serial_and_batch_bundle"):
+			type_of_transaction = "Inward"
+			if (
+				frappe.db.get_value(
+					"Serial and Batch Bundle", source_doc.serial_and_batch_bundle, "type_of_transaction"
+				)
+				== "Inward"
+			):
+				type_of_transaction = "Outward"
 
-		if source_doc.get("rejected_serial_no"):
-			returned_serial_nos = get_returned_serial_nos(
-				source_doc, source_parent, serial_no_field="rejected_serial_no"
+			cls_obj = SerialBatchCreation(
+				{
+					"type_of_transaction": type_of_transaction,
+					"serial_and_batch_bundle": source_doc.serial_and_batch_bundle,
+				}
 			)
-			rejected_serial_nos = list(
-				set(get_serial_nos(source_doc.rejected_serial_no)) - set(returned_serial_nos)
+
+			cls_obj.duplicate_package()
+			if cls_obj.serial_and_batch_bundle:
+				target_doc.serial_and_batch_bundle = cls_obj.serial_and_batch_bundle
+
+		if source_doc.get("rejected_serial_and_batch_bundle"):
+			type_of_transaction = "Inward"
+			if (
+				frappe.db.get_value(
+					"Serial and Batch Bundle", source_doc.rejected_serial_and_batch_bundle, "type_of_transaction"
+				)
+				== "Inward"
+			):
+				type_of_transaction = "Outward"
+
+			cls_obj = SerialBatchCreation(
+				{
+					"type_of_transaction": type_of_transaction,
+					"serial_and_batch_bundle": source_doc.rejected_serial_and_batch_bundle,
+				}
 			)
-			if rejected_serial_nos:
-				target_doc.rejected_serial_no = "\n".join(rejected_serial_nos)
+
+			cls_obj.duplicate_package()
+			if cls_obj.serial_and_batch_bundle:
+				target_doc.serial_and_batch_bundle = cls_obj.serial_and_batch_bundle
 
 		if doctype in ["Purchase Receipt", "Subcontracting Receipt"]:
 			returned_qty_map = get_returned_qty_map_for_row(
diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py
index b929883..814657d 100644
--- a/erpnext/controllers/subcontracting_controller.py
+++ b/erpnext/controllers/subcontracting_controller.py
@@ -294,13 +294,13 @@
 				for batch_no, qty in consumed_bundles.batch_nos.items():
 					self.available_materials[key]["batch_no"][batch_no] -= abs(qty)
 
-			# Will be deperecated in v16
+			# Will be deprecated in v16
 			if row.serial_no:
 				self.available_materials[key]["serial_no"] = list(
 					set(self.available_materials[key]["serial_no"]) - set(get_serial_nos(row.serial_no))
 				)
 
-			# Will be deperecated in v16
+			# Will be deprecated in v16
 			if row.batch_no:
 				self.available_materials[key]["batch_no"][row.batch_no] -= row.consumed_qty
 
@@ -814,8 +814,7 @@
 							"posting_date": self.posting_date,
 							"posting_time": self.posting_time,
 							"qty": -1 * item.consumed_qty,
-							"serial_no": item.serial_no,
-							"batch_no": item.batch_no,
+							"serial_and_batch_bundle": item.serial_and_batch_bundle,
 						}
 					)