Merge pull request #17263 from rohitwaghchaure/finance_book_blank_issue_develop

fix: If finance book filter is not set then show all the entries(Cherry-pick)
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.js b/erpnext/hr/doctype/upload_attendance/upload_attendance.js
index 776fd3c..277c060 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.js
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.js
@@ -29,19 +29,12 @@
 			});
 	},
 
-	show_upload: function() {
-		var me = this;
+	show_upload() {
 		var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty();
-
-		// upload
-		frappe.upload.make({
-			parent: $wrapper,
-			args: {
-				method: 'erpnext.hr.doctype.upload_attendance.upload_attendance.upload'
-			},
-			no_socketio: true,
-			sample_url: "e.g. http://example.com/somefile.csv",
-			callback: function(attachment, r) {
+		new frappe.ui.FileUploader({
+			wrapper: $wrapper,
+			method: 'erpnext.hr.doctype.upload_attendance.upload_attendance.upload',
+			on_success(file_doc, r) {
 				var $log_wrapper = $(cur_frm.fields_dict.import_log.wrapper).empty();
 
 				if(!r.messages) r.messages = [];
@@ -59,10 +52,10 @@
 					});
 
 					r.messages = ["<h4 style='color:red'>"+__("Import Failed!")+"</h4>"]
-						.concat(r.messages)
+						.concat(r.messages);
 				} else {
-					r.messages = ["<h4 style='color:green'>"+__("Import Successful!")+"</h4>"].
-						concat(r.message.messages)
+					r.messages = ["<h4 style='color:green'>"+__("Import Successful!")+"</h4>"]
+						.concat(r.message.messages);
 				}
 
 				$.each(r.messages, function(i, v) {
@@ -79,11 +72,7 @@
 				});
 			}
 		});
-
-		// rename button
-		$wrapper.find('form input[type="submit"]')
-			.attr('value', 'Upload and Import')
-	}
+	},
 })
 
 cur_frm.cscript = new erpnext.hr.AttendanceControlPanel({frm: cur_frm});
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
index db74b10..6a4ea6a 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
@@ -116,10 +116,10 @@
 	if not frappe.has_permission("Attendance", "create"):
 		raise frappe.PermissionError
 
-	from frappe.utils.csvutils import read_csv_content_from_uploaded_file
+	from frappe.utils.csvutils import read_csv_content
 	from frappe.modules import scrub
 
-	rows = read_csv_content_from_uploaded_file()
+	rows = read_csv_content(frappe.local.uploaded_file)
 	rows = list(filter(lambda x: x and any(x), rows))
 	if not rows:
 		msg = [_("Please select a csv file")]
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index fb4f350..6860d6a 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -58,43 +58,9 @@
 				.css({"margin-bottom": "10px", "margin-top": "10px"})
 				.appendTo(grid_row.grid_form.fields_dict.serial_no.$wrapper));
 
+		var me = this;
 		$btn.on("click", function() {
-			var d = new frappe.ui.Dialog({
-				title: __("Add Serial No"),
-				fields: [
-					{
-						"fieldtype": "Link",
-						"fieldname": "serial_no",
-						"options": "Serial No",
-						"label": __("Serial No"),
-						"get_query": function () {
-							return {
-								filters: {
-									item_code:grid_row.doc.item_code,
-									warehouse:cur_frm.doc.is_return ? null : grid_row.doc.warehouse
-								}
-							}
-						}
-					},
-					{
-						"fieldtype": "Button",
-						"fieldname": "add",
-						"label": __("Add")
-					}
-				]
-			});
-
-			d.get_input("add").on("click", function() {
-				var serial_no = d.get_value("serial_no");
-				if(serial_no) {
-					var val = (grid_row.doc.serial_no || "").split("\n").concat([serial_no]).join("\n");
-					grid_row.grid_form.fields_dict.serial_no.set_model_value(val.trim());
-				}
-				d.hide();
-				return false;
-			});
-
-			d.show();
+			me.show_serial_batch_selector(grid_row.frm, grid_row.doc);
 		});
 	}
 });
diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js
index b94cdd8..b22d5ca 100644
--- a/erpnext/public/js/utils/serial_no_batch_selector.js
+++ b/erpnext/public/js/utils/serial_no_batch_selector.js
@@ -5,12 +5,11 @@
 		this.show_dialog = show_dialog;
 		// frm, item, warehouse_details, has_batch, oldest
 		let d = this.item;
-
-		// Don't show dialog if batch no or serial no already set
-		if(d && d.has_batch_no && (!d.batch_no || this.show_dialog)) {
+		if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) {
 			this.has_batch = 1;
 			this.setup();
-		} else if(d && d.has_serial_no && (!d.serial_no || this.show_dialog)) {
+		// !(this.show_dialog == false) ensures that show_dialog is implictly true, even when undefined
+		} else if(d && d.has_serial_no && !(this.show_dialog == false)) {
 			this.has_batch = 0;
 			this.setup();
 		}
@@ -68,13 +67,41 @@
 			{
 				fieldname: 'qty',
 				fieldtype:'Float',
-				read_only: 1,
+				read_only: me.has_batch,
 				label: __(me.has_batch ? 'Total Qty' : 'Qty'),
 				default: 0
 			},
+			{
+				fieldname: 'auto_fetch_button',
+				fieldtype:'Button',
+				hidden: me.has_batch,
+				label: __('Fetch based on FIFO'),
+				click: () => {
+					let qty = this.dialog.fields_dict.qty.get_value();
+					let numbers = frappe.call({
+						method: "erpnext.stock.doctype.serial_no.serial_no.auto_fetch_serial_number",
+						args: {
+							qty: qty,
+							item_code: me.item_code,
+							warehouse: me.warehouse_details.name
+						}
+					});
+
+					numbers.then((data) => {
+						let auto_fetched_serial_numbers = data.message;
+						let records_length = auto_fetched_serial_numbers.length;
+						if (records_length < qty) {
+							frappe.msgprint(`Fetched only ${records_length} serial numbers.`);
+						}
+						let serial_no_list_field = this.dialog.fields_dict.serial_no;
+						numbers = auto_fetched_serial_numbers.join('\n');
+						serial_no_list_field.set_value(numbers);
+					});
+				}
+			}
 		];
 
-		if(this.has_batch) {
+		if (this.has_batch) {
 			title = __("Select Batch Numbers");
 			fields = fields.concat(this.get_batch_fields());
 		} else {
@@ -87,6 +114,10 @@
 			fields: fields
 		});
 
+		if (this.item.serial_no) {
+			this.dialog.fields_dict.serial_no.set_value(this.item.serial_no);
+		}
+
 		this.dialog.set_primary_action(__('Insert'), function() {
 			me.values = me.dialog.get_values();
 			if(me.validate()) {
@@ -234,7 +265,7 @@
 		var me = this;
 		return [
 			{fieldtype:'Section Break', label: __('Batches')},
-			{fieldname: 'batches', fieldtype: 'Table',
+			{fieldname: 'batches', fieldtype: 'Table', label: __('Batch Entries'),
 				fields: [
 					{
 						fieldtype:'Link',
@@ -343,10 +374,10 @@
 		var me = this;
 		this.serial_list = [];
 		return [
-			{fieldtype: 'Section Break', label: __('Serial No')},
+			{fieldtype: 'Section Break', label: __('Serial Numbers')},
 			{
 				fieldtype: 'Link', fieldname: 'serial_no_select', options: 'Serial No',
-				label: __('Select'),
+				label: __('Select to add Serial Number.'),
 				get_query: function() {
 					return { filters: {item_code: me.item_code, warehouse: me.warehouse_details.name}};
 				},
@@ -383,6 +414,7 @@
 			{
 				fieldname: 'serial_no',
 				fieldtype: 'Small Text',
+				label: __(me.has_batch ? 'Selected Batch Numbers' : 'Selected Serial Numbers'),
 				onchange: function() {
 					me.serial_list = this.get_value()
 						.replace(/\n/g, ' ').match(/\S+/g) || [];
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index 4c0f42d..308b8ed 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -54,15 +54,39 @@
 				this.prepare_menu();
 				this.set_online_status();
 			},
-			() => this.setup_company(),
 			() => this.make_new_invoice(),
 			() => {
+				if(!this.frm.doc.company) {
+					this.setup_company()
+						.then((company) => {
+							this.frm.doc.company = company;
+							this.get_pos_profile();
+						});
+				}
+			},
+			() => {
 				frappe.dom.unfreeze();
 			},
 			() => this.page.set_title(__('Point of Sale'))
 		]);
 	}
 
+	get_pos_profile() {
+		return frappe.xcall("erpnext.stock.get_item_details.get_pos_profile",
+			{'company': this.frm.doc.company})
+			.then((r) => {
+				if(r) {
+					this.frm.doc.pos_profile = r.name;
+					this.set_pos_profile_data()
+						.then(() => {
+							this.on_change_pos_profile();
+						});
+				} else {
+					this.raise_exception_for_pos_profile();
+				}
+		});
+	}
+
 	set_online_status() {
 		this.connection_status = false;
 		this.page.set_indicator(__("Offline"), "grey");
@@ -77,6 +101,11 @@
 		});
 	}
 
+	raise_exception_for_pos_profile() {
+		setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
+		frappe.throw(__("POS Profile is required to use Point-of-Sale"));
+	}
+
 	prepare_dom() {
 		this.wrapper.append(`
 			<div class="pos">
@@ -489,7 +518,7 @@
 
 	setup_company() {
 		return new Promise(resolve => {
-			if(!frappe.sys_defaults.company) {
+			if(!this.frm.doc.company) {
 				frappe.prompt({fieldname:"company", options: "Company", fieldtype:"Link",
 					label: __("Select Company"), reqd: 1}, (data) => {
 						this.company = data.company;
@@ -529,6 +558,10 @@
 		return new Promise(resolve => {
 			if (this.frm) {
 				this.frm = get_frm(this.frm);
+				if(this.company) {
+					this.frm.doc.company = this.company;
+				}
+
 				resolve();
 			} else {
 				frappe.model.with_doctype(doctype, () => {
@@ -545,6 +578,7 @@
 			frm.refresh(name);
 			frm.doc.items = [];
 			frm.doc.is_pos = 1;
+
 			return frm;
 		}
 	}
@@ -554,6 +588,10 @@
 			this.frm.doc.company = this.company;
 		}
 
+		if (!this.frm.doc.company) {
+			return;
+		}
+
 		return new Promise(resolve => {
 			return this.frm.call({
 				doc: this.frm.doc,
@@ -562,8 +600,7 @@
 				if(!r.exc) {
 					if (!this.frm.doc.pos_profile) {
 						frappe.dom.unfreeze();
-						setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
-						frappe.throw(__("POS Profile is required to use Point-of-Sale"));
+						this.raise_exception_for_pos_profile();
 					}
 					this.frm.script_manager.trigger("update_stock");
 					frappe.model.set_default_values(this.frm.doc);
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index cb1d153..c1aef95 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -459,3 +459,13 @@
 		serial_nos = '\n'.join(dn_serial_nos)
 
 	return serial_nos
+
+@frappe.whitelist()
+def auto_fetch_serial_number(qty, item_code, warehouse):
+	serial_numbers = frappe.get_list("Serial No", filters={
+		"item_code": item_code,
+		"warehouse": warehouse,
+		"delivery_document_no": "",
+		"sales_invoice": ""
+	}, limit=qty, order_by="creation")
+	return [item['name'] for item in serial_numbers]