feat!: add pick batch button (#25413)

* feat!: add pick batch button

BREAKING CHANGE: replaces setup_serial_no with setup_serial_or_batch_no.

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* refactor: use setup_serial_or_batch_no instead of setup_serial_no

* style: add sider review changes

* refactor: make consice, extract function

* refactor: camel to snake casing
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 8a42d9e..7c73ad6 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -356,11 +356,11 @@
 	},
 
 	items_on_form_rendered: function() {
-		erpnext.setup_serial_no();
+		erpnext.setup_serial_or_batch_no();
 	},
 
 	packed_items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no();
+		erpnext.setup_serial_or_batch_no();
 	},
 
 	make_sales_return: function() {
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 19c9073..472746a 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -48,31 +48,24 @@
 		return cint(frappe.boot.sysdefaults.allow_stale);
 	},
 
-	setup_serial_no: function() {
-		var grid_row = cur_frm.open_grid_row();
-		if(!grid_row || !grid_row.grid_form.fields_dict.serial_no ||
-			grid_row.grid_form.fields_dict.serial_no.get_status()!=="Write") return;
+	setup_serial_or_batch_no: function() {
+		let grid_row = cur_frm.open_grid_row();
+		if (!grid_row || !grid_row.grid_form.fields_dict.serial_no ||
+			grid_row.grid_form.fields_dict.serial_no.get_status() !== "Write") return;
 
-		var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
-			.appendTo($("<div>")
-				.css({"margin-bottom": "10px", "margin-top": "10px"})
-				.appendTo(grid_row.grid_form.fields_dict.serial_no.$wrapper));
+		frappe.model.get_value('Item', {'name': grid_row.doc.item_code},
+			['has_serial_no', 'has_batch_no'], ({has_serial_no, has_batch_no}) => {
+				Object.assign(grid_row.doc, {has_serial_no, has_batch_no});
 
-		var me = this;
-		$btn.on("click", function() {
-			let callback = '';
-			let on_close = '';
-
-			frappe.model.get_value('Item', {'name':grid_row.doc.item_code}, 'has_serial_no',
-				(data) => {
-					if(data) {
-						grid_row.doc.has_serial_no = data.has_serial_no;
-						me.show_serial_batch_selector(grid_row.frm, grid_row.doc,
-							callback, on_close, true);
-					}
+				if (has_serial_no) {
+					attach_selector_button(__("Add Serial No"),
+						grid_row.grid_form.fields_dict.serial_no.$wrapper, this, grid_row);
+				} else if (has_batch_no) {
+					attach_selector_button(__("Pick Batch No"),
+						grid_row.grid_form.fields_dict.batch_no.$wrapper, this, grid_row);
 				}
-			);
-		});
+			}
+		);
 	},
 
 	route_to_adjustment_jv: (args) => {
@@ -743,3 +736,14 @@
 		});
 	}
 });
+
+function attach_selector_button(inner_text, append_loction, context, grid_row) {
+	let $btn_div = $("<div>").css({"margin-bottom": "10px", "margin-top": "10px"})
+		.appendTo(append_loction);
+	let $btn = $(`<button class="btn btn-sm btn-default">${inner_text}</button>`)
+		.appendTo($btn_div);
+
+	$btn.on("click", function() {
+		context.show_serial_batch_selector(grid_row.frm, grid_row.doc, "", "", true);
+	});
+}
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 334bdea..7875b9c 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -273,11 +273,11 @@
 	},
 
 	items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no();
+		erpnext.setup_serial_or_batch_no();
 	},
 
 	packed_items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no();
+		erpnext.setup_serial_or_batch_no();
 	},
 
 	close_delivery_note: function(doc){
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index ef7d54a..772c8df 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -996,7 +996,7 @@
 	},
 
 	items_on_form_rendered: function(doc, grid_row) {
-		erpnext.setup_serial_no();
+		erpnext.setup_serial_or_batch_no();
 	},
 
 	toggle_related_fields: function(doc) {