fix: use old serial / batch fields to make serial batch bundle
diff --git a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
index 5a281aa..ad2889d 100644
--- a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
+++ b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
@@ -80,13 +80,16 @@
   "target_warehouse",
   "quality_inspection",
   "serial_and_batch_bundle",
-  "batch_no",
+  "use_serial_batch_fields",
   "col_break5",
   "allow_zero_valuation_rate",
-  "serial_no",
   "item_tax_rate",
   "actual_batch_qty",
   "actual_qty",
+  "section_break_tlhi",
+  "serial_no",
+  "column_break_ciit",
+  "batch_no",
   "edit_references",
   "sales_order",
   "so_detail",
@@ -628,13 +631,13 @@
    "options": "Quality Inspection"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "hidden": 1,
    "label": "Batch No",
    "options": "Batch",
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "fieldname": "col_break5",
@@ -649,14 +652,14 @@
    "print_hide": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
    "hidden": 1,
    "in_list_view": 1,
    "label": "Serial No",
    "oldfieldname": "serial_no",
-   "oldfieldtype": "Small Text",
-   "read_only": 1
+   "oldfieldtype": "Small Text"
   },
   {
    "fieldname": "item_tax_rate",
@@ -824,17 +827,33 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
    "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "print_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_tlhi",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_ciit",
+   "fieldtype": "Column Break"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-11-14 18:33:22.585715",
+ "modified": "2024-02-04 16:36:25.665743",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "POS Invoice Item",
diff --git a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
index e2a62f1..55a577b 100644
--- a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
+++ b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
@@ -82,6 +82,7 @@
 		target_warehouse: DF.Link | None
 		total_weight: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 		weight_per_unit: DF.Float
 		weight_uom: DF.Link | None
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index c4e09b4..c68ff83 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -696,6 +696,7 @@
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty in bin depends upon updated ordered qty in PO
 		if self.update_stock == 1:
+			self.make_bundle_using_old_serial_batch_fields()
 			self.update_stock_ledger()
 
 			if self.is_old_subcontracting_flow:
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 26984d9..3ee4214 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -62,16 +62,19 @@
   "rm_supp_cost",
   "warehouse_section",
   "warehouse",
-  "from_warehouse",
-  "quality_inspection",
   "add_serial_batch_bundle",
   "serial_and_batch_bundle",
-  "serial_no",
+  "use_serial_batch_fields",
   "col_br_wh",
+  "from_warehouse",
+  "quality_inspection",
   "rejected_warehouse",
   "rejected_serial_and_batch_bundle",
-  "batch_no",
+  "section_break_rqbe",
+  "serial_no",
   "rejected_serial_no",
+  "column_break_vbbb",
+  "batch_no",
   "manufacture_details",
   "manufacturer",
   "column_break_13",
@@ -440,13 +443,11 @@
    "print_hide": 1
   },
   {
-   "depends_on": "eval:!doc.is_fixed_asset",
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
-   "hidden": 1,
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
   },
   {
@@ -454,21 +455,18 @@
    "fieldtype": "Column Break"
   },
   {
-   "depends_on": "eval:!doc.is_fixed_asset",
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
    "fieldname": "serial_no",
    "fieldtype": "Text",
-   "hidden": 1,
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
-   "depends_on": "eval:!doc.is_fixed_asset",
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
    "fieldname": "rejected_serial_no",
    "fieldtype": "Text",
    "label": "Rejected Serial No",
    "no_copy": 1,
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "fieldname": "accounting",
@@ -891,7 +889,7 @@
    "label": "Apply TDS"
   },
   {
-   "depends_on": "eval:parent.update_stock == 1",
+   "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -901,7 +899,7 @@
    "search_index": 1
   },
   {
-   "depends_on": "eval:parent.update_stock == 1",
+   "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
    "fieldname": "rejected_serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Rejected Serial and Batch Bundle",
@@ -916,16 +914,31 @@
    "options": "Asset"
   },
   {
-   "depends_on": "eval:parent.update_stock === 1",
+   "depends_on": "eval:parent.update_stock === 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
    "fieldname": "add_serial_batch_bundle",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No"
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
+   "fieldname": "section_break_rqbe",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_vbbb",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2024-01-21 19:46:25.537861",
+ "modified": "2024-02-04 14:11:52.742228",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
index e48d223..ccbc347 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
@@ -88,6 +88,7 @@
 		stock_uom_rate: DF.Currency
 		total_weight: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		valuation_rate: DF.Currency
 		warehouse: DF.Link | None
 		weight_per_unit: DF.Float
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index c381b8a..abc0694 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -447,6 +447,7 @@
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		if self.update_stock == 1:
+			self.make_bundle_using_old_serial_batch_fields()
 			self.update_stock_ledger()
 
 		# this sequence because outstanding may get -ve
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index ec9e792..d06c786 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -83,14 +83,17 @@
   "quality_inspection",
   "pick_serial_and_batch",
   "serial_and_batch_bundle",
-  "batch_no",
-  "incoming_rate",
+  "use_serial_batch_fields",
   "col_break5",
   "allow_zero_valuation_rate",
-  "serial_no",
+  "incoming_rate",
   "item_tax_rate",
   "actual_batch_qty",
   "actual_qty",
+  "section_break_eoec",
+  "serial_no",
+  "column_break_ytgd",
+  "batch_no",
   "edit_references",
   "sales_order",
   "so_detail",
@@ -600,12 +603,11 @@
    "options": "Quality Inspection"
   },
   {
+   "depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
-   "hidden": 1,
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
   },
   {
@@ -621,13 +623,12 @@
    "print_hide": 1
   },
   {
+   "depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
-   "hidden": 1,
    "label": "Serial No",
    "oldfieldname": "serial_no",
-   "oldfieldtype": "Small Text",
-   "read_only": 1
+   "oldfieldtype": "Small Text"
   },
   {
    "fieldname": "item_group",
@@ -891,6 +892,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -904,12 +906,27 @@
    "fieldname": "pick_serial_and_batch",
    "fieldtype": "Button",
    "label": "Pick Serial / Batch No"
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
+   "fieldname": "section_break_eoec",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_ytgd",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-12-29 13:03:14.121298",
+ "modified": "2024-02-04 11:52:16.106541",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
index 80f6774..c71d08e 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
@@ -86,6 +86,7 @@
 		target_warehouse: DF.Link | None
 		total_weight: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 		weight_per_unit: DF.Float
 		weight_uom: DF.Link | None
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
index 5e251a5..c9ed806 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
@@ -126,6 +126,7 @@
 		self.create_target_asset()
 
 	def on_submit(self):
+		self.make_bundle_using_old_serial_batch_fields()
 		self.update_stock_ledger()
 		self.make_gl_entries()
 		self.update_target_asset()
diff --git a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json
index 26e1c3c..d301454 100644
--- a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json
+++ b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json
@@ -18,9 +18,12 @@
   "amount",
   "batch_and_serial_no_section",
   "serial_and_batch_bundle",
+  "use_serial_batch_fields",
   "column_break_13",
-  "batch_no",
+  "section_break_bfqc",
   "serial_no",
+  "column_break_mbuv",
+  "batch_no",
   "accounting_dimensions_section",
   "cost_center",
   "dimension_col_break"
@@ -39,13 +42,13 @@
    "reqd": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "no_copy": 1,
    "options": "Batch",
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "fieldname": "section_break_6",
@@ -102,12 +105,12 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
    "hidden": 1,
    "label": "Serial No",
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "fieldname": "item_code",
@@ -148,18 +151,34 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
    "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "print_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_bfqc",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_mbuv",
+   "fieldtype": "Column Break"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-04-06 01:10:17.947952",
+ "modified": "2024-02-04 16:41:09.239762",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Capitalization Stock Item",
diff --git a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
index 122cbb6..d2b075c 100644
--- a/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
+++ b/erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.py
@@ -27,6 +27,7 @@
 		serial_no: DF.SmallText | None
 		stock_qty: DF.Float
 		stock_uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		valuation_rate: DF.Currency
 		warehouse: DF.Link
 	# end: auto-generated types
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 11e9f9f..17d3369 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -126,6 +126,54 @@
 				# remove extra whitespace and store one serial no on each line
 				row.serial_no = clean_serial_no_string(row.serial_no)
 
+	def make_bundle_using_old_serial_batch_fields(self):
+		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+		from erpnext.stock.serial_batch_bundle import SerialBatchCreation
+
+		for row in self.items:
+			if not row.serial_no and not row.batch_no and not row.get("rejected_serial_no"):
+				continue
+
+			if not row.use_serial_batch_fields and (
+				row.serial_no or row.batch_no or row.get("rejected_serial_no")
+			):
+				frappe.throw(_("Please enable Use Old Serial / Batch Fields to make_bundle"))
+
+			if row.use_serial_batch_fields and (
+				not row.serial_and_batch_bundle or not row.get("rejected_serial_and_batch_bundle")
+			):
+				sn_doc = SerialBatchCreation(
+					{
+						"item_code": row.item_code,
+						"warehouse": row.warehouse,
+						"posting_date": self.posting_date,
+						"posting_time": self.posting_time,
+						"voucher_type": self.doctype,
+						"voucher_no": self.name,
+						"voucher_detail_no": row.name,
+						"qty": row.stock_qty,
+						"type_of_transaction": "Inward" if row.stock_qty > 0 else "Outward",
+						"company": self.company,
+						"is_rejected": 1 if row.get("rejected_warehouse") else 0,
+						"serial_nos": get_serial_nos(row.serial_no) if row.serial_no else None,
+						"batches": frappe._dict({row.batch_no: row.stock_qty}) if row.batch_no else None,
+						"batch_no": row.batch_no,
+						"use_serial_batch_fields": row.use_serial_batch_fields,
+					}
+				).make_serial_and_batch_bundle()
+
+				if sn_doc.is_rejected:
+					row.rejected_serial_and_batch_bundle = sn_doc.name
+					row.db_set("rejected_serial_and_batch_bundle", sn_doc.name)
+				else:
+					row.serial_and_batch_bundle = sn_doc.name
+					row.db_set("serial_and_batch_bundle", sn_doc.name)
+
+	def set_use_serial_batch_fields(self):
+		if frappe.db.get_single_value("Stock Settings", "use_serial_batch_fields"):
+			for row in self.items:
+				row.use_serial_batch_fields = 1
+
 	def get_gl_entries(
 		self, warehouse_account=None, default_expense_account=None, default_cost_center=None
 	):
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 26795f7..18b963d 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -7,6 +7,7 @@
 		super.setup();
 		let me = this;
 
+		this.set_fields_onload_for_line_item();
 		this.frm.ignore_doctypes_on_cancel_all = ['Serial and Batch Bundle'];
 
 		frappe.flags.hide_serial_batch_dialog = true;
@@ -105,6 +106,7 @@
 
 		frappe.ui.form.on(this.frm.doctype + " Item", {
 			items_add: function(frm, cdt, cdn) {
+				debugger
 				var item = frappe.get_doc(cdt, cdn);
 				if (!item.warehouse && frm.doc.set_warehouse) {
 					item.warehouse = frm.doc.set_warehouse;
@@ -118,6 +120,13 @@
 					item.from_warehouse = frm.doc.set_from_warehouse;
 				}
 
+				if (item.docstatus === 0
+					&& frappe.meta.has_field(item.doctype, "use_serial_batch_fields")
+					&& cint(frappe.user_defaults?.use_serial_batch_fields) === 1
+				) {
+					frappe.model.set_value(item.doctype, item.name, "use_serial_batch_fields", 1);
+				}
+
 				erpnext.accounts.dimensions.copy_dimension_from_first_row(frm, cdt, cdn, 'items');
 			}
 		});
@@ -222,7 +231,19 @@
 				};
 			});
 		}
+	}
 
+	set_fields_onload_for_line_item() {
+		if (this.frm.is_new && this.frm.doc?.items) {
+			this.frm.doc.items.forEach(item => {
+				if (item.docstatus === 0
+					&& frappe.meta.has_field(item.doctype, "use_serial_batch_fields")
+					&& cint(frappe.user_defaults?.use_serial_batch_fields) === 1
+				) {
+					frappe.model.set_value(item.doctype, item.name, "use_serial_batch_fields", 1);
+				}
+			})
+		}
 	}
 
 	toggle_enable_for_stock_uom(field) {
@@ -462,6 +483,11 @@
 			this.frm.doc.doctype === 'Delivery Note') {
 			show_batch_dialog = 1;
 		}
+
+		if (show_batch_dialog && item.use_serial_batch_fields === 1) {
+			show_batch_dialog = 0;
+		}
+
 		item.barcode = null;
 
 
@@ -1242,20 +1268,6 @@
 		}
 	}
 
-	sync_bundle_data() {
-		let doctypes = ["Sales Invoice", "Purchase Invoice", "Delivery Note", "Purchase Receipt"];
-
-		if (this.frm.is_new() && doctypes.includes(this.frm.doc.doctype)) {
-			const barcode_scanner = new erpnext.utils.BarcodeScanner({frm:this.frm});
-			barcode_scanner.sync_bundle_data();
-			barcode_scanner.remove_item_from_localstorage();
-		}
-	}
-
-	before_save(doc) {
-		this.sync_bundle_data();
-	}
-
 	service_start_date(frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
 
diff --git a/erpnext/public/js/utils/barcode_scanner.js b/erpnext/public/js/utils/barcode_scanner.js
index aacab0f..4d1c0c1 100644
--- a/erpnext/public/js/utils/barcode_scanner.js
+++ b/erpnext/public/js/utils/barcode_scanner.js
@@ -1,12 +1,15 @@
 erpnext.utils.BarcodeScanner = class BarcodeScanner {
 	constructor(opts) {
 		this.frm = opts.frm;
+		// frappe.flags.trigger_from_barcode_scanner is used for custom scripts
 
 		// field from which to capture input of scanned data
 		this.scan_field_name = opts.scan_field_name || "scan_barcode";
 		this.scan_barcode_field = this.frm.fields_dict[this.scan_field_name];
 
 		this.barcode_field = opts.barcode_field || "barcode";
+		this.serial_no_field = opts.serial_no_field || "serial_no";
+		this.batch_no_field = opts.batch_no_field || "batch_no";
 		this.uom_field = opts.uom_field || "uom";
 		this.qty_field = opts.qty_field || "qty";
 		// field name on row which defines max quantity to be scanned e.g. picklist
@@ -105,53 +108,52 @@
 				this.frm.has_items = false;
 			}
 
-			if (serial_no) {
-				this.is_duplicate_serial_no(row, item_code, serial_no)
-					.then((is_duplicate) => {
-						if (!is_duplicate) {
-							this.run_serially_tasks(row, data, resolve);
-						} else {
-							this.clean_up();
-							reject();
-							return;
-						}
-					});
-			} else {
-				this.run_serially_tasks(row, data, resolve);
+			if (this.is_duplicate_serial_no(row, serial_no)) {
+				this.clean_up();
+				reject();
+				return;
 			}
 
-
+			frappe.run_serially([
+				() => this.set_selector_trigger_flag(data),
+				() => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
+					this.show_scan_message(row.idx, row.item_code, qty);
+				}),
+				() => this.set_barcode_uom(row, uom),
+				() => this.set_serial_no(row, serial_no),
+				() => this.set_batch_no(row, batch_no),
+				() => this.set_barcode(row, barcode),
+				() => this.clean_up(),
+				() => this.revert_selector_flag(),
+				() => resolve(row)
+			]);
 		});
 	}
 
-	run_serially_tasks(row, data, resolve) {
-		const {item_code, barcode, batch_no, serial_no, uom} = data;
+	// batch and serial selector is reduandant when all info can be added by scan
+	// this flag on item row is used by transaction.js to avoid triggering selector
+	set_selector_trigger_flag(data) {
+		const {batch_no, serial_no, has_batch_no, has_serial_no} = data;
 
-		frappe.run_serially([
-			() => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
-			() => this.set_barcode(row, barcode),
-			() => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
-				this.show_scan_message(row.idx, row.item_code, qty);
-			}),
-			() => this.set_barcode_uom(row, uom),
-			() => this.clean_up(),
-			() => {
-				if (row.serial_and_batch_bundle && !this.frm.is_new()) {
-					this.frm.save();
-				}
+		const require_selecting_batch = has_batch_no && !batch_no;
+		const require_selecting_serial = has_serial_no && !serial_no;
 
-				frappe.flags.trigger_from_barcode_scanner = false;
-			},
-			() => resolve(row),
-		]);
+		if (!(require_selecting_batch || require_selecting_serial)) {
+			frappe.flags.hide_serial_batch_dialog = true;
+		}
+	}
+
+	revert_selector_flag() {
+		frappe.flags.hide_serial_batch_dialog = false;
+		frappe.flags.trigger_from_barcode_scanner = false;
 	}
 
 	set_item(row, item_code, barcode, batch_no, serial_no) {
 		return new Promise(resolve => {
 			const increment = async (value = 1) => {
-				const item_data = {item_code: item_code};
-				item_data[this.qty_field] = Number((row[this.qty_field] || 0)) + Number(value);
+				const item_data = {item_code: item_code, use_serial_batch_fields: 1.0};
 				frappe.flags.trigger_from_barcode_scanner = true;
+				item_data[this.qty_field] = Number((row[this.qty_field] || 0)) + Number(value);
 				await frappe.model.set_value(row.doctype, row.name, item_data);
 				return value;
 			};
@@ -160,6 +162,8 @@
 				frappe.prompt(__("Please enter quantity for item {0}", [item_code]), ({value}) => {
 					increment(value).then((value) => resolve(value));
 				});
+			} else if (this.frm.has_items) {
+				this.prepare_item_for_scan(row, item_code, barcode, batch_no, serial_no);
 			} else {
 				increment().then((value) => resolve(value));
 			}
@@ -182,8 +186,9 @@
 			frappe.model.set_value(row.doctype, row.name, item_data);
 
 			frappe.run_serially([
+				() => this.set_batch_no(row, this.dialog.get_value("batch_no")),
 				() => this.set_barcode(row, this.dialog.get_value("barcode")),
-				() => this.set_serial_and_batch(row, item_code, this.dialog.get_value("serial_no"), this.dialog.get_value("batch_no")),
+				() => this.set_serial_no(row, this.dialog.get_value("serial_no")),
 				() => this.add_child_for_remaining_qty(row),
 				() => this.clean_up()
 			]);
@@ -337,144 +342,32 @@
 		}
 	}
 
-	async set_serial_and_batch(row, item_code, serial_no, batch_no) {
-		if (this.frm.is_new() || !row.serial_and_batch_bundle) {
-			this.set_bundle_in_localstorage(row, item_code, serial_no, batch_no);
-		} else if(row.serial_and_batch_bundle) {
-			frappe.call({
-				method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.update_serial_or_batch",
-				args: {
-					bundle_id: row.serial_and_batch_bundle,
-					serial_no: serial_no,
-					batch_no: batch_no,
-				},
-			})
-		}
-	}
+	async set_serial_no(row, serial_no) {
+		if (serial_no && frappe.meta.has_field(row.doctype, this.serial_no_field)) {
+			const existing_serial_nos = row[this.serial_no_field];
+			let new_serial_nos = "";
 
-	get_key_for_localstorage() {
-		let parts = this.frm.doc.name.split("-");
-		return parts[parts.length - 1] + this.frm.doc.doctype;
-	}
-
-	update_localstorage_scanned_data() {
-		let docname = this.frm.doc.name
-		if (localStorage[docname]) {
-			let items = JSON.parse(localStorage[docname]);
-			let existing_items = this.frm.doc.items.map(d => d.item_code);
-			if (!existing_items.length) {
-				localStorage.removeItem(docname);
-				return;
+			if (!!existing_serial_nos) {
+				new_serial_nos = existing_serial_nos + "\n" + serial_no;
+			} else {
+				new_serial_nos = serial_no;
 			}
-
-			for (let item_code in items) {
-				if (!existing_items.includes(item_code)) {
-					delete items[item_code];
-				}
-			}
-
-			localStorage[docname] = JSON.stringify(items);
+			await frappe.model.set_value(row.doctype, row.name, this.serial_no_field, new_serial_nos);
 		}
 	}
 
-	async set_bundle_in_localstorage(row, item_code, serial_no, batch_no) {
-		let docname = this.frm.doc.name
-
-		let entries = JSON.parse(localStorage.getItem(docname));
-		if (!entries) {
-			entries = {};
-		}
-
-		let key = item_code;
-		if (!entries[key]) {
-			entries[key] = [];
-		}
-
-		let existing_row = [];
-		if (!serial_no && batch_no) {
-			existing_row = entries[key].filter((e) => e.batch_no === batch_no);
-			if (existing_row.length) {
-				existing_row[0].qty += 1;
-			}
-		} else if (serial_no) {
-			existing_row = entries[key].filter((e) => e.serial_no === serial_no);
-			if (existing_row.length) {
-				frappe.throw(__("Serial No {0} has already scanned.", [serial_no]));
-			}
-		}
-
-		if (!existing_row.length) {
-			entries[key].push({
-				"serial_no": serial_no,
-				"batch_no": batch_no,
-				"qty": 1
-			});
-		}
-
-		localStorage.setItem(docname, JSON.stringify(entries));
-
-		// Auto remove from localstorage after 1 hour
-		setTimeout(() => {
-			localStorage.removeItem(docname);
-		}, 3600000)
-	}
-
-	remove_item_from_localstorage() {
-		let docname = this.frm.doc.name;
-		if (localStorage[docname]) {
-			localStorage.removeItem(docname);
-		}
-	}
-
-	async sync_bundle_data() {
-		let docname = this.frm.doc.name;
-
-		if (localStorage[docname]) {
-			let entries = JSON.parse(localStorage[docname]);
-			if (entries) {
-				for (let entry in entries) {
-					let row = this.frm.doc.items.filter((item) => {
-						if (item.item_code === entry) {
-							return true;
-						}
-					})[0];
-
-					if (row) {
-						this.create_serial_and_batch_bundle(row, entries, entry)
-							.then(() => {
-								if (!entries) {
-									localStorage.removeItem(docname);
-								}
-							});
-					}
-				}
-			}
-		}
-	}
-
-	async create_serial_and_batch_bundle(row, entries, key) {
-		frappe.call({
-			method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers",
-			args: {
-				entries: entries[key],
-				child_row: row,
-				doc: this.frm.doc,
-				warehouse: row.warehouse,
-				do_not_save: 1
-			},
-			callback: function(r) {
-				row.serial_and_batch_bundle = r.message.name;
-				delete entries[key];
-			}
-		})
-	}
-
 	async set_barcode_uom(row, uom) {
 		if (uom && frappe.meta.has_field(row.doctype, this.uom_field)) {
 			await frappe.model.set_value(row.doctype, row.name, this.uom_field, uom);
 		}
 	}
 
+	async set_batch_no(row, batch_no) {
+		if (batch_no && frappe.meta.has_field(row.doctype, this.batch_no_field)) {
+			await frappe.model.set_value(row.doctype, row.name, this.batch_no_field, batch_no);
+		}
+	}
+
 	async set_barcode(row, barcode) {
 		if (barcode && frappe.meta.has_field(row.doctype, this.barcode_field)) {
 			await frappe.model.set_value(row.doctype, row.name, this.barcode_field, barcode);
@@ -490,58 +383,13 @@
 		}
 	}
 
-	async is_duplicate_serial_no(row, item_code, serial_no) {
-		let is_duplicate = false;
-		const promise = new Promise((resolve, reject) => {
-			if (this.frm.is_new() || !row.serial_and_batch_bundle) {
-				is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
-				if (is_duplicate) {
-					this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
-				}
+	is_duplicate_serial_no(row, serial_no) {
+		const is_duplicate = row[this.serial_no_field]?.includes(serial_no);
 
-				resolve(is_duplicate);
-			} else if (row.serial_and_batch_bundle) {
-				this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
-					if (r.message) {
-						this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
-					}
-
-					is_duplicate = r.message;
-					resolve(is_duplicate);
-				})
-			}
-		});
-
-		return await promise;
-	}
-
-	check_duplicate_serial_no_in_db(row, serial_no, response) {
-		frappe.call({
-			method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_duplicate_serial_no",
-			args: {
-				serial_no: serial_no,
-				bundle_id: row.serial_and_batch_bundle
-			},
-			callback(r) {
-				response(r);
-			}
-		});
-	}
-
-	check_duplicate_serial_no_in_localstorage(item_code, serial_no) {
-		let docname = this.frm.doc.name
-		let entries = JSON.parse(localStorage.getItem(docname));
-
-		if (!entries) {
-			return false;
+		if (is_duplicate) {
+			this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
 		}
-
-		let existing_row = [];
-		if (entries[item_code]) {
-			existing_row = entries[item_code].filter((e) => e.serial_no === serial_no);
-		}
-
-		return existing_row.length;
+		return is_duplicate;
 	}
 
 	get_row_to_modify_on_scan(item_code, batch_no, uom, barcode) {
@@ -587,4 +435,4 @@
 	show_alert(msg, indicator, duration=3) {
 		frappe.show_alert({message: msg, indicator: indicator}, duration);
 	}
-};
+};
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 79f24d1..9661bac 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -906,6 +906,7 @@
 		target.run_method("set_missing_values")
 		target.run_method("set_po_nos")
 		target.run_method("calculate_taxes_and_totals")
+		target.run_method("set_use_serial_batch_fields")
 
 		if source.company_address:
 			target.update({"company_address": source.company_address})
@@ -1026,6 +1027,7 @@
 		target.run_method("set_missing_values")
 		target.run_method("set_po_nos")
 		target.run_method("calculate_taxes_and_totals")
+		target.run_method("set_use_serial_batch_fields")
 
 		if source.company_address:
 			target.update({"company_address": source.company_address})
@@ -1608,7 +1610,11 @@
 		"Sales Order",
 		source_name,
 		{
-			"Sales Order": {"doctype": "Pick List", "validation": {"docstatus": ["=", 1]}},
+			"Sales Order": {
+				"doctype": "Pick List",
+				"field_map": {"set_warehouse": "parent_warehouse"},
+				"validation": {"docstatus": ["=", 1]},
+			},
 			"Sales Order Item": {
 				"doctype": "Pick List Item",
 				"field_map": {"parent": "sales_order", "name": "sales_order_item"},
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 58990d4..4eacbc1 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -398,6 +398,8 @@
 			self.check_credit_limit()
 		elif self.issue_credit_note:
 			self.make_return_invoice()
+
+		self.make_bundle_using_old_serial_batch_fields()
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		self.update_stock_ledger()
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index a44b9ac..247672f 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -80,8 +80,11 @@
   "section_break_40",
   "pick_serial_and_batch",
   "serial_and_batch_bundle",
+  "use_serial_batch_fields",
   "column_break_eaoe",
+  "section_break_qyjv",
   "serial_no",
+  "column_break_rxvc",
   "batch_no",
   "available_qty_section",
   "actual_batch_qty",
@@ -850,6 +853,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -859,6 +863,7 @@
    "search_index": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
    "fieldname": "pick_serial_and_batch",
    "fieldtype": "Button",
    "label": "Pick Serial / Batch No"
@@ -874,27 +879,40 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Text",
-   "hidden": 1,
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
-   "hidden": 1,
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_qyjv",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_rxvc",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-14 18:37:38.638144",
+ "modified": "2024-02-04 14:10:31.750340",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note Item",
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
index c11c410..b76f742 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
@@ -82,6 +82,7 @@
 		target_warehouse: DF.Link | None
 		total_weight: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 		weight_per_unit: DF.Float
 		weight_uom: DF.Link | None
diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json
index 5dd8934..0b006ab 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.json
+++ b/erpnext/stock/doctype/packed_item/packed_item.json
@@ -20,9 +20,12 @@
   "uom",
   "section_break_9",
   "pick_serial_and_batch",
-  "serial_and_batch_bundle",
-  "serial_no",
+  "use_serial_batch_fields",
   "column_break_11",
+  "serial_and_batch_bundle",
+  "section_break_bgys",
+  "serial_no",
+  "column_break_qlha",
   "batch_no",
   "actual_batch_qty",
   "section_break_13",
@@ -118,10 +121,10 @@
    "fieldtype": "Section Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Text",
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
    "fieldname": "column_break_11",
@@ -131,8 +134,7 @@
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
-   "options": "Batch",
-   "read_only": 1
+   "options": "Batch"
   },
   {
    "fieldname": "section_break_13",
@@ -259,6 +261,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -267,16 +270,32 @@
    "print_hide": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "pick_serial_and_batch",
    "fieldtype": "Button",
    "label": "Pick Serial / Batch No"
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_bgys",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_qlha",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-04-28 13:16:38.460806",
+ "modified": "2024-02-04 16:30:44.263964",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Packed Item",
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index ed667c2..c115e33 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -47,6 +47,7 @@
 		serial_no: DF.Text | None
 		target_warehouse: DF.Link | None
 		uom: DF.Link | None
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 	# end: auto-generated types
 
diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js
index afd6ce8..aa0e125 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.js
+++ b/erpnext/stock/doctype/pick_list/pick_list.js
@@ -16,7 +16,6 @@
 		frm.set_query('parent_warehouse', () => {
 			return {
 				filters: {
-					'is_group': 1,
 					'company': frm.doc.company
 				}
 			};
diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json
index 7259dc0..bd84aad 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.json
+++ b/erpnext/stock/doctype/pick_list/pick_list.json
@@ -51,7 +51,7 @@
    "description": "Items under this warehouse will be suggested",
    "fieldname": "parent_warehouse",
    "fieldtype": "Link",
-   "label": "Parent Warehouse",
+   "label": "Warehouse",
    "options": "Warehouse"
   },
   {
@@ -188,7 +188,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2023-01-24 10:33:43.244476",
+ "modified": "2024-02-01 16:17:44.877426",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Pick List",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 758448a..f2edeea 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -13,7 +13,7 @@
 from frappe.query_builder import Case
 from frappe.query_builder.custom import GROUP_CONCAT
 from frappe.query_builder.functions import Coalesce, Locate, Replace, Sum
-from frappe.utils import cint, floor, flt
+from frappe.utils import ceil, cint, floor, flt
 from frappe.utils.nestedset import get_descendants_of
 
 from erpnext.selling.doctype.sales_order.sales_order import (
@@ -122,11 +122,43 @@
 
 	def on_submit(self):
 		self.validate_serial_and_batch_bundle()
+		self.make_bundle_using_old_serial_batch_fields()
 		self.update_status()
 		self.update_bundle_picked_qty()
 		self.update_reference_qty()
 		self.update_sales_order_picking_status()
 
+	def make_bundle_using_old_serial_batch_fields(self):
+		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+
+		for row in self.locations:
+			if not row.serial_no and not row.batch_no:
+				continue
+
+			if not row.use_serial_batch_fields and (row.serial_no or row.batch_no):
+				frappe.throw(_("Please enable Use Old Serial / Batch Fields to make_bundle"))
+
+			if row.use_serial_batch_fields and (not row.serial_and_batch_bundle):
+				sn_doc = SerialBatchCreation(
+					{
+						"item_code": row.item_code,
+						"warehouse": row.warehouse,
+						"voucher_type": self.doctype,
+						"voucher_no": self.name,
+						"voucher_detail_no": row.name,
+						"qty": row.stock_qty,
+						"type_of_transaction": "Inward" if row.stock_qty > 0 else "Outward",
+						"company": self.company,
+						"serial_nos": get_serial_nos(row.serial_no) if row.serial_no else None,
+						"batches": frappe._dict({row.batch_no: row.stock_qty}) if row.batch_no else None,
+						"batch_no": row.batch_no,
+						"use_serial_batch_fields": row.use_serial_batch_fields,
+					}
+				).make_serial_and_batch_bundle()
+
+				row.serial_and_batch_bundle = sn_doc.name
+				row.db_set("serial_and_batch_bundle", sn_doc.name)
+
 	def on_update_after_submit(self) -> None:
 		if self.has_reserved_stock():
 			msg = _(
@@ -317,8 +349,12 @@
 		self.item_location_map = frappe._dict()
 
 		from_warehouses = None
-		if self.parent_warehouse:
+		if self.parent_warehouse and frappe.get_cached_value(
+			"Warehouse", self.parent_warehouse, "is_group"
+		):
 			from_warehouses = get_descendants_of("Warehouse", self.parent_warehouse)
+		elif self.parent_warehouse:
+			from_warehouses = [self.parent_warehouse]
 
 		# Create replica before resetting, to handle empty table on update after submit.
 		locations_replica = self.get("locations")
@@ -351,13 +387,13 @@
 			for row in locations:
 				location = item_doc.as_dict()
 				location.update(row)
+				bundle = location.serial_and_batch_bundle or location.serial_no or location.batch_no
 				key = (
 					location.item_code,
 					location.warehouse,
 					location.uom,
-					location.batch_no,
-					location.serial_no,
 					location.sales_order_item or location.material_request_item,
+					bundle,
 				)
 
 				if key not in updated_locations:
@@ -645,7 +681,9 @@
 					"qty": qty,
 					"stock_qty": stock_qty,
 					"warehouse": item_location.warehouse,
-					"serial_and_batch_bundle": item_location.serial_and_batch_bundle,
+					"serial_no": item_location.serial_no,
+					"batch_no": item_location.batch_no,
+					"use_serial_batch_fields": 1,
 				}
 			)
 		)
@@ -673,6 +711,7 @@
 	company,
 	ignore_validation=False,
 	picked_item_details=None,
+	consider_rejected_warehouses=False,
 ):
 	locations = []
 	total_picked_qty = (
@@ -681,7 +720,16 @@
 	has_serial_no = frappe.get_cached_value("Item", item_code, "has_serial_no")
 	has_batch_no = frappe.get_cached_value("Item", item_code, "has_batch_no")
 
-	if has_serial_no:
+	if has_batch_no and has_serial_no:
+		locations = get_available_item_locations_for_serial_and_batched_item(
+			item_code,
+			from_warehouses,
+			required_qty,
+			company,
+			total_picked_qty,
+			consider_rejected_warehouses=consider_rejected_warehouses,
+		)
+	elif has_serial_no:
 		locations = get_available_item_locations_for_serialized_item(
 			item_code, from_warehouses, required_qty, company, total_picked_qty
 		)
@@ -724,6 +772,49 @@
 	return locations
 
 
+def get_available_item_locations_for_serial_and_batched_item(
+	item_code,
+	from_warehouses,
+	required_qty,
+	company,
+	total_picked_qty=0,
+	consider_rejected_warehouses=False,
+):
+	# Get batch nos by FIFO
+	locations = get_available_item_locations_for_batched_item(
+		item_code,
+		from_warehouses,
+		required_qty,
+		company,
+		consider_rejected_warehouses=consider_rejected_warehouses,
+	)
+
+	if locations:
+		sn = frappe.qb.DocType("Serial No")
+		conditions = (sn.item_code == item_code) & (sn.company == company)
+
+		for location in locations:
+			location.qty = (
+				required_qty if location.qty > required_qty else location.qty
+			)  # if extra qty in batch
+
+			serial_nos = (
+				frappe.qb.from_(sn)
+				.select(sn.name)
+				.where(
+					(conditions) & (sn.batch_no == location.batch_no) & (sn.warehouse == location.warehouse)
+				)
+				.orderby(sn.purchase_date)
+				.limit(ceil(location.qty + total_picked_qty))
+			).run(as_dict=True)
+
+			serial_nos = [sn.name for sn in serial_nos]
+			location.serial_no = serial_nos
+			location.qty = len(serial_nos)
+
+	return locations
+
+
 def get_available_item_locations_for_serialized_item(
 	item_code, from_warehouses, required_qty, company, total_picked_qty=0
 ):
@@ -760,25 +851,12 @@
 	for warehouse, serial_nos in warehouse_serial_nos_map.items():
 		qty = len(serial_nos)
 
-		bundle_doc = SerialBatchCreation(
-			{
-				"item_code": item_code,
-				"warehouse": warehouse,
-				"voucher_type": "Pick List",
-				"total_qty": qty * -1,
-				"serial_nos": serial_nos,
-				"type_of_transaction": "Outward",
-				"company": company,
-				"do_not_submit": True,
-			}
-		).make_serial_and_batch_bundle()
-
 		locations.append(
 			{
 				"qty": qty,
 				"warehouse": warehouse,
 				"item_code": item_code,
-				"serial_and_batch_bundle": bundle_doc.name,
+				"serial_nos": serial_nos,
 			}
 		)
 
@@ -808,29 +886,15 @@
 		warehouse_wise_batches[d.warehouse][d.batch_no] += d.qty
 
 	for warehouse, batches in warehouse_wise_batches.items():
-		qty = sum(batches.values())
-
-		bundle_doc = SerialBatchCreation(
-			{
-				"item_code": item_code,
-				"warehouse": warehouse,
-				"voucher_type": "Pick List",
-				"total_qty": qty * -1,
-				"batches": batches,
-				"type_of_transaction": "Outward",
-				"company": company,
-				"do_not_submit": True,
-			}
-		).make_serial_and_batch_bundle()
-
-		locations.append(
-			{
-				"qty": qty,
-				"warehouse": warehouse,
-				"item_code": item_code,
-				"serial_and_batch_bundle": bundle_doc.name,
-			}
-		)
+		for batch_no, qty in batches.items():
+			locations.append(
+				{
+					"qty": qty,
+					"warehouse": warehouse,
+					"item_code": item_code,
+					"batch_no": batch_no,
+				}
+			)
 
 	return locations
 
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
index e8e4afc..c8001fd 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
@@ -24,8 +24,11 @@
   "serial_no_and_batch_section",
   "pick_serial_and_batch",
   "serial_and_batch_bundle",
-  "serial_no",
+  "use_serial_batch_fields",
   "column_break_20",
+  "section_break_ecxc",
+  "serial_no",
+  "column_break_belw",
   "batch_no",
   "column_break_15",
   "sales_order",
@@ -72,19 +75,17 @@
    "read_only": 1
   },
   {
-   "depends_on": "serial_no",
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
-   "depends_on": "batch_no",
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
   },
   {
@@ -195,6 +196,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -204,6 +206,7 @@
    "search_index": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "pick_serial_and_batch",
    "fieldtype": "Button",
    "label": "Pick Serial / Batch No"
@@ -218,11 +221,26 @@
    "print_hide": 1,
    "read_only": 1,
    "report_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_ecxc",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_belw",
+   "fieldtype": "Column Break"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-07-26 12:54:15.785962",
+ "modified": "2024-02-04 16:12:16.257951",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Pick List Item",
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.py b/erpnext/stock/doctype/pick_list_item/pick_list_item.py
index 6e5a94e..f3f6298 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.py
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.py
@@ -37,6 +37,7 @@
 		stock_reserved_qty: DF.Float
 		stock_uom: DF.Link | None
 		uom: DF.Link | None
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 	# end: auto-generated types
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index bf6080b..14d5b94 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -369,6 +369,7 @@
 		else:
 			self.db_set("status", "Completed")
 
+		self.make_bundle_using_old_serial_batch_fields()
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating ordered qty, reserved_qty_for_subcontract in bin
 		# depends upon updated ordered qty in PO
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 9bd692a..6b01047 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -94,6 +94,7 @@
   "section_break_45",
   "add_serial_batch_bundle",
   "serial_and_batch_bundle",
+  "use_serial_batch_fields",
   "col_break5",
   "add_serial_batch_for_rejected_qty",
   "rejected_serial_and_batch_bundle",
@@ -1003,6 +1004,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -1020,24 +1022,22 @@
   {
    "fieldname": "serial_no",
    "fieldtype": "Text",
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
    "fieldname": "rejected_serial_no",
    "fieldtype": "Text",
-   "label": "Rejected Serial No",
-   "read_only": 1
+   "label": "Rejected Serial No"
   },
   {
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
    "fieldname": "rejected_serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Rejected Serial and Batch Bundle",
@@ -1045,11 +1045,13 @@
    "options": "Serial and Batch Bundle"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "add_serial_batch_for_rejected_qty",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No (Rejected Qty)"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "section_break_3vxt",
    "fieldtype": "Section Break"
   },
@@ -1058,6 +1060,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "add_serial_batch_bundle",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No"
@@ -1098,12 +1101,18 @@
    "read_only": 1,
    "report_hide": 1,
    "search_index": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-12-25 22:32:09.801965",
+ "modified": "2024-02-04 11:48:06.653771",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
index aed8d21..3c6dcdc 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
@@ -99,6 +99,7 @@
 		supplier_part_no: DF.Data | None
 		total_weight: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		valuation_rate: DF.Currency
 		warehouse: DF.Link | None
 		weight_per_unit: DF.Float
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
index 9cad8f6..ea33c54 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
@@ -1677,7 +1677,10 @@
 			query = query.where(sb_entry.batch_no == kwargs.batch_no)
 
 	if kwargs.warehouse:
-		query = query.where(sre.warehouse == kwargs.warehouse)
+		if isinstance(kwargs.warehouse, list):
+			query = query.where(sre.warehouse.isin(kwargs.warehouse))
+		else:
+			query = query.where(sre.warehouse == kwargs.warehouse)
 
 	if kwargs.ignore_voucher_nos:
 		query = query.where(sre.name.notin(kwargs.ignore_voucher_nos))
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index faccfa3..10e3522 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -274,6 +274,7 @@
 
 	def on_submit(self):
 		self.validate_closed_subcontracting_order()
+		self.make_bundle_using_old_serial_batch_fields()
 		self.update_stock_ledger()
 		self.update_work_order()
 		self.validate_subcontract_order()
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index bd84a2b..bd11d0b 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -47,9 +47,12 @@
   "amount",
   "serial_no_batch",
   "add_serial_batch_bundle",
-  "serial_and_batch_bundle",
+  "use_serial_batch_fields",
   "col_break4",
+  "serial_and_batch_bundle",
+  "section_break_rdtg",
   "serial_no",
+  "column_break_prps",
   "batch_no",
   "accounting",
   "expense_account",
@@ -289,27 +292,27 @@
    "no_copy": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
    "label": "Serial No",
    "no_copy": 1,
    "oldfieldname": "serial_no",
-   "oldfieldtype": "Text",
-   "read_only": 1
+   "oldfieldtype": "Text"
   },
   {
    "fieldname": "col_break4",
    "fieldtype": "Column Break"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "no_copy": 1,
    "oldfieldname": "batch_no",
    "oldfieldtype": "Link",
-   "options": "Batch",
-   "read_only": 1
+   "options": "Batch"
   },
   {
    "depends_on": "eval:parent.inspection_required && doc.t_warehouse",
@@ -573,24 +576,41 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "add_serial_batch_bundle",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
    "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "print_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_rdtg",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_prps",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2024-01-12 11:56:04.626103",
+ "modified": "2024-02-04 16:16:47.606270",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Entry Detail",
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
index a6dd0fa..47c443c 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py
@@ -63,6 +63,7 @@
 		transfer_qty: DF.Float
 		transferred_qty: DF.Float
 		uom: DF.Link
+		use_serial_batch_fields: DF.Check
 		valuation_rate: DF.Currency
 	# end: auto-generated types
 
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 788ae0d..cc8a7c5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -99,6 +99,7 @@
 					)
 
 	def on_submit(self):
+		self.make_bundle_using_old_serial_batch_fields()
 		self.update_stock_ledger()
 		self.make_gl_entries()
 		self.repost_future_sle_and_gle()
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
index fc4ae6a..27693d2 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -19,11 +19,14 @@
   "allow_zero_valuation_rate",
   "serial_no_and_batch_section",
   "add_serial_batch_bundle",
-  "serial_and_batch_bundle",
-  "batch_no",
+  "use_serial_batch_fields",
   "column_break_11",
+  "serial_and_batch_bundle",
   "current_serial_and_batch_bundle",
+  "section_break_lypk",
   "serial_no",
+  "column_break_eefq",
+  "batch_no",
   "section_break_3",
   "current_qty",
   "current_amount",
@@ -103,10 +106,10 @@
    "label": "Serial No and Batch"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Long Text",
-   "label": "Serial No",
-   "read_only": 1
+   "label": "Serial No"
   },
   {
    "fieldname": "column_break_11",
@@ -171,11 +174,11 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "options": "Batch",
-   "read_only": 1,
    "search_index": 1
   },
   {
@@ -195,6 +198,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial / Batch Bundle",
@@ -204,6 +208,7 @@
    "search_index": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "current_serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Current Serial / Batch Bundle",
@@ -212,6 +217,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "add_serial_batch_bundle",
    "fieldtype": "Button",
    "label": "Add Serial / Batch No"
@@ -222,11 +228,26 @@
    "fieldtype": "Link",
    "label": "Item Group",
    "options": "Item Group"
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_lypk",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_eefq",
+   "fieldtype": "Column Break"
   }
  ],
  "istable": 1,
  "links": [],
- "modified": "2024-01-14 10:04:23.599951",
+ "modified": "2024-02-04 16:19:44.576022",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reconciliation Item",
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
index c82cdf5..1938fec 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
@@ -26,6 +26,7 @@
 		current_valuation_rate: DF.Currency
 		has_item_scanned: DF.Data | None
 		item_code: DF.Link
+		item_group: DF.Link | None
 		item_name: DF.Data | None
 		parent: DF.Data
 		parentfield: DF.Data
@@ -34,6 +35,7 @@
 		quantity_difference: DF.ReadOnly | None
 		serial_and_batch_bundle: DF.Link | None
 		serial_no: DF.LongText | None
+		use_serial_batch_fields: DF.Check
 		valuation_rate: DF.Currency
 		warehouse: DF.Link
 	# end: auto-generated types
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json
index dc27974..344486c 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.json
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -50,6 +50,7 @@
   "disable_serial_no_and_batch_selector",
   "use_naming_series",
   "naming_series_prefix",
+  "use_serial_batch_fields",
   "stock_planning_tab",
   "auto_material_request",
   "auto_indent",
@@ -420,6 +421,12 @@
    "fieldname": "auto_reserve_stock_for_sales_order_on_purchase",
    "fieldtype": "Check",
    "label": "Auto Reserve Stock for Sales Order on Purchase"
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial / Batch Fields"
   }
  ],
  "icon": "icon-cog",
@@ -427,7 +434,7 @@
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2024-01-30 14:03:52.143457",
+ "modified": "2024-02-04 12:01:31.931864",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Settings",
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index 088c7cd..c4960aa 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -57,6 +57,7 @@
 		stock_uom: DF.Link | None
 		update_existing_price_list_rate: DF.Check
 		use_naming_series: DF.Check
+		use_serial_batch_fields: DF.Check
 		valuation_method: DF.Literal["FIFO", "Moving Average", "LIFO"]
 	# end: auto-generated types
 
@@ -68,6 +69,7 @@
 			"allow_negative_stock",
 			"default_warehouse",
 			"set_qty_in_transactions_based_on_serial_no_input",
+			"use_serial_batch_fields",
 		]:
 			frappe.db.set_default(key, self.get(key, ""))
 
diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py
index 4cfe5d8..41baf59 100644
--- a/erpnext/stock/serial_batch_bundle.py
+++ b/erpnext/stock/serial_batch_bundle.py
@@ -793,6 +793,9 @@
 			setattr(self, "actual_qty", qty)
 			self.__dict__["actual_qty"] = self.actual_qty
 
+		if not hasattr(self, "use_serial_batch_fields"):
+			setattr(self, "use_serial_batch_fields", 0)
+
 	def duplicate_package(self):
 		if not self.serial_and_batch_bundle:
 			return
@@ -901,9 +904,14 @@
 			self.batches = get_available_batches(kwargs)
 
 	def set_auto_serial_batch_entries_for_inward(self):
+		print(self.get("serial_nos"))
+
 		if (self.get("batches") and self.has_batch_no) or (
 			self.get("serial_nos") and self.has_serial_no
 		):
+			if self.use_serial_batch_fields and self.get("serial_nos"):
+				self.make_serial_no_if_not_exists()
+
 			return
 
 		self.batch_no = None
@@ -915,6 +923,59 @@
 		else:
 			self.batches = frappe._dict({self.batch_no: abs(self.actual_qty)})
 
+	def make_serial_no_if_not_exists(self):
+		non_exists_serial_nos = []
+		for row in self.serial_nos:
+			if not frappe.db.exists("Serial No", row):
+				non_exists_serial_nos.append(row)
+
+		if non_exists_serial_nos:
+			self.make_serial_nos(non_exists_serial_nos)
+
+	def make_serial_nos(self, serial_nos):
+		serial_nos_details = []
+		batch_no = None
+		if self.batches:
+			batch_no = list(self.batches.keys())[0]
+
+		for serial_no in serial_nos:
+			serial_nos_details.append(
+				(
+					serial_no,
+					serial_no,
+					now(),
+					now(),
+					frappe.session.user,
+					frappe.session.user,
+					self.warehouse,
+					self.company,
+					self.item_code,
+					self.item_name,
+					self.description,
+					"Active",
+					batch_no,
+				)
+			)
+
+		if serial_nos_details:
+			fields = [
+				"name",
+				"serial_no",
+				"creation",
+				"modified",
+				"owner",
+				"modified_by",
+				"warehouse",
+				"company",
+				"item_code",
+				"item_name",
+				"description",
+				"status",
+				"batch_no",
+			]
+
+			frappe.db.bulk_insert("Serial No", fields=fields, values=set(serial_nos_details))
+
 	def set_serial_batch_entries(self, doc):
 		if self.get("serial_nos"):
 			serial_no_wise_batch = frappe._dict({})
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
index 7c2a1f1..3467b82 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
@@ -149,6 +149,7 @@
 		self.update_prevdoc_status()
 		self.set_subcontracting_order_status()
 		self.set_consumed_qty_in_subcontract_order()
+		self.make_bundle_using_old_serial_batch_fields()
 		self.update_stock_ledger()
 		self.make_gl_entries()
 		self.repost_future_sle_and_gle()
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
index 9bfc2fd..9d36359 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
@@ -48,11 +48,14 @@
   "reference_name",
   "section_break_45",
   "serial_and_batch_bundle",
-  "serial_no",
+  "use_serial_batch_fields",
   "col_break5",
   "rejected_serial_and_batch_bundle",
-  "batch_no",
+  "section_break_jshh",
+  "serial_no",
   "rejected_serial_no",
+  "column_break_henr",
+  "batch_no",
   "manufacture_details",
   "manufacturer",
   "column_break_16",
@@ -311,22 +314,20 @@
    "label": "Serial and Batch Details"
   },
   {
-   "depends_on": "eval:!doc.is_fixed_asset",
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Small Text",
    "label": "Serial No",
-   "no_copy": 1,
-   "read_only": 1
+   "no_copy": 1
   },
   {
-   "depends_on": "eval:!doc.is_fixed_asset",
+   "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "no_copy": 1,
    "options": "Batch",
-   "print_hide": 1,
-   "read_only": 1
+   "print_hide": 1
   },
   {
    "depends_on": "eval: !parent.is_return",
@@ -478,6 +479,7 @@
    "label": "Accounting Details"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Serial and Batch Bundle",
@@ -486,6 +488,7 @@
    "print_hide": 1
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "rejected_serial_and_batch_bundle",
    "fieldtype": "Link",
    "label": "Rejected Serial and Batch Bundle",
@@ -546,12 +549,27 @@
    "fieldtype": "Check",
    "label": "Include Exploded Items",
    "print_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_jshh",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_henr",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-11-30 12:05:51.920705",
+ "modified": "2024-02-04 16:23:30.374865",
  "modified_by": "Administrator",
  "module": "Subcontracting",
  "name": "Subcontracting Receipt Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
index d02160e..1a4ce5b 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
@@ -58,6 +58,7 @@
 		subcontracting_order: DF.Link | None
 		subcontracting_order_item: DF.Data | None
 		subcontracting_receipt_item: DF.Data | None
+		use_serial_batch_fields: DF.Check
 		warehouse: DF.Link | None
 	# end: auto-generated types
 
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
index 90bcf4e..1c8e9dd 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
@@ -26,10 +26,13 @@
   "current_stock",
   "secbreak_3",
   "serial_and_batch_bundle",
-  "batch_no",
+  "use_serial_batch_fields",
   "col_break4",
+  "subcontracting_order",
+  "section_break_zwnh",
   "serial_no",
-  "subcontracting_order"
+  "column_break_qibi",
+  "batch_no"
  ],
  "fields": [
   {
@@ -60,19 +63,19 @@
    "width": "300px"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "label": "Batch No",
    "no_copy": 1,
-   "options": "Batch",
-   "read_only": 1
+   "options": "Batch"
   },
   {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
    "fieldname": "serial_no",
    "fieldtype": "Text",
    "label": "Serial No",
-   "no_copy": 1,
-   "read_only": 1
+   "no_copy": 1
   },
   {
    "fieldname": "col_break1",
@@ -198,6 +201,7 @@
   },
   {
    "columns": 2,
+   "depends_on": "eval:doc.use_serial_batch_fields === 0",
    "fieldname": "serial_and_batch_bundle",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -205,12 +209,27 @@
    "no_copy": 1,
    "options": "Serial and Batch Bundle",
    "print_hide": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "use_serial_batch_fields",
+   "fieldtype": "Check",
+   "label": "Use Serial No / Batch Fields"
+  },
+  {
+   "depends_on": "eval:doc.use_serial_batch_fields === 1",
+   "fieldname": "section_break_zwnh",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_qibi",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2023-03-15 13:55:08.132626",
+ "modified": "2024-02-04 16:32:17.534162",
  "modified_by": "Administrator",
  "module": "Subcontracting",
  "name": "Subcontracting Receipt Supplied Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
index 2ee5551..8f09197a 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.py
@@ -35,6 +35,7 @@
 		serial_no: DF.Text | None
 		stock_uom: DF.Link | None
 		subcontracting_order: DF.Link | None
+		use_serial_batch_fields: DF.Check
 	# end: auto-generated types
 
 	pass