Merge pull request #10953 from rohitwaghchaure/has_batch_item_in_demo

[minor] Added batch item in the demo data
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 514e5b3..ce16a6e 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 import frappe
 from erpnext.hooks import regional_overrides
 
-__version__ = '9.0.0'
+__version__ = '9.0.3'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 8860b09..6fae8f7 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1023,7 +1023,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1284,7 +1284,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-08-31 16:34:41.614743", 
+ "modified": "2017-09-27 08:31:38.432574", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Pricing Rule", 
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index 41b794c..613f384 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -699,7 +699,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -2166,7 +2166,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-07-17 17:54:48.246507", 
+ "modified": "2017-09-27 08:31:37.827893", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice Item", 
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 2d91a3c..9c091e8 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -8,6 +8,7 @@
 from frappe.model.document import Document
 from frappe.utils import cstr, cint
 from frappe.contacts.doctype.address.address import get_default_address
+from frappe.utils.nestedset import get_root_of
 from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
 
 class IncorrectCustomerGroup(frappe.ValidationError): pass
@@ -136,7 +137,7 @@
 		if key=="use_for_shopping_cart":
 			conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
 		if key == 'customer_group':
-			if not value: value = _("All Customer Groups")
+			if not value: value = get_root_of("Customer Group")
 			customer_group_condition = get_customer_group_condition(value)
 			conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition))
 		else:
diff --git a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
index ad6ea7d..0dc0ee6 100644
--- a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
+++ b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
@@ -2,29 +2,29 @@
 // For license information, please see license.txt
 
 frappe.query_reports["Quoted Item Comparison"] = {
-	"filters": [
+	filters: [
 		{
-			"fieldname": "supplier_quotation",
-			"label": __("Supplier Quotation"),
-			"fieldtype": "Link",
-			"options": "Supplier Quotation",
-			"default": "",
-			"get_query": function () {
+			fieldtype: "Link",
+			label: __("Supplier Quotation"),
+			options: "Supplier Quotation",
+			fieldname: "supplier_quotation",
+			default: "",
+			get_query: () => {
 				return { filters: { "docstatus": ["<", 2] } }
 			}
 		},
 		{
-			"fieldname": "item",
-			"label": __("Item"),
-			"fieldtype": "Link",
-			"options": "Item",
-			"default": "",
-			"reqd": 1,
-			"get_query": function () {
-				var quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
+			reqd: 1,
+			default: "",
+			options: "Item",
+			label: __("Item"),
+			fieldname: "item",
+			fieldtype: "Link",
+			get_query: () => {
+				let quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
 				if (quote != "") {
 					return {
-						query: "erpnext.buying.doctype.quality_inspection.quality_inspection.item_query",
+						query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
 						filters: {
 							"from": "Supplier Quotation Item",
 							"parent": quote
@@ -39,47 +39,50 @@
 			}
 		}
 	],
-	onload: function (report) {
+	onload: (report) => {
 		// Create a button for setting the default supplier
-		report.page.add_inner_button(__("Select Default Supplier"), function () {
-
-			var reporter = frappe.query_reports["Quoted Item Comparison"];
+		report.page.add_inner_button(__("Select Default Supplier"), () => {
+			let reporter = frappe.query_reports["Quoted Item Comparison"];
 
 			//Always make a new one so that the latest values get updated
 			reporter.make_default_supplier_dialog(report);
-			report.dialog.show();
-			setTimeout(function () { report.dialog.input.focus(); }, 1000);
-
 		}, 'Tools');
 
 	},
-	"make_default_supplier_dialog": function (report) {
+	make_default_supplier_dialog: (report) => {
 		// Get the name of the item to change
-		var filters = report.get_values();
-		var item_code = filters.item;
+		if(!report.data) return;
+
+		let filters = report.get_values();
+		let item_code = filters.item;
 
 		// Get a list of the suppliers (with a blank as well) for the user to select
-		var select_options = "";
-		for (let supplier of report.data) {
-			select_options += supplier.supplier_name + '\n'
-		}
+		let suppliers = $.map(report.data, (row, idx)=>{ return row.supplier_name })
 
 		// Create a dialog window for the user to pick their supplier
-		var d = new frappe.ui.Dialog({
+		let dialog = new frappe.ui.Dialog({
 			title: __('Select Default Supplier'),
 			fields: [
-				{ fieldname: 'supplier', fieldtype: 'Select', label: 'Supplier', reqd: 1, options: select_options },
-				{ fieldname: 'ok_button', fieldtype: 'Button', label: 'Set Default Supplier' },
+				{
+					reqd: 1,
+					label: 'Supplier',
+					fieldtype: 'Link',
+					options: 'Supplier',
+					fieldname: 'supplier',
+					get_query: () => {
+						return {
+							filters: {
+								'name': ['in', suppliers]
+							}
+						}
+					}
+				}
 			]
 		});
 
-		// On the user clicking the ok button
-		d.fields_dict.ok_button.input.onclick = function () {
-			var btn = d.fields_dict.ok_button.input;
-			var v = report.dialog.get_values();
-			if (v) {
-				$(btn).set_working();
-
+		dialog.set_primary_action("Set Default Supplier", () => {
+			let values = dialog.get_values();
+			if(values) {
 				// Set the default_supplier field of the appropriate Item to the selected supplier
 				frappe.call({
 					method: "frappe.client.set_value",
@@ -87,17 +90,17 @@
 						doctype: "Item",
 						name: item_code,
 						fieldname: "default_supplier",
-						value: v.supplier,
+						value: values.supplier,
 					},
-					callback: function (r) {
-						$(btn).done_working();
+					freeze: true,
+					callback: (r) => {
 						frappe.msgprint("Successfully Set Supplier");
-						report.dialog.hide();
+						dialog.hide();
 					}
 				});
 			}
-		}
-		report.dialog = d;
+		});
+		dialog.show();
 	}
 }
 
diff --git a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
index 44e247e..c399f3e 100644
--- a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
+++ b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.py
@@ -8,53 +8,55 @@
 
 def execute(filters=None):
 	qty_list = get_quantity_list(filters.item)
-	
 	data = get_quote_list(filters.item, qty_list)
-	
 	columns = get_columns(qty_list)
-	
 	return columns, data
 	
 def get_quote_list(item, qty_list):
 	out = []
-	if item:
-		price_data = []
-		suppliers = []
-		company_currency = frappe.db.get_default("currency")
-		float_precision = cint(frappe.db.get_default("float_precision")) or 2 
-		# Get the list of suppliers
-		for root in frappe.db.sql("""select parent, qty, rate from `tabSupplier Quotation Item` where item_code=%s and docstatus < 2""", item, as_dict=1):
-			for splr in frappe.db.sql("""SELECT supplier from `tabSupplier Quotation` where name =%s and docstatus < 2""", root.parent, as_dict=1):
-				ip = frappe._dict({
+	if not item:
+		return []
+
+	suppliers = []
+	price_data = []
+	company_currency = frappe.db.get_default("currency")
+	float_precision = cint(frappe.db.get_default("float_precision")) or 2 
+	# Get the list of suppliers
+	for root in frappe.db.sql("""select parent, qty, rate from `tabSupplier Quotation Item`
+		where item_code=%s and docstatus < 2""", item, as_dict=1):
+		for splr in frappe.db.sql("""select supplier from `tabSupplier Quotation`
+			where name =%s and docstatus < 2""", root.parent, as_dict=1):
+			ip = frappe._dict({
 				"supplier": splr.supplier,
 				"qty": root.qty,
 				"parent": root.parent,
-				"rate": root.rate})
-				price_data.append(ip)
-				suppliers.append(splr.supplier)
-			
-		#Add a row for each supplier
-		for root in set(suppliers):
-			supplier_currency = frappe.db.get_value("Supplier", root, "default_currency")
-			if supplier_currency:
-				exchange_rate = get_exchange_rate(supplier_currency, company_currency)
-			else:
-				exchange_rate = 1
-
-			row = frappe._dict({
-				"supplier_name": root
+				"rate": root.rate
 			})
-			for col in qty_list:
-				# Get the quantity for this row
-				for item_price in price_data:
-					if str(item_price.qty) == col.key and item_price.supplier == root:
-						row[col.key] = flt(item_price.rate * exchange_rate, float_precision)
-						row[col.key + "QUOTE"] = item_price.parent
-						break
-					else:
-						row[col.key] = ""
-						row[col.key + "QUOTE"] = ""
-			out.append(row)
+			price_data.append(ip)
+			suppliers.append(splr.supplier)
+
+	#Add a row for each supplier
+	for root in set(suppliers):
+		supplier_currency = frappe.db.get_value("Supplier", root, "default_currency")
+		if supplier_currency:
+			exchange_rate = get_exchange_rate(supplier_currency, company_currency)
+		else:
+			exchange_rate = 1
+
+		row = frappe._dict({
+			"supplier_name": root
+		})
+		for col in qty_list:
+			# Get the quantity for this row
+			for item_price in price_data:
+				if str(item_price.qty) == col.key and item_price.supplier == root:
+					row[col.key] = flt(item_price.rate * exchange_rate, float_precision)
+					row[col.key + "QUOTE"] = item_price.parent
+					break
+				else:
+					row[col.key] = ""
+					row[col.key + "QUOTE"] = ""
+		out.append(row)
 			
 	return out
 	
@@ -62,7 +64,8 @@
 	out = []
 	
 	if item:
-		qty_list = frappe.db.sql("""select distinct qty from `tabSupplier Quotation Item` where ifnull(item_code,'')=%s and docstatus < 2""", item, as_dict=1)
+		qty_list = frappe.db.sql("""select distinct qty from `tabSupplier Quotation Item`
+			where ifnull(item_code,'')=%s and docstatus < 2""", item, as_dict=1)
 		qty_list.sort(reverse=False)
 		for qt in qty_list:
 			col = frappe._dict({
@@ -98,4 +101,4 @@
 			"width": 90
 		})
 
-	return columns
+	return columns
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 6687965..48ed741 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -80,7 +80,7 @@
 	{"from_route": "/supplier-quotations/<path:name>", "to_route": "order",
 		"defaults": {
 			"doctype": "Supplier Quotation",
-			"parents": [{"label": _("Supplier Quotation"), "route": "quotations"}]
+			"parents": [{"label": _("Supplier Quotation"), "route": "supplier-quotations"}]
 		}
 	},
 	{"from_route": "/quotations", "to_route": "Quotation"},
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 1147570..f04fddf 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -51,9 +51,9 @@
 	def validate_sales_order(self):
 		if self.sales_order:
 			so = frappe.db.sql("""
-				select so.name, so_item.delivery_date, so.project 
+				select so.name, so_item.delivery_date, so.project
 				from `tabSales Order` so, `tabSales Order Item` so_item
-				where so.name=%s and so.name=so_item.parent 
+				where so.name=%s and so.name=so_item.parent
 					and so.docstatus = 1 and so_item.item_code=%s
 			""", (self.sales_order, self.production_item), as_dict=1)
 
@@ -112,7 +112,7 @@
 
 		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
 			"over_production_allowance_percentage"))
-			
+
 		if total_qty > so_qty + (allowance_percentage/100 * so_qty):
 			frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
 				.format(self.production_item, so_qty), OverProductionError)
@@ -217,27 +217,27 @@
 	def set_production_order_operations(self):
 		"""Fetch operations from BOM and set in 'Production Order'"""
 		self.set('operations', [])
-		
+
 		if not self.bom_no \
 			or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")):
 				return
-		
+
 		if self.use_multi_level_bom:
 			bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
 		else:
 			bom_list = [self.bom_no]
-		
+
 		operations = frappe.db.sql("""
-			select 
+			select
 				operation, description, workstation, idx,
-				base_hour_rate as hour_rate, time_in_mins, 
+				base_hour_rate as hour_rate, time_in_mins,
 				"Pending" as status, parent as bom
 			from
 				`tabBOM Operation`
 			where
 				 parent in (%s) order by idx
 		"""	% ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
-			
+
 		self.set('operations', operations)
 		self.calculate_time()
 
@@ -277,7 +277,7 @@
 		timesheet.set('time_logs', [])
 
 		for i, d in enumerate(self.operations):
-			
+
 			if d.status != 'Completed':
 				self.set_start_end_time_for_workstation(d, i)
 
@@ -370,8 +370,8 @@
 		self.actual_start_date = None
 		self.actual_end_date = None
 		if self.get("operations"):
-			self.actual_start_date = min([d.actual_start_time for d in self.get("operations")])
-			self.actual_end_date = max([d.actual_end_time for d in self.get("operations")])
+			self.actual_start_date = min([d.actual_start_time for d in self.get("operations") if d.actual_start_time])
+			self.actual_end_date = max([d.actual_end_time for d in self.get("operations") if d.actual_end_time])
 
 	def delete_timesheet(self):
 		for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}):
@@ -411,18 +411,18 @@
 			if d.source_warehouse:
 				stock_bin = get_bin(d.item_code, d.source_warehouse)
 				stock_bin.update_reserved_qty_for_production()
-			
+
 	def get_items_and_operations_from_bom(self):
 		self.set_required_items()
 		self.set_production_order_operations()
-		
+
 		return check_if_scrap_warehouse_mandatory(self.bom_no)
-		
+
 	def set_available_qty(self):
 		for d in self.get("required_items"):
 			if d.source_warehouse:
 				d.available_qty_at_source_warehouse = get_latest_stock_qty(d.item_code, d.source_warehouse)
-				
+
 			if self.wip_warehouse:
 				d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
 
@@ -439,7 +439,7 @@
 					'required_qty': item.qty,
 					'source_warehouse': item.source_warehouse or item.default_warehouse
 				})
-			
+
 			self.set_available_qty()
 
 	def update_transaferred_qty_for_required_items(self):
@@ -463,12 +463,12 @@
 def get_item_details(item, project = None):
 	res = frappe.db.sql("""
 		select stock_uom, description
-		from `tabItem` 
-		where disabled=0 
+		from `tabItem`
+		where disabled=0
 			and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)
 			and name=%s
 	""", (nowdate(), item), as_dict=1)
-	
+
 	if not res:
 		return {}
 
@@ -611,14 +611,14 @@
 @frappe.whitelist()
 def stop_unstop(production_order, status):
 	""" Called from client side on Stop/Unstop event"""
-	
+
 	if not frappe.has_permission("Production Order", "write"):
 		frappe.throw(_("Not permitted"), frappe.PermissionError)
-		
+
 	pro_order = frappe.get_doc("Production Order", production_order)
 	pro_order.update_status(status)
 	pro_order.update_planned_qty()
 	frappe.msgprint(_("Production Order has been {0}").format(status))
 	pro_order.notify_update()
-	
+
 	return pro_order.status
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 030d44c..e75c490 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -408,6 +408,8 @@
 erpnext.patches.v8_0.update_sales_cost_in_project
 erpnext.patches.v8_0.save_system_settings
 erpnext.patches.v8_1.delete_deprecated_reports
+erpnext.patches.v9_0.remove_subscription_module
+erpnext.patches.v8_7.make_subscription_from_recurring_data
 erpnext.patches.v8_1.setup_gst_india #2017-06-27
 execute:frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
 erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
@@ -432,18 +434,17 @@
 erpnext.patches.v8_6.update_timesheet_company_from_PO
 erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
 erpnext.patches.v8_5.remove_project_type_property_setter
-erpnext.patches.v8_7.add_more_gst_fields
+erpnext.patches.v8_7.add_more_gst_fields #21-09-2017
 erpnext.patches.v8_7.fix_purchase_receipt_status
 erpnext.patches.v8_6.rename_bom_update_tool
 erpnext.patches.v8_7.set_offline_in_pos_settings #11-09-17
 erpnext.patches.v8_9.add_setup_progress_actions #08-09-2017 #26-09-2017
 erpnext.patches.v8_9.rename_company_sales_target_field
 erpnext.patches.v8_8.set_bom_rate_as_per_uom
-erpnext.patches.v8_7.make_subscription_from_recurring_data
 erpnext.patches.v8_8.add_new_fields_in_accounts_settings
-erpnext.patches.v9_0.remove_subscription_module
 erpnext.patches.v8_9.set_print_zero_amount_taxes
 erpnext.patches.v8_9.set_default_customer_group
 erpnext.patches.v8_9.remove_employee_from_salary_structure_parent
 erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
-erpnext.patches.v8_9.set_default_fields_in_variant_settings
\ No newline at end of file
+erpnext.patches.v8_9.set_default_fields_in_variant_settings
+erpnext.patches.v8_9.update_billing_gstin_for_indian_account
diff --git a/erpnext/patches/v8_7/make_subscription_from_recurring_data.py b/erpnext/patches/v8_7/make_subscription_from_recurring_data.py
index ab0fc12..c5d7d72 100644
--- a/erpnext/patches/v8_7/make_subscription_from_recurring_data.py
+++ b/erpnext/patches/v8_7/make_subscription_from_recurring_data.py
@@ -8,9 +8,15 @@
 def execute():
 	frappe.reload_doc('accounts', 'doctype', 'subscription')
 	frappe.reload_doc('selling', 'doctype', 'sales_order')
+	frappe.reload_doc('selling', 'doctype', 'quotation')
 	frappe.reload_doc('buying', 'doctype', 'purchase_order')
+	frappe.reload_doc('buying', 'doctype', 'supplier_quotation')
 	frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
 	frappe.reload_doc('accounts', 'doctype', 'purchase_invoice')
+	frappe.reload_doc('stock', 'doctype', 'purchase_receipt')
+	frappe.reload_doc('stock', 'doctype', 'delivery_note')
+	frappe.reload_doc('accounts', 'doctype', 'journal_entry')
+	frappe.reload_doc('accounts', 'doctype', 'payment_entry')
 
 	for doctype in ['Sales Order', 'Sales Invoice',
 		'Purchase Invoice', 'Purchase Invoice']:
diff --git a/erpnext/patches/v8_9/update_billing_gstin_for_indian_account.py b/erpnext/patches/v8_9/update_billing_gstin_for_indian_account.py
new file mode 100644
index 0000000..24e2040
--- /dev/null
+++ b/erpnext/patches/v8_9/update_billing_gstin_for_indian_account.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	company = frappe.get_all('Company', filters = {'country': 'India'})
+
+	if company:
+		for doctype in ['Sales Invoice', 'Delivery Note']:
+			frappe.db.sql(""" update `tab{0}`
+				set billing_address_gstin = (select gstin from `tabAddress` 
+					where name = customer_address) 
+			where customer_address is not null and customer_address != ''""".format(doctype))
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 12ab732..84624b8 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -288,8 +288,11 @@
 	},
 
 	set_cumulative_total: function(row_idx, tax) {
-		var tax_amount = (in_list(["Valuation and Total", "Total"], tax.category) ?
-			tax.tax_amount_after_discount_amount : 0);
+		var tax_amount = tax.tax_amount_after_discount_amount;
+		if (tax.category == 'Valuation') {
+			tax_amount = 0;
+		}
+
 		if (tax.add_deduct_tax == "Deduct") { tax_amount = -1*tax_amount; }
 
 		if(row_idx==0) {
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 106a3d5..fb40e32 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -12,7 +12,7 @@
 	make_custom_fields()
 	add_permissions()
 	add_custom_roles_for_reports()
-	add_hsn_sac_codes()
+	frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes')
 	add_print_formats()
 	if not patch:
 		update_address_template()
@@ -47,12 +47,14 @@
 
 def create_hsn_codes(data, code_field):
 	for d in data:
-		if not frappe.db.exists("GST HSN Code", d[code_field]):
-			hsn_code = frappe.new_doc('GST HSN Code')
-			hsn_code.description = d["description"]
-			hsn_code.hsn_code = d[code_field]
-			hsn_code.name = d[code_field]
+		hsn_code = frappe.new_doc('GST HSN Code')
+		hsn_code.description = d["description"]
+		hsn_code.hsn_code = d[code_field]
+		hsn_code.name = d[code_field]
+		try:
 			hsn_code.db_insert()
+		except frappe.DuplicateEntryError:
+			pass
 
 def add_custom_roles_for_reports():
 	for report_name in ('GST Sales Register', 'GST Purchase Register',
@@ -111,12 +113,15 @@
 		]
 
 	sales_invoice_gst_fields = [
+			dict(fieldname='billing_address_gstin', label='Billing Address GSTIN',
+				fieldtype='Data', insert_after='customer_address',
+				options='customer_address.gstin', print_hide=1),
 			dict(fieldname='customer_gstin', label='Customer GSTIN',
 				fieldtype='Data', insert_after='shipping_address',
 				options='shipping_address_name.gstin', print_hide=1),
 			dict(fieldname='place_of_supply', label='Place of Supply',
 				fieldtype='Data', insert_after='customer_gstin', print_hide=1,
-				options='shipping_address_name.gst_state_number', read_only=1),
+				options='shipping_address_name.gst_state_number', read_only=0),
 			dict(fieldname='company_gstin', label='Company GSTIN',
 				fieldtype='Data', insert_after='company_address',
 				options='company_address.gstin', print_hide=1)
diff --git a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
index 40bbae8..4e57a52 100644
--- a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
+++ b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
@@ -8,6 +8,7 @@
 def execute(filters=None):
 	return _execute(filters, additional_table_columns=[
 		dict(fieldtype='Data', label='Customer GSTIN', width=120),
+		dict(fieldtype='Data', label='Billing Address GSTIN', width=140),
 		dict(fieldtype='Data', label='Company GSTIN', width=120),
 		dict(fieldtype='Data', label='Place of Supply', width=120),
 		dict(fieldtype='Data', label='Reverse Charge', width=120),
@@ -17,6 +18,7 @@
 		dict(fieldtype='Data', label='HSN Code', width=120)
 	], additional_query_columns=[
 		'customer_gstin',
+		'billing_address_gstin',
 		'company_gstin',
 		'place_of_supply',
 		'reverse_charge',
diff --git a/erpnext/regional/report/gst_sales_register/gst_sales_register.py b/erpnext/regional/report/gst_sales_register/gst_sales_register.py
index 7f6f809..e79d722 100644
--- a/erpnext/regional/report/gst_sales_register/gst_sales_register.py
+++ b/erpnext/regional/report/gst_sales_register/gst_sales_register.py
@@ -8,6 +8,7 @@
 def execute(filters=None):
 	return _execute(filters, additional_table_columns=[
 		dict(fieldtype='Data', label='Customer GSTIN', width=120),
+		dict(fieldtype='Data', label='Billing Address GSTIN', width=140),
 		dict(fieldtype='Data', label='Company GSTIN', width=120),
 		dict(fieldtype='Data', label='Place of Supply', width=120),
 		dict(fieldtype='Data', label='Reverse Charge', width=120),
@@ -16,6 +17,7 @@
 		dict(fieldtype='Data', label='E-Commerce GSTIN', width=130)
 	], additional_query_columns=[
 		'customer_gstin',
+		'billing_address_gstin',
 		'company_gstin',
 		'place_of_supply',
 		'reverse_charge',
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 794494d..3fc56fa 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -684,7 +684,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1583,7 +1583,7 @@
  "istable": 1, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-05-10 17:14:45.736424", 
+ "modified": "2017-09-27 08:31:37.485134", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Quotation Item", 
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index 47bc1b6..fd7b0f2 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -714,7 +714,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -745,7 +745,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
@@ -1963,7 +1963,7 @@
  "istable": 1, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-07-28 14:04:04.289428", 
+ "modified": "2017-09-27 08:31:37.129537", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Sales Order Item", 
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 ec1a292..1b67ff2 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -21,7 +21,9 @@
 };
 
 frappe.pages['point-of-sale'].refresh = function(wrapper) {
-	cur_frm = wrapper.pos.frm;
+	if (wrapper.pos) {
+		cur_frm = wrapper.pos.frm;
+	}
 }
 
 erpnext.pos.PointOfSale = class PointOfSale {
@@ -742,7 +744,7 @@
 
 		this.wrapper.find('.discount_amount').on('change', (e) => {
 			frappe.model.set_value(this.frm.doctype, this.frm.docname,
-				'discount_amount', e.target.value);
+				'discount_amount', flt(e.target.value));
 			this.frm.trigger('discount_amount')
 				.then(() => {
 					let discount_wrapper = this.wrapper.find('.additional_discount_percentage');
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 8ed288b..d74f1f0 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -3,12 +3,15 @@
 
 from __future__ import unicode_literals
 import frappe, json
+from frappe.utils.nestedset import get_root_of
 
 @frappe.whitelist()
 def get_items(start, page_length, price_list, item_group, search_value=""):
 	serial_no = ""
 	batch_no = ""
 	item_code = search_value
+	if not frappe.db.exists('Item Group', item_group):
+		item_group = get_root_of('Item Group')
 
 	if search_value:
 		# search serial no
@@ -31,7 +34,7 @@
 		ON
 			(item_det.item_code=i.name or item_det.item_code=i.variant_of)
 		where
-			i.disabled = 0 and i.has_variants = 0
+			i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
 			and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
 			and (i.item_code like %(item_code)s
 			or i.item_name like %(item_code)s or i.barcode like %(item_code)s)
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 809c7ea..043dc73 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -103,14 +103,15 @@
 def set_batch_nos(doc, warehouse_field, throw = False):
 	'''Automatically select `batch_no` for outgoing items in item table'''
 	for d in doc.items:
+		qty = d.get('stock_qty') or d.get('qty') or 0
 		has_batch_no = frappe.db.get_value('Item', d.item_code, 'has_batch_no')
 		warehouse = d.get(warehouse_field, None)
-		if has_batch_no and warehouse and d.qty > 0:
+		if has_batch_no and warehouse and qty > 0:
 			if not d.batch_no:
-				d.batch_no = get_batch_no(d.item_code, warehouse, d.qty, throw)
+				d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw)
 			else:
 				batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
-				if flt(batch_qty) < flt(d.qty):
+				if flt(batch_qty) < flt(qty):
 					frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, d.qty))
 
 def get_batch_no(item_code, warehouse, qty, throw=False):
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index a441a7f..4e1ea40 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -713,7 +713,7 @@
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
-   "precision": "2", 
+   "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -1956,7 +1956,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-05-10 17:14:50.456930", 
+ "modified": "2017-09-27 08:31:38.768846", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Note Item", 
diff --git a/erpnext/stock/doctype/item_price/item_price.json b/erpnext/stock/doctype/item_price/item_price.json
index 0bd0009..fee229f 100644
--- a/erpnext/stock/doctype/item_price/item_price.json
+++ b/erpnext/stock/doctype/item_price/item_price.json
@@ -1,5 +1,5 @@
 {
- "allow_copy": 0, 
+ "allow_copy": 0,
  "allow_import": 1, 
  "allow_rename": 0, 
  "autoname": "ITEM-PRICE-.#####", 
@@ -165,7 +165,7 @@
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
-   "in_filter": 0, 
+   "in_filter": 0,
    "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "", 
@@ -357,19 +357,19 @@
    "set_only_once": 0, 
    "unique": 0
   }
- ], 
+ ],
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "icon": "fa fa-flag", 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
- "is_submittable": 0, 
+ "in_dialog": 0,
+ "is_submittable": 0,
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-02-20 13:27:23.896148", 
+ "modified": "2017-09-28 03:56:20.814993", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Item Price", 
@@ -422,6 +422,6 @@
  "show_name_in_global_search": 0, 
  "sort_order": "ASC", 
  "title_field": "item_code", 
- "track_changes": 0, 
+ "track_changes": 1, 
  "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/templates/includes/rfq.js b/erpnext/templates/includes/rfq.js
index 3b45cbe..b56c416 100644
--- a/erpnext/templates/includes/rfq.js
+++ b/erpnext/templates/includes/rfq.js
@@ -85,7 +85,7 @@
 					frappe.unfreeze();
 					if(r.message){
 						$('.btn-sm').hide()
-						window.location.href = "/quotations/" + encodeURIComponent(r.message);
+						window.location.href = "/supplier-quotations/" + encodeURIComponent(r.message);
 					}
 				}
 			})