fix: multiple pos issues (#23725)

* fix: point of sale search

* fix: pos fetches expired serial nos

* fix: pos doesn't refresh on route change

* fix: opening balances not set in opening entry

* fix: remove debug statement

* fix: invalid query if no serial no is reserved by pos invoice

* chore: make new order btn primary

* chore: filter warehouse by company

* chore: add shortcuts for new order and email

* fix: cannot fetch serial no if no batch control

* chore: add shortcuts for menu items

* feat: standard keyboard shortcuts for pos page

* feat: display only items that are in stock

* fix: empty point of sale page if opening entry dialog is closed

* feat: conversion factor in pos item details

* fix: show all invalid mode of payments

* chore: show all items if allow negative stock is checked

* fix: -ve amount set when changing mode of payment

* fix: pos closing validations

* fix: test

* fix: non expired serial no fetching query

* fix: cannot dismiss pos opening creation dialog

* fix: transalation strings

* fix: msgprint to throw

* chore: use as_list in frappe.throw

* chore: clean up pos invoice.js & .py

* fix: codacy

* fix: transalation syntax

* fix: codacy

* fix: set_missing_values called twice from pos page

* fix: mode selector with double spaces

* fix: do not allow tables in pos additional fields

* fix: pos is not defined

* feat: set mode of payments for returns

* fix: remove naming series from pos profile

* fix: error message

* fix: minor bugs

* chore: re-arrange pos closing entry detail fields

* fix: sider & frappe linter

* fix: more translation strings

* fix: travis

* fix: more translation strings

* fix: sider

* fix: travis

* fix: unexpected end of string

* fix: travis
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index be30086..99f3995 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -6,6 +6,7 @@
 
 	apply_pricing_rule_on_item: function(item){
 		let effective_item_rate = item.price_list_rate;
+		let item_rate = item.rate;
 		if (in_list(["Sales Order", "Quotation"], item.parenttype) && item.blanket_order_rate) {
 			effective_item_rate = item.blanket_order_rate;
 		}
@@ -17,15 +18,17 @@
 		}
 		item.base_rate_with_margin = flt(item.rate_with_margin) * flt(this.frm.doc.conversion_rate);
 
-		item.rate = flt(item.rate_with_margin , precision("rate", item));
+		item_rate = flt(item.rate_with_margin , precision("rate", item));
 
 		if(item.discount_percentage){
 			item.discount_amount = flt(item.rate_with_margin) * flt(item.discount_percentage) / 100;
 		}
 
 		if (item.discount_amount) {
-			item.rate = flt((item.rate_with_margin) - (item.discount_amount), precision('rate', item));
+			item_rate = flt((item.rate_with_margin) - (item.discount_amount), precision('rate', item));
 		}
+
+		frappe.model.set_value(item.doctype, item.name, "rate", item_rate);
 	},
 
 	calculate_taxes_and_totals: function(update_paid_amount) {
@@ -88,11 +91,8 @@
 			if(this.frm.doc.currency == company_currency) {
 				this.frm.set_value("conversion_rate", 1);
 			} else {
-				const err_message = __('{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}', [
-					conversion_rate_label,
-					this.frm.doc.currency,
-					company_currency
-				]);
+				const subs =  [conversion_rate_label, this.frm.doc.currency, company_currency];
+				const err_message = __('{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}', subs);
 				frappe.throw(err_message);
 			}
 		}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3391179..23705a8 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1049,14 +1049,13 @@
 		if(item.item_code && item.uom) {
 			return this.frm.call({
 				method: "erpnext.stock.get_item_details.get_conversion_factor",
-				child: item,
 				args: {
 					item_code: item.item_code,
 					uom: item.uom
 				},
 				callback: function(r) {
 					if(!r.exc) {
-						me.conversion_factor(me.frm.doc, cdt, cdn);
+						frappe.model.set_value(cdt, cdn, 'conversion_factor', r.message.conversion_factor);
 					}
 				}
 			});
diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js
index d9f6e1d..2623c3c 100644
--- a/erpnext/public/js/utils/serial_no_batch_selector.js
+++ b/erpnext/public/js/utils/serial_no_batch_selector.js
@@ -75,7 +75,7 @@
 				fieldtype:'Float',
 				read_only: me.has_batch && !me.has_serial_no,
 				label: __(me.has_batch && !me.has_serial_no ? 'Total Qty' : 'Qty'),
-				default: 0
+				default: flt(me.item.stock_qty),
 			},
 			{
 				fieldname: 'auto_fetch_button',
@@ -91,7 +91,8 @@
 							qty: qty,
 							item_code: me.item_code,
 							warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '',
-							batch_no: me.item.batch_no || null
+							batch_no: me.item.batch_no || null,
+							posting_date: me.frm.doc.posting_date || me.frm.doc.transaction_date
 						}
 					});
 
@@ -100,11 +101,12 @@
 						let records_length = auto_fetched_serial_numbers.length;
 						if (!records_length) {
 							const warehouse = me.dialog.fields_dict.warehouse.get_value().bold();
-							frappe.msgprint(__(`Serial numbers unavailable for Item ${me.item.item_code.bold()} 
-								under warehouse ${warehouse}. Please try changing warehouse.`));
+							frappe.msgprint(
+								__('Serial numbers unavailable for Item {0} under warehouse {1}. Please try changing warehouse.', [me.item.item_code.bold(), warehouse])
+							);
 						}
 						if (records_length < qty) {
-							frappe.msgprint(__(`Fetched only ${records_length} available serial numbers.`));
+							frappe.msgprint(__('Fetched only {0} available serial numbers.', [records_length]));
 						}
 						let serial_no_list_field = this.dialog.fields_dict.serial_no;
 						numbers = auto_fetched_serial_numbers.join('\n');
@@ -189,15 +191,12 @@
 		}
 		if(this.has_batch && !this.has_serial_no) {
 			if(values.batches.length === 0 || !values.batches) {
-				frappe.throw(__("Please select batches for batched item "
-					+ values.item_code));
-				return false;
+				frappe.throw(__("Please select batches for batched item {0}", [values.item_code]));
 			}
 			values.batches.map((batch, i) => {
 				if(!batch.selected_qty || batch.selected_qty === 0 ) {
 					if (!this.show_dialog) {
-						frappe.throw(__("Please select quantity on row " + (i+1)));
-						return false;
+						frappe.throw(__("Please select quantity on row {0}", [i+1]));
 					}
 				}
 			});
@@ -206,9 +205,7 @@
 		} else {
 			let serial_nos = values.serial_no || '';
 			if (!serial_nos || !serial_nos.replace(/\s/g, '').length) {
-				frappe.throw(__("Please enter serial numbers for serialized item "
-					+ values.item_code));
-				return false;
+				frappe.throw(__("Please enter serial numbers for serialized item {0}", [values.item_code]));
 			}
 			return true;
 		}
@@ -355,8 +352,7 @@
 							});
 							if (selected_batches.includes(val)) {
 								this.set_value("");
-								frappe.throw(__(`Batch ${val} already selected.`));
-								return;
+								frappe.throw(__('Batch {0} already selected.', [val]));
 							}
 
 							if (me.warehouse_details.name) {
@@ -375,8 +371,7 @@
 
 							} else {
 								this.set_value("");
-								frappe.throw(__(`Please select a warehouse to get available
-									quantities`));
+								frappe.throw(__('Please select a warehouse to get available quantities'));
 							}
 							// e.stopImmediatePropagation();
 						}
@@ -411,8 +406,7 @@
 								parseFloat(available_qty) < parseFloat(selected_qty)) {
 
 								this.set_value('0');
-								frappe.throw(__(`For transfer from source, selected quantity cannot be
-									greater than available quantity`));
+								frappe.throw(__('For transfer from source, selected quantity cannot be greater than available quantity'));
 							} else {
 								this.grid.refresh();
 							}
@@ -451,20 +445,12 @@
 			frappe.call({
 				method: "erpnext.stock.doctype.serial_no.serial_no.get_pos_reserved_serial_nos",
 				args: {
-					item_code: me.item_code,
-					warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : ''
+					filters: {
+						item_code: me.item_code,
+						warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '',
+					}
 				}
 			}).then((data) => {
-				if (!data.message[1].length) {
-					this.showing_reserved_serial_nos_error = true;
-					const warehouse = me.dialog.fields_dict.warehouse.get_value().bold();
-					const d = frappe.msgprint(__(`Serial numbers unavailable for Item ${me.item.item_code.bold()} 
-						under warehouse ${warehouse}. Please try changing warehouse.`));
-					d.get_close_btn().on('click', () => {
-						this.showing_reserved_serial_nos_error = false;
-						d.hide();
-					});
-				}
 				serial_no_filters['name'] = ["not in", data.message[0]]
 			})
 		}