Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 3eaf994..5aedcdd 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.1.33'
+__version__ = '10.1.34'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index d6b12f1..eca4320 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -111,8 +111,8 @@
 
 	item_list = args.get("items")
 	args.pop("items")
-	
-	set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings", 
+
+	set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
 		"automatically_set_serial_nos_based_on_fifo")
 
 	for item in item_list:
@@ -122,7 +122,7 @@
 		if set_serial_nos_based_on_fifo and not args.get('is_return'):
 			out.append(get_serial_no_for_item(args_copy))
 	return out
-	
+
 def get_serial_no_for_item(args):
 	from erpnext.stock.get_item_details import get_serial_no
 
@@ -143,7 +143,7 @@
 		"name": args.name,
 		"pricing_rule": None
 	})
-	
+
 	if args.ignore_pricing_rule or not args.item_code:
 		if frappe.db.exists(args.doctype, args.name) and args.get("pricing_rule"):
 			item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
@@ -180,7 +180,7 @@
 		item_details.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
 		if pricing_rule.price_or_discount == "Price":
 			item_details.update({
-				"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * args.conversion_factor or 1.0 \
+				"price_list_rate": (pricing_rule.price/flt(args.conversion_rate)) * (args.conversion_factor or 1.0) \
 					if args.conversion_rate else 0.0,
 				"discount_percentage": 0.0
 			})
@@ -192,7 +192,7 @@
 	return item_details
 
 def remove_pricing_rule_for_item(pricing_rule, item_details):
-	pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule, 
+	pricing_rule = frappe.db.get_value('Pricing Rule', pricing_rule,
 		['price_or_discount', 'margin_type'], as_dict=1)
 	if pricing_rule and pricing_rule.price_or_discount == 'Discount Percentage':
 		item_details.discount_percentage = 0.0
@@ -209,14 +209,14 @@
 def remove_pricing_rules(item_list):
 	if isinstance(item_list, basestring):
 		item_list = json.loads(item_list)
-	
-	out = []	
+
+	out = []
 	for item in item_list:
 		item = frappe._dict(item)
 		out.append(remove_pricing_rule_for_item(item.get("pricing_rule"), item))
-		
+
 	return out
-	
+
 def get_pricing_rules(args):
 	def _get_tree_conditions(parenttype, allow_blank=True):
 		field = frappe.scrub(parenttype)
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 3dc4fd7..6977512 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -71,8 +71,8 @@
 			if gle_currency:
 				account_currency = gle_currency
 			else:
-				account_currency = None if filters.party_type in ["Employee", "Student", "Shareholder"] else \
-					frappe.db.get_value(filters.party_type, filters.party, "default_currency")
+				account_currency = (None if filters.party_type in ["Employee", "Student", "Shareholder", "Member"] else
+					frappe.db.get_value(filters.party_type, filters.party, "default_currency"))
 
 		filters["account_currency"] = account_currency or filters.company_currency
 
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 15a93bd..bc18d77 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -157,9 +157,10 @@
 		# scan description only if items are less than 50000
 		description_cond = 'or tabItem.description LIKE %(txt)s'
 
-	return frappe.db.sql("""select tabItem.name, tabItem.item_group,
+	return frappe.db.sql("""select tabItem.name,
 		if(length(tabItem.item_name) > 40,
 			concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
+		tabItem.item_group,
 		if(length(tabItem.description) > 40, \
 			concat(substr(tabItem.description, 1, 40), "..."), description) as decription
 		from tabItem
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 06eee61..b335717 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -42,6 +42,7 @@
 
 	employee: function(frm) {
 		frm.trigger("get_leave_balance");
+		frm.trigger("set_leave_approver");
 	},
 
 	leave_type: function(frm) {
@@ -125,4 +126,21 @@
 			});
 		}
 	},
+
+	set_leave_approver: function(frm) {
+		if(frm.doc.employee) {
+				// server call is done to include holidays in leave days calculations
+			return frappe.call({
+				method: 'erpnext.hr.doctype.leave_application.leave_application.get_leave_approver_data',
+				args: {
+					"employee": frm.doc.employee,
+				},
+				callback: function(r) {
+					if (r && r.message) {
+						frm.set_value('leave_approver', r.message);
+					}
+				}
+			});
+		}
+	}
 });
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 4e1b54b..e03764a 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -116,7 +116,7 @@
 					frappe.db.sql("""update `tabAttendance` set status = %s, leave_type = %s\
 						where name = %s""",(status, self.leave_type, d.name))
 
-			elif self.from_date <= nowdate():
+			elif self.to_date <= nowdate():
 				for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
 					date = dt.strftime("%Y-%m-%d")
 					if not date == self.half_day_date:
@@ -126,6 +126,7 @@
 						doc.company = self.company
 						doc.status = "On Leave"
 						doc.leave_type = self.leave_type
+						doc.insert(ignore_permissions=True)
 						doc.submit()
 					else:
 						doc = frappe.new_doc("Attendance")
@@ -134,6 +135,7 @@
 						doc.company = self.company
 						doc.status = "Half Day"
 						doc.leave_type = self.leave_type
+						doc.insert(ignore_permissions=True)
 						doc.submit()
 
 	def validate_salary_processed_days(self):
@@ -530,3 +532,8 @@
 				"title": _("Holiday") + ": " + cstr(holiday.description),
 				"name": holiday.name
 			})
+
+@frappe.whitelist()
+def get_leave_approver_data(employee):
+	return frappe.db.get_value("Employee Leave Approver",
+		{'parent': employee}, 'leave_approver')
diff --git a/erpnext/manufacturing/page/production_analytics/production_analytics.js b/erpnext/manufacturing/page/production_analytics/production_analytics.js
index efbd0a5..21b4293 100644
--- a/erpnext/manufacturing/page/production_analytics/production_analytics.js
+++ b/erpnext/manufacturing/page/production_analytics/production_analytics.js
@@ -64,8 +64,7 @@
 
 		var chart_data = this.get_chart_data ? this.get_chart_data() : null;
 
-		this.chart = new Chart({
-			parent: ".chart",
+		this.chart = new frappeChart.Chart(".chart", {
 			data: chart_data,
 			type: 'line'
 		});
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index a14500a..52f0748 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -23,7 +23,7 @@
 			posting_date,
 			base_grand_total,
 			base_rounded_total,
-			customer_gstin,
+			COALESCE(NULLIF(customer_gstin,''), NULLIF(billing_address_gstin, '')) as customer_gstin,
 			place_of_supply,
 			ecommerce_gstin,
 			reverse_charge,
diff --git a/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py b/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py
index e57636c..e7bb5b4 100644
--- a/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py
+++ b/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py
@@ -91,17 +91,22 @@
 	start_date, end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:]
 
 	item_details = frappe.db.sql("""
-		select
-			sum(soi.stock_qty * (st.allocated_percentage/100)) as qty,
-			sum(soi.base_net_amount * (st.allocated_percentage/100)) as amount,
-			st.sales_person, MONTHNAME(so.transaction_date) as month_name
+		SELECT st.sales_person, MONTHNAME(so.transaction_date) as month_name,
+		CASE
+			WHEN so.status = "Closed" THEN sum(soi.delivered_qty * soi.conversion_factor * (st.allocated_percentage/100))
+			ELSE sum(soi.stock_qty * (st.allocated_percentage/100))
+		END as qty,
+		CASE
+			WHEN so.status = "Closed" THEN sum(soi.delivered_qty * soi.conversion_factor * soi.base_net_rate * (st.allocated_percentage/100))
+			ELSE soi.base_net_amount * (st.allocated_percentage/100))
+		END as amount
 		from
 			`tabSales Order Item` soi, `tabSales Order` so, `tabSales Team` st
 		where
 			soi.parent=so.name and so.docstatus=1 and st.parent=so.name
 			and so.transaction_date>=%s and so.transaction_date<=%s
-			and exists(select name from `tabSales Person` where lft >= %s and rgt <= %s and name=st.sales_person)
-			and exists(select name from `tabItem Group` where lft >= %s and rgt <= %s and name=soi.item_group)
+			and exists(SELECT name from `tabSales Person` where lft >= %s and rgt <= %s and name=st.sales_person)
+			and exists(SELECT name from `tabItem Group` where lft >= %s and rgt <= %s and name=soi.item_group)
 		group by
 			sales_person, month_name
 			""",
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
index 025e740..19b6774 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
@@ -15,11 +15,12 @@
 	data = []
 
 	for d in entries:
-		data.append([
-			d.name, d.customer, d.territory, d.posting_date, d.item_code,
-			item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
-			d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt
-		])
+		if d.stock_qty > 0:
+			data.append([
+				d.name, d.customer, d.territory, d.posting_date, d.item_code,
+				item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
+				d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt
+			])
 
 	if data:
 		total_row = [""]*len(data[0])
@@ -40,18 +41,34 @@
 
 def get_entries(filters):
 	date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date"
+	if filters["doc_type"] == "Sales Order":
+		qty_field = "delivered_qty"
+	else:
+		qty_field = "qty"
 	conditions, values = get_conditions(filters, date_field)
+
 	entries = frappe.db.sql("""
 		select
 			dt.name, dt.customer, dt.territory, dt.%s as posting_date, dt_item.item_code,
-			dt_item.stock_qty, dt_item.base_net_amount, st.sales_person, st.allocated_percentage,
-			dt_item.base_net_amount*st.allocated_percentage/100 as contribution_amt
+			st.sales_person, st.allocated_percentage,
+		CASE 
+			WHEN dt.status = "Closed" THEN dt_item.%s * dt_item.conversion_factor
+			ELSE dt_item.stock_qty
+		END as stock_qty,
+		CASE
+			WHEN dt.status = "Closed" THEN (dt_item.base_net_rate * dt_item.%s * dt_item.conversion_factor)
+			ELSE dt_item.base_net_amount
+		END as base_net_amount,
+		CASE
+			WHEN dt.status = "Closed" THEN ((dt_item.base_net_rate * dt_item.%s * dt_item.conversion_factor) * st.allocated_percentage/100)
+			ELSE dt_item.base_net_amount * st.allocated_percentage/100
+		END as contribution_amt
 		from
 			`tab%s` dt, `tab%s Item` dt_item, `tabSales Team` st
 		where
 			st.parent = dt.name and dt.name = dt_item.parent and st.parenttype = %s
 			and dt.docstatus = 1 %s order by st.sales_person, dt.name desc
-		""" %(date_field, filters["doc_type"], filters["doc_type"], '%s', conditions),
+		""" %(date_field, qty_field, qty_field, qty_field, filters["doc_type"], filters["doc_type"], '%s', conditions),
 			tuple([filters["doc_type"]] + values), as_dict=1)
 
 	return entries
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 203458e..effbe82 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -501,7 +501,7 @@
 
 	def update_item_price(self):
 		frappe.db.sql("""update `tabItem Price` set item_name=%s,
-			item_description=%s, modified=NOW() where item_code=%s""",
+			item_description=%s where item_code=%s""",
 			(self.item_name, self.description, self.name))
 
 	def on_trash(self):
diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js
index 1bfa416..1bea00e 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -39,6 +39,8 @@
 		
 		frm.toggle_enable(['is_group', 'company'], false);
 
+		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Warehouse'};
+		
 		frm.fields_dict['parent_warehouse'].get_query = function(doc) {
 			return {
 				filters: {
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index d2ec7c3..923a79c 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -926,6 +926,37 @@
    "set_only_once": 0, 
    "translatable": 0, 
    "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "via_customer_portal", 
+   "fieldtype": "Check", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Via Customer Portal", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
   }
  ], 
  "has_web_view": 0, 
@@ -939,7 +970,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-04-13 13:03:14.748090", 
+ "modified": "2018-05-07 05:53:20.684275", 
  "modified_by": "Administrator", 
  "module": "Support", 
  "name": "Issue", 
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 6a18f11..dfcc2a8 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -17,6 +17,8 @@
 		return "{0}: {1}".format(_(self.status), self.subject)
 
 	def validate(self):
+		if (self.get("__islocal") and self.via_customer_portal):
+			self.flags.create_communication = True
 		if not self.raised_by:
 			self.raised_by = frappe.session.user
 		self.update_status()
@@ -26,6 +28,12 @@
 			from frappe.desk.form.assign_to import clear
 			clear(self.doctype, self.name)
 
+	def on_update(self):
+		# create the communication email and remove the description
+		if (self.flags.create_communication and self.via_customer_portal):
+			self.create_communication()
+			self.flags.communication_created = None
+
 	def set_lead_contact(self, email_id):
 		import email.utils
 		email_id = email.utils.parseaddr(email_id)[1]
@@ -53,6 +61,26 @@
 			# if no date, it should be set as None and not a blank string "", as per mysql strict config
 			self.resolution_date = None
 
+	def create_communication(self):
+		communication = frappe.new_doc("Communication")
+		communication.update({
+			"communication_type": "Communication",
+			"communication_medium": "Email",
+			"sent_or_received": "Received",
+			"email_status": "Open",
+			"subject": self.subject,
+			"sender": self.raised_by,
+			"content": self.description,
+			"status": "Linked",
+			"reference_doctype": "Issue",
+			"reference_name": self.name
+		})
+		communication.ignore_permissions = True
+		communication.ignore_mandatory = True
+		communication.save()
+
+		self.db_set("description", "")
+
 def get_list_context(context=None):
 	return {
 		"title": _("Issues"),
diff --git a/erpnext/support/web_form/issues/issues.json b/erpnext/support/web_form/issues/issues.json
index 264b9df..a8c7ab9 100644
--- a/erpnext/support/web_form/issues/issues.json
+++ b/erpnext/support/web_form/issues/issues.json
@@ -18,7 +18,7 @@
  "is_standard": 1, 
  "login_required": 1, 
  "max_attachment_size": 0, 
- "modified": "2017-07-25 22:49:10.762704", 
+ "modified": "2018-05-07 05:54:22.213127", 
  "modified_by": "Administrator", 
  "module": "Support", 
  "name": "issues", 
@@ -83,6 +83,17 @@
    "max_value": 0, 
    "read_only": 0, 
    "reqd": 0
+  }, 
+  {
+   "default": "1", 
+   "fieldname": "via_customer_portal", 
+   "fieldtype": "Check", 
+   "hidden": 1, 
+   "label": "Via Customer Portal", 
+   "max_length": 0, 
+   "max_value": 0, 
+   "read_only": 1, 
+   "reqd": 0
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/support/web_form/issues/issues.py b/erpnext/support/web_form/issues/issues.py
index 2334f8b..bb9197a 100644
--- a/erpnext/support/web_form/issues/issues.py
+++ b/erpnext/support/web_form/issues/issues.py
@@ -4,4 +4,5 @@
 
 def get_context(context):
 	# do your magic here
-	pass
+	if context.doc:
+		context.read_only = 1
\ No newline at end of file
diff --git a/erpnext/utilities/page/leaderboard/leaderboard.js b/erpnext/utilities/page/leaderboard/leaderboard.js
index 1a9efd5..1c085f2 100644
--- a/erpnext/utilities/page/leaderboard/leaderboard.js
+++ b/erpnext/utilities/page/leaderboard/leaderboard.js
@@ -146,7 +146,6 @@
 
 				me.$graph_area.show().empty();
 				let args = {
-					parent: '.leaderboard-graph',
 					data: {
 						datasets: [
 							{
@@ -160,7 +159,7 @@
 					type: 'bar',
 					height: 140
 				};
-				new Chart(args);
+				new frappeChart.Chart('.leaderboard-graph', args);
 
 				notify(me, r, $container);
 			}
@@ -280,7 +279,7 @@
 			fields.map(col => {
 					let val = item[col];
 					if(col=="name") {
-						var formatted_value = `<a class="grey list-id ellipsis" 
+						var formatted_value = `<a class="grey list-id ellipsis"
 							href="#Form/${me.options.selected_doctype}/${item["name"]}"> ${val} </a>`
 					} else {
 						var formatted_value = `<span class="text-muted ellipsis">