Item search refactor
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 56af066..60caf0f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -431,7 +431,4 @@
 erpnext.patches.v8_5.update_customer_group_in_POS_profile
 erpnext.patches.v8_6.update_timesheet_company_from_PO
 erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
-<<<<<<< HEAD
-erpnext.patches.v8_5.remove_project_type_property_setter
-=======
->>>>>>> Set write permission to sales manger for permlevel 1 in Quotation doctype
+erpnext.patches.v8_5.remove_project_type_property_setter
\ No newline at end of file
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 84ee8f5..00f8865 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -39,6 +39,7 @@
 				this.make_cart();
 				this.make_items();
 				this.bind_events();
+				this.disable_text_box_and_button();
 			}
 		]);
 	}
@@ -72,6 +73,7 @@
 
 	make_cart() {
 		this.cart = new POSCart({
+			frm: this.frm,
 			wrapper: this.wrapper.find('.cart-container'),
 			events: {
 				customer_change: (customer) => this.frm.set_value('customer', customer),
@@ -93,6 +95,10 @@
 		});
 	}
 
+	disable_text_box_and_button() {
+		$(this.wrapper).find('input, button').prop("disabled", !(this.frm.doc.docstatus===0));
+	}
+
 	make_items() {
 		this.items = new POSItems({
 			wrapper: this.wrapper.find('.item-container'),
@@ -108,21 +114,28 @@
 		});
 	}
 
-	add_item_to_cart(item_code, qty = 1) {
+	add_item_to_cart(item_code, qty = 1, barcode) {
 
 		if(this.cart.exists(item_code)) {
 			// increase qty by 1
 			this.frm.doc.items.forEach((item) => {
 				if (item.item_code === item_code) {
-					const final_qty = item.qty + qty;
-					frappe.model.set_value(item.doctype, item.name, 'qty', final_qty)
-						.then(() => {
-							if (final_qty === 0) {
-								frappe.model.clear_doc(item.doctype, item.name);
-							}
-							// update cart
-							this.cart.add_item(item);
-						});
+					if (barcode) {
+						value = barcode['serial_no'] ?
+							item.serial_no + '\n' + barcode['serial_no'] : barcode['batch_no'];
+						frappe.model.set_value(item.doctype, item.name, 
+							Object.keys(barcode)[0], final_qty);
+					} else {
+						const final_qty = item.qty + qty;
+						frappe.model.set_value(item.doctype, item.name, 'qty', final_qty)
+							.then(() => {
+								if (final_qty === 0) {
+									frappe.model.clear_doc(item.doctype, item.name);
+								}
+								// update cart
+								this.cart.add_item(item);
+							});
+					}
 				}
 			});
 			return;
@@ -200,7 +213,8 @@
 }
 
 class POSCart {
-	constructor({wrapper, events}) {
+	constructor({frm, wrapper, events}) {
+		this.frm = frm;
 		this.wrapper = wrapper;
 		this.events = events;
 		this.make();
@@ -301,25 +315,9 @@
 			$item.remove();
 		}
 	}
-
-	exists(item_code) {
-		let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
-		return $item.length > 0;
-	}
-
-	highlight_item(item_code) {
-		const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
-		$item.addClass('highlight');
-		setTimeout(() => $item.removeClass('highlight'), 1000);
-	}
-
-	scroll_to_item(item_code) {
-		const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
-		// const scrollTop = $item.offset().top - this.$cart_items.offset().top + this.$cart_items.scrollTop();
-		// this.$cart_items.animate({ scrollTop });
-	}
-
+	
 	get_item_html(item) {
+		const rate = format_currency(item.rate, this.frm.doc.currency);
 		return `
 			<div class="list-item" data-item-code="${item.item_code}">
 				<div class="item-name list-item__content list-item__content--flex-2 ellipsis">
@@ -332,7 +330,7 @@
 					${item.discount_percentage}%
 				</div>
 				<div class="rate list-item__content text-right">
-					${item.rate}
+					${rate}
 				</div>
 			</div>
 		`;
@@ -354,6 +352,23 @@
 		}
 	}
 
+	exists(item_code) {
+		let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+		return $item.length > 0;
+	}
+
+	highlight_item(item_code) {
+		const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+		$item.addClass('highlight');
+		setTimeout(() => $item.removeClass('highlight'), 1000);
+	}
+
+	scroll_to_item(item_code) {
+		const $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
+		// const scrollTop = $item.offset().top - this.$cart_items.offset().top + this.$cart_items.scrollTop();
+		// this.$cart_items.animate({ scrollTop });
+	}
+
 	bind_events() {
 		const events = this.events;
 		this.$cart_items.on('click',
@@ -381,6 +396,8 @@
 		this.wrapper = wrapper;
 		this.pos_profile = pos_profile;
 		this.items = {};
+		this.currency = this.pos_profile.currency || 
+			frappe.defaults.get_default('currency');
 
 		this.make_dom();
 		this.make_fields();
@@ -516,7 +533,8 @@
 	}
 
 	get_item_html(item) {
-		const { item_code, item_name, image: item_image, item_stock=0, item_price=0} = item;
+		const price_list_rate = format_currency(item.price_list_rate, this.currency)
+		const { item_code, item_name, item_image, item_stock=0} = item;
 		const item_title = item_name || item_code;
 
 		const template = `
@@ -542,7 +560,7 @@
 							${item_image ? `<img src="${item_image}" alt="${item_title}">` : '' }
 						</div>
 						<span class="price-info">
-							${item_price}
+							${price_list_rate}
 						</span>
 					</a>
 				</div>
@@ -552,38 +570,17 @@
 		return template;
 	}
 
-	get_items(start = 0, page_length = 20) {
+	get_items(start = 10, page_length = 20) {
+		var me = this;
 		return new Promise(res => {
 			frappe.call({
-				method: "frappe.desk.reportview.get",
-				type: "GET",
+				method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
 				args: {
-					doctype: "Item",
-					fields: [
-						"`tabItem`.`name`",
-						"`tabItem`.`owner`",
-						"`tabItem`.`docstatus`",
-						"`tabItem`.`modified`",
-						"`tabItem`.`modified_by`",
-						"`tabItem`.`item_name`",
-						"`tabItem`.`item_code`",
-						"`tabItem`.`disabled`",
-						"`tabItem`.`item_group`",
-						"`tabItem`.`stock_uom`",
-						"`tabItem`.`image`",
-						"`tabItem`.`variant_of`",
-						"`tabItem`.`has_variants`",
-						"`tabItem`.`end_of_life`",
-						"`tabItem`.`total_projected_qty`"
-					],
-					filters: [['disabled', '=', '0']],
-					order_by: "`tabItem`.`modified` desc",
-					page_length: page_length,
-					start: start
+					'price_list': this.pos_profile.selling_price_list,
+					'item': me.search_field.$input.value || ""
 				}
 			}).then(r => {
-				const data = r.message;
-				const items = frappe.utils.dict(data.keys, data.values);
+				const items = r.message;
 
 				// convert to key, value
 				let items_dict = {};
@@ -687,8 +684,11 @@
 	}
 
 	set_primary_action() {
+		var me = this;
+
 		this.dialog.set_primary_action(__("Submit"), function() {
-			// save form
+			this.frm.doc.savesubmit()
+			this.dialog.hide()
 		});
 	}
 
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
new file mode 100644
index 0000000..045ef07
--- /dev/null
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe, json
+from frappe import _
+from frappe.utils import nowdate
+from erpnext.setup.utils import get_exchange_rate
+from frappe.core.doctype.communication.email import make
+from erpnext.stock.get_item_details import get_pos_profile
+from erpnext.accounts.party import get_party_account_currency
+from erpnext.controllers.accounts_controller import get_taxes_and_charges
+
+@frappe.whitelist()
+def get_items(price_list, item=None):
+	condition = ""
+	order_by = ""
+	args = {"price_list": price_list}
+
+	if item:
+		# search serial no
+		item_code = frappe.db.sql("""select name as serial_no, item_code
+			from `tabSerial No` where name=%s""", (item), as_dict=1)
+		if item_code:
+			item_code[0]["name"] = item_code[0]["item_code"]
+			return item_code
+
+		# search barcode
+		item_code = frappe.db.sql("""select name, item_code from `tabItem`
+			where barcode=%s""",
+			(item), as_dict=1)
+		if item_code:
+			item_code[0]["barcode"] = item
+			return item_code
+
+	# locate function is used to sort by closest match from the beginning of the value
+	return frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image,
+		item_det.price_list_rate, item_det.currency
+		from `tabItem` i LEFT JOIN
+			(select item_code, price_list_rate, currency from
+				`tabItem Price`	where price_list=%(price_list)s) item_det
+		ON
+			(item_det.item_code=i.name or item_det.item_code=i.variant_of)
+		where
+			i.has_variants = 0 and (i.item_code like %(item_code)s or i.item_name like %(item_code)s)
+		limit 24""", {'item_code': '%%%s%%'%(frappe.db.escape(item)), 'price_list': price_list} , as_dict=1)