Merge branch 'develop' into not_able_to_save_asset_for_manual_method_develop
diff --git a/.travis.yml b/.travis.yml
index 869fe95..a8a0d82 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,11 @@
 
 python:
   - "2.7"
+  - "3.6"
+
+env:
+  - TEST_TYPE="Server Side Test"
+  - TEST_TYPE="Patch Test"
 
 services:
   - mysql
@@ -39,18 +44,8 @@
   - bench start &
   - sleep 10
 
-jobs:
-  include:
-    - stage: test
-      script:
-        - set -e
-        - bench run-tests --app erpnext --coverage
-      after_script:
-        - coveralls -b apps/erpnext -d ../../sites/.coverage
-      env: Server Side Test
-    - # stage
-      script:
-        - wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
-        - bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
-        - bench migrate
-      env: Patch Testing
+script:
+  - bash $TRAVIS_BUILD_DIR/travis/run-tests.sh
+
+after_script:
+  - coveralls -b apps/erpnext -d ../../sites/.coverage
diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
index f2abb81..648cc68 100644
--- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
+++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe, json
-from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day
+from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate
 from erpnext.accounts.report.general_ledger.general_ledger import execute
 from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
 from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
@@ -37,7 +37,7 @@
 	result = build_result(account, dates, gl_entries)
 
 	return {
-		"labels": [r[0].strftime('%Y-%m-%d') for r in result],
+		"labels": [formatdate(r[0].strftime('%Y-%m-%d')) for r in result],
 		"datasets": [{
 			"name": account,
 			"values": [r[1] for r in result]
diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
index 2a44cb3..0acbe20 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
@@ -43,8 +43,13 @@
 
 	reference_docname: function(frm) {
 		if (frm.doc.reference_docname && frm.doc.reference_doctype) {
-			let fields_to_fetch = ["project", "grand_total"];
+			let fields_to_fetch = ["grand_total"];
 			let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
+
+			if (frm.doc.reference_doctype == "Sales Order") {
+				fields_to_fetch.push("project");
+			}
+
 			fields_to_fetch.push(party_field);
 			frappe.call({
 				method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_vouchar_detials",
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 8a8e329..5795b8f 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -232,7 +232,7 @@
 	if len(pricing_rules) > 1:
 		rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules]))
 		if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage":
-			pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
+			pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
 				or pricing_rules
 
 	if len(pricing_rules) > 1 and not args.for_shopping_cart:
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 41205ae..c06856a 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -390,8 +390,8 @@
 	if filters:
 		if filters.get("project"):
 			if not isinstance(filters.get("project"), list):
-				projects = frappe.safe_encode(filters.get("project"))
-				filters.project = [d.strip() for d in projects.strip().split(',') if d]
+				filters.project = frappe.parse_json(filters.get("project"))
+
 			additional_conditions.append("project in %(project)s")
 
 		if filters.get("cost_center"):
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 4235b7f..5c98b24 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -72,46 +72,25 @@
 		{
 			"fieldname":"party",
 			"label": __("Party"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
 				if (!frappe.query_report.filters) return;
-				var party_type = frappe.query_report.get_filter_value('party_type');
-				var parties = frappe.query_report.get_filter_value('party');
-				if(!party_type) return;
 
-				const values = parties.split(/\s*,\s*/).filter(d => d);
-				const txt = parties.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
+				let party_type = frappe.query_report.get_filter_value('party_type');
+				if (!party_type) return;
 
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: frappe.query_report.get_filter_value('party_type'),
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+				return frappe.db.get_link_options(party_type, txt);
 			},
 			on_change: function() {
 				var party_type = frappe.query_report.get_filter_value('party_type');
 				var parties = frappe.query_report.get_filter_value('party');
-				const values = parties.split(/\s*,\s*/).filter(d => d);
 
-				if(!party_type || !parties || values.length>1) {
+				if(!party_type || parties.length === 0 || parties.length > 1) {
 					frappe.query_report.set_filter_value('party_name', "");
 					frappe.query_report.set_filter_value('tax_id', "");
 					return;
 				} else {
-					var party = values[0];
+					var party = parties[0];
 					var fieldname = erpnext.utils.get_party_name(party_type) || "name";
 					frappe.db.get_value(party_type, party, fieldname, function(value) {
 						frappe.query_report.set_filter_value('party_name', value[fieldname]);
@@ -154,62 +133,17 @@
 		{
 			"fieldname":"cost_center",
 			"label": __("Cost Center"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
-				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
-				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Cost Center",
-						txt: txt,
-						filters: {
-							"company": frappe.query_report.get_filter_value("company"),
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Cost Center', txt);
 			}
 		},
 		{
 			"fieldname":"project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index d9f395b..1c5e089 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -26,8 +26,7 @@
 		account_details.setdefault(acc.name, acc)
 
 	if filters.get('party'):
-		parties = cstr(filters.get("party")).strip()
-		filters.party = [d.strip() for d in parties.split(',') if d]
+		filters.party = frappe.parse_json(filters.get("party"))
 
 	validate_filters(filters, account_details)
 
@@ -61,12 +60,10 @@
 		frappe.throw(_("From Date must be before To Date"))
 
 	if filters.get('project'):
-		projects = cstr(filters.get("project")).strip()
-		filters.project = [d.strip() for d in projects.split(',') if d]
+		filters.project = frappe.parse_json(filters.get('project'))
 
 	if filters.get('cost_center'):
-		cost_centers = cstr(filters.get("cost_center")).strip()
-		filters.cost_center = [d.strip() for d in cost_centers.split(',') if d]
+		filters.cost_center = frappe.parse_json(filters.get('cost_center'))
 
 
 def validate_party(filters):
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
index 63ac281..8dc5ab3 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
@@ -13,33 +13,11 @@
 
 	frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
 		{
-			"fieldname":"project",
+			"fieldname": "project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 250e516..df5c982 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -8,33 +8,11 @@
 
 	frappe.query_reports["Profit and Loss Statement"]["filters"].push(
 		{
-			"fieldname":"project",
+			"fieldname": "project",
 			"label": __("Project"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var projects = frappe.query_report.get_filter_value("project") || "";
-
-				const values = projects.split(/\s*,\s*/).filter(d => d);
-				const txt = projects.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Project",
-						txt: txt,
-						filters: {
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
-				});
-				return data;
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Project', txt);
 			}
 		},
 		{
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 22d25b5..c98b0b0 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -25,9 +25,12 @@
 			temp['features'][0]['properties']['feature_of'] = location
 			formatted_locations.extend(temp['features'])
 
-		formatted_location_string = str(formatted_locations)
 		test_location = frappe.get_doc('Location', 'Test Location Area')
 		test_location.save()
 
-		self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+		test_location_features = json.loads(test_location.get('location'))['features']
+		ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
+		ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
+
+		self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
 		self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 4d45936..adac8f5 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -342,7 +342,7 @@
 	elif doc.lead:
 		assign_user = frappe.db.get_value('Lead', doc.lead, 'lead_owner')
 
-	if assign_user and assign_user != 'Administrator':
+	if assign_user and assign_user not in ['Administrator', 'Guest']:
 		if not assign_to.get(dict(doctype = doc.doctype, name = doc.name)):
 			assign_to.add({
 				"assign_to": assign_user,
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
index 79f3c19..0211bc8 100644
--- a/erpnext/demo/user/hr.py
+++ b/erpnext/demo/user/hr.py
@@ -97,7 +97,7 @@
 			"expense_date": frappe.flags.current_date,
 			"expense_type": expense_type.name,
 			"default_account": expense_type.default_account or "Miscellaneous Expenses - WPL",
-			"claim_amount": claim_amount,
+			"amount": claim_amount,
 			"sanctioned_amount": claim_amount
 		})
 
@@ -107,7 +107,7 @@
 	for expense in expense_claim.expenses:
 		sanctioned_amount = random.randint(1,20)*10
 
-		if sanctioned_amount < expense.claim_amount:
+		if sanctioned_amount < expense.amount:
 			expense.sanctioned_amount = sanctioned_amount
 
 def get_timesheet_based_salary_slip_employee():
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index da0972b..9502006 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -10,6 +10,7 @@
 app_email = "info@erpnext.com"
 app_license = "GNU General Public License (v3)"
 source_link = "https://github.com/frappe/erpnext"
+app_logo_url = '/assets/erpnext/images/erp-icon.svg'
 
 
 develop_version = '12.x.x-develop'
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
index 376d0c0..22ba5ad 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
@@ -2,9 +2,8 @@
 	refresh: function(frm) {
 		frm.disable_save();
 	},
-	
+
 	onload: function(frm) {
-		frm.doc.department = frm.doc.branch = frm.doc.company = "All";
 		frm.set_value("date", frappe.datetime.get_today());
 		erpnext.employee_attendance_tool.load_employees(frm);
 	},
@@ -24,7 +23,7 @@
 	company: function(frm) {
 		erpnext.employee_attendance_tool.load_employees(frm);
 	}
-	
+
 });
 
 
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
index ea5f4bd..32fcee1 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
@@ -17,12 +17,11 @@
 	attendance_not_marked = []
 	attendance_marked = []
 	filters = {"status": "Active", "date_of_joining": ["<=", date]}
-	if department != "All":
-		filters["department"] = department
-	if branch != "All":
-		filters["branch"] = branch
-	if company != "All":
-		filters["company"] = company
+
+	for field, value in {'department': department,
+		'branch': branch, 'company': company}.items():
+		if value:
+			filters[field] = value
 
 	employee_list = frappe.get_list("Employee", fields=["employee", "employee_name"], filters=filters, order_by="employee_name")
 	marked_employee = {}
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
index e71ce12..b73dcf8 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
@@ -2,20 +2,8 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Employee Benefit Application', {
-	setup: function(frm) {
-		if(!frm.doc.employee || !frm.doc.date) {
-			frappe.throw(__("Please select Employee and Date first"));
-		} else {
-			frm.set_query("earning_component", "employee_benefits", function() {
-				return {
-					query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
-					filters: {date: frm.doc.date, employee: frm.doc.employee}
-				};
-			});
-		}
-	},
-
 	employee: function(frm) {
+		frm.trigger('set_earning_component');
 		var method, args;
 		if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
 			method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining";
@@ -35,6 +23,21 @@
 			get_max_benefits(frm, method, args);
 		}
 	},
+
+	date: function(frm) {
+		frm.trigger('set_earning_component');
+	},
+
+	set_earning_component: function(frm) {
+		if(!frm.doc.employee && !frm.doc.date) return;
+		frm.set_query("earning_component", "employee_benefits", function() {
+			return {
+				query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
+				filters: {date: frm.doc.date, employee: frm.doc.employee}
+			};
+		});
+	},
+
 	payroll_period: function(frm) {
 		var method, args;
 		if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 7c6abc7..40bec6d 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -109,12 +109,9 @@
 	doc.total_claimed_amount = 0;
 	doc.total_sanctioned_amount = 0;
 	$.each((doc.expenses || []), function(i, d) {
-		doc.total_claimed_amount += d.claim_amount;
+		doc.total_claimed_amount += d.amount;
 		doc.total_sanctioned_amount += d.sanctioned_amount;
 	});
-
-	refresh_field("total_claimed_amount");
-	refresh_field('total_sanctioned_amount');
 };
 
 cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){
@@ -157,6 +154,14 @@
 				}
 			};
 		});
+		frm.set_query("account_head", "taxes", function(doc) {
+			return {
+				filters: [
+					['company', '=', doc.company],
+					['account_type', 'in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation"]]
+				]
+			};
+		});
 	},
 
 	onload: function(frm) {
@@ -197,6 +202,12 @@
 		}
 	},
 
+	calculate_grand_total: function(frm) {
+		var grand_total = flt(frm.doc.total_sanctioned_amount) + flt(frm.doc.total_taxes_and_charges) - flt(frm.doc.total_advance_amount);
+		frm.set_value("grand_total", grand_total);
+		frm.refresh_fields();
+	},
+
 	make_payment_entry: function(frm) {
 		var method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry";
 		if(frm.doc.__onload && frm.doc.__onload.make_payment_via_journal_entry) {
@@ -259,6 +270,18 @@
 		frm.events.get_advances(frm);
 	},
 
+	get_taxes: function(frm) {
+		if(frm.doc.taxes) {
+			frappe.call({
+				method: "calculate_taxes",
+				doc: frm.doc,
+				callback: () => {
+					refresh_field("taxes");
+				}
+			});
+		}
+	},
+
 	get_advances: function(frm) {
 		frappe.model.clear_table(frm.doc, "advances");
 		if (frm.doc.employee) {
@@ -288,16 +311,18 @@
 });
 
 frappe.ui.form.on("Expense Claim Detail", {
-	claim_amount: function(frm, cdt, cdn) {
+	amount: function(frm, cdt, cdn) {
 		var child = locals[cdt][cdn];
 		var doc = frm.doc;
-		frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount);
+		frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount);
 		cur_frm.cscript.calculate_total(doc,cdt,cdn);
 	},
 
 	sanctioned_amount: function(frm, cdt, cdn) {
 		var doc = frm.doc;
 		cur_frm.cscript.calculate_total(doc,cdt,cdn);
+		frm.trigger("get_taxes");
+		frm.trigger("calculate_grand_total");
 	}
 });
 
@@ -324,6 +349,7 @@
 						child.advance_paid = r.message[0].paid_amount;
 						child.unclaimed_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount);
 						child.allocated_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount);
+						frm.trigger('calculate_grand_total');
 						refresh_field("advances");
 					}
 				}
@@ -332,6 +358,43 @@
 	}
 });
 
+frappe.ui.form.on("Expense Taxes and Charges", {
+	account_head: function(frm, cdt, cdn) {
+		var child = locals[cdt][cdn];
+		if(child.account_head && !child.description) {
+			// set description from account head
+			child.description = child.account_head.split(' - ').slice(0, -1).join(' - ');
+			refresh_field("taxes");
+		}
+	},
+
+	calculate_total_tax: function(frm, cdt, cdn) {
+		var child = locals[cdt][cdn];
+		child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount);
+		frm.trigger("calculate_tax_amount", cdt, cdn);
+	},
+
+	calculate_tax_amount: function(frm) {
+		frm.doc.total_taxes_and_charges = 0;
+		(frm.doc.taxes || []).forEach(function(d) {
+			frm.doc.total_taxes_and_charges += d.tax_amount;
+		});
+		frm.trigger("calculate_grand_total");
+	},
+
+	rate: function(frm, cdt, cdn) {
+		var child = locals[cdt][cdn];
+		if(!child.amount) {
+			child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100);
+		}
+		frm.trigger("calculate_total_tax", cdt, cdn);
+	},
+
+	tax_amount: function(frm, cdt, cdn) {
+		frm.trigger("calculate_total_tax", cdt, cdn);
+	}
+});
+
 cur_frm.fields_dict['task'].get_query = function(doc) {
 	return {
 		filters:{
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 6e04644..f0bc268 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -4,6 +4,7 @@
  "creation": "2013-01-10 16:34:14",
  "doctype": "DocType",
  "document_type": "Setup",
+ "engine": "InnoDB",
  "field_order": [
   "naming_series",
   "employee",
@@ -12,17 +13,24 @@
   "column_break_5",
   "expense_approver",
   "approval_status",
-  "total_claimed_amount",
-  "total_sanctioned_amount",
   "is_paid",
   "expense_details",
   "expenses",
   "sb1",
+  "taxes",
+  "transactions_section",
+  "total_sanctioned_amount",
+  "total_taxes_and_charges",
+  "total_advance_amount",
+  "column_break_17",
+  "grand_total",
+  "total_claimed_amount",
+  "total_amount_reimbursed",
+  "section_break_16",
   "posting_date",
   "vehicle_log",
   "task",
   "cb1",
-  "total_amount_reimbursed",
   "remark",
   "title",
   "email_id",
@@ -39,8 +47,7 @@
   "status",
   "amended_from",
   "advance_payments",
-  "advances",
-  "total_advance_amount"
+  "advances"
  ],
  "fields": [
   {
@@ -117,7 +124,6 @@
   {
    "fieldname": "total_sanctioned_amount",
    "fieldtype": "Currency",
-   "in_list_view": 1,
    "label": "Total Sanctioned Amount",
    "no_copy": 1,
    "oldfieldname": "total_sanctioned_amount",
@@ -315,12 +321,45 @@
   {
    "fieldname": "dimension_col_break",
    "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "taxes",
+   "fieldtype": "Table",
+   "label": "Expense Taxes and Charges",
+   "options": "Expense Taxes and Charges"
+  },
+  {
+   "fieldname": "section_break_16",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "transactions_section",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "grand_total",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Grand Total",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_17",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "total_taxes_and_charges",
+   "fieldtype": "Currency",
+   "label": "Total Taxes and Charges",
+   "options": "Company:company:default_currency",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-money",
  "idx": 1,
  "is_submittable": 1,
- "modified": "2019-05-25 22:53:31.682151",
+ "modified": "2019-06-13 18:05:52.530462",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index d6b0eca..caeb2dd 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -12,6 +12,7 @@
 from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
 from erpnext.controllers.accounts_controller import AccountsController
 from frappe.utils.csvutils import getlink
+from erpnext.accounts.utils import get_account_currency
 
 class InvalidExpenseApproverError(frappe.ValidationError): pass
 class ExpenseApproverIdentityError(frappe.ValidationError): pass
@@ -29,6 +30,7 @@
 		self.set_expense_account(validate=True)
 		self.set_payable_account()
 		self.set_cost_center()
+		self.calculate_taxes()
 		self.set_status()
 		if self.task and not self.project:
 			self.project = frappe.db.get_value("Task", self.task, "project")
@@ -93,7 +95,7 @@
 		elif self.project:
 			frappe.get_doc("Project", self.project).update_project()
 
-	def make_gl_entries(self, cancel = False):
+	def make_gl_entries(self, cancel=False):
 		if flt(self.total_sanctioned_amount) > 0:
 			gl_entries = self.get_gl_entries()
 			make_gl_entries(gl_entries, cancel)
@@ -102,15 +104,13 @@
 		gl_entry = []
 		self.validate_account_details()
 
-		payable_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_amount)
-
 		# payable entry
-		if payable_amount:
+		if self.grand_total:
 			gl_entry.append(
 				self.get_gl_dict({
 					"account": self.payable_account,
-					"credit": payable_amount,
-					"credit_in_account_currency": payable_amount,
+					"credit": self.grand_total,
+					"credit_in_account_currency": self.grand_total,
 					"against": ",".join([d.default_account for d in self.expenses]),
 					"party_type": "Employee",
 					"party": self.employee,
@@ -144,15 +144,16 @@
 					"against_voucher": self.name
 				})
 			)
+		self.add_tax_gl_entries(gl_entry)
 
-		if self.is_paid and payable_amount:
+		if self.is_paid and self.grand_total:
 			# payment entry
 			payment_account = get_bank_cash_account(self.mode_of_payment, self.company).get("account")
 			gl_entry.append(
 				self.get_gl_dict({
 					"account": payment_account,
-					"credit": payable_amount,
-					"credit_in_account_currency": payable_amount,
+					"credit": self.grand_total,
+					"credit_in_account_currency": self.grand_total,
 					"against": self.employee
 				})
 			)
@@ -163,8 +164,8 @@
 					"party_type": "Employee",
 					"party": self.employee,
 					"against": payment_account,
-					"debit": payable_amount,
-					"debit_in_account_currency": payable_amount,
+					"debit": self.grand_total,
+					"debit_in_account_currency": self.grand_total,
 					"against_voucher": self.name,
 					"against_voucher_type": self.doctype,
 				})
@@ -172,6 +173,21 @@
 
 		return gl_entry
 
+	def add_tax_gl_entries(self, gl_entries):
+		# tax table gl entries
+		for tax in self.get("taxes"):
+			gl_entries.append(
+				self.get_gl_dict({
+					"account": tax.account_head,
+					"debit": tax.tax_amount,
+					"debit_in_account_currency": tax.tax_amount,
+					"against": self.employee,
+					"cost_center": self.cost_center,
+					"against_voucher_type": self.doctype,
+					"against_voucher": self.name
+				})
+			)
+
 	def validate_account_details(self):
 		if not self.cost_center:
 			frappe.throw(_("Cost center is required to book an expense claim"))
@@ -190,9 +206,20 @@
 			if self.approval_status == 'Rejected':
 				d.sanctioned_amount = 0.0
 
-			self.total_claimed_amount += flt(d.claim_amount)
+			self.total_claimed_amount += flt(d.amount)
 			self.total_sanctioned_amount += flt(d.sanctioned_amount)
 
+	def calculate_taxes(self):
+		self.total_taxes_and_charges = 0
+		for tax in self.taxes:
+			if tax.rate:
+				tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100)
+
+			tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount)
+			self.total_taxes_and_charges += flt(tax.tax_amount)
+
+		self.grand_total = flt(self.total_sanctioned_amount) + flt(self.total_taxes_and_charges) - flt(self.total_advance_amount)
+
 	def update_task(self):
 		task = frappe.get_doc("Task", self.task)
 		task.update_total_expense_claim()
@@ -224,7 +251,7 @@
 
 	def validate_sanctioned_amount(self):
 		for d in self.get('expenses'):
-			if flt(d.sanctioned_amount) > flt(d.claim_amount):
+			if flt(d.sanctioned_amount) > flt(d.amount):
 				frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
 
 	def set_expense_account(self, validate=False):
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.js b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
index 070474e..d0c43d3 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
@@ -17,7 +17,7 @@
 			d.expense_date = '2017-08-01',
 			d.expense_type = 'Test Expense Type 1',
 			d.description  = 'This is just to test Expense Claim',
-			d.claim_amount = 2000,
+			d.amount = 2000,
 			d.sanctioned_amount=2000,
 			refresh_field('expenses');
 		},
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 075bc63..a42209f 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -6,6 +6,7 @@
 import unittest
 from frappe.utils import random_string, nowdate
 from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry
+from erpnext.accounts.doctype.account.test_account import create_account
 
 test_records = frappe.get_test_records('Expense Claim')
 test_dependencies = ['Employee']
@@ -26,7 +27,7 @@
 		task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
 		payable_account = get_payable_account("Wind Power LLC")
 
-		make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name)
+		make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", "_Test Project 1", task_name)
 
 		self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
 		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
@@ -62,7 +63,8 @@
 
 	def test_expense_claim_gl_entry(self):
 		payable_account = get_payable_account("Wind Power LLC")
-		expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP")
+		taxes = generate_taxes()
+		expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", do_not_submit=True, taxes=taxes)
 		expense_claim.submit()
 
 		gl_entries = frappe.db.sql("""select account, debit, credit
@@ -72,7 +74,8 @@
 		self.assertTrue(gl_entries)
 
 		expected_values = dict((d[0], d) for d in [
-			[payable_account, 0.0, 200.0],
+			['CGST - WP',10.0, 0.0],
+			[payable_account, 0.0, 210.0],
 			["Travel Expenses - WP", 200.0, 0.0]
 		])
 
@@ -89,7 +92,7 @@
 			 "payable_account": payable_account,
 			 "approval_status": "Rejected",
 			 "expenses":
-			 	[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
+			 	[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "amount": 300, "sanctioned_amount": 200 }]
 		})
 		expense_claim.submit()
 
@@ -100,22 +103,44 @@
 		self.assertEquals(len(gl_entry), 0)
 
 def get_payable_account(company):
-	return frappe.get_cached_value('Company',  company,  'default_payable_account')
+	return frappe.get_cached_value('Company', company, 'default_payable_account')
 
-def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None):
-	expense_claim = frappe.get_doc({
+def generate_taxes():
+	parent_account = frappe.db.get_value('Account',
+		{'company': "Wind Power LLC", 'is_group':1, 'account_type': 'Tax'},
+		'name')
+	account = create_account(company="Wind Power LLC", account_name="CGST", account_type="Tax", parent_account=parent_account)
+	return {'taxes':[{
+		"account_head": account,
+		"rate": 0,
+		"description": "CGST",
+		"tax_amount": 10,
+		"total": 210
+	}]}
+
+def make_expense_claim(payable_account, amount, sanctioned_amount, company, account, project=None, task_name=None, do_not_submit=False, taxes=None):
+	expense_claim = {
 		 "doctype": "Expense Claim",
 		 "employee": "_T-Employee-00001",
 		 "payable_account": payable_account,
 		 "approval_status": "Approved",
 		 "company": company,
 		 "expenses":
-			[{ "expense_type": "Travel", "default_account": account, "claim_amount": claim_amount, "sanctioned_amount": sanctioned_amount }]
-		})
+			[{"expense_type": "Travel",
+			"default_account": account,
+			"amount": amount,
+			"sanctioned_amount": sanctioned_amount}]}
+	if taxes:
+		expense_claim.update(taxes)
+
+	expense_claim = frappe.get_doc(expense_claim)
+
 	if project:
 		expense_claim.project = project
 	if task_name:
 		expense_claim.task = task_name
 
+	if do_not_submit:
+		return expense_claim
 	expense_claim.submit()
 	return expense_claim
diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
index d4e7057..b23fb6a 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -253,7 +253,7 @@
    "bold": 0,
    "collapsible": 0,
    "columns": 0,
-   "fieldname": "claim_amount",
+   "fieldname": "amount",
    "fieldtype": "Currency",
    "hidden": 0,
    "ignore_user_permissions": 0,
@@ -262,7 +262,7 @@
    "in_global_search": 0,
    "in_list_view": 1,
    "in_standard_filter": 0,
-   "label": "Claim Amount",
+   "label": "Amount",
    "length": 0,
    "no_copy": 0,
    "oldfieldname": "claim_amount",
@@ -360,7 +360,7 @@
  "issingle": 0,
  "istable": 1,
  "max_attachments": 0,
- "modified": "2019-02-24 08:41:36.122565",
+ "modified": "2019-06-10 08:41:36.122565",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim Detail",
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py b/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
new file mode 100644
index 0000000..9bf69da
--- /dev/null
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -0,0 +1,105 @@
+{
+ "autoname": "hash",
+ "creation": "2019-06-03 11:42:33.123976",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "account_head",
+  "cost_center",
+  "col_break1",
+  "rate",
+  "description",
+  "section_break_6",
+  "tax_amount",
+  "column_break_8",
+  "total"
+ ],
+ "fields": [
+  {
+   "fieldname": "col_break1",
+   "fieldtype": "Column Break"
+  },
+  {
+   "columns": 2,
+   "fieldname": "account_head",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Account Head",
+   "oldfieldname": "account_head",
+   "oldfieldtype": "Link",
+   "options": "Account",
+   "reqd": 1
+  },
+  {
+   "default": ":Company",
+   "fieldname": "cost_center",
+   "fieldtype": "Link",
+   "label": "Cost Center",
+   "oldfieldname": "cost_center",
+   "oldfieldtype": "Link",
+   "options": "Cost Center"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "Description",
+   "oldfieldname": "description",
+   "oldfieldtype": "Small Text",
+   "print_width": "300px",
+   "reqd": 1,
+   "width": "300px"
+  },
+  {
+   "columns": 2,
+   "fetch_from": "account_head.tax_rate",
+   "fetch_if_empty": 1,
+   "fieldname": "rate",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Rate",
+   "oldfieldname": "rate",
+   "oldfieldtype": "Currency"
+  },
+  {
+   "columns": 2,
+   "fieldname": "tax_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Amount",
+   "oldfieldname": "tax_amount",
+   "oldfieldtype": "Currency",
+   "options": "currency"
+  },
+  {
+   "columns": 2,
+   "fieldname": "total",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Total",
+   "oldfieldname": "total",
+   "oldfieldtype": "Currency",
+   "options": "currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  }
+ ],
+ "istable": 1,
+ "modified": "2019-06-20 12:01:33.919555",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expense Taxes and Charges",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py
new file mode 100644
index 0000000..4103bef
--- /dev/null
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExpenseTaxesandCharges(Document):
+	pass
diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
index ceea493..df63361 100644
--- a/erpnext/hr/doctype/vehicle_log/vehicle_log.py
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
@@ -18,11 +18,11 @@
 			if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount):
 					if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount):
 							frappe.throw(_("Service Item,Type,frequency and expense amount are required"))
-							
+
 	def on_submit(self):
 		frappe.db.sql("update `tabVehicle` set last_odometer=%s where license_plate=%s",
 			(self.odometer, self.license_plate))
-	
+
 @frappe.whitelist()
 def get_make_model(license_plate):
 	vehicle=frappe.get_doc("Vehicle",license_plate)
@@ -41,7 +41,7 @@
 		for serdetail in vehicle_log.service_detail:
 			total_exp_amt = total_exp_amt + serdetail.expense_amount
 		return total_exp_amt
-		
+
 	vehicle_log = frappe.get_doc("Vehicle Log", docname)
 	exp_claim = frappe.new_doc("Expense Claim")
 	exp_claim.employee=vehicle_log.employee
@@ -52,6 +52,6 @@
 	exp_claim.append("expenses",{
 		"expense_date":vehicle_log.date,
 		"description":_("Vehicle Expenses"),
-		"claim_amount":total_claim_amt
+		"amount":total_claim_amt
 	})
 	return exp_claim.as_dict()
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 42fce5a..e9ef70c 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -152,7 +152,7 @@
 				make_bom(item = item, raw_materials = raw_materials)
 		production_plan = create_production_plan(item_code = 'Production Item CUST')
 		production_plan.make_material_request()
-		material_request = frappe.get_value('Material Request Item', {'production_plan': production_plan.name}, 'parent')
+		material_request = frappe.db.get_value('Material Request Item', {'production_plan': production_plan.name, 'item_code': 'CUST-0987'}, 'parent')
 		mr = frappe.get_doc('Material Request', material_request)
 		self.assertTrue(mr.material_request_type, 'Customer Provided')
 		self.assertTrue(mr.customer, '_Test Customer')
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 15fd82e..747177a 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -602,6 +602,6 @@
 erpnext.patches.v11_1.rename_depends_on_lwp
 execute:frappe.delete_doc("Report", "Inactive Items")
 erpnext.patches.v11_1.delete_scheduling_tool
-erpnext.patches.v12_0.make_custom_fields_for_bank_remittance
+erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
 execute:frappe.delete_doc_if_exists("Page", "support-analytics")
 erpnext.patches.v12_0.make_item_manufacturer
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index f117903..32f0428 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -103,8 +103,8 @@
 			{
 				"billable": 1,
 				"activity_type": "_Test Activity Type",
-				"from_type": now_datetime(),
-				"hours": 3,
+				"from_time": now_datetime(),
+				"to_time": now_datetime() + datetime.timedelta(hours=3),
 				"company": "_Test Company"
 			}
 		)
@@ -113,8 +113,8 @@
 			{
 				"billable": 1,
 				"activity_type": "_Test Activity Type",
-				"from_type": now_datetime(),
-				"hours": 3,
+				"from_time": now_datetime(),
+				"to_time": now_datetime() + datetime.timedelta(hours=3),
 				"company": "_Test Company"
 			}
 		)
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 477781b..047922f 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -11,9 +11,6 @@
 		href="https://discuss.erpnext.com">Feedback</a></p>'
 
 
-	$('.navbar-home').html('<img class="erpnext-icon" src="'+
-			frappe.urllib.get_base_url()+'/assets/erpnext/images/erp-icon.svg" />');
-
 	$('[data-link="docs"]').attr("href", "https://erpnext.com/docs")
 	$('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues")
 
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 7e61f03..97c823d 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -144,7 +144,9 @@
 			item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100;
 		}
 
-		item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+		if (item.discount_amount) {
+			item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+		}
 
 		this.calculate_taxes_and_totals();
 	},
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 73e04c0..d1113a4 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -118,34 +118,13 @@
 			"options": erpnext.get_presentation_currency_list()
 		},
 		{
-			"fieldname":"cost_center",
+			"fieldname": "cost_center",
 			"label": __("Cost Center"),
-			"fieldtype": "MultiSelect",
-			get_data: function() {
-				var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
-				const values = cost_centers.split(/\s*,\s*/).filter(d => d);
-				const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
-				let data = [];
-
-				frappe.call({
-					type: "GET",
-					method:'frappe.desk.search.search_link',
-					async: false,
-					no_spinner: true,
-					args: {
-						doctype: "Cost Center",
-						txt: txt,
-						filters: {
-							"company": frappe.query_report.get_filter_value("company"),
-							"name": ["not in", values]
-						}
-					},
-					callback: function(r) {
-						data = r.results;
-					}
+			"fieldtype": "MultiSelectList",
+			get_data: function(txt) {
+				return frappe.db.get_link_options('Cost Center', txt, {
+					company: frappe.query_report.get_filter_value("company")
 				});
-				return data;
 			}
 		}
 	]
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index f44fb0c..f4bb64a 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -65,6 +65,9 @@
 	},
 
 	get_dimension_filters: async function() {
+		if (!frappe.model.can_read('Accounting Dimension')) {
+			return [];
+		}
 		let dimensions = await frappe.db.get_list('Accounting Dimension', {
 			fields: ['label', 'fieldname', 'document_type'],
 			filters: {
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index 16c1d4d..fef4507 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -14,8 +14,12 @@
 		onload: function(frm) {
 			dimension_filters.then((dimensions) => {
 				dimensions.forEach((dimension) => {
-					frm.set_query(dimension['fieldname'],{
-						"is_group": 0
+					frappe.model.with_doctype(dimension['document_type'], () => {
+						if (frappe.meta.has_field(dimension['document_type'], 'is_group')) {
+							frm.set_query(dimension['fieldname'], {
+								"is_group": 0
+							});
+						}
 					});
 				});
 			});
diff --git a/erpnext/public/js/website_theme.js b/erpnext/public/js/website_theme.js
index 6c7edfa..84de2f5 100644
--- a/erpnext/public/js/website_theme.js
+++ b/erpnext/public/js/website_theme.js
@@ -2,16 +2,13 @@
 // MIT License. See license.txt
 
 frappe.ui.form.on('Website Theme', {
-	apply_custom_theme(frm) {
-		let custom_theme = frm.doc.custom_theme;
-		custom_theme = custom_theme.split('\n');
-		if (
-			frm.doc.apply_custom_theme
-				&& custom_theme.length === 2
-				&& custom_theme[1].includes('frappe/public/scss/website')
+	validate(frm) {
+		let theme_scss = frm.doc.theme_scss;
+		if (theme_scss.includes('frappe/public/scss/website')
+			&& !theme_scss.includes('erpnext/public/scss/website')
 		) {
-			frm.set_value('custom_theme',
-				`$primary: #7575ff;\n@import "frappe/public/scss/website";\n@import "erpnext/public/scss/website";`);
+			frm.set_value('theme_scss',
+				`${frm.doc.theme_scss}\n@import "erpnext/public/scss/website";`);
 		}
 	}
 });
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index f69c17e..26fdb1a 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -275,7 +275,7 @@
 		],
 		'Company': [
 			dict(fieldname='hra_section', label='HRA Settings',
-				fieldtype='Section Break', insert_after='asset_received_but_not_billed'),
+				fieldtype='Section Break', insert_after='asset_received_but_not_billed', collapsible=1),
 			dict(fieldname='basic_component', label='Basic Component',
 				fieldtype='Link', options='Salary Component', insert_after='hra_section'),
 			dict(fieldname='hra_component', label='HRA Component',
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 9d8fa2a..3a8149d 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -60,11 +60,8 @@
 		else:
 			for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
 				invoice_details = self.invoices.get(inv)
-				for key, items in items_based_on_rate.items():
-					rate = key[0]
-					account = key[1]
-
-					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+				for rate, items in items_based_on_rate.items():
+					row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
 
 					if self.filters.get("type_of_business") ==  "CDNR":
 						row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
@@ -103,7 +100,7 @@
 		for key, value in iteritems(b2cs_output):
 			self.data.append(value)
 
-	def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, account, items):
+	def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
 		row = []
 		for fieldname in self.invoice_fields:
 			if self.filters.get("type_of_business") ==  "CDNR" and fieldname == "invoice_value":
@@ -120,10 +117,8 @@
 		taxable_value = 0
 		for item_code, net_amount in self.invoice_items.get(invoice).items():
 				if item_code in items:
-					if self.item_tax_rate.get(invoice) and self.item_tax_rate.get(invoice, {}).get(item_code):
-						item_tax_rate = self.item_tax_rate.get(invoice, {}).get(item_code)
-						if account in item_tax_rate and tax_rate == item_tax_rate.get(account):
-							taxable_value += abs(net_amount)
+					if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code):
+						taxable_value += abs(net_amount)
 					elif not self.item_tax_rate.get(invoice):
 						taxable_value += abs(net_amount)
 
@@ -214,8 +209,9 @@
 				if d.item_tax_rate:
 					item_tax_rate = json.loads(d.item_tax_rate)
 
-				if item_tax_rate:
-					self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, item_tax_rate)
+					for account, rate in item_tax_rate.items():
+						tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, [])
+						tax_rate_dict.append(rate)
 
 	def get_items_based_on_tax_rate(self):
 		self.tax_details = frappe.db.sql("""
@@ -255,7 +251,7 @@
 								tax_rate *= 2
 
 							rate_based_dict = self.items_based_on_tax_rate\
-								.setdefault(parent, {}).setdefault((tax_rate, account), [])
+								.setdefault(parent, {}).setdefault(tax_rate, [])
 							if item_code not in rate_based_dict:
 								rate_based_dict.append(item_code)
 					except ValueError:
diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py
index d9cab63..a362269 100644
--- a/erpnext/regional/report/gstr_2/gstr_2.py
+++ b/erpnext/regional/report/gstr_2/gstr_2.py
@@ -43,11 +43,8 @@
 		self.get_igst_invoices()
 		for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
 			invoice_details = self.invoices.get(inv)
-			for key, items in items_based_on_rate.items():
-				rate = key[0]
-				account = key[1]
-
-				row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+			for rate, items in items_based_on_rate.items():
+				row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
 				tax_amount = taxable_value * rate / 100
 				if inv in self.igst_invoices:
 					row += [tax_amount, 0, 0]
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
index dcb81cb..dfdf9dc 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
@@ -29,7 +29,20 @@
 			"placeholder":"Company GSTIN",
 			"options": [""],
 			"width": "80"
-		}
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"width": "80"
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"width": "80"
+		},
+
 	],
 	onload: (report) => {
 		fetch_gstins(report);
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
index e938e29..222dfa1 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
@@ -88,7 +88,9 @@
 
 	for opts in (("company", " and company=%(company)s"),
 		("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"),
-		("company_gstin", " and company_gstin=%(company_gstin)s")):
+		("company_gstin", " and company_gstin=%(company_gstin)s"),
+		("from_date", " and posting_date >= %(from_date)s"),
+		("to_date", "and posting_date <= %(to_date)s")):
 			if filters.get(opts[0]):
 				conditions += opts[1]
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index fb7a335..b87ad03 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -581,8 +581,8 @@
 
 		if item:
 			target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
-				or item.get("selling_cost_center") \
-				or item_group.get("selling_cost_center")
+				or item.get("buying_cost_center") \
+				or item_group.get("buying_cost_center")
 
 	target_doc = get_mapped_doc("Sales Order", source_name, {
 		"Sales Order": {
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 1218dd3..d233b41 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -779,6 +779,17 @@
 
 		const customer = this.frm.doc.customer;
 		this.customer_field.set_value(customer);
+
+		if (this.numpad) {
+			const disable_btns = this.disable_numpad_control()
+			const enable_btns = [__('Rate'), __('Disc')]
+
+			if (disable_btns) {
+				enable_btns.filter(btn => !disable_btns.includes(btn))
+			}
+
+			this.numpad.enable_buttons(enable_btns);
+		}
 	}
 
 	get_grand_total() {
@@ -1551,6 +1562,16 @@
 		}
 	}
 
+	enable_buttons(btns) {
+		btns.forEach((btn) => {
+			const $btn = this.get_btn(btn);
+			$btn.prop("disabled", false)
+			$btn.hover(() => {
+				$btn.css('cursor','pointer');
+			})
+		})
+	}
+
 	set_class() {
 		for (const btn in this.add_class) {
 			const class_name = this.add_class[btn];
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index fcccf5a..d85fc45 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -170,9 +170,10 @@
    "label": "Company Description"
   },
   {
+   "collapsible": 1,
    "fieldname": "sales_settings",
    "fieldtype": "Section Break",
-   "label": "Sales"
+   "label": "Sales Settings"
   },
   {
    "fieldname": "sales_monthly_history",
@@ -530,6 +531,7 @@
    "options": "Account"
   },
   {
+   "collapsible": 1,
    "fieldname": "fixed_asset_depreciation_settings",
    "fieldtype": "Section Break",
    "label": "Fixed Asset Depreciation Settings"
@@ -602,6 +604,7 @@
    "options": "Role"
   },
   {
+   "collapsible": 1,
    "description": "For reference only.",
    "fieldname": "company_info",
    "fieldtype": "Section Break",
@@ -708,7 +711,7 @@
  "icon": "fa fa-building",
  "idx": 1,
  "image_field": "company_logo",
- "modified": "2019-06-13 18:03:14.764423",
+ "modified": "2019-06-14 14:36:11.363309",
  "modified_by": "Administrator",
  "module": "Setup",
  "name": "Company",
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 01b4734..bc8c749 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -20,8 +20,7 @@
 		# Google Maps returns distances in meters by default
 		self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter"
 		self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor",
-														{"from_uom": "Meter", "to_uom": self.default_distance_uom},
-														"value")
+			{"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value")
 
 	def validate(self):
 		self.validate_stop_addresses()
@@ -139,7 +138,7 @@
 				# Include last leg in the final distance calculation
 				self.uom = self.default_distance_uom
 				total_distance = sum([leg.get("distance", {}).get("value", 0.0)
-											for leg in directions.get("legs")])  # in meters
+					for leg in directions.get("legs")])  # in meters
 				self.total_distance = total_distance * self.uom_conversion_factor
 			else:
 				idx += len(route) - 1
@@ -358,8 +357,12 @@
 	email_recipients = []
 
 	for stop in delivery_trip.delivery_stops:
-		contact_info = frappe.db.get_value("Contact", stop.contact,
-											["first_name", "last_name", "email_id", "gender"], as_dict=1)
+		contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1)
+
+		context.update({"items": []})
+		if stop.delivery_note:
+			items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"])
+			context.update({"items": items})
 
 		if contact_info and contact_info.email_id:
 			context.update(stop.as_dict())
@@ -369,9 +372,9 @@
 			dispatch_template = frappe.get_doc("Email Template", dispatch_template_name)
 
 			frappe.sendmail(recipients=contact_info.email_id,
-							subject=dispatch_template.subject,
-							message=frappe.render_template(dispatch_template.response, context),
-							attachments=get_attachments(stop))
+				subject=dispatch_template.subject,
+				message=frappe.render_template(dispatch_template.response, context),
+				attachments=get_attachments(stop))
 
 			stop.db_set("email_sent_to", contact_info.email_id)
 			email_recipients.append(contact_info.email_id)
@@ -388,9 +391,7 @@
 		return []
 
 	dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment")
-	attachments = frappe.attach_print("Delivery Note",
-										delivery_stop.delivery_note,
-										file_name="Delivery Note",
-										print_format=dispatch_attachment)
+	attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note,
+		file_name="Delivery Note", print_format=dispatch_attachment)
 
 	return [attachments]
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 4869335..1a88473 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -67,8 +67,6 @@
 				from frappe.model.naming import set_name_by_naming_series
 				set_name_by_naming_series(self)
 				self.item_code = self.name
-		elif not self.item_code:
-			msgprint(_("Item Code is mandatory because Item is not automatically numbered"), raise_exception=1)
 
 		self.item_code = strip(self.item_code)
 		self.name = self.item_code
diff --git a/erpnext/stock/report/delayed_item_report/__init__.py b/erpnext/stock/report/delayed_item_report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/__init__.py
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.js b/erpnext/stock/report/delayed_item_report/delayed_item_report.js
new file mode 100644
index 0000000..5d160b1
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Delayed Item Report"] = {
+	"filters": [
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_default("company"),
+			reqd: 1
+		},
+		{
+			fieldname:"from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.month_start(),
+			reqd: 1
+		},
+		{
+			fieldname:"to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.now_date(),
+			reqd: 1
+		},
+		{
+			fieldname:"sales_order",
+			label: __("Sales Order"),
+			fieldtype: "Link",
+			options: "Sales Order",
+		},
+		{
+			fieldname:"customer",
+			label: __("Customer"),
+			fieldtype: "Link",
+			options: "Customer",
+		},
+		{
+			fieldname:"customer_group",
+			label: __("Customer Group"),
+			fieldtype: "Link",
+			options: "Customer Group",
+		},
+		{
+			fieldname:"item_group",
+			label: __("Item Group"),
+			fieldtype: "Link",
+			options: "Item Group",
+		},
+		{
+			fieldname:"based_on",
+			label: __("Based On"),
+			fieldtype: "Select",
+			options: ["Delivery Note", "Sales Invoice"],
+			default: "Delivery Note",
+			reqd: 1
+		},
+	]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.json b/erpnext/stock/report/delayed_item_report/delayed_item_report.json
new file mode 100644
index 0000000..f336cec
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.json
@@ -0,0 +1,37 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-06-17 12:45:07.324014",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2019-06-17 12:45:07.324014",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Delayed Item Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Delivery Note",
+ "report_name": "Delayed Item Report",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Stock Manager"
+  },
+  {
+   "role": "Stock User"
+  },
+  {
+   "role": "Maintenance User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.py b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
new file mode 100644
index 0000000..7b968b8
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
@@ -0,0 +1,168 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import date_diff
+
+def execute(filters=None, consolidated = False):
+	data, columns = DelayedItemReport(filters).run()
+
+	return data, columns
+
+class DelayedItemReport(object):
+	def __init__(self, filters=None):
+		self.filters = frappe._dict(filters or {})
+
+	def run(self):
+		return self.get_columns(), self.get_data() or []
+
+	def get_data(self, consolidated=False):
+		conditions = ""
+
+		doctype = self.filters.get("based_on")
+		child_doc= "%s Item" % doctype
+
+		if doctype == "Sales Invoice":
+			conditions = " and `tabSales Invoice`.update_stock = 1 and `tabSales Invoice`.is_pos = 0"
+
+		if self.filters.get("item_group"):
+			conditions += " and `tab%s`.item_group = %s" % (child_doc,
+				frappe.db.escape(self.filters.get("item_group")))
+
+		for field in ["customer", "customer_group", "company"]:
+			if self.filters.get(field):
+				conditions += " and `tab%s`.%s = %s" % (doctype,
+					field, frappe.db.escape(self.filters.get(field)))
+
+		sales_order_field = "against_sales_order"
+		if doctype == "Sales Invoice":
+			sales_order_field = "sales_order"
+
+		if self.filters.get("sales_order"):
+			conditions = " and `tab%s`.%s = '%s'" %(child_doc, sales_order_field, self.filters.get("sales_order"))
+
+		self.transactions = frappe.db.sql(""" SELECT `tab{child_doc}`.item_code, `tab{child_doc}`.item_name,
+				`tab{child_doc}`.item_group, `tab{child_doc}`.qty, `tab{child_doc}`.rate, `tab{child_doc}`.amount,
+				`tab{child_doc}`.so_detail, `tab{child_doc}`.{so_field} as sales_order,
+				`tab{doctype}`.customer, `tab{doctype}`.posting_date, `tab{doctype}`.name, `tab{doctype}`.grand_total
+			FROM `tab{child_doc}`, `tab{doctype}`
+			WHERE
+				`tab{child_doc}`.parent = `tab{doctype}`.name and `tab{doctype}`.docstatus = 1 and
+				`tab{doctype}`.posting_date between %(from_date)s and %(to_date)s and
+				`tab{child_doc}`.{so_field} is not null and `tab{child_doc}`.{so_field} != '' {cond}
+		""".format(cond=conditions, doctype=doctype, child_doc=child_doc, so_field=sales_order_field), {
+			'from_date': self.filters.get('from_date'),
+			'to_date': self.filters.get('to_date')
+		}, as_dict=1)
+
+		if self.transactions:
+			self.filter_transactions_data(consolidated)
+
+			return self.transactions
+
+	def filter_transactions_data(self, consolidated=False):
+		sales_orders = [d.sales_order for d in self.transactions]
+		doctype = "Sales Order"
+		filters = {'name': ('in', sales_orders)}
+
+		if not consolidated:
+			sales_order_items = [d.so_detail for d in self.transactions]
+			doctype = "Sales Order Item"
+			filters = {'parent': ('in', sales_orders), 'name': ('in', sales_order_items)}
+
+		so_data = {}
+		for d in frappe.get_all(doctype, filters = filters,
+			fields = ["delivery_date", "parent", "name"]):
+			key = d.name if consolidated else (d.parent, d.name)
+			if key not in so_data:
+				so_data.setdefault(key, d.delivery_date)
+
+		for row in self.transactions:
+			key = row.sales_order if consolidated else (row.sales_order, row.so_detail)
+			row.update({
+				'delivery_date': so_data.get(key),
+				'delayed_days': date_diff(row.posting_date, so_data.get(key))
+			})
+
+		return self.transactions
+
+	def get_columns(self):
+		based_on = self.filters.get("based_on")
+
+		return [{
+			"label": _(based_on),
+			"fieldname": "name",
+			"fieldtype": "Link",
+			"options": based_on,
+			"width": 100
+		},{
+			"label": _("Customer"),
+			"fieldname": "customer",
+			"fieldtype": "Link",
+			"options": "Customer",
+			"width": 100
+		},
+		{
+			"label": _("Expected Delivery Date"),
+			"fieldname": "delivery_date",
+			"fieldtype": "Date",
+			"width": 100
+		},
+		{
+			"label": _("Actual Delivery Date"),
+			"fieldname": "posting_date",
+			"fieldtype": "Date",
+			"width": 100
+		},
+		{
+			"label": _("Item Code"),
+			"fieldname": "item_code",
+			"fieldtype": "Link",
+			"options": "Item",
+			"width": 100
+		},
+		{
+			"label": _("Item Name"),
+			"fieldname": "item_name",
+			"fieldtype": "Data",
+			"width": 100
+		},
+		{
+			"label": _("Quantity"),
+			"fieldname": "qty",
+			"fieldtype": "Float",
+			"width": 100
+		},
+		{
+			"label": _("Rate"),
+			"fieldname": "rate",
+			"fieldtype": "Currency",
+			"width": 100
+		},
+		{
+			"label": _("Amount"),
+			"fieldname": "amount",
+			"fieldtype": "Currency",
+			"width": 100
+		},
+		{
+			"label": _("Delayed Days"),
+			"fieldname": "delayed_days",
+			"fieldtype": "Int",
+			"width": 100
+		},
+		{
+			"label": _("Sales Order"),
+			"fieldname": "sales_order",
+			"fieldtype": "Link",
+			"options": "Sales Order",
+			"width": 100
+		},
+		{
+			"label": _("Customer PO"),
+			"fieldname": "po_no",
+			"fieldtype": "Data",
+			"width": 100
+		}]
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/__init__.py b/erpnext/stock/report/delayed_order_report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/__init__.py
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.js b/erpnext/stock/report/delayed_order_report/delayed_order_report.js
new file mode 100644
index 0000000..11752ae
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Delayed Order Report"] = {
+	"filters": [
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_default("company"),
+			reqd: 1
+		},
+		{
+			fieldname:"from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.month_start(),
+			reqd: 1
+		},
+		{
+			fieldname:"to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.now_date(),
+			reqd: 1
+		},
+		{
+			fieldname:"sales_order",
+			label: __("Sales Order"),
+			fieldtype: "Link",
+			options: "Sales Order",
+		},
+		{
+			fieldname:"customer",
+			label: __("Customer"),
+			fieldtype: "Link",
+			options: "Customer",
+		},
+		{
+			fieldname:"customer_group",
+			label: __("Customer Group"),
+			fieldtype: "Link",
+			options: "Customer Group",
+		},
+		{
+			fieldname:"item_group",
+			label: __("Item Group"),
+			fieldtype: "Link",
+			options: "Item Group",
+		},
+		{
+			fieldname:"based_on",
+			label: __("Based On"),
+			fieldtype: "Select",
+			options: ["Delivery Note", "Sales Invoice"],
+			default: "Delivery Note",
+			reqd: 1
+		},
+	]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.json b/erpnext/stock/report/delayed_order_report/delayed_order_report.json
new file mode 100644
index 0000000..29c27cb
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.json
@@ -0,0 +1,37 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-06-17 12:45:56.359322",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2019-06-17 12:45:56.359322",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Delayed Order Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Delivery Note",
+ "report_name": "Delayed Order Report",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Stock Manager"
+  },
+  {
+   "role": "Stock User"
+  },
+  {
+   "role": "Maintenance User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.py b/erpnext/stock/report/delayed_order_report/delayed_order_report.py
new file mode 100644
index 0000000..d2a1a30
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.py
@@ -0,0 +1,83 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe import _
+from erpnext.stock.report.delayed_item_report.delayed_item_report import DelayedItemReport
+
+def execute(filters=None):
+	columns, data = [], []
+
+	columns, data = DelayedOrderReport(filters).run()
+
+	return columns, data
+
+class DelayedOrderReport(DelayedItemReport):
+	def run(self):
+		return self.get_columns(), self.get_data(consolidated=True) or []
+
+	def get_data(self, consolidated=False):
+		data = super(DelayedOrderReport, self).get_data(consolidated) or []
+
+		so_list = []
+		result = []
+		for d in data:
+			if d.sales_order not in so_list:
+				so_list.append(d.sales_order)
+				result.append(d)
+
+		return result
+
+	def get_columns(self):
+		based_on = self.filters.get("based_on")
+
+		return [{
+			"label": _(based_on),
+			"fieldname": "name",
+			"fieldtype": "Link",
+			"options": based_on,
+			"width": 100
+		},{
+			"label": _("Customer"),
+			"fieldname": "customer",
+			"fieldtype": "Link",
+			"options": "Customer",
+			"width": 100
+		},
+		{
+			"label": _("Expected Delivery Date"),
+			"fieldname": "delivery_date",
+			"fieldtype": "Date",
+			"width": 100
+		},
+		{
+			"label": _("Actual Delivery Date"),
+			"fieldname": "posting_date",
+			"fieldtype": "Date",
+			"width": 100
+		},
+		{
+			"label": _("Amount"),
+			"fieldname": "grand_total",
+			"fieldtype": "Currency",
+			"width": 100
+		},
+		{
+			"label": _("Delayed Days"),
+			"fieldname": "delayed_days",
+			"fieldtype": "Int",
+			"width": 100
+		},
+		{
+			"label": _("Sales Order"),
+			"fieldname": "sales_order",
+			"fieldtype": "Link",
+			"options": "Sales Order",
+			"width": 100
+		},
+		{
+			"label": _("Customer PO"),
+			"fieldname": "po_no",
+			"fieldtype": "Data",
+			"width": 100
+		}]
\ No newline at end of file
diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.js b/erpnext/stock/report/total_stock_summary/total_stock_summary.js
index b7461c4..90648f1 100644
--- a/erpnext/stock/report/total_stock_summary/total_stock_summary.js
+++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.js
@@ -10,8 +10,23 @@
 			"fieldtype": "Select",
 			"width": "80",
 			"reqd": 1,
-			"options": ["","Warehouse", "Company"],
-			"default": "Warehouse"
+			"options": ["", "Warehouse", "Company"],
+			"change": function() {
+				let group_by = frappe.query_report.get_filter_value("group_by")
+				let company_filter = frappe.query_report.get_filter("company")
+				if (group_by == "Company") {
+					company_filter.df.reqd = 0;
+					company_filter.df.hidden = 1;
+					frappe.query_report.set_filter_value("company", "");
+					company_filter.refresh();
+				}
+				else {
+					company_filter.df.reqd = 1;
+					company_filter.df.hidden = 0;
+					company_filter.refresh();
+					frappe.query_report.refresh();
+				}
+			}
 		},
 		{
 			"fieldname": "company",
diff --git a/travis/run-tests.sh b/travis/run-tests.sh
new file mode 100755
index 0000000..7cfd648
--- /dev/null
+++ b/travis/run-tests.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+if [[ $TEST_TYPE == 'Server Side Test' ]]; then
+    bench run-tests --app erpnext --coverage
+
+elif [[ $TEST_TYPE == 'Patch Test' ]]; then
+    wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
+    bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
+    bench migrate
+fi