Merge branch 'master' into staging
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index c589e35..405274a 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 import frappe
 from erpnext.hooks import regional_overrides
 
-__version__ = '9.0.5'
+__version__ = '9.0.6'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 2b3459a..dd10977 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -417,6 +417,7 @@
 				'link_doctype': 'Customer',
 				'link_name': customer
 			})
+		doc.flags.ignore_mandatory = True
 		doc.save(ignore_permissions=True)
 
 def make_address(args, customer):
@@ -441,6 +442,7 @@
 	address.is_primary_address = 1
 	address.is_shipping_address = 1
 	address.update(args)
+	address.flags.ignore_mandatory = True
 	address.save(ignore_permissions = True)
 
 def make_email_queue(email_queue):
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index be0b6f7..57a8a18 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -113,6 +113,7 @@
 		});
 
 		this.page.add_menu_item(__("Sync Offline Invoices"), function () {
+			me.freeze_screen = true;
 			me.sync_sales_invoice()
 		});
 
@@ -1684,6 +1685,7 @@
 	set_interval_for_si_sync: function () {
 		var me = this;
 		setInterval(function () {
+			me.freeze_screen = false;
 			me.sync_sales_invoice()
 		}, 60000)
 	},
@@ -1697,9 +1699,12 @@
 			this.freeze = this.customer_doc.display
 		}
 
+		freeze_screen = this.freeze_screen || false;
+
 		if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
 			frappe.call({
 				method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
+				freeze: freeze_screen,
 				args: {
 					doc_list: me.si_docs,
 					email_queue_list: me.email_queue_list,
diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js
index 3e2414e..69e3d2f 100644
--- a/erpnext/public/js/utils/serial_no_batch_selector.js
+++ b/erpnext/public/js/utils/serial_no_batch_selector.js
@@ -96,7 +96,17 @@
 
 		if(this.show_dialog) {
 			let d = this.item;
-			this.dialog.set_value('serial_no', d.serial_no);
+			if (d.has_serial_no && d.serial_no) {
+				this.dialog.set_value('serial_no', d.serial_no);
+			} else if (d.batch_no) {
+				this.dialog.fields_dict.batches.df.data.push({
+					'batch_no': d.batch_no,
+					'actual_qty': d.actual_qty,
+					'selected_qty': d.qty
+				});
+
+				this.dialog.fields_dict.batches.grid.refresh();
+			}
 		}
 
 		this.dialog.show();
@@ -116,8 +126,10 @@
 			}
 			values.batches.map((batch, i) => {
 				if(!batch.selected_qty || batch.selected_qty === 0 ) {
-					frappe.throw(__("Please select quantity on row " + (i+1)));
-					return false;
+					if (!this.show_dialog) {
+						frappe.throw(__("Please select quantity on row " + (i+1)));
+						return false;
+					}
 				}
 			});
 			return true;
@@ -125,9 +137,11 @@
 		} 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;
+				if (!this.show_dialog) {
+					frappe.throw(__("Please enter serial numbers for serialized item "
+						+ values.item_code));
+					return false;
+				}
 			}
 			return true;
 		}
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 1b67ff2..f9045b5 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -89,6 +89,7 @@
 		this.cart = new POSCart({
 			frm: this.frm,
 			wrapper: this.wrapper.find('.cart-container'),
+			pos_profile: this.pos_profile,
 			events: {
 				on_customer_change: (customer) => this.frm.set_value('customer', customer),
 				on_field_change: (item_code, field, value) => {
@@ -196,6 +197,7 @@
 			this.update_item_in_frm(item)
 				.then(() => {
 					// update cart
+					this.remove_item_from_cart(item);
 					this.update_cart_data(item);
 				});
 		}, true);
@@ -215,12 +217,18 @@
 		return this.frm.script_manager
 			.trigger('qty', item.doctype, item.name)
 			.then(() => {
-				if (field === 'qty' && value === 0) {
-					frappe.model.clear_doc(item.doctype, item.name);
+				if (field === 'qty') {
+					this.remove_item_from_cart(item);
 				}
 			});
 	}
 
+	remove_item_from_cart(item) {
+		if (item.qty === 0) {
+			frappe.model.clear_doc(item.doctype, item.name);
+		}
+	}
+
 	make_payment_modal() {
 		this.payment = new Payment({
 			frm: this.frm,
@@ -363,10 +371,11 @@
 };
 
 class POSCart {
-	constructor({frm, wrapper, events}) {
+	constructor({frm, wrapper, pos_profile, events}) {
 		this.frm = frm;
 		this.wrapper = wrapper;
 		this.events = events;
+		this.pos_profile = pos_profile;
 		this.make();
 		this.bind_events();
 	}
@@ -514,6 +523,7 @@
 	}
 
 	make_customer_field() {
+		let customer = this.frm.doc.customer || this.pos_profile['customer'];
 		this.customer_field = frappe.ui.form.make_control({
 			df: {
 				fieldtype: 'Link',
@@ -521,7 +531,6 @@
 				fieldname: 'customer',
 				options: 'Customer',
 				reqd: 1,
-				default: this.frm.doc.customer,
 				onchange: () => {
 					this.events.on_customer_change(this.customer_field.get_value());
 				}
@@ -529,6 +538,10 @@
 			parent: this.wrapper.find('.customer-field'),
 			render_input: true
 		});
+
+		if (customer) {
+			this.customer_field.set_value(customer);
+		}
 	}
 
 	make_numpad() {
@@ -919,7 +932,7 @@
 				}
 				if(batch_no) {
 					this.events.update_cart(items[0].item_code,
-						'batch_no', serial_no);
+						'batch_no', batch_no);
 					this.search_field.set_value('');
 				}
 			});