Add online, offline option, fix search
diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.json b/erpnext/accounts/doctype/pos_settings/pos_settings.json
index ab3976e..cdd1865 100644
--- a/erpnext/accounts/doctype/pos_settings/pos_settings.json
+++ b/erpnext/accounts/doctype/pos_settings/pos_settings.json
@@ -18,8 +18,9 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "type_of_pos", 
-   "fieldtype": "Select", 
+   "default": "0", 
+   "fieldname": "is_online", 
+   "fieldtype": "Check", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -27,10 +28,10 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Type of POS", 
+   "label": "Online", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Online\nOffline", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -54,7 +55,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-08-28 16:46:41.732676", 
+ "modified": "2017-08-29 14:34:36.166049", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "POS Settings", 
diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.py b/erpnext/accounts/doctype/pos_settings/pos_settings.py
index 4a71775..c978a4e 100644
--- a/erpnext/accounts/doctype/pos_settings/pos_settings.py
+++ b/erpnext/accounts/doctype/pos_settings/pos_settings.py
@@ -7,10 +7,4 @@
 from frappe.model.document import Document
 
 class POSSettings(Document):
-	def validate(self):
-		link = 'point-of-sale' if self.type_of_pos == 'Online' else 'pos'
-		desktop_icon = frappe.db.get_value('Desktop Icon', {'module_name': 'POS'}, 'name')
-		if desktop_icon:
-			doc = frappe.get_doc('Desktop Icon', desktop_icon)
-			doc.link = link
-			doc.save()
\ No newline at end of file
+	pass
\ No newline at end of file
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 5993724..3d5d5f4 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -8,8 +8,16 @@
 		single_column: true
 	});
 
-	wrapper.pos = new erpnext.pos.PointOfSale(wrapper);
-	cur_pos = wrapper.pos;
+	frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
+		if (r && r.is_online && !cint(r.is_online)) {
+			// offline
+			wrapper.pos = new erpnext.pos.PointOfSale(wrapper);
+			cur_pos = wrapper.pos;
+		} else {
+			// online
+			frappe.set_route('point-of-sale');
+		}
+	});
 }
 
 frappe.pages['pos'].refresh = function (wrapper) {
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 cc1e3f1..b523a49 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -7,8 +7,16 @@
 		single_column: true
 	});
 
-	wrapper.pos = new PointOfSale(wrapper);
-	window.cur_pos = wrapper.pos;
+	frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
+		if (r && r.is_online && cint(r.is_online)) {
+			// online
+			wrapper.pos = new PointOfSale(wrapper);
+			window.cur_pos = wrapper.pos;
+		} else {
+			// offline
+			frappe.set_route('pos');
+		}
+	});
 };
 
 class PointOfSale {
@@ -117,16 +125,12 @@
 			wrapper: this.wrapper.find('.item-container'),
 			pos_profile: this.pos_profile,
 			events: {
-				item_click: (item_code) => {
+				update_cart: (item, field, value) => {
 					if(!this.frm.doc.customer) {
 						frappe.throw(__('Please select a customer'));
 					}
-
-					this.update_item_in_cart(item_code, 'qty', '+1');
+					this.update_item_in_cart(item, field, value);
 					this.cart && this.cart.unselect_all();
-				},
-				update_cart: (item, field, value) => {
-					this.update_item_in_cart(item, field, value)
 				}
 			}
 		});
@@ -146,7 +150,7 @@
 			}
 
 			if(field === 'qty' && (item.serial_no || item.batch_no)) {
-				this.select_batch_and_serial_no(item)
+				this.select_batch_and_serial_no(item);
 			} else {
 				this.update_item_in_frm(item, field, value)
 					.then(() => {
@@ -257,6 +261,13 @@
 			}
 		}).then(r => {
 			this.pos_profile = r.message;
+
+			if (!this.pos_profile) {
+				this.pos_profile = {
+					currency: frappe.defaults.get_default('currency'),
+					selling_price_list: frappe.defaults.get_default('selling_price_list')
+				};
+			}
 		});
 	}
 
@@ -307,9 +318,9 @@
 		this.page.clear_menu();
 
 		// for mobile
-		this.page.add_menu_item(__("Pay"), function () {
-			//
-		}).addClass('visible-xs');
+		// this.page.add_menu_item(__("Pay"), function () {
+		//
+		// }).addClass('visible-xs');
 
 		this.page.add_menu_item(__("Form View"), function () {
 			var doc = frappe.model.sync(me.frm.doc);
@@ -319,6 +330,10 @@
 		this.page.add_menu_item(__("POS Profile"), function () {
 			frappe.set_route('List', 'POS Profile');
 		});
+
+		this.page.add_menu_item(__('POS Settings'), function() {
+			frappe.set_route('Form', 'POS Settings');
+		});
 	}
 
 	set_form_action() {
@@ -740,8 +755,7 @@
 		this.pos_profile = pos_profile;
 		this.items = {};
 		this.events = events;
-		this.currency = this.pos_profile.currency ||
-			frappe.defaults.get_default('currency');
+		this.currency = this.pos_profile.currency;
 
 		this.make_dom();
 		this.make_fields();
@@ -751,10 +765,11 @@
 
 		// bootstrap with 20 items
 		this.get_items()
-			.then((items, serial_no) => {
+			.then(({ items }) => {
+				this.all_items = items;
 				this.items = items;
-			})
-			.then(() => this.render_items());
+				this.render_items(items);
+			});
 	}
 
 	make_dom() {
@@ -795,8 +810,11 @@
 		});
 
 		this.search_field.$input.on('input', (e) => {
-			const search_term = e.target.value;
-			this.filter_items({ search_term });
+			clearTimeout(this.last_search);
+			this.last_search = setTimeout(() => {
+				const search_term = e.target.value;
+				this.filter_items({ search_term });
+			}, 300);
 		});
 
 		this.item_group_field = frappe.ui.form.make_control({
@@ -861,18 +879,26 @@
 				this.render_items(items);
 				return;
 			}
+		} else {
+			return this.render_items(this.all_items);
 		}
 
 		this.get_items({search_value: search_term, item_group })
-			.then((items) => {
+			.then(({ items, serial_no, batch_no }) => {
 				if (search_term) {
 					this.search_index[search_term] = items;
 				}
 
 				this.render_items(items);
-				if(this.serial_no) {
+				if(serial_no) {
 					this.events.update_cart(items[0].item_code,
-						'serial_no', this.serial_no);
+						'serial_no', serial_no);
+					this.search_field.set_value('');
+				}
+				if(batch_no) {
+					this.events.update_cart(items[0].item_code,
+						'batch_no', serial_no);
+					this.search_field.set_value('');
 				}
 			});
 	}
@@ -882,7 +908,7 @@
 		this.wrapper.on('click', '.pos-item-wrapper', function(e) {
 			const $item = $(this);
 			const item_code = $item.attr('data-item-code');
-			me.events.item_click.apply(null, [item_code]);
+			me.events.update_cart(item_code, 'qty', '+1');
 		});
 	}
 
@@ -944,10 +970,10 @@
 					search_value
 				}
 			}).then(r => {
-				const { items, serial_no } = r.message;
+				// const { items, serial_no, batch_no } = r.message;
 
-				this.serial_no = serial_no || "";
-				res(items);
+				// this.serial_no = serial_no || "";
+				res(r.message);
 			});
 		});
 	}
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index d34fc54..4e2b1b1 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -15,6 +15,7 @@
 def get_items(start, page_length, price_list, item_group, search_value=""):
 	condition = ""
 	serial_no = ""
+	batch_no = ""
 	item_code = search_value
 
 	if search_value:
@@ -23,6 +24,11 @@
 		if serial_no_data:
 			serial_no, item_code = serial_no_data
 
+		if not serial_no:
+			batch_no_data = frappe.db.get_value('Batch', search_value, ['name', 'item'])
+			if batch_no_data:
+				batch_no, item_code = batch_no_data
+
 	lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt'])
 	# locate function is used to sort by closest match from the beginning of the value
 	res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image,
@@ -52,6 +58,11 @@
 			'serial_no': serial_no
 		})
 
+	if batch_no:
+		res.update({
+			'batch_no': batch_no
+		})
+
 	return res
 
 @frappe.whitelist()