Merge branch 'develop' into pur-inv-status-fix
diff --git a/erpnext/accounts/dashboard_fixtures.py b/erpnext/accounts/dashboard_fixtures.py
index a106f70..cdd1661 100644
--- a/erpnext/accounts/dashboard_fixtures.py
+++ b/erpnext/accounts/dashboard_fixtures.py
@@ -1,15 +1,22 @@
 # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
+from erpnext import get_default_company
 
 import frappe
 import json
 
 
 def get_data():
-	return frappe._dict({
-		"dashboards": get_dashboards(),
-		"charts": get_charts(),
+	data = frappe._dict({
+		"dashboards": [],
+		"charts": []
 	})
+	company = get_company_for_dashboards()
+	if company:
+		company_doc = frappe.get_doc("Company", company)
+		data.dashboards = get_dashboards()
+		data.charts = get_charts(company_doc)
+	return data
 
 def get_dashboards():
 	return [{
@@ -24,88 +31,87 @@
 		]
 	}]
 
-def get_charts():
-	company = frappe.get_doc("Company", get_company_for_dashboards())
+def get_charts(company):
 	income_account = company.default_income_account or get_account("Income Account", company.name)
 	expense_account = company.default_expense_account or get_account("Expense Account", company.name)
 	bank_account = company.default_bank_account or get_account("Bank", company.name)
 
 	return [
-			{
-				"doctype": "Dashboard Chart",
-				"time_interval": "Quarterly",
-				"name": "Income",
-				"chart_name": "Income",
-				"timespan": "Last Year",
-				"color": None,
-				"filters_json": json.dumps({"company": company.name, "account": income_account}),
-				"source": "Account Balance Timeline",
-				"chart_type": "Custom",
-				"timeseries": 1,
-				"owner": "Administrator",
-				"type": "Line"
-			},
-			{
-				"doctype": "Dashboard Chart",
-				"time_interval": "Quarterly",
-				"name": "Expenses",
-				"chart_name": "Expenses",
-				"timespan": "Last Year",
-				"color": None,
-				"filters_json": json.dumps({"company": company.name, "account": expense_account}),
-				"source": "Account Balance Timeline",
-				"chart_type": "Custom",
-				"timeseries": 1,
-				"owner": "Administrator",
-				"type": "Line"
-			},
-			{
-				"doctype": "Dashboard Chart",
-				"time_interval": "Quarterly",
-				"name": "Bank Balance",
-				"chart_name": "Bank Balance",
-				"timespan": "Last Year",
-				"color": "#ffb868",
-				"filters_json": json.dumps({"company": company.name, "account": bank_account}),
-				"source": "Account Balance Timeline",
-				"chart_type": "Custom",
-				"timeseries": 1,
-				"owner": "Administrator",
-				"type": "Line"
-			},
-			{
-				"doctype": "Dashboard Chart",
-				"time_interval": "Monthly",
-				"name": "Incoming Bills (Purchase Invoice)",
-				"chart_name": "Incoming Bills (Purchase Invoice)",
-				"timespan": "Last Year",
-				"color": "#a83333",
-				"value_based_on": "base_grand_total",
-				"filters_json": json.dumps({}),
-				"chart_type": "Sum",
-				"timeseries": 1,
-				"based_on": "posting_date",
-				"owner": "Administrator",
-				"document_type": "Purchase Invoice",
-				"type": "Bar"
-			},
-			{
-				"doctype": "Dashboard Chart",
-				"time_interval": "Monthly",
-				"name": "Outgoing Bills (Sales Invoice)",
-				"chart_name": "Outgoing Bills (Sales Invoice)",
-				"timespan": "Last Year",
-				"color": "#7b933d",
-				"value_based_on": "base_grand_total",
-				"filters_json": json.dumps({}),
-				"chart_type": "Sum",
-				"timeseries": 1,
-				"based_on": "posting_date",
-				"owner": "Administrator",
-				"document_type": "Sales Invoice",
-				"type": "Bar"
-			}
-		]
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Quarterly",
+			"name": "Income",
+			"chart_name": "Income",
+			"timespan": "Last Year",
+			"color": None,
+			"filters_json": json.dumps({"company": company.name, "account": income_account}),
+			"source": "Account Balance Timeline",
+			"chart_type": "Custom",
+			"timeseries": 1,
+			"owner": "Administrator",
+			"type": "Line"
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Quarterly",
+			"name": "Expenses",
+			"chart_name": "Expenses",
+			"timespan": "Last Year",
+			"color": None,
+			"filters_json": json.dumps({"company": company.name, "account": expense_account}),
+			"source": "Account Balance Timeline",
+			"chart_type": "Custom",
+			"timeseries": 1,
+			"owner": "Administrator",
+			"type": "Line"
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Quarterly",
+			"name": "Bank Balance",
+			"chart_name": "Bank Balance",
+			"timespan": "Last Year",
+			"color": "#ffb868",
+			"filters_json": json.dumps({"company": company.name, "account": bank_account}),
+			"source": "Account Balance Timeline",
+			"chart_type": "Custom",
+			"timeseries": 1,
+			"owner": "Administrator",
+			"type": "Line"
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Monthly",
+			"name": "Incoming Bills (Purchase Invoice)",
+			"chart_name": "Incoming Bills (Purchase Invoice)",
+			"timespan": "Last Year",
+			"color": "#a83333",
+			"value_based_on": "base_grand_total",
+			"filters_json": json.dumps({}),
+			"chart_type": "Sum",
+			"timeseries": 1,
+			"based_on": "posting_date",
+			"owner": "Administrator",
+			"document_type": "Purchase Invoice",
+			"type": "Bar"
+		},
+		{
+			"doctype": "Dashboard Chart",
+			"time_interval": "Monthly",
+			"name": "Outgoing Bills (Sales Invoice)",
+			"chart_name": "Outgoing Bills (Sales Invoice)",
+			"timespan": "Last Year",
+			"color": "#7b933d",
+			"value_based_on": "base_grand_total",
+			"filters_json": json.dumps({}),
+			"chart_type": "Sum",
+			"timeseries": 1,
+			"based_on": "posting_date",
+			"owner": "Administrator",
+			"document_type": "Sales Invoice",
+			"type": "Bar"
+		}
+	]
 
 def get_account(account_type, company):
 	accounts = frappe.get_list("Account", filters={"account_type": account_type, "company": company})
@@ -113,11 +119,9 @@
 		return accounts[0].name
 
 def get_company_for_dashboards():
-	company = frappe.defaults.get_defaults().company
-	if company:
-		return company
-	else:
+	company = get_default_company()
+	if not company:
 		company_list = frappe.get_list("Company")
 		if company_list:
-			return company_list[0].name
-	return None
\ No newline at end of file
+			company = company_list[0].name
+	return company
diff --git a/erpnext/assets/doctype/location/location.json b/erpnext/assets/doctype/location/location.json
index 6a35130..f56fd05 100644
--- a/erpnext/assets/doctype/location/location.json
+++ b/erpnext/assets/doctype/location/location.json
@@ -141,7 +141,7 @@
  ],
  "is_tree": 1,
  "links": [],
- "modified": "2020-03-18 18:00:08.885805",
+ "modified": "2020-05-08 16:11:11.375701",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Location",
@@ -221,7 +221,6 @@
   }
  ],
  "quick_entry": 1,
- "restrict_to_domain": "Agriculture",
  "show_name_in_global_search": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json
index 9161ed8..ebf8723 100644
--- a/erpnext/hr/doctype/hr_settings/hr_settings.json
+++ b/erpnext/hr/doctype/hr_settings/hr_settings.json
@@ -13,12 +13,12 @@
   "stop_birthday_reminders",
   "expense_approver_mandatory_in_expense_claim",
   "payroll_settings",
-  "payroll_based_on", 
-  "max_working_hours_against_timesheet", 
+  "payroll_based_on",
+  "max_working_hours_against_timesheet",
   "include_holidays_in_total_working_days",
   "disable_rounded_total",
   "column_break_11",
-  "daily_wages_fraction_for_half_day", 
+  "daily_wages_fraction_for_half_day",
   "email_salary_slip_to_employee",
   "encrypt_salary_slips_in_emails",
   "password_policy",
@@ -191,7 +191,7 @@
    "default": "Leave",
    "fieldname": "payroll_based_on",
    "fieldtype": "Select",
-   "label": "Calculate Working Days in Payroll based on",
+   "label": "Calculate Payroll Working Days Based On",
    "options": "Leave\nAttendance"
   },
   {
@@ -206,7 +206,7 @@
  "idx": 1,
  "issingle": 1,
  "links": [],
- "modified": "2020-04-13 21:20:59.382394",
+ "modified": "2020-05-11 13:02:51.274347",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR Settings",
diff --git a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
index f97e596..961c05c 100644
--- a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
+++ b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
@@ -38,7 +38,7 @@
 		for pledge in self.securities:
 
 			if not pledge.qty and not pledge.amount:
-				frappe.throw(_("Qty or Amount is mandatroy for loan security"))
+				frappe.throw(_("Qty or Amount is mandatory for loan security!"))
 
 			if not (self.loan_application and pledge.loan_security_price):
 				pledge.loan_security_price = get_loan_security_price(pledge.loan_security)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 3f90d36..f721724 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -680,3 +680,4 @@
 erpnext.patches.v12_0.retain_permission_rules_for_video_doctype
 erpnext.patches.v13_0.patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive
 execute:frappe.delete_doc_if_exists("Page", "appointment-analytic")
+execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
diff --git a/erpnext/patches/v11_0/set_default_email_template_in_hr.py b/erpnext/patches/v11_0/set_default_email_template_in_hr.py
index 14954fb..4622376 100644
--- a/erpnext/patches/v11_0/set_default_email_template_in_hr.py
+++ b/erpnext/patches/v11_0/set_default_email_template_in_hr.py
@@ -1,8 +1,9 @@
 from __future__ import unicode_literals
+from frappe import _
 import frappe
 
 def execute():
 	hr_settings = frappe.get_single("HR Settings")
-	hr_settings.leave_approval_notification_template = "Leave Approval Notification"
-	hr_settings.leave_status_notification_template = "Leave Status Notification"
-	hr_settings.save()
\ No newline at end of file
+	hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
+	hr_settings.leave_status_notification_template = _("Leave Status Notification")
+	hr_settings.save()
diff --git a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
index 179be2c..ec94cd0 100644
--- a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
+++ b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
@@ -7,7 +7,7 @@
 from frappe.model.utils.rename_field import rename_field
 
 def execute():
-	if not frappe.db.table_exists("Payroll Period"):
+	if not (frappe.db.table_exists("Payroll Period") and frappe.db.table_exists("Taxable Salary Slab")):
 		return
 
 	for doctype in ("income_tax_slab", "salary_structure_assignment", "employee_other_income", "income_tax_slab_other_charges"):
@@ -60,6 +60,9 @@
 				""", (income_tax_slab.name, company.name, period.start_date))
 
 	# move other incomes to separate document
+	if not frappe.db.table_exists("Employee Tax Exemption Proof Submission"):
+		return
+
 	migrated = []
 	proofs = frappe.get_all("Employee Tax Exemption Proof Submission",
 		filters = {'docstatus': 1},
@@ -79,6 +82,9 @@
 			except:
 				pass
 
+	if not frappe.db.table_exists("Employee Tax Exemption Declaration"):
+		return
+
 	declerations = frappe.get_all("Employee Tax Exemption Declaration",
 		filters = {'docstatus': 1},
 		fields =['payroll_period', 'employee', 'company', 'income_from_other_sources']
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.json b/erpnext/selling/report/sales_analytics/sales_analytics.json
index 7193261..bf9edd6 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.json
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.json
@@ -1,31 +1,31 @@
 {
- "add_total_row": 0, 
- "creation": "2018-09-21 12:46:29.451048", 
- "disable_prepared_report": 0, 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 0, 
- "is_standard": "Yes", 
- "modified": "2019-05-24 05:37:02.866139", 
- "modified_by": "Administrator", 
- "module": "Selling", 
- "name": "Sales Analytics", 
- "owner": "Administrator", 
- "prepared_report": 0, 
- "ref_doctype": "Sales Order", 
- "report_name": "Sales Analytics", 
- "report_type": "Script Report", 
+ "add_total_row": 0,
+ "creation": "2018-09-21 12:46:29.451048",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-04-30 19:49:02.303320",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Sales Analytics",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Sales Order",
+ "report_name": "Sales Analytics",
+ "report_type": "Script Report",
  "roles": [
   {
    "role": "Stock User"
-  }, 
+  },
   {
    "role": "Maintenance User"
-  }, 
+  },
   {
    "role": "Accounts User"
-  }, 
+  },
   {
    "role": "Sales Manager"
   }
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index f1726ab..97d9322 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -194,6 +194,9 @@
 	def get_rows(self):
 		self.data = []
 		self.get_periodic_data()
+		total_row = {
+			"entity": "Total",
+		}
 
 		for entity, period_data in iteritems(self.entity_periodic_data):
 			row = {
@@ -207,6 +210,9 @@
 				row[scrub(period)] = amount
 				total += amount
 
+				if not total_row.get(scrub(period)): total_row[scrub(period)] = 0
+				total_row[scrub(period)] += amount
+
 			row["total"] = total
 
 			if self.filters.tree_type == "Item":
@@ -214,6 +220,8 @@
 
 			self.data.append(row)
 
+		self.data.append(total_row)
+
 	def get_rows_by_group(self):
 		self.get_periodic_data()
 		out = []
@@ -232,8 +240,10 @@
 					self.entity_periodic_data.setdefault(d.parent, frappe._dict()).setdefault(period, 0.0)
 					self.entity_periodic_data[d.parent][period] += amount
 				total += amount
+
 			row["total"] = total
 			out = [row] + out
+
 		self.data = out
 
 	def get_periodic_data(self):
diff --git a/erpnext/selling/report/sales_analytics/test_analytics.py b/erpnext/selling/report/sales_analytics/test_analytics.py
index 4d81a1e..7e8501d 100644
--- a/erpnext/selling/report/sales_analytics/test_analytics.py
+++ b/erpnext/selling/report/sales_analytics/test_analytics.py
@@ -34,6 +34,21 @@
 
 		expected_data = [
 			{
+				'entity': 'Total',
+				'apr_2017': 0.0,
+				'may_2017': 0.0,
+				'jun_2017': 2000.0,
+				'jul_2017': 1000.0,
+				'aug_2017': 0.0,
+				'sep_2017': 1500.0,
+				'oct_2017': 1000.0,
+				'nov_2017': 0.0,
+				'dec_2017': 0.0,
+				'jan_2018': 0.0,
+				'feb_2018': 2000.0,
+				'mar_2018': 0.0
+  			},
+			{
 				"entity": "_Test Customer 1",
 				"entity_name": "_Test Customer 1",
 				"apr_2017": 0.0,
@@ -135,6 +150,21 @@
 
 		expected_data = [
 			{
+				'entity': 'Total',
+				'apr_2017': 0.0,
+				'may_2017': 0.0,
+				'jun_2017': 20.0,
+				'jul_2017': 10.0,
+				'aug_2017': 0.0,
+				'sep_2017': 15.0,
+				'oct_2017': 10.0,
+				'nov_2017': 0.0,
+				'dec_2017': 0.0,
+				'jan_2018': 0.0,
+				'feb_2018': 20.0,
+				'mar_2018': 0.0
+  			},
+			{
 				"entity": "_Test Customer 1",
 				"entity_name": "_Test Customer 1",
 				"apr_2017": 0.0,
diff --git a/erpnext/setup/desk_page/getting_started/getting_started.json b/erpnext/setup/desk_page/home/home.json
similarity index 96%
rename from erpnext/setup/desk_page/getting_started/getting_started.json
rename to erpnext/setup/desk_page/home/home.json
index 63d8984..63cd5c5 100644
--- a/erpnext/setup/desk_page/getting_started/getting_started.json
+++ b/erpnext/setup/desk_page/home/home.json
@@ -47,26 +47,20 @@
   }
  ],
  "category": "Modules",
- "charts": [
-  {
-   "chart_name": "Bank Balance",
-   "label": "Bank Balance"
-  }
- ],
+ "charts": [],
  "creation": "2020-01-23 13:46:38.833076",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
- "icon": "",
  "idx": 0,
  "is_standard": 1,
- "label": "Getting Started",
- "modified": "2020-04-01 11:30:19.763099",
+ "label": "Home",
+ "modified": "2020-05-11 10:20:37.358701",
  "modified_by": "Administrator",
  "module": "Setup",
- "name": "Getting Started",
+ "name": "Home",
  "owner": "Administrator",
  "pin_to_bottom": 0,
  "pin_to_top": 1,
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 10f2555..62c9eb1 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -470,7 +470,7 @@
 			"qty": item.s_warehouse and -1*flt(item.transfer_qty) or flt(item.transfer_qty),
 			"serial_no": item.serial_no,
 			"voucher_type": self.doctype,
-			"voucher_no": item.name,
+			"voucher_no": self.name,
 			"company": self.company,
 			"allow_zero_valuation": item.allow_zero_valuation_rate,
 		})
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index b4cb8ca..e1b3730 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -548,7 +548,16 @@
 	if not allow_zero_rate and not valuation_rate and raise_error_if_no_rate \
 			and cint(erpnext.is_perpetual_inventory_enabled(company)):
 		frappe.local.message_log = []
-		frappe.throw(_("Valuation rate not found for the Item {0}, which is required to do accounting entries for {1} {2}. If the item is transacting as a zero valuation rate item in the {1}, please mention that in the {1} Item table. Otherwise, please create an incoming stock transaction for the item or mention valuation rate in the Item record, and then try submiting / cancelling this entry.")
-			.format(item_code, voucher_type, voucher_no))
+		form_link = frappe.utils.get_link_to_form("Item", item_code)
+
+		message = _("Valuation Rate for the Item {0}, is required to do accounting entries for {1} {2}.").format(form_link, voucher_type, voucher_no)
+		message += "<br><br>" + _(" Here are the options to proceed:")
+		solutions = "<li>" + _("If the item is transacting as a Zero Valuation Rate item in this entry, please enable 'Allow Zero Valuation Rate' in the {0} Item table.").format(voucher_type) + "</li>"
+		solutions += "<li>" + _("If not, you can Cancel / Submit this entry ") + _("{0}").format(frappe.bold("after")) + _(" performing either one below:") + "</li>"
+		sub_solutions = "<ul><li>" + _("Create an incoming stock transaction for the Item.") + "</li>"
+		sub_solutions += "<li>" + _("Mention Valuation Rate in the Item master.") + "</li></ul>"
+		msg = message + solutions + sub_solutions + "</li>"
+
+		frappe.throw(msg=msg, title=_("Valuation Rate Missing"))
 
 	return valuation_rate