Merge branch 'develop' of https://github.com/frappe/erpnext into develop
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 68aeb6d..287e00f 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -69,7 +69,7 @@
 		elif self.payment_request_type == 'Inward':
 			self.db_set('status', 'Requested')
 
-		send_mail = self.payment_gateway_validation()
+		send_mail = self.payment_gateway_validation() if self.payment_gateway else None
 		ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
 
 		if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 7fb598b..4a35a66 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -19,7 +19,7 @@
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children
 
 def get_period_list(from_fiscal_year, to_fiscal_year, period_start_date, period_end_date, filter_based_on, periodicity, accumulated_values=False,
-	company=None, reset_period_on_fy_change=True):
+	company=None, reset_period_on_fy_change=True, ignore_fiscal_year=False):
 	"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
 		Periodicity can be (Yearly, Quarterly, Monthly)"""
 
@@ -67,8 +67,9 @@
 			# if a fiscal year ends before a 12 month period
 			period.to_date = year_end_date
 
-		period.to_date_fiscal_year = get_fiscal_year(period.to_date, company=company)[0]
-		period.from_date_fiscal_year_start_date = get_fiscal_year(period.from_date, company=company)[1]
+		if not ignore_fiscal_year:
+			period.to_date_fiscal_year = get_fiscal_year(period.to_date, company=company)[0]
+			period.from_date_fiscal_year_start_date = get_fiscal_year(period.from_date, company=company)[1]
 
 		period_list.append(period)
 
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 8bd4399..5a699b6 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -71,7 +71,8 @@
 	opening_balances = get_opening_balances(filters)
 
 	#add filter inside list so that the query in financial_statements.py doesn't break
-	filters.project = [filters.project]
+	if filters.project:
+		filters.project = [filters.project]
 
 	set_gl_entries_by_account(filters.company, filters.from_date,
 		filters.to_date, min_lft, max_rgt, filters, gl_entries_by_account, ignore_closing_entries=not flt(filters.with_period_closing_entry))
diff --git a/erpnext/assets/dashboard_fixtures.py b/erpnext/assets/dashboard_fixtures.py
new file mode 100644
index 0000000..9af45d1
--- /dev/null
+++ b/erpnext/assets/dashboard_fixtures.py
@@ -0,0 +1,185 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+import json
+from frappe.utils import nowdate, add_months, get_date_str
+from frappe import _
+from erpnext.accounts.utils import get_fiscal_year
+
+
+def get_data():
+	return frappe._dict({
+		"dashboards": get_dashboards(),
+		"charts": get_charts(),
+		"number_cards": get_number_cards(),
+	})
+
+def get_dashboards():
+	return [{
+		"name": "Asset",
+		"dashboard_name": "Asset",
+        "charts": [
+			{ "chart": "Asset Value Analytics", "width": "Full" },
+            { "chart": "Category-wise Asset Value", "width": "Half" },
+            { "chart": "Location-wise Asset Value", "width": "Half" },
+        ],
+		"cards": [
+			{"card": "Total Assets"},
+			{"card": "New Assets (This Year)"},
+			{"card": "Asset Value"}
+		]
+    }]
+
+fiscal_year = get_fiscal_year(date=nowdate())
+year_start_date = get_date_str(fiscal_year[1])
+year_end_date = get_date_str(fiscal_year[2])
+
+
+def get_charts():
+	company = get_company_for_dashboards()
+	return [
+		{
+			"name": "Asset Value Analytics",
+			"chart_name": _("Asset Value Analytics"),
+			"chart_type": "Report",
+			"report_name": "Fixed Asset Register",
+			"is_custom": 1,
+			"group_by_type": "Count",
+			"number_of_groups": 0,
+			"is_public": 0,
+			"timespan": "Last Year",
+			"time_interval": "Yearly",
+			"timeseries": 0,
+			"filters_json": json.dumps({
+				"company": company,
+				"status": "In Location",
+				"filter_based_on": "Fiscal Year",
+				"from_fiscal_year": fiscal_year[0],
+				"to_fiscal_year": fiscal_year[0],
+				"period_start_date": year_start_date,
+				"period_end_date": year_end_date,
+				"date_based_on": "Purchase Date",
+				"group_by": "--Select a group--"
+			}),
+			"type": "Bar",
+			"custom_options": json.dumps({
+				"type": "bar",
+				"barOptions": { "stacked": 1 },
+				"axisOptions": { "shortenYAxisNumbers": 1 },
+				"tooltipOptions": {}
+			}),
+			"doctype": "Dashboard Chart",
+			"y_axis": []
+		},
+		{
+			"name": "Category-wise Asset Value",
+			"chart_name": _("Category-wise Asset Value"),
+			"chart_type": "Report",
+			"report_name": "Fixed Asset Register",
+			"x_field": "asset_category",
+			"timeseries": 0,
+			"filters_json": json.dumps({
+				"company": company,
+				"status":"In Location",
+				"group_by":"Asset Category",
+				"is_existing_asset":0
+			}),
+			"type": "Donut",
+			"doctype": "Dashboard Chart",
+			"y_axis": [
+				{
+					"parent": "Category-wise Asset Value",
+					"parentfield": "y_axis",
+					"parenttype": "Dashboard Chart",
+					"y_field": "asset_value",
+					"doctype": "Dashboard Chart Field"
+				}
+			],
+			"custom_options": json.dumps({
+				"type": "donut",
+				"height": 300,
+				"axisOptions": {"shortenYAxisNumbers": 1}
+			})
+		},
+		{
+			"name": "Location-wise Asset Value",
+			"chart_name": "Location-wise Asset Value",
+			"chart_type": "Report",
+			"report_name": "Fixed Asset Register",
+			"x_field": "location",
+			"timeseries": 0,
+			"filters_json": json.dumps({
+				"company": company,
+				"status":"In Location",
+				"group_by":"Location",
+				"is_existing_asset":0
+			}),
+			"type": "Donut",
+			"doctype": "Dashboard Chart",
+			"y_axis": [
+				{
+					"parent": "Location-wise Asset Value",
+					"parentfield": "y_axis",
+					"parenttype": "Dashboard Chart",
+					"y_field": "asset_value",
+					"doctype": "Dashboard Chart Field"
+				}
+			],
+			"custom_options": json.dumps({
+				"type": "donut",
+				"height": 300,
+				"axisOptions": {"shortenYAxisNumbers": 1}
+			})
+		}
+	]
+
+def get_number_cards():
+	return [
+		{
+			"name": "Total Assets",
+			"label": _("Total Assets"),
+			"function": "Count",
+			"document_type": "Asset",
+			"is_public": 1,
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Monthly",
+			"filters_json": "[]",
+			"doctype": "Number Card",
+		},
+		{
+			"name": "New Assets (This Year)",
+			"label": _("New Assets (This Year)"),
+			"function": "Count",
+			"document_type": "Asset",
+			"is_public": 1,
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Monthly",
+			"filters_json": json.dumps([
+				['Asset', 'creation', 'between', [year_start_date, year_end_date]]
+			]),
+			"doctype": "Number Card",
+		},
+		{
+			"name": "Asset Value",
+			"label": _("Asset Value"),
+			"function": "Sum",
+			"aggregate_function_based_on": "value_after_depreciation",
+			"document_type": "Asset",
+			"is_public": 1,
+			"show_percentage_stats": 1,
+			"stats_time_interval": "Monthly",
+			"filters_json": "[]",
+			"doctype": "Number Card"
+		}
+	]
+
+def get_company_for_dashboards():
+	company = frappe.defaults.get_defaults().company
+	if company:
+		return company
+	else:
+		company_list = frappe.get_list("Company")
+		if company_list:
+			return company_list[0].name
+	return None
\ No newline at end of file
diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json
index 0309416..94939fd 100644
--- a/erpnext/assets/desk_page/assets/assets.json
+++ b/erpnext/assets/desk_page/assets/assets.json
@@ -17,21 +17,27 @@
   }
  ],
  "category": "Modules",
- "charts": [],
+ "charts": [
+  {
+   "chart_name": "Asset Value Analytics",
+   "label": "Asset Value Analytics"
+  }
+ ],
  "creation": "2020-03-02 15:43:27.634865",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
- "icon": "",
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "Assets",
- "modified": "2020-04-01 11:28:51.072198",
+ "modified": "2020-05-20 18:05:23.994795",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Assets",
+ "onboarding": "Assets",
  "owner": "Administrator",
  "pin_to_bottom": 0,
  "pin_to_top": 0,
@@ -42,14 +48,19 @@
    "type": "DocType"
   },
   {
-   "label": "Asset Movement",
-   "link_to": "Asset Movement",
+   "label": "Asset Category",
+   "link_to": "Asset Category",
    "type": "DocType"
   },
   {
    "label": "Fixed Asset Register",
    "link_to": "Fixed Asset Register",
    "type": "Report"
+  },
+  {
+   "label": "Assets Dashboard",
+   "link_to": "Asset",
+   "type": "Dashboard"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index a53ff88..fba20c0 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -387,7 +387,8 @@
 		}
 		frm.set_value('gross_purchase_amount', item.base_net_rate + item.item_tax_amount);
 		frm.set_value('purchase_receipt_amount', item.base_net_rate + item.item_tax_amount);
-		frm.set_value('location', item.asset_location);
+		item.asset_location && frm.set_value('location', item.asset_location);
+		frm.set_value('cost_center', item.cost_center || purchase_doc.cost_center);
 	},
 
 	set_depreciation_rate: function(frm, row) {
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 505ba4c..2ecabe6 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -127,6 +127,8 @@
 			frappe.throw(_("Available-for-use Date should be after purchase date"))
 
 	def validate_gross_and_purchase_amount(self):
+		if self.is_existing_asset: return
+		
 		if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_receipt_amount:
 			frappe.throw(_("Gross Purchase Amount should be {} to purchase amount of one single Asset. {}\
 				Please do not book expense of multiple assets against one single Asset.")
diff --git a/erpnext/assets/module_onboarding/assets/assets.json b/erpnext/assets/module_onboarding/assets/assets.json
new file mode 100644
index 0000000..66dd60a
--- /dev/null
+++ b/erpnext/assets/module_onboarding/assets/assets.json
@@ -0,0 +1,42 @@
+{
+ "allow_roles": [
+  {
+   "role": "Accounts User"
+  },
+  {
+   "role": "Maintenance User"
+  }
+ ],
+ "creation": "2020-05-08 15:10:45.571457",
+ "docstatus": 0,
+ "doctype": "Module Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/asset",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-08 16:17:31.685943",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Assets",
+ "owner": "Administrator",
+ "steps": [
+  {
+   "step": "Introduction to Assets"
+  },
+  {
+   "step": "Create a Fixed Asset Item"
+  },
+  {
+   "step": "Create an Asset Category"
+  }, 
+  {
+   "step": "Purchase an Asset Item"
+  },
+  {
+   "step": "Create an Asset"
+  }
+ ],
+ "subtitle": "Assets, Depreciations, Repairs and more",
+ "success_message": "The Asset Module is all set up!",
+ "title": "Let's Setup Asset Management",
+ "user_can_dismiss": 1
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json b/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json
new file mode 100644
index 0000000..f5818c0
--- /dev/null
+++ b/erpnext/assets/onboarding_step/create_a_fixed_asset_item/create_a_fixed_asset_item.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:20:00.259985",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:20:00.259985",
+ "modified_by": "Administrator",
+ "name": "Create a Fixed Asset Item",
+ "owner": "Administrator",
+ "reference_document": "Item",
+ "title": "Create a Fixed Asset Item"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/create_an_asset/create_an_asset.json b/erpnext/assets/onboarding_step/create_an_asset/create_an_asset.json
new file mode 100644
index 0000000..5488b1d
--- /dev/null
+++ b/erpnext/assets/onboarding_step/create_an_asset/create_an_asset.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:21:53.332538",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:21:53.332538",
+ "modified_by": "Administrator",
+ "name": "Create an Asset",
+ "owner": "Administrator",
+ "reference_document": "Asset",
+ "title": "Create an Asset"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/create_an_asset_category/create_an_asset_category.json b/erpnext/assets/onboarding_step/create_an_asset_category/create_an_asset_category.json
new file mode 100644
index 0000000..3bf54af
--- /dev/null
+++ b/erpnext/assets/onboarding_step/create_an_asset_category/create_an_asset_category.json
@@ -0,0 +1,16 @@
+{
+    "action": "Create Entry",
+    "creation": "2020-05-08 13:21:53.332538",
+    "docstatus": 0,
+    "doctype": "Onboarding Step",
+    "idx": 0,
+    "is_complete": 0,
+    "is_mandatory": 0,
+    "is_skipped": 0,
+    "modified": "2020-05-08 13:21:53.332538",
+    "modified_by": "Administrator",
+    "name": "Create an Asset Category",
+    "owner": "Administrator",
+    "reference_document": "Asset Category",
+    "title": "Create an Asset Category"
+   }
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json b/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json
new file mode 100644
index 0000000..d48dd1c
--- /dev/null
+++ b/erpnext/assets/onboarding_step/introduction_to_assets/introduction_to_assets.json
@@ -0,0 +1,16 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-05-08 13:18:25.424715",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 16:06:16.625646",
+ "modified_by": "Administrator",
+ "name": "Introduction to Assets",
+ "owner": "Administrator",
+ "title": "Introduction to Assets",
+ "video_url": "https://www.youtube.com/watch?v=I-K8pLRmvSo"
+}
\ No newline at end of file
diff --git a/erpnext/assets/onboarding_step/purchase_an_asset_item/purchase_an_asset_item.json b/erpnext/assets/onboarding_step/purchase_an_asset_item/purchase_an_asset_item.json
new file mode 100644
index 0000000..732ff7f
--- /dev/null
+++ b/erpnext/assets/onboarding_step/purchase_an_asset_item/purchase_an_asset_item.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-08 13:21:28.208059",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-08 13:21:28.208059",
+ "modified_by": "Administrator",
+ "name": "Purchase an Asset Item",
+ "owner": "Administrator",
+ "reference_document": "Purchase Receipt",
+ "title": "Purchase an Asset Item"
+}
\ No newline at end of file
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
index 91ce9ce..1a6ef54 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js
@@ -21,20 +21,54 @@
 			reqd: 1
 		},
 		{
-			fieldname:"purchase_date",
-			label: __("Purchase Date"),
-			fieldtype: "Date"
+			"fieldname":"filter_based_on",
+			"label": __("Period Based On"),
+			"fieldtype": "Select",
+			"options": ["Fiscal Year", "Date Range"],
+			"default": ["Fiscal Year"],
+			"reqd": 1
 		},
 		{
-			fieldname:"available_for_use_date",
-			label: __("Available For Use Date"),
-			fieldtype: "Date"
+			"fieldname":"from_date",
+			"label": __("Start Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.nowdate(), -12),
+			"depends_on": "eval: doc.filter_based_on == 'Date Range'",
+			"reqd": 1
 		},
 		{
-			fieldname:"finance_book",
-			label: __("Finance Book"),
-			fieldtype: "Link",
-			options: "Finance Book"
+			"fieldname":"to_date",
+			"label": __("End Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.nowdate(),
+			"depends_on": "eval: doc.filter_based_on == 'Date Range'",
+			"reqd": 1
+		},
+		{
+			"fieldname":"from_fiscal_year",
+			"label": __("Start Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": frappe.defaults.get_user_default("fiscal_year"),
+			"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
+			"reqd": 1
+		},
+		{
+			"fieldname":"to_fiscal_year",
+			"label": __("End Year"),
+			"fieldtype": "Link",
+			"options": "Fiscal Year",
+			"default": frappe.defaults.get_user_default("fiscal_year"),
+			"depends_on": "eval: doc.filter_based_on == 'Fiscal Year'",
+			"reqd": 1
+		},
+		{
+			"fieldname":"date_based_on",
+			"label": __("Date Based On"),
+			"fieldtype": "Select",
+			"options": ["Purchase Date", "Available For Use Date"],
+			"default": "Purchase Date",
+			"reqd": 1
 		},
 		{
 			fieldname:"asset_category",
@@ -42,6 +76,26 @@
 			fieldtype: "Link",
 			options: "Asset Category"
 		},
+		{	
+			fieldname:"finance_book",
+			label: __("Finance Book"),
+			fieldtype: "Link",
+			options: "Finance Book"
+		},
+		{
+			fieldname:"cost_center",
+			label: __("Cost Center"),
+			fieldtype: "Link",
+			options: "Cost Center"
+		},
+		{
+			fieldname:"group_by",
+			label: __("Group By"),
+			fieldtype: "Select",
+			options: ["--Select a group--", "Asset Category", "Location"],
+			default: "--Select a group--",
+			reqd: 1
+		},
 		{
 			fieldname:"is_existing_asset",
 			label: __("Is Existing Asset"),
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
index fa2fe7b..af08a2a 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
@@ -4,122 +4,39 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import cstr, today, flt
+from frappe.utils import cstr, today, flt, add_years, formatdate, getdate
+from erpnext.accounts.report.financial_statements import get_period_list, get_fiscal_year_data, validate_fiscal_year
 
 def execute(filters=None):
 	filters = frappe._dict(filters or {})
 	columns = get_columns(filters)
 	data = get_data(filters)
-	return columns, data
+	chart = prepare_chart_data(data, filters) if filters.get("group_by") not in ("Asset Category", "Location") else {}
 
-def get_columns(filters):
-	return [
-		{
-			"label": _("Asset Id"),
-			"fieldtype": "Link",
-			"fieldname": "asset_id",
-			"options": "Asset",
-			"width": 100
-		},
-		{
-			"label": _("Asset Name"),
-			"fieldtype": "Data",
-			"fieldname": "asset_name",
-			"width": 140
-		},
-		{
-			"label": _("Asset Category"),
-			"fieldtype": "Link",
-			"fieldname": "asset_category",
-			"options": "Asset Category",
-			"width": 100
-		},
-		{
-			"label": _("Status"),
-			"fieldtype": "Data",
-			"fieldname": "status",
-			"width": 90
-		},
-		{
-			"label": _("Purchase Date"),
-			"fieldtype": "Date",
-			"fieldname": "purchase_date",
-			"width": 90
-		},
-		{
-			"label": _("Available For Use Date"),
-			"fieldtype": "Date",
-			"fieldname": "available_for_use_date",
-			"width": 90
-		},
-		{
-			"label": _("Gross Purchase Amount"),
-			"fieldname": "gross_purchase_amount",
-			"options": "Currency",
-			"width": 90
-		},
-		{
-			"label": _("Asset Value"),
-			"fieldname": "asset_value",
-			"options": "Currency",
-			"width": 90
-		},
-		{
-			"label": _("Opening Accumulated Depreciation"),
-			"fieldname": "opening_accumulated_depreciation",
-			"options": "Currency",
-			"width": 90
-		},
-		{
-			"label": _("Depreciated Amount"),
-			"fieldname": "depreciated_amount",
-			"options": "Currency",
-			"width": 90
-		},
-		{
-			"label": _("Cost Center"),
-			"fieldtype": "Link",
-			"fieldname": "cost_center",
-			"options": "Cost Center",
-			"width": 100
-		},
-		{
-			"label": _("Department"),
-			"fieldtype": "Link",
-			"fieldname": "department",
-			"options": "Department",
-			"width": 100
-		},
-		{
-			"label": _("Vendor Name"),
-			"fieldtype": "Data",
-			"fieldname": "vendor_name",
-			"width": 100
-		},
-		{
-			"label": _("Location"),
-			"fieldtype": "Link",
-			"fieldname": "location",
-			"options": "Location",
-			"width": 100
-		},
-	]
+	return columns, data, None, chart
 
 def get_conditions(filters):
 	conditions = { 'docstatus': 1 }
 	status = filters.status
-	date = filters.date
+	date_field = frappe.scrub(filters.date_based_on or "Purchase Date")
 
 	if filters.get('company'):
 		conditions["company"] = filters.company
-	if filters.get('purchase_date'):
-		conditions["purchase_date"] = ('<=', filters.get('purchase_date'))
-	if filters.get('available_for_use_date'):
-		conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date'))
+	if filters.filter_based_on == "Date Range":
+		conditions[date_field] = ["between", [filters.from_date, filters.to_date]]
+	if filters.filter_based_on == "Fiscal Year":
+		fiscal_year = get_fiscal_year_data(filters.from_fiscal_year, filters.to_fiscal_year)
+		validate_fiscal_year(fiscal_year, filters.from_fiscal_year, filters.to_fiscal_year)
+		filters.year_start_date = getdate(fiscal_year.year_start_date)
+		filters.year_end_date = getdate(fiscal_year.year_end_date)
+
+		conditions[date_field] = ["between", [filters.year_start_date, filters.year_end_date]]
 	if filters.get('is_existing_asset'):
 		conditions["is_existing_asset"] = filters.get('is_existing_asset')
 	if filters.get('asset_category'):
 		conditions["asset_category"] = filters.get('asset_category')
+	if filters.get('cost_center'):
+		conditions["cost_center"] = filters.get('cost_center')
 
 	# In Store assets are those that are not sold or scrapped
 	operand = 'not in'
@@ -139,18 +56,28 @@
 	pr_supplier_map = get_purchase_receipt_supplier_map()
 	pi_supplier_map = get_purchase_invoice_supplier_map()
 
-	assets_record = frappe.db.get_all("Asset",
-		filters=conditions,
-		fields=["name", "asset_name", "department", "cost_center", "purchase_receipt",
+	group_by = frappe.scrub(filters.get("group_by"))
+
+	if group_by == "asset_category":
+		fields = ["asset_category", "gross_purchase_amount", "opening_accumulated_depreciation"]
+		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
+
+	elif group_by == "location":
+		fields = ["location", "gross_purchase_amount", "opening_accumulated_depreciation"]
+		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields, group_by=group_by)
+
+	else:
+		fields = ["name as asset_id", "asset_name", "status", "department", "cost_center", "purchase_receipt",
 			"asset_category", "purchase_date", "gross_purchase_amount", "location",
-			"available_for_use_date", "status", "purchase_invoice", "opening_accumulated_depreciation"])
+			"available_for_use_date", "purchase_invoice", "opening_accumulated_depreciation"]
+		assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
 
 	for asset in assets_record:
 		asset_value = asset.gross_purchase_amount - flt(asset.opening_accumulated_depreciation) \
 			- flt(depreciation_amount_map.get(asset.name))
 		if asset_value:
 			row = {
-				"asset_id": asset.name,
+				"asset_id": asset.asset_id,
 				"asset_name": asset.asset_name,
 				"status": asset.status,
 				"department": asset.department,
@@ -158,7 +85,7 @@
 				"vendor_name": pr_supplier_map.get(asset.purchase_receipt) or pi_supplier_map.get(asset.purchase_invoice),
 				"gross_purchase_amount": asset.gross_purchase_amount,
 				"opening_accumulated_depreciation": asset.opening_accumulated_depreciation,
-				"depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0,
+				"depreciated_amount": depreciation_amount_map.get(asset.asset_id) or 0.0,
 				"available_for_use_date": asset.available_for_use_date,
 				"location": asset.location,
 				"asset_category": asset.asset_category,
@@ -169,8 +96,39 @@
 
 	return data
 
+def prepare_chart_data(data, filters):
+	labels_values_map = {}
+	date_field = frappe.scrub(filters.date_based_on)
+
+	period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, 
+		filters.from_date, filters.to_date, filters.filter_based_on, "Monthly", company=filters.company)
+
+	for d in period_list:
+		labels_values_map.setdefault(d.get('label'), frappe._dict({'asset_value': 0, 'depreciated_amount': 0}))
+
+	for d in data:
+		date = d.get(date_field)
+		belongs_to_month = formatdate(date, "MMM YYYY")
+
+		labels_values_map[belongs_to_month].asset_value += d.get("asset_value")
+		labels_values_map[belongs_to_month].depreciated_amount += d.get("depreciated_amount")
+
+	return {
+		"data" : {
+			"labels": labels_values_map.keys(),
+			"datasets": [
+				{ 'name': _('Asset Value'), 'values': [d.get("asset_value") for d in labels_values_map.values()] },
+				{ 'name': _('Depreciatied Amount'), 'values': [d.get("depreciated_amount") for d in labels_values_map.values()] }
+			]
+		},
+		"type": "bar",
+		"barOptions": {
+			"stacked": 1
+		},
+	}
+
 def get_finance_book_value_map(filters):
-	date = filters.get('purchase_date') or filters.get('available_for_use_date') or today()
+	date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date
 
 	return frappe._dict(frappe.db.sql(''' Select
 		parent, SUM(depreciation_amount)
@@ -201,3 +159,139 @@
 			AND pii.is_fixed_asset=1
 			AND pi.docstatus=1
 			AND pi.is_return=0'''))
+
+def get_columns(filters):
+	if filters.get("group_by") in ["Asset Category", "Location"]:
+		return [
+			{
+				"label": _("{}").format(filters.get("group_by")),
+				"fieldtype": "Link",
+				"fieldname": frappe.scrub(filters.get("group_by")),
+				"options": filters.get("group_by"),
+				"width": 120
+			},
+			{
+				"label": _("Gross Purchase Amount"),
+				"fieldname": "gross_purchase_amount",
+				"fieldtype": "Currency",
+				"options": "company:currency",
+				"width": 100
+			},
+			{
+				"label": _("Opening Accumulated Depreciation"),
+				"fieldname": "opening_accumulated_depreciation",
+				"fieldtype": "Currency",
+				"options": "company:currency",
+				"width": 90
+			},
+			{
+				"label": _("Depreciated Amount"),
+				"fieldname": "depreciated_amount",
+				"fieldtype": "Currency",
+				"options": "company:currency",
+				"width": 100
+			},
+			{
+				"label": _("Asset Value"),
+				"fieldname": "asset_value",
+				"fieldtype": "Currency",
+				"options": "company:currency",
+				"width": 100
+			}
+		]
+
+	return [
+		{
+			"label": _("Asset Id"),
+			"fieldtype": "Link",
+			"fieldname": "asset_id",
+			"options": "Asset",
+			"width": 60
+		},
+		{
+			"label": _("Asset Name"),
+			"fieldtype": "Data",
+			"fieldname": "asset_name",
+			"width": 140
+		},
+		{
+			"label": _("Asset Category"),
+			"fieldtype": "Link",
+			"fieldname": "asset_category",
+			"options": "Asset Category",
+			"width": 100
+		},
+		{
+			"label": _("Status"),
+			"fieldtype": "Data",
+			"fieldname": "status",
+			"width": 80
+		},
+		{
+			"label": _("Purchase Date"),
+			"fieldtype": "Date",
+			"fieldname": "purchase_date",
+			"width": 90
+		},
+		{
+			"label": _("Available For Use Date"),
+			"fieldtype": "Date",
+			"fieldname": "available_for_use_date",
+			"width": 90
+		},
+		{
+			"label": _("Gross Purchase Amount"),
+			"fieldname": "gross_purchase_amount",
+			"fieldtype": "Currency",
+			"options": "company:currency",
+			"width": 100
+		},
+		{
+			"label": _("Asset Value"),
+			"fieldname": "asset_value",
+			"fieldtype": "Currency",
+			"options": "company:currency",
+			"width": 100
+		},
+		{
+			"label": _("Opening Accumulated Depreciation"),
+			"fieldname": "opening_accumulated_depreciation",
+			"fieldtype": "Currency",
+			"options": "company:currency",
+			"width": 90
+		},
+		{
+			"label": _("Depreciated Amount"),
+			"fieldname": "depreciated_amount",
+			"fieldtype": "Currency",
+			"options": "company:currency",
+			"width": 100
+		},
+		{
+			"label": _("Cost Center"),
+			"fieldtype": "Link",
+			"fieldname": "cost_center",
+			"options": "Cost Center",
+			"width": 100
+		},
+		{
+			"label": _("Department"),
+			"fieldtype": "Link",
+			"fieldname": "department",
+			"options": "Department",
+			"width": 100
+		},
+		{
+			"label": _("Vendor Name"),
+			"fieldtype": "Data",
+			"fieldname": "vendor_name",
+			"width": 100
+		},
+		{
+			"label": _("Location"),
+			"fieldtype": "Link",
+			"fieldname": "location",
+			"options": "Location",
+			"width": 100
+		},
+	]
\ No newline at end of file
diff --git a/erpnext/crm/dashboard_fixtures.py b/erpnext/crm/dashboard_fixtures.py
new file mode 100644
index 0000000..16904b3
--- /dev/null
+++ b/erpnext/crm/dashboard_fixtures.py
@@ -0,0 +1,202 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe, erpnext, json
+from frappe import _
+
+def get_data():
+	return frappe._dict({
+        "dashboards": get_dashboards(),
+        "charts": get_charts(),
+        "number_cards": get_number_cards()
+	})
+
+def get_dashboards():
+	return [{
+            "doctype": "Dashboard",
+            "name": "CRM",
+            "dashboard_name": "CRM",
+            "charts": [
+                { "chart": "Incoming Leads", "width": "Full" },
+                { "chart": "Opportunity Trends", "width": "Full"},
+                { "chart": "Won Opportunities", "width": "Full" },
+                { "chart": "Territory Wise Opportunity Count", "width": "Half"},
+                { "chart": "Territory Wise Sales", "width": "Half"},
+                { "chart": "Opportunities via Campaigns", "width": "Half" },
+                { "chart": "Lead Source", "width": "Half"}
+            ],
+            "cards": [
+                { "card": "New Lead (Last 1 Month)" },
+                { "card": "New Opportunity (Last 1 Month)" },
+                { "card": "Won Opportunity (Last 1 Month)" },
+                { "card": "Open Opportunity"},
+            ]
+        }]
+
+def get_company_for_dashboards():
+	company = frappe.defaults.get_defaults().company
+	if company:
+		return company
+	else:
+		company_list = frappe.get_list("Company")
+		if company_list:
+			return company_list[0].name
+	return None
+
+def get_charts():
+	company = get_company_for_dashboards()
+
+	return [{
+        "name": "Incoming Leads",
+        "doctype": "Dashboard Chart",
+        "time_interval": "Yearly",
+        "chart_type": "Count",
+        "chart_name": _("Incoming Leads"),
+        "timespan": "Last Quarter",
+        "time_interval": "Weekly",
+        "document_type": "Lead",
+        "based_on": "creation",
+        'is_public': 1,
+        'timeseries': 1,
+        "owner": "Administrator",
+        "filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
+        "type": "Bar"
+    },
+    {
+        "name": "Opportunity Trends",
+        "doctype": "Dashboard Chart",
+        "time_interval": "Yearly",
+        "chart_type": "Count",
+        "chart_name": _("Opportunity Trends"),
+        "timespan": "Last Quarter",
+        "time_interval": "Weekly",
+        "document_type": "Opportunity",
+        "based_on": "creation",
+        'is_public': 1,
+        'timeseries': 1,
+        "owner": "Administrator",
+        "filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
+        "type": "Bar"
+    },
+    {
+        "name": "Opportunities via Campaigns",
+        "chart_name": _("Opportunities via Campaigns"),
+        "doctype": "Dashboard Chart",
+        "chart_type": "Group By",
+        "group_by_type": "Count",
+        "group_by_based_on": "campaign",
+        "document_type": "Opportunity",
+        'is_public': 1,
+        'timeseries': 1,
+        "owner": "Administrator",
+        "filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
+        "type": "Pie"
+    },
+    {
+        "name": "Won Opportunities",
+        "doctype": "Dashboard Chart",
+        "time_interval": "Yearly",
+        "chart_type": "Count",
+        "chart_name": _("Won Opportunities"),
+        "timespan": "Last Year",
+        "time_interval": "Monthly",
+        "document_type": "Opportunity",
+        "based_on": "modified",
+        'is_public': 1,
+        'timeseries': 1,
+        "owner": "Administrator",
+        "filters_json": json.dumps([
+            ["Opportunity", "company", "=", company, False],
+            ["Opportunity", "status", "=", "Converted", False]]),
+        "type": "Bar"
+    },
+    {
+        "name": "Territory Wise Opportunity Count",
+        "doctype": "Dashboard Chart",
+        "chart_type": "Group By",
+        "group_by_type": "Count",
+        "group_by_based_on": "territory",
+        "chart_name": _("Territory Wise Opportunity Count"),
+        "document_type": "Opportunity",
+        'is_public': 1,
+        "filters_json": json.dumps([
+            ["Opportunity", "company", "=", company, False]
+        ]),
+        "owner": "Administrator",
+        "type": "Donut"
+    },
+    {
+        "name": "Territory Wise Sales",
+        "doctype": "Dashboard Chart",
+        "chart_type": "Group By",
+        "group_by_type": "Sum",
+        "group_by_based_on": "territory",
+        "chart_name": _("Territory Wise Sales"),
+        "aggregate_function_based_on": "opportunity_amount",
+        "document_type": "Opportunity",
+        'is_public': 1,
+        "owner": "Administrator",
+        "filters_json": json.dumps([
+            ["Opportunity", "company", "=", company, False],
+            ["Opportunity", "status", "=", "Converted", False]
+        ]),
+        "type": "Donut"
+    },
+    {
+        "name": "Lead Source",
+        "doctype": "Dashboard Chart",
+        "chart_type": "Group By",
+        "group_by_type": "Count",
+        "group_by_based_on": "source",
+        "chart_name": _("Lead Source"),
+        "document_type": "Lead",
+        'is_public': 1,
+        "owner": "Administrator",
+        "type": "Pie"
+    }]
+
+def get_number_cards():
+	return [{
+        "doctype": "Number Card",
+        "document_type": "Lead",
+        "name": "New Lead (Last 1 Month)",
+        "filters_json": json.dumps([["Lead","creation","Previous","1 month",False]]),
+        "function": "Count",
+        "is_public": 1,
+        "label": _("New Lead (Last 1 Month)"),
+        "show_percentage_stats": 1,
+        "stats_time_interval": "Daily"
+    },
+    {
+        "doctype": "Number Card",
+        "document_type": "Opportunity",
+        "name": "New Opportunity (Last 1 Month)",
+        "filters_json": json.dumps([["Opportunity","creation","Previous","1 month",False]]),
+        "function": "Count",
+        "is_public": 1,
+        "label": _("New Opportunity (Last 1 Month)"),
+        "show_percentage_stats": 1,
+        "stats_time_interval": "Daily"
+    },
+    {
+        "doctype": "Number Card",
+        "document_type": "Opportunity",
+        "name": "Won Opportunity (Last 1 Month)",
+        "filters_json": json.dumps([["Opportunity","creation","Previous","1 month",False]]),
+        "function": "Count",
+        "is_public": 1,
+        "label": _("Won Opportunity (Last 1 Month)"),
+        "show_percentage_stats": 1,
+        "stats_time_interval": "Daily"
+    },
+    {
+        "doctype": "Number Card",
+        "document_type": "Opportunity",
+        "name": "Open Opportunity",
+        "filters_json": json.dumps([["Opportunity","status","=","Open",False]]),
+        "function": "Count",
+        "is_public": 1,
+        "label": _("Open Opportunity"),
+        "show_percentage_stats": 1,
+        "stats_time_interval": "Daily"
+    }] 
\ No newline at end of file
diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json
index ca13d6a..2fc4582 100644
--- a/erpnext/crm/desk_page/crm/crm.json
+++ b/erpnext/crm/desk_page/crm/crm.json
@@ -27,21 +27,26 @@
   }
  ],
  "category": "Modules",
- "charts": [],
+ "charts": [
+  {
+   "chart_name": "Territory Wise Sales"
+  }
+ ],
  "creation": "2020-01-23 14:48:30.183272",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
- "icon": "",
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "CRM",
- "modified": "2020-04-27 22:32:26.682911",
+ "modified": "2020-05-20 12:11:36.250491",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "CRM",
+ "onboarding": "CRM",
  "owner": "Administrator",
  "pin_to_bottom": 0,
  "pin_to_top": 0,
@@ -69,6 +74,11 @@
    "label": "Sales Analytics",
    "link_to": "Sales Analytics",
    "type": "Report"
+  },
+  {
+   "label": "CRM Dashboard",
+   "link_to": "CRM",
+   "type": "Dashboard"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/crm/doctype/sales_stage/sales_stage.json b/erpnext/crm/doctype/sales_stage/sales_stage.json
index 4374bb5..77aa559 100644
--- a/erpnext/crm/doctype/sales_stage/sales_stage.json
+++ b/erpnext/crm/doctype/sales_stage/sales_stage.json
@@ -1,96 +1,44 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "field:stage_name", 
- "beta": 0, 
- "creation": "2018-10-01 09:28:16.399518", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:stage_name",
+ "creation": "2018-10-01 09:28:16.399518",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "stage_name"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "stage_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Stage Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
+   "fieldname": "stage_name",
+   "fieldtype": "Data",
+   "label": "Stage Name",
    "unique": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-10-01 09:29:43.230378", 
- "modified_by": "Administrator", 
- "module": "CRM", 
- "name": "Sales Stage", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2020-05-20 12:22:01.866472",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "Sales Stage",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Sales Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Sales Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/crm/module_onboarding/crm/crm.json b/erpnext/crm/module_onboarding/crm/crm.json
new file mode 100644
index 0000000..694763f
--- /dev/null
+++ b/erpnext/crm/module_onboarding/crm/crm.json
@@ -0,0 +1,42 @@
+{
+ "allow_roles": [
+  {
+   "role": "Sales Master Manager"
+  },
+  {
+   "role": "Sales Manager"
+  },
+  {
+   "role": "Sales User"
+  }
+ ],
+ "creation": "2020-05-09 23:42:50.901548",
+ "docstatus": 0,
+ "doctype": "Module Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-20 12:53:47.029412",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "CRM",
+ "owner": "Administrator",
+ "steps": [
+  {
+   "step": "Introduction to CRM"
+  },
+  {
+   "step": "Create Lead"
+  },
+  {
+   "step": "Create Opportunity"
+  },
+  {
+   "step": "Create and Send Quotation"
+  }
+ ],
+ "subtitle": "Lead, Opportunity, Customer and more",
+ "success_message": "CRM Module is all setup!",
+ "title": "Let's Setup Your CRM",
+ "user_can_dismiss": 1
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding/crm/crm.json b/erpnext/crm/onboarding/crm/crm.json
new file mode 100644
index 0000000..016a830
--- /dev/null
+++ b/erpnext/crm/onboarding/crm/crm.json
@@ -0,0 +1,45 @@
+{
+ "allow_roles": [
+  {
+   "role": "Sales Master Manager"
+  },
+  {
+   "role": "Administrator"
+  },
+  {
+   "role": "Sales Manager"
+  }
+ ],
+ "creation": "2020-05-09 23:42:50.901548",
+ "docstatus": 0,
+ "doctype": "Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-09 23:42:50.901548",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "CRM",
+ "owner": "Administrator",
+ "steps": [
+  {
+   "step": "Introduction to CRM"
+  },
+  {
+   "step": "Start Campaign"
+  },
+  {
+   "step": "Create Lead"
+  },
+  {
+   "step": "Convert Lead to Customer"
+  },
+  {
+   "step": "Create and Send Quotation"
+  }
+ ],
+ "subtitle": "Campaign, Lead, Opportunity, Customer and more",
+ "success_message": "CRM Module is all setup!",
+ "title": "Let's Setup Your CRM",
+ "user_can_dismiss": 1
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json b/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json
new file mode 100644
index 0000000..a6edfd7
--- /dev/null
+++ b/erpnext/crm/onboarding_step/create_and_send_quotation/create_and_send_quotation.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-09 23:42:46.592075",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 17:30:07.887411",
+ "modified_by": "Administrator",
+ "name": "Create and Send Quotation",
+ "owner": "Administrator",
+ "reference_document": "Quotation",
+ "show_full_form": 0,
+ "title": "Create and Send Quotation",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding_step/create_lead/create_lead.json b/erpnext/crm/onboarding_step/create_lead/create_lead.json
new file mode 100644
index 0000000..47a45d7
--- /dev/null
+++ b/erpnext/crm/onboarding_step/create_lead/create_lead.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-09 23:40:25.192503",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 17:28:36.441387",
+ "modified_by": "Administrator",
+ "name": "Create Lead",
+ "owner": "Administrator",
+ "reference_document": "Lead",
+ "show_full_form": 0,
+ "title": "Create Lead",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
new file mode 100644
index 0000000..231cf17
--- /dev/null
+++ b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 17:38:27.496696",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 17:38:27.496696",
+ "modified_by": "Administrator",
+ "name": "Create Opportunity",
+ "owner": "Administrator",
+ "reference_document": "Opportunity",
+ "show_full_form": 0,
+ "title": "Create Opportunity",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json b/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
new file mode 100644
index 0000000..552ade0
--- /dev/null
+++ b/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
@@ -0,0 +1,19 @@
+{
+ "action": "Watch Video",
+ "creation": "2020-05-09 23:37:08.926812",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 17:28:16.448676",
+ "modified_by": "Administrator",
+ "name": "Introduction to CRM",
+ "owner": "Administrator",
+ "show_full_form": 0,
+ "title": "Introduction to CRM",
+ "validate_action": 0,
+ "video_url": "https://www.youtube.com/watch?v=o9XCSZHJfpA"
+}
\ No newline at end of file
diff --git a/erpnext/hr/dashboard_fixtures.py b/erpnext/hr/dashboard_fixtures.py
new file mode 100644
index 0000000..004477c
--- /dev/null
+++ b/erpnext/hr/dashboard_fixtures.py
@@ -0,0 +1,228 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+import erpnext
+import json
+from frappe import _
+
+def get_data():
+	return frappe._dict({
+		"dashboards": get_dashboards(),
+		"charts": get_charts(),
+		"number_cards": get_number_cards(),
+	})
+
+def get_dashboards():
+	dashboards = []
+	dashboards.append(get_human_resource_dashboard())
+	return dashboards
+
+def get_human_resource_dashboard():
+	return {
+		"name": "Human Resource",
+		"dashboard_name": "Human Resource",
+		"is_default": 1,
+		"charts": [
+			{ "chart": "Outgoing Salary", "width": "Full"},
+			{ "chart": "Gender Diversity Ratio", "width": "Half"},
+			{ "chart": "Job Application Status", "width": "Half"},
+			{ "chart": 'Designation Wise Employee Count', "width": "Half"},
+			{ "chart": 'Department Wise Employee Count', "width": "Half"},
+			{ "chart": 'Designation Wise Openings', "width": "Half"},
+			{ "chart": 'Department Wise Openings', "width": "Half"},
+			{ "chart": "Attendance Count", "width": "Full"}
+		],
+		"cards": [
+			{"card": "Total Employees"},
+			{"card": "New Joinees (Last year)"},
+			{'card': "Employees Left (Last year)"},
+			{'card': "Total Job Openings (Last month)"},
+			{'card': "Total Applicants (Last month)"},
+			{'card': "Shortlisted Candidates (Last month)"},
+			{'card': "Rejected Candidates (Last month)"},
+			{'card': "Total Job Offered (Last month)"},
+		]
+	}
+
+def get_recruitment_dashboard():
+	pass
+
+
+def get_charts():
+	company = erpnext.get_default_company()
+	date = frappe.utils.get_datetime()
+
+	month_map = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"]
+
+
+	if not company:
+		company = frappe.db.get_value("Company", {"is_group": 0}, "name")
+
+	dashboard_charts = [
+		get_dashboards_chart_doc('Gender Diversity Ratio', "Group By", "Pie",
+			document_type = "Employee", group_by_type="Count", group_by_based_on="gender",
+			filters_json = json.dumps([["Employee", "status", "=", "Active"]]))
+	]
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Job Application Status', "Group By", "Pie",
+			document_type = "Job Applicant", group_by_type="Count", group_by_based_on="status",
+			filters_json = json.dumps([["Job Applicant", "creation", "Previous", "1 month"]]))
+	)
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Outgoing Salary', "Sum", "Line",
+			document_type = "Salary Slip", based_on="end_date",
+			value_based_on = "rounded_total", time_interval = "Monthly", timeseries = 1,
+			filters_json = json.dumps([["Salary Slip", "docstatus", "=", 1]]))
+	)
+
+	custom_options = '''{
+		"type": "line",
+		"axisOptions": {
+			"shortenYAxisNumbers": 1
+		},
+		"tooltipOptions": {}
+	}'''
+
+	filters_json = json.dumps({
+		"month": month_map[date.month - 1],
+		"year": str(date.year),
+		"company":company
+	})
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Attendance Count', "Report", "Line",
+			report_name = "Monthly Attendance Sheet", is_custom =1, group_by_type="Count",
+			filters_json = filters_json, custom_options=custom_options)
+	)
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Department Wise Employee Count', "Group By", "Donut",
+			document_type = "Employee", group_by_type="Count", group_by_based_on="department",
+			filters_json = json.dumps([["Employee", "status", "=", "Active"]]))
+	)
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Designation Wise Employee Count', "Group By", "Donut",
+			document_type = "Employee", group_by_type="Count", group_by_based_on="designation",
+			filters_json = json.dumps([["Employee", "status", "=", "Active"]]))
+	)
+
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Designation Wise Openings', "Group By", "Bar",
+			document_type = "Job Opening", group_by_type="Sum", group_by_based_on="designation",
+			time_interval = "Monthly", aggregate_function_based_on = "planned_vacancies")
+	)
+	dashboard_charts.append(
+		get_dashboards_chart_doc('Department Wise Openings', "Group By", "Bar",
+			document_type = "Job Opening", group_by_type="Sum", group_by_based_on="department",
+			time_interval = "Monthly", aggregate_function_based_on = "planned_vacancies")
+	)
+	return dashboard_charts
+
+
+def get_number_cards():
+	number_cards = []
+
+	number_cards = [
+		get_number_cards_doc("Employee", "Total Employees", filters_json = json.dumps([
+				["Employee","status","=","Active"]
+			])
+		)
+	]
+
+	number_cards.append(
+		get_number_cards_doc("Employee", "New Joinees (Last year)", filters_json = json.dumps([
+				["Employee","date_of_joining","Previous","1 year"],
+				["Employee","status","=","Active"]
+			])
+		)
+	)
+
+	number_cards.append(
+		get_number_cards_doc("Employee", "Employees Left (Last year)", filters_json = json.dumps([
+				["Employee", "modified", "Previous", "1 year"],
+				["Employee", "status", "=", "Left"]
+			])
+		)
+	)
+
+	number_cards.append(
+		get_number_cards_doc("Job Applicant", "Total Applicants (Last month)", filters_json = json.dumps([
+				["Job Applicant", "creation", "Previous", "1 month"]
+			])
+		)
+	)
+
+	number_cards.append(
+		get_number_cards_doc("Job Opening", "Total Job Openings (Last month)", func = "Sum",
+			aggregate_function_based_on = "planned_vacancies",
+			filters_json = json.dumps([["Job Opening", "creation", "Previous", "1 month"]])
+		)
+	)
+	number_cards.append(
+		get_number_cards_doc("Job Applicant", "Shortlisted Candidates (Last month)", filters_json = json.dumps([
+				["Job Applicant", "status", "=", "Accepted"],
+				["Job Applicant", "creation", "Previous", "1 month"]
+			])
+		)
+	)
+	number_cards.append(
+		get_number_cards_doc("Job Applicant", "Rejected Candidates (Last month)", filters_json = json.dumps([
+				["Job Applicant", "status", "=", "Rejected"],
+				["Job Applicant", "creation", "Previous", "1 month"]
+			])
+		)
+	)
+	number_cards.append(
+		get_number_cards_doc("Job Offer", "Total Job Offered (Last month)",
+			filters_json = json.dumps([["Job Offer", "creation", "Previous", "1 month"]])
+		)
+	)
+
+	return number_cards
+
+
+def get_number_cards_doc(document_type, label, **args):
+	args = frappe._dict(args)
+
+	return {
+			"doctype": "Number Card",
+			"document_type": document_type,
+			"function": args.func or "Count",
+			"is_public": args.is_public or 1,
+			"label": _(label),
+			"name": args.name or label,
+			"show_percentage_stats": args.show_percentage_stats or 1,
+			"stats_time_interval": args.stats_time_interval or 'Monthly',
+			"filters_json": args.filters_json or '[]',
+			"aggregate_function_based_on": args.aggregate_function_based_on or None
+		}
+
+def get_dashboards_chart_doc(name, chart_type, graph_type, **args):
+	args = frappe._dict(args)
+
+	return {
+			"name": name,
+			"chart_name": _(args.chart_name or name),
+			"chart_type": chart_type,
+			"document_type": args.document_type or None,
+			"report_name": args.report_name or None,
+			"is_custom": args.is_custom or 0,
+			"group_by_type": args.group_by_type or None,
+			"group_by_based_on": args.group_by_based_on or None,
+			"based_on": args.based_on or None,
+			"value_based_on": args.value_based_on or None,
+			"number_of_groups": args.number_of_groups or 0,
+			"is_public": args.is_public or 1,
+			"timespan": args.timespan or "Last Year",
+			"time_interval": args.time_interval or "Yearly",
+			"timeseries": args.timeseries or 0,
+			"filters_json": args.filters_json or '[]',
+			"type": graph_type,
+			"custom_options": args.custom_options or '',
+			"doctype": "Dashboard Chart",
+			"aggregate_function_based_on": args.aggregate_function_based_on or None
+		}
\ No newline at end of file
diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json
index 22aa170..2d0e885 100644
--- a/erpnext/hr/desk_page/hr/hr.json
+++ b/erpnext/hr/desk_page/hr/hr.json
@@ -77,21 +77,27 @@
   }
  ],
  "category": "Modules",
- "charts": [],
+ "charts": [
+  {
+   "chart_name": "Outgoing Salary",
+   "label": "Outgoing Salary"
+  }
+ ],
  "creation": "2020-03-02 15:48:58.322521",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
- "icon": "",
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "HR",
- "modified": "2020-04-29 20:29:22.114309",
+ "modified": "2020-05-20 11:20:54.255557",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR",
+ "onboarding": "Human Resource",
  "owner": "Administrator",
  "pin_to_bottom": 0,
  "pin_to_top": 0,
@@ -104,33 +110,33 @@
    "type": "DocType"
   },
   {
-   "format": "{} Unpaid",
-   "label": "Expense Claim",
-   "link_to": "Expense Claim",
-   "stats_filter": "{\"approval_status\":\"Draft\"}",
-   "type": "DocType"
-  },
-  {
-   "format": "{} Open",
-   "label": "Job Applicant",
-   "link_to": "Job Applicant",
-   "stats_filter": "{\n    \"status\": \"Open\"\n}",
-   "type": "DocType"
-  },
-  {
-   "label": "Salary Structure",
-   "link_to": "Salary Structure",
+   "label": "Attendance",
+   "link_to": "Attendance",
+   "stats_filter": "",
    "type": "DocType"
   },
   {
    "label": "Leave Application",
    "link_to": "Leave Application",
+   "stats_filter": "{\"status\":\"Open\"}",
+   "type": "DocType"
+  },
+  {
+   "label": "Salary Structure",
+   "link_to": "Payroll Entry",
    "type": "DocType"
   },
   {
    "label": "Salary Register",
-   "link_to": "Salary Register",
+   "link_to": "Monthly Attendance Sheet",
    "type": "Report"
+  },
+  {
+   "format": "{} Open",
+   "label": "HR Dashboard",
+   "link_to": "Human Resource",
+   "stats_filter": "{\n    \"status\": \"Open\"\n}",
+   "type": "Dashboard"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/attendance/attendance.py b/erpnext/hr/doctype/attendance/attendance.py
index 6c7ee00..45b7060 100644
--- a/erpnext/hr/doctype/attendance/attendance.py
+++ b/erpnext/hr/doctype/attendance/attendance.py
@@ -172,8 +172,8 @@
 
 
 	records = frappe.get_all("Attendance", fields = ['attendance_date', 'employee'] , filters = [
-		["attendance_date", ">", month_start],
-		["attendance_date", "<", month_end],
+		["attendance_date", ">=", month_start],
+		["attendance_date", "<=", month_end],
 		["employee", "=", employee],
 		["docstatus", "!=", 2]
 	])
diff --git a/erpnext/hr/doctype/leave_application/leave_application.json b/erpnext/hr/doctype/leave_application/leave_application.json
index 74707a2..7f50ace 100644
--- a/erpnext/hr/doctype/leave_application/leave_application.json
+++ b/erpnext/hr/doctype/leave_application/leave_application.json
@@ -174,7 +174,8 @@
    "label": "Status",
    "no_copy": 1,
    "options": "Open\nApproved\nRejected\nCancelled",
-   "permlevel": 1
+   "permlevel": 1,
+   "reqd": 1
   },
   {
    "fieldname": "sb10",
@@ -189,14 +190,14 @@
    "reqd": 1
   },
   {
+   "fetch_from": "employee.company",
    "fieldname": "company",
    "fieldtype": "Link",
    "label": "Company",
    "options": "Company",
    "read_only": 1,
    "remember_last_selected_value": 1,
-   "reqd": 1,
-   "fetch_from": "employee.company"
+   "reqd": 1
   },
   {
    "allow_on_submit": 1,
@@ -249,7 +250,7 @@
  "is_submittable": 1,
  "links": [],
  "max_attachments": 3,
- "modified": "2020-03-10 22:40:43.487721",
+ "modified": "2020-05-18 13:00:41.577327",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Leave Application",
@@ -334,4 +335,4 @@
  "sort_order": "DESC",
  "timeline_field": "employee",
  "title_field": "employee_name"
-}
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index d2620be..84f2c83 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -131,6 +131,8 @@
 			for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
 				date = dt.strftime("%Y-%m-%d")
 				status = "Half Day" if getdate(date) == getdate(self.half_day_date) else "On Leave"
+				print("-------->>>", status)
+				# frappe.throw("Hello")
 
 				attendance_name = frappe.db.exists('Attendance', dict(employee = self.employee,
 					attendance_date = date, docstatus = ('!=', 2)))
@@ -596,7 +598,7 @@
 			is_carry_forward, is_expired
 		FROM `tabLeave Ledger Entry`
 		WHERE employee=%(employee)s AND leave_type=%(leave_type)s
-			AND docstatus=1 
+			AND docstatus=1
 			AND (leaves<0
 				OR is_expired=1)
 			AND (from_date between %(from_date)s AND %(to_date)s
diff --git a/erpnext/hr/module_onboarding/human_resource/human_resource.json b/erpnext/hr/module_onboarding/human_resource/human_resource.json
new file mode 100644
index 0000000..e64582b
--- /dev/null
+++ b/erpnext/hr/module_onboarding/human_resource/human_resource.json
@@ -0,0 +1,51 @@
+{
+ "allow_roles": [
+  {
+   "role": "HR Manager"
+  },
+  {
+   "role": "HR User"
+  }
+ ],
+ "creation": "2020-05-14 11:51:45.050242",
+ "docstatus": 0,
+ "doctype": "Module Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/human-resources",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-20 11:20:07.992597",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Human Resource",
+ "owner": "Administrator",
+ "steps": [
+  {
+   "step": "Create Department"
+  },
+  {
+   "step": "Create Designation"
+  },
+  {
+   "step": "Create Holiday list"
+  },
+  {
+   "step": "Create Employee"
+  },
+  {
+   "step": "Create Leave Type"
+  },
+  {
+   "step": "Create Leave Allocation"
+  },
+  {
+   "step": "Create Leave Application"
+  },
+  {
+   "step": "HR Settings"
+  }
+ ],
+ "subtitle": "Employee, Leaves and more.",
+ "success_message": "The HR Module is all set up!",
+ "title": "Let's Setup the Human Resource Module. ",
+ "user_can_dismiss": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_department/create_department.json b/erpnext/hr/onboarding_step/create_department/create_department.json
new file mode 100644
index 0000000..66a54cf
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_department/create_department.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:44:34.682115",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 12:22:26.448420",
+ "modified_by": "Administrator",
+ "name": "Create Department",
+ "owner": "Administrator",
+ "reference_document": "Department",
+ "show_full_form": 0,
+ "title": "Create Department",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_designation/create_designation.json b/erpnext/hr/onboarding_step/create_designation/create_designation.json
new file mode 100644
index 0000000..c4e9cc7
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_designation/create_designation.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:45:07.514193",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 12:22:41.500795",
+ "modified_by": "Administrator",
+ "name": "Create Designation",
+ "owner": "Administrator",
+ "reference_document": "Designation",
+ "show_full_form": 0,
+ "title": "Create Designation",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_employee/create_employee.json b/erpnext/hr/onboarding_step/create_employee/create_employee.json
new file mode 100644
index 0000000..3aa33c6
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_employee/create_employee.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:43:25.561152",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 12:26:28.629074",
+ "modified_by": "Administrator",
+ "name": "Create Employee",
+ "owner": "Administrator",
+ "reference_document": "Employee",
+ "show_full_form": 0,
+ "title": "Create Employee",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json b/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
new file mode 100644
index 0000000..25cb9fe
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:47:34.700174",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 12:25:38.068582",
+ "modified_by": "Administrator",
+ "name": "Create Holiday list",
+ "owner": "Administrator",
+ "reference_document": "Holiday List",
+ "show_full_form": 0,
+ "title": "Create Holiday list",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json b/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json
new file mode 100644
index 0000000..fa9941e
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_leave_allocation/create_leave_allocation.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:48:56.123718",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 11:48:56.123718",
+ "modified_by": "Administrator",
+ "name": "Create Leave Allocation",
+ "owner": "Administrator",
+ "reference_document": "Leave Allocation",
+ "show_full_form": 0,
+ "title": "Create Leave Allocation",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json b/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json
new file mode 100644
index 0000000..1ed074e
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_leave_application/create_leave_application.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-14 11:49:45.400764",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-14 11:49:45.400764",
+ "modified_by": "Administrator",
+ "name": "Create Leave Application",
+ "owner": "Administrator",
+ "reference_document": "Leave Application",
+ "show_full_form": 0,
+ "title": "Create Leave Application",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json b/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json
new file mode 100644
index 0000000..e8b97c2
--- /dev/null
+++ b/erpnext/hr/onboarding_step/create_leave_type/create_leave_type.json
@@ -0,0 +1,19 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-20 11:17:31.119312",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_single": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-20 11:17:31.119312",
+ "modified_by": "Administrator",
+ "name": "Create Leave Type",
+ "owner": "Administrator",
+ "reference_document": "Leave Type",
+ "show_full_form": 0,
+ "title": "Create Leave Type",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/onboarding_step/hr_settings/hr_settings.json b/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
new file mode 100644
index 0000000..a8c96fb
--- /dev/null
+++ b/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
@@ -0,0 +1,19 @@
+{
+ "action": "Update Settings",
+ "creation": "2020-05-14 13:13:52.427711",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_single": 1,
+ "is_skipped": 0,
+ "modified": "2020-05-20 11:16:42.430974",
+ "modified_by": "Administrator",
+ "name": "HR Settings",
+ "owner": "Administrator",
+ "reference_document": "HR Settings",
+ "show_full_form": 0,
+ "title": "HR settings",
+ "validate_action": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/report/department_analytics/department_analytics.js b/erpnext/hr/report/department_analytics/department_analytics.js
deleted file mode 100644
index 29fedcd..0000000
--- a/erpnext/hr/report/department_analytics/department_analytics.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.query_reports["Department Analytics"] = {
-	"filters": [
-		{
-			"fieldname":"company",
-			"label": __("Company"),
-			"fieldtype": "Link",
-			"options": "Company",
-			"default": frappe.defaults.get_user_default("Company"),
-			"reqd": 1
-		},
-	]
-};
\ No newline at end of file
diff --git a/erpnext/hr/report/department_analytics/department_analytics.json b/erpnext/hr/report/department_analytics/department_analytics.json
deleted file mode 100644
index 1e26b33..0000000
--- a/erpnext/hr/report/department_analytics/department_analytics.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "add_total_row": 0, 
- "creation": "2018-05-15 15:37:20.883263", 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 0, 
- "is_standard": "Yes", 
- "modified": "2018-05-15 17:19:32.934321", 
- "modified_by": "Administrator", 
- "module": "HR", 
- "name": "Department Analytics", 
- "owner": "Administrator", 
- "ref_doctype": "Employee", 
- "report_name": "Department Analytics", 
- "report_type": "Script Report", 
- "roles": [
-  {
-   "role": "Employee"
-  }, 
-  {
-   "role": "HR User"
-  }, 
-  {
-   "role": "HR Manager"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/hr/report/department_analytics/department_analytics.py b/erpnext/hr/report/department_analytics/department_analytics.py
deleted file mode 100644
index b28eac4..0000000
--- a/erpnext/hr/report/department_analytics/department_analytics.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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 _
-
-def execute(filters=None):
-	if not filters: filters = {}
-
-	if not filters["company"]:
-		frappe.throw(_('{0} is mandatory').format(_('Company')))
-
-	columns = get_columns()
-	employees = get_employees(filters)
-	departments_result = get_department(filters)
-	departments = []
-	if departments_result:
-		for department in departments_result:
-			departments.append(department)
-	chart = get_chart_data(departments,employees)
-	return columns, employees, None, chart
-
-def get_columns():
-	return [
-		_("Employee") + ":Link/Employee:120", _("Name") + ":Data:200", _("Date of Birth")+ ":Date:100",
-		_("Branch") + ":Link/Branch:120", _("Department") + ":Link/Department:120",
-		_("Designation") + ":Link/Designation:120", _("Gender") + "::60", _("Company") + ":Link/Company:120"
-	]
-
-def get_conditions(filters):
-	conditions = ""
-	if filters.get("department"): conditions += " and department = '%s'" % \
-		filters["department"].replace("'", "\\'")
-	
-	if filters.get("company"): conditions += " and company = '%s'" % \
-		filters["company"].replace("'", "\\'")
-	return conditions
-
-def get_employees(filters):
-	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, employee_name, date_of_birth,
-	branch, department, designation,
-	gender, company from `tabEmployee` where status = 'Active' %s""" % conditions, as_list=1)
-
-def get_department(filters):
-	return frappe.db.sql("""select name from `tabDepartment` where company = %s""", (filters["company"]), as_list=1)
-	
-def get_chart_data(departments,employees):
-	if not departments:
-		departments = []
-	datasets = []
-	for department in departments:
-		if department:
-			total_employee = frappe.db.sql("""select count(*) from \
-				`tabEmployee` where \
-				department = %s""" ,(department[0]), as_list=1)
-			datasets.append(total_employee[0][0])
-	chart = {
-		"data": {
-			'labels': departments,
-			'datasets': [{'name': 'Employees','values': datasets}]
-		}
-	}
-	chart["type"] = "bar"
-	return chart
-
diff --git a/erpnext/hr/report/department_analytics/__init__.py b/erpnext/hr/report/employee_analytics/__init__.py
similarity index 100%
rename from erpnext/hr/report/department_analytics/__init__.py
rename to erpnext/hr/report/employee_analytics/__init__.py
diff --git a/erpnext/hr/report/employee_analytics/employee_analytics.js b/erpnext/hr/report/employee_analytics/employee_analytics.js
new file mode 100644
index 0000000..8620a65
--- /dev/null
+++ b/erpnext/hr/report/employee_analytics/employee_analytics.js
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Employee Analytics"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname":"parameter",
+			"label": __("Parameter"),
+			"fieldtype": "Select",
+			"options": ["Branch","Grade","Department","Designation", "Employment Type"],
+			"reqd": 1
+		}
+	]
+};
diff --git a/erpnext/hr/report/employee_analytics/employee_analytics.json b/erpnext/hr/report/employee_analytics/employee_analytics.json
new file mode 100644
index 0000000..5a7ab9a
--- /dev/null
+++ b/erpnext/hr/report/employee_analytics/employee_analytics.json
@@ -0,0 +1,30 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-05-12 13:52:50.631086",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-05-12 13:52:50.631086",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Employee Analytics",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Employee",
+ "report_name": "Employee Analytics",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Employee"
+  },
+  {
+   "role": "HR User"
+  },
+  {
+   "role": "HR Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/hr/report/employee_analytics/employee_analytics.py b/erpnext/hr/report/employee_analytics/employee_analytics.py
new file mode 100644
index 0000000..df64006
--- /dev/null
+++ b/erpnext/hr/report/employee_analytics/employee_analytics.py
@@ -0,0 +1,79 @@
+# 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 _
+
+def execute(filters=None):
+	if not filters: filters = {}
+
+	if not filters["company"]:
+		frappe.throw(_('{0} is mandatory').format(_('Company')))
+
+	columns = get_columns()
+	employees = get_employees(filters)
+	parameters_result = get_parameters(filters)
+	parameters = []
+	if parameters_result:
+		for department in parameters_result:
+			parameters.append(department)
+
+	chart = get_chart_data(parameters,employees, filters)
+	return columns, employees, None, chart
+
+def get_columns():
+	return [
+		_("Employee") + ":Link/Employee:120", _("Name") + ":Data:200", _("Date of Birth")+ ":Date:100",
+		_("Branch") + ":Link/Branch:120", _("Department") + ":Link/Department:120",
+		_("Designation") + ":Link/Designation:120", _("Gender") + "::60", _("Company") + ":Link/Company:120"
+	]
+
+def get_conditions(filters):
+	conditions = " and "+filters.get("parameter").lower().replace(" ","_")+" IS NOT NULL "
+
+	if filters.get("company"): conditions += " and company = '%s'" % \
+		filters["company"].replace("'", "\\'")
+	return conditions
+
+def get_employees(filters):
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""select name, employee_name, date_of_birth,
+	branch, department, designation,
+	gender, company from `tabEmployee` where status = 'Active' %s""" % conditions, as_list=1)
+
+def get_parameters(filters):
+	return frappe.db.sql("""select name from `tab"""+filters.get("parameter")+"""` """, as_list=1)
+
+def get_chart_data(parameters,employees, filters):
+	if not parameters:
+		parameters = []
+	datasets = []
+	parameter_field_name = filters.get("parameter").lower().replace(" ","_")
+	label = []
+	for parameter in parameters:
+		if parameter:
+			total_employee = frappe.db.sql("""select count(*) from
+				`tabEmployee` where """+
+				parameter_field_name + """ = %s and  company = %s""" ,( parameter[0], filters.get("company")), as_list=1)
+			if total_employee[0][0]:
+				label.append(parameter)
+			datasets.append(total_employee[0][0])
+
+	values = [ value for value in datasets if value !=0]
+
+	total_employee = frappe.db.count('Employee', {'status':'Active'})
+	others = total_employee - sum(values)
+
+	label.append(["Not Set"])
+	values.append(others)
+
+	chart = {
+		"data": {
+			'labels': label,
+			'datasets': [{'name': 'Employees','values': values}]
+		}
+	}
+	chart["type"] = "donut"
+	return chart
+
diff --git a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
index 82ed277..60767b5 100644
--- a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
+++ b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.py
@@ -30,8 +30,11 @@
 def execute(filters=None):
 	if not filters: filters = {}
 
+	if filters.hide_year_field == 1:
+		filters.year = 2020
+
 	conditions, filters = get_conditions(filters)
-	columns = get_columns(filters)
+	columns, days = get_columns(filters)
 	att_map = get_attendance_list(conditions, filters)
 
 	if filters.group_by:
@@ -60,20 +63,67 @@
 		columns.extend([_("Total Late Entries") + ":Float:120", _("Total Early Exits") + ":Float:120"])
 
 	if filters.group_by:
+		emp_att_map = {}
 		for parameter in group_by_parameters:
 			data.append([ "<b>"+ parameter + "</b>"])
-			record = add_data(emp_map[parameter], att_map, filters, holiday_map, conditions, leave_list=leave_list)
+			record, aaa = add_data(emp_map[parameter], att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=leave_list)
+			emp_att_map.update(aaa)
 			data += record
 	else:
-		record = add_data(emp_map, att_map, filters, holiday_map, conditions, leave_list=leave_list)
+		record, emp_att_map = add_data(emp_map, att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=leave_list)
 		data += record
 
-	return columns, data
+	chart_data = get_chart_data(emp_att_map, days)
+
+	return columns, data, None, chart_data
+
+def get_chart_data(emp_att_map, days):
+	labels = []
+	datasets = [
+		{"name": "Absent", "values": []},
+		{"name": "Present", "values": []},
+		{"name": "Leave", "values": []},
+	]
+	for idx, day in enumerate(days, start=0):
+		p = day.replace("::65", "")
+		labels.append(day.replace("::65", ""))
+		total_absent_on_day = 0
+		total_leave_on_day = 0
+		total_present_on_day = 0
+		total_holiday = 0
+		for emp in emp_att_map.keys():
+			if emp_att_map[emp][idx]:
+				if emp_att_map[emp][idx] == "A":
+					total_absent_on_day += 1
+				if emp_att_map[emp][idx] in ["P", "WFH"]:
+					total_present_on_day += 1
+				if emp_att_map[emp][idx] == "HD":
+					total_present_on_day += 0.5
+					total_leave_on_day += 0.5
+				if emp_att_map[emp][idx] == "L":
+					total_leave_on_day += 1
 
 
-def add_data(employee_map, att_map, filters, holiday_map, conditions, leave_list=None):
+		datasets[0]["values"].append(total_absent_on_day)
+		datasets[1]["values"].append(total_present_on_day)
+		datasets[2]["values"].append(total_leave_on_day)
+
+
+	chart = {
+		"data": {
+			'labels': labels,
+			'datasets': datasets
+		}
+	}
+
+	chart["type"] = "line"
+
+	return chart
+
+def add_data(employee_map, att_map, filters, holiday_map, conditions, default_holiday_list, leave_list=None):
 
 	record = []
+	emp_att_map = {}
 	for emp in employee_map:
 		emp_det = employee_map.get(emp)
 		if not emp_det or emp not in att_map:
@@ -85,6 +135,7 @@
 		row += [emp, emp_det.employee_name]
 
 		total_p = total_a = total_l = total_h = total_um= 0.0
+		ggg = []
 		for day in range(filters["total_days_in_month"]):
 			status = None
 			status = att_map.get(emp).get(day + 1)
@@ -101,19 +152,12 @@
 								status = "Holiday"
 							total_h += 1
 
-
-				# if emp_holiday_list in holiday_map and (day+1) in holiday_map[emp_holiday_list][0]:
-				# 	if holiday_map[emp_holiday_list][1]:
-				# 		status= "Weekly Off"
-				# 	else:
-				# 		status = "Holiday"
-
-				# 	 += 1
+			ggg.append(status_map.get(status, ""))
 
 			if not filters.summarized_view:
-				row.append(status_map.get(status, ""))
+				row += ggg
 			else:
-				if status == "Present":
+				if status == "Present" or status == "Work From Home":
 					total_p += 1
 				elif status == "Absent":
 					total_a += 1
@@ -159,10 +203,10 @@
 					row.append("0.0")
 
 			row.extend([time_default_counts[0][0],time_default_counts[0][1]])
+		emp_att_map[emp] = ggg
 		record.append(row)
 
-
-	return record
+	return record, emp_att_map
 
 def get_columns(filters):
 
@@ -174,15 +218,17 @@
 	columns += [
 		_("Employee") + ":Link/Employee:120", _("Employee Name") + ":Link/Employee:120"
 	]
-
+	days = []
+	for day in range(filters["total_days_in_month"]):
+		date = str(filters.year) + "-" + str(filters.month)+ "-" + str(day+1)
+		day_name = day_abbr[getdate(date).weekday()]
+		days.append(cstr(day+1)+ " " +day_name +"::65")
 	if not filters.summarized_view:
-		for day in range(filters["total_days_in_month"]):
-			date = str(filters.year) + "-" + str(filters.month)+ "-" + str(day+1)
-			day_name = day_abbr[getdate(date).weekday()]
-			columns.append(cstr(day+1)+ " " +day_name +"::65")
-	else:
+		columns += days
+
+	if filters.summarized_view:
 		columns += [_("Total Present") + ":Float:120", _("Total Leaves") + ":Float:120",  _("Total Absent") + ":Float:120", _("Total Holidays") + ":Float:120", _("Unmarked Days")+ ":Float:120"]
-	return columns
+	return columns, days
 
 def get_attendance_list(conditions, filters):
 	attendance_list = frappe.db.sql("""select employee, day(attendance_date) as day_of_month,
diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
index ecd2dc9..f2e07bf 100644
--- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
+++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
@@ -43,10 +43,11 @@
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "Manufacturing",
- "modified": "2020-05-19 14:05:59.100891",
+ "modified": "2020-05-20 11:50:20.029056",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Manufacturing",
@@ -89,16 +90,31 @@
    "type": "DocType"
   },
   {
+   "label": "Dashboard",
+   "link_to": "Manufacturing",
+   "restrict_to_domain": "Manufacturing",
+   "type": "Dashboard"
+  },
+  {
+   "label": "Forecasting",
+   "link_to": "Exponential Smoothing Forecasting",
+   "type": "Report"
+  },
+  {
    "label": "Work Order Summary",
    "link_to": "Work Order Summary",
    "restrict_to_domain": "Manufacturing",
    "type": "Report"
   },
   {
-   "label": "Dashboard",
-   "link_to": "Manufacturing",
-   "restrict_to_domain": "Manufacturing",
-   "type": "Dashboard"
+   "label": "BOM Stock Report",
+   "link_to": "BOM Stock Report",
+   "type": "Report"
+  },
+  {
+   "label": "Production Planning Report",
+   "link_to": "Production Planning Report",
+   "type": "Report"
   }
  ]
 }
\ No newline at end of file
diff --git a/erpnext/hr/report/department_analytics/__init__.py b/erpnext/manufacturing/report/exponential_smoothing_forecasting/__init__.py
similarity index 100%
copy from erpnext/hr/report/department_analytics/__init__.py
copy to erpnext/manufacturing/report/exponential_smoothing_forecasting/__init__.py
diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js
new file mode 100644
index 0000000..123a82a
--- /dev/null
+++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.js
@@ -0,0 +1,97 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Exponential Smoothing Forecasting"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"reqd": 1,
+			"default": frappe.defaults.get_user_default("Company")
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), 12),
+			"reqd": 1
+		},
+		{
+			"fieldname":"based_on_document",
+			"label": __("Based On Document"),
+			"fieldtype": "Select",
+			"options": ["Sales Order", "Delivery Note", "Quotation"],
+			"default": "Sales Order",
+			"reqd": 1
+		},
+		{
+			"fieldname":"based_on_field",
+			"label": __("Based On"),
+			"fieldtype": "Select",
+			"options": ["Qty", "Amount"],
+			"default": "Qty",
+			"reqd": 1
+		},
+		{
+			"fieldname":"no_of_years",
+			"label": __("Based On Data ( in years )"),
+			"fieldtype": "Select",
+			"options": [3, 6, 9],
+			"default": 3,
+			"reqd": 1
+		},
+		{
+			"fieldname": "periodicity",
+			"label": __("Periodicity"),
+			"fieldtype": "Select",
+			"options": [
+				{ "value": "Monthly", "label": __("Monthly") },
+				{ "value": "Quarterly", "label": __("Quarterly") },
+				{ "value": "Half-Yearly", "label": __("Half-Yearly") },
+				{ "value": "Yearly", "label": __("Yearly") }
+			],
+			"default": "Yearly",
+			"reqd": 1
+		},
+		{
+			"fieldname":"smoothing_constant",
+			"label": __("Smoothing Constant"),
+			"fieldtype": "Select",
+			"options": [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
+			"reqd": 1,
+			"default": 0.3
+		},
+		{
+			"fieldname":"item_code",
+			"label": __("Item Code"),
+			"fieldtype": "Link",
+			"options": "Item"
+		},
+		{
+			"fieldname":"warehouse",
+			"label": __("Warehouse"),
+			"fieldtype": "Link",
+			"options": "Warehouse",
+			get_query: () => {
+				var company = frappe.query_report.get_filter_value('company');
+				if (company) {
+					return {
+						filters: {
+							'company': company
+						}
+					};
+				}
+			}
+		}
+	]
+};
diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.json b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.json
new file mode 100644
index 0000000..5092ef4
--- /dev/null
+++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.json
@@ -0,0 +1,40 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-05-15 05:18:55.838030",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "",
+ "modified": "2020-05-15 05:18:55.838030",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Exponential Smoothing Forecasting",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Sales Order",
+ "report_name": "Exponential Smoothing Forecasting",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Manufacturing User"
+  },
+  {
+   "role": "Stock User"
+  },
+  {
+   "role": "Manufacturing Manager"
+  },
+  {
+   "role": "Stock Manager"
+  },
+  {
+   "role": "Sales Manager"
+  },
+  {
+   "role": "Sales User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
new file mode 100644
index 0000000..b5127f1
--- /dev/null
+++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
@@ -0,0 +1,222 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe, erpnext
+from frappe import _
+from frappe.utils import flt, nowdate, add_years, cint, getdate
+from erpnext.accounts.report.financial_statements import get_period_list
+from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
+
+def execute(filters=None):
+	return ForecastingReport(filters).execute_report()
+
+class ExponentialSmoothingForecast(object):
+	def forecast_future_data(self):
+		for key, value in self.period_wise_data.items():
+			forecast_data = []
+			for period in self.period_list:
+				forecast_key = "forecast_" + period.key
+
+				if value.get(period.key) and not forecast_data:
+					value[forecast_key] = flt(value.get("avg", 0)) or flt(value.get(period.key))
+
+					# will be use to forecaset next period
+					forecast_data.append([value.get(period.key), value.get(forecast_key)])
+				elif forecast_data:
+					previous_period_data = forecast_data[-1]
+					value[forecast_key] = (previous_period_data[1] +
+						flt(self.filters.smoothing_constant) * (
+							flt(previous_period_data[0]) - flt(previous_period_data[1])
+						)
+					)
+
+class ForecastingReport(ExponentialSmoothingForecast):
+	def __init__(self, filters=None):
+		self.filters = frappe._dict(filters or {})
+		self.data = []
+		self.doctype = self.filters.based_on_document
+		self.child_doctype = self.doctype + " Item"
+		self.based_on_field = ("qty"
+			if self.filters.based_on_field == "Qty" else "amount")
+		self.fieldtype = "Float" if self.based_on_field == "qty" else "Currency"
+		self.company_currency = erpnext.get_company_currency(self.filters.company)
+
+	def execute_report(self):
+		self.prepare_periodical_data()
+		self.forecast_future_data()
+		self.data = self.period_wise_data.values()
+		self.add_total()
+
+		columns = self.get_columns()
+		charts = self.get_chart_data()
+		summary_data = self.get_summary_data()
+
+		return columns, self.data, None, charts, summary_data
+
+	def prepare_periodical_data(self):
+		self.period_wise_data = {}
+
+		from_date = add_years(self.filters.from_date, cint(self.filters.no_of_years) * -1)
+		self.period_list = get_period_list(from_date, self.filters.to_date,
+			from_date, self.filters.to_date, None, self.filters.periodicity, ignore_fiscal_year=True)
+
+		order_data = self.get_data_for_forecast() or []
+
+		for entry in order_data:
+			key = (entry.item_code, entry.warehouse)
+			if key not in self.period_wise_data:
+				self.period_wise_data[key] = entry
+
+			period_data = self.period_wise_data[key]
+			for period in self.period_list:
+				# check if posting date is within the period
+				if (entry.posting_date >= period.from_date and entry.posting_date <= period.to_date):
+					period_data[period.key] = period_data.get(period.key, 0.0) + flt(entry.get(self.based_on_field))
+
+		for key, value in self.period_wise_data.items():
+			list_of_period_value = [value.get(p.key, 0) for p in self.period_list]
+
+			if list_of_period_value:
+				value["avg"] = sum(list_of_period_value) / len(list_of_period_value)
+
+	def get_data_for_forecast(self):
+		cond = ""
+		if self.filters.item_code:
+			cond = " AND soi.item_code = %s" %(frappe.db.escape(self.filters.item_code))
+
+		warehouses = []
+		if self.filters.warehouse:
+			warehouses = get_child_warehouses(self.filters.warehouse)
+			cond += " AND soi.warehouse in ({})".format(','.join(['%s'] * len(warehouses)))
+
+		input_data = [self.filters.from_date, self.filters.company]
+		if warehouses:
+			input_data.extend(warehouses)
+
+		date_field = "posting_date" if self.doctype == "Delivery Note" else "transaction_date"
+
+		return frappe.db.sql("""
+			SELECT
+				so.{date_field} as posting_date, soi.item_code, soi.warehouse,
+				soi.item_name, soi.stock_qty as qty, soi.base_amount as amount
+			FROM
+				`tab{doc}` so, `tab{child_doc}` soi
+			WHERE
+				so.docstatus = 1 AND so.name = soi.parent AND
+				so.{date_field} < %s AND so.company = %s {cond}
+		""".format(doc=self.doctype, child_doc=self.child_doctype, date_field=date_field, cond=cond),
+			tuple(input_data), as_dict=1)
+
+	def add_total(self):
+		total_row = {
+			"item_code": _(frappe.bold("Total Quantity"))
+		}
+
+		for value in self.data:
+			for period in self.period_list:
+				forecast_key = "forecast_" + period.key
+				if forecast_key not in total_row:
+					total_row.setdefault(forecast_key, 0.0)
+
+				if period.key not in total_row:
+					total_row.setdefault(period.key, 0.0)
+
+				total_row[forecast_key] += value.get(forecast_key, 0.0)
+				total_row[period.key] += value.get(period.key, 0.0)
+
+		self.data.append(total_row)
+
+	def get_columns(self):
+		columns = [{
+			"label": _("Item Code"),
+			"options": "Item",
+			"fieldname": "item_code",
+			"fieldtype": "Link",
+			"width": 130
+		}, {
+			"label": _("Warehouse"),
+			"options": "Warehouse",
+			"fieldname": "warehouse",
+			"fieldtype": "Link",
+			"width": 130
+		}]
+
+		width = 150 if self.filters.periodicity in ['Yearly', "Half-Yearly", "Quarterly"] else 100
+		for period in self.period_list:
+			if (self.filters.periodicity in ['Yearly', "Half-Yearly", "Quarterly"]
+				or period.from_date >= getdate(self.filters.from_date)):
+
+				forecast_key = 'forecast_' + period.key
+
+				columns.append({
+					"label": _(period.label),
+					"fieldname": forecast_key,
+					"fieldtype": self.fieldtype,
+					"width": width,
+					"default": 0.0
+				})
+
+		return columns
+
+	def get_chart_data(self):
+		if not self.data: return
+
+		labels = []
+		self.total_demand = []
+		self.total_forecast = []
+		self.total_history_forecast = []
+		self.total_future_forecast = []
+
+		for period in self.period_list:
+			forecast_key = "forecast_" + period.key
+
+			labels.append(_(period.label))
+
+			if period.from_date < getdate(self.filters.from_date):
+				self.total_demand.append(self.data[-1].get(period.key, 0))
+				self.total_history_forecast.append(self.data[-1].get(forecast_key, 0))
+			else:
+				self.total_future_forecast.append(self.data[-1].get(forecast_key, 0))
+
+			self.total_forecast.append(self.data[-1].get(forecast_key, 0))
+
+		return {
+			"data": {
+				"labels": labels,
+				"datasets": [
+					{
+						"name": "Demand",
+						"values": self.total_demand
+					},
+					{
+						"name": "Forecast",
+						"values": self.total_forecast
+					}
+				]
+			},
+			"type": "line"
+		}
+
+	def get_summary_data(self):
+		return [
+			{
+				"value": sum(self.total_demand),
+				"label": _("Total Demand (Past Data)"),
+				"currency": self.company_currency,
+				"datatype": self.fieldtype
+			},
+			{
+				"value": sum(self.total_history_forecast),
+				"label": _("Total Forecast (Past Data)"),
+				"currency": self.company_currency,
+				"datatype": self.fieldtype
+			},
+			{
+				"value": sum(self.total_future_forecast),
+				"indicator": "Green",
+				"label": _("Total Forecast (Future Data)"),
+				"currency": self.company_currency,
+				"datatype": self.fieldtype
+			}
+		]
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.py b/erpnext/manufacturing/report/production_analytics/production_analytics.py
index f62cd25..79af8a1 100644
--- a/erpnext/manufacturing/report/production_analytics/production_analytics.py
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.py
@@ -55,32 +55,27 @@
 				if d.status == 'Completed':
 					if getdate(d.actual_end_date) < getdate(from_date) or getdate(d.modified) < getdate(from_date):
 						periodic_data = update_periodic_data(periodic_data, "Completed", period)
-
 					elif getdate(d.actual_start_date) < getdate(from_date) :
 						periodic_data = update_periodic_data(periodic_data, "Pending", period)
-
 					elif getdate(d.planned_start_date) < getdate(from_date) :
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
-
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
 
 				elif d.status == 'In Process':
 					if getdate(d.actual_start_date) < getdate(from_date) :
 						periodic_data = update_periodic_data(periodic_data, "Pending", period)
-
 					elif getdate(d.planned_start_date) < getdate(from_date) :
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
-
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
 
 				elif d.status == 'Not Started':
 					if getdate(d.planned_start_date) < getdate(from_date) :
 						periodic_data = update_periodic_data(periodic_data, "Overdue", period)
-
 					else:
 						periodic_data = update_periodic_data(periodic_data, "Not Started", period)
+
 	return periodic_data
 
 def update_periodic_data(periodic_data, status, period):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index bb9bb97..af7cb8e 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -690,3 +690,4 @@
 erpnext.patches.v13_0.update_actual_start_and_end_date_in_wo
 erpnext.patches.v13_0.set_company_field_in_healthcare_doctypes
 erpnext.patches.v12_0.update_bom_in_so_mr
+execute:frappe.delete_doc("Report", "Department Analytics")
diff --git a/erpnext/patches/v13_0/set_company_field_in_healthcare_doctypes.py b/erpnext/patches/v13_0/set_company_field_in_healthcare_doctypes.py
index 2c646b1..9d0dae4 100644
--- a/erpnext/patches/v13_0/set_company_field_in_healthcare_doctypes.py
+++ b/erpnext/patches/v13_0/set_company_field_in_healthcare_doctypes.py
@@ -6,4 +6,5 @@
 	doctypes = ['Clinical Procedure', 'Inpatient Record', 'Lab Test', 'Patient Appointment', 'Patient Encounter', 'Vital Signs']
 	for entry in doctypes:
 		if frappe.db.exists('DocType', entry):
+			frappe.reload_doc("Healthcare", "doctype", entry)
 			frappe.db.sql("update `tab{dt}` set company = '{company}' where ifnull(company, '') = ''".format(dt=entry, company=company))
diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py
index 4ca43a8..2b80fb8 100644
--- a/erpnext/startup/boot.py
+++ b/erpnext/startup/boot.py
@@ -10,7 +10,6 @@
 	"""boot session - send website info if guest"""
 
 	bootinfo.custom_css = frappe.db.get_value('Style Settings', None, 'custom_css') or ''
-	bootinfo.website_settings = frappe.get_doc('Website Settings')
 
 	if frappe.session['user']!='Guest':
 		update_page_info(bootinfo)