Merge pull request #22113 from Anurag810/leave_application-fixes

fix: Wrong filters
diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml
new file mode 100644
index 0000000..d36b115
--- /dev/null
+++ b/.github/workflows/docker-release.yml
@@ -0,0 +1,14 @@
+name: Trigger Docker build on release
+on:
+  release:
+    types: [created]
+jobs:
+  curl:
+    runs-on: ubuntu-latest
+    container:
+      image: alpine:latest
+    steps:
+    - name: curl
+      run: |
+        apk add curl bash
+        curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.org/repo/frappe%2Ffrappe_docker/requests
diff --git a/erpnext/accounts/dashboard_fixtures.py b/erpnext/accounts/dashboard_fixtures.py
index 1eed5a0..421c86d 100644
--- a/erpnext/accounts/dashboard_fixtures.py
+++ b/erpnext/accounts/dashboard_fixtures.py
@@ -60,9 +60,9 @@
 			"report_name": "Profit and Loss Statement",
 			"filters_json": json.dumps({
 				"company": company.name,
-				"filter_based_on": "Date Range",
-				"period_start_date": get_date_str(fiscal_year[1]),
-				"period_end_date": get_date_str(fiscal_year[2]),
+				"filter_based_on": "Fiscal Year",
+				"from_fiscal_year": fiscal_year[0],
+				"to_fiscal_year": fiscal_year[0],
 				"periodicity": "Monthly",
 				"include_default_book_entries": 1
 			}),
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 2da71df..2bf0b72 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -385,6 +385,50 @@
 		so.load_from_db()
 		self.assertEqual(so.items[1].is_free_item, 1)
 		self.assertEqual(so.items[1].item_code, "_Test Item 2")
+	
+	def test_cumulative_pricing_rule(self):
+		frappe.delete_doc_if_exists('Pricing Rule', '_Test Cumulative Pricing Rule')
+		test_record = {
+			"doctype": "Pricing Rule",
+			"title": "_Test Cumulative Pricing Rule",
+			"apply_on": "Item Code",
+			"currency": "USD",
+			"items": [{
+				"item_code": "_Test Item",
+			}],
+			"is_cumulative": 1,
+			"selling": 1,
+			"applicable_for": "Customer",
+			"customer": "_Test Customer",
+			"rate_or_discount": "Discount Percentage",
+			"rate": 0,
+			"min_amt": 0,
+			"max_amt": 10000,
+			"discount_percentage": 17.5,
+			"price_or_product_discount": "Price",
+			"company": "_Test Company",
+			"valid_from": frappe.utils.nowdate(),
+			"valid_upto": frappe.utils.nowdate()
+		}
+		frappe.get_doc(test_record.copy()).insert()
+
+		args = frappe._dict({
+			"item_code": "_Test Item",
+			"company": "_Test Company",
+			"price_list": "_Test Price List",
+			"currency": "_Test Currency",
+			"doctype": "Sales Invoice",
+			"conversion_rate": 1,
+			"price_list_currency": "_Test Currency",
+			"plc_conversion_rate": 1,
+			"order_type": "Sales",
+			"customer": "_Test Customer",
+			"name": None,
+			"transaction_date": frappe.utils.nowdate()
+		})
+		details = get_item_details(args)
+
+		self.assertTrue(details)
 
 def make_pricing_rule(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index cb05481..53115f9 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -366,8 +366,7 @@
 	sum_qty, sum_amt = [0, 0]
 	doctype = doc.get('parenttype') or doc.doctype
 
-	date_field = ('transaction_date'
-		if doc.get('transaction_date') else 'posting_date')
+	date_field = 'transaction_date' if frappe.get_meta(doctype).has_field('transaction_date') else 'posting_date'
 
 	child_doctype = '{0} Item'.format(doctype)
 	apply_on = frappe.scrub(pr_doc.get('apply_on'))
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 05b85da..57dc179 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1519,14 +1519,22 @@
 	def update_details(source_doc, target_doc, source_parent):
 		target_doc.inter_company_invoice_reference = source_doc.name
 		if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
+			currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency')
 			target_doc.company = details.get("company")
 			target_doc.supplier = details.get("party")
 			target_doc.buying_price_list = source_doc.selling_price_list
+
+			if currency:
+				target_doc.currency = currency
 		else:
+			currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency')
 			target_doc.company = details.get("company")
 			target_doc.customer = details.get("party")
 			target_doc.selling_price_list = source_doc.buying_price_list
 
+			if currency:
+				target_doc.currency = currency
+
 	doclist = get_mapped_doc(doctype, source_name,	{
 		doctype: {
 			"doctype": target_doctype,
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index b2638c7..d32a348 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -45,7 +45,9 @@
 		shipping_amount = 0.0
 		by_value = False
 
-		self.validate_countries(doc)
+		if doc.get_shipping_address():
+			# validate country only if there is address
+			self.validate_countries(doc)
 
 		if self.calculate_based_on == 'Net Total':
 			value = doc.base_net_total
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index d40e58b..66aa180 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -169,9 +169,11 @@
 
 	def append_subtotal_row(self, party):
 		sub_total_row = self.total_row_map.get(party)
-		self.data.append(sub_total_row)
-		self.data.append({})
-		self.update_sub_total_row(sub_total_row, 'Total')
+
+		if sub_total_row:
+			self.data.append(sub_total_row)
+			self.data.append({})
+			self.update_sub_total_row(sub_total_row, 'Total')
 
 	def get_voucher_balance(self, gle):
 		if self.filters.get("sales_person"):
@@ -232,7 +234,8 @@
 
 		if self.filters.get('group_by_party'):
 			self.append_subtotal_row(self.previous_party)
-			self.data.append(self.total_row_map.get('Total'))
+			if self.data:
+				self.data.append(self.total_row_map.get('Total'))
 
 	def append_row(self, row):
 		self.allocate_future_payments(row)
diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
index 80bccaf..5001ad9 100644
--- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
+++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
@@ -93,7 +93,7 @@
 			   sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
 			   sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
 		from (SELECT a.asset_category,
-				   ifnull(sum(case when ds.schedule_date < %(from_date)s then
+				   ifnull(sum(case when ds.schedule_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
 								   ds.depreciation_amount
 							  else
 								   0
@@ -115,9 +115,7 @@
 			group by a.asset_category
 			union
 			SELECT a.asset_category,
-				   ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
-										and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) 
-										then
+				   ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
 									0
 							   else
 									a.opening_accumulated_depreciation
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
index 38fd5fa..0947922 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
@@ -33,7 +33,6 @@
 			"fieldname":"period_start_date",
 			"label": __("Start Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.nowdate(),
 			"hidden": 1,
 			"reqd": 1
 		},
@@ -41,7 +40,6 @@
 			"fieldname":"period_end_date",
 			"label": __("End Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
 			"hidden": 1,
 			"reqd": 1
 		},
@@ -106,5 +104,16 @@
 			value = $value.wrap("<p></p>").parent().html();
 		}
 		return value;
+	},
+	onload: function() {
+		let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
+
+		frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+			var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+			frappe.query_report.set_filter_value({
+				period_start_date: fy.year_start_date,
+				period_end_date: fy.year_end_date
+			});
+		});
 	}
 }
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
index 4ac0f65..a9fb237 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
@@ -111,7 +111,7 @@
 	# {"purchase_invoice": list of dict of all gle created for this invoice}
 	gle_map = {}
 	gle = frappe.db.get_all('GL Entry',\
-		{"voucher_no": ["in", [d.get("name") for d in filters["invoices"]]]},
+		{"voucher_no": ["in", [d.get("name") for d in filters["invoices"]]], 'is_cancelled': 0},
 		["fiscal_year", "credit", "debit", "account", "voucher_no", "posting_date"])
 
 	for d in gle:
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
index efb2de3..c0c2566 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
@@ -1,559 +1,140 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "field:asset_name", 
- "beta": 0, 
- "creation": "2017-10-19 16:50:22.879545", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "autoname": "field:asset_name",
+ "creation": "2017-10-19 16:50:22.879545",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "asset_name",
+  "asset_category",
+  "company",
+  "column_break_3",
+  "item_code",
+  "item_name",
+  "section_break_6",
+  "maintenance_team",
+  "column_break_9",
+  "maintenance_manager",
+  "maintenance_manager_name",
+  "section_break_8",
+  "asset_maintenance_tasks"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "asset_name", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Asset Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Asset", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "asset_name",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Asset Name",
+   "options": "Asset",
+   "reqd": 1,
+   "unique": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fetch_from": "asset_name.asset_category",
-   "fieldname": "asset_category", 
-   "fieldtype": "Read Only", 
-   "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": "Asset Category", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "asset_category",
+   "fieldtype": "Read Only",
+   "label": "Asset Category"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fetch_from": "asset_name.item_code",
-   "fieldname": "item_code", 
-   "fieldtype": "Read Only", 
-   "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": "Item Code", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "item_code",
+   "fieldtype": "Read Only",
+   "label": "Item Code"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fetch_from": "asset_name.item_name",
-   "fieldname": "item_name", 
-   "fieldtype": "Read Only", 
-   "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": "Item Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "item_name",
+   "fieldtype": "Read Only",
+   "label": "Item Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "company", 
-   "fieldtype": "Link", 
-   "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": "Company", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "select_serial_no", 
-   "fieldtype": "Link", 
-   "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": "Select Serial No", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Serial No", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "serial_no", 
-   "fieldtype": "Small Text", 
-   "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": "Serial No", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "maintenance_team",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Maintenance Team",
+   "options": "Asset Maintenance Team",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_6", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "maintenance_team", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Maintenance Team", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Asset Maintenance Team", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_9", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fetch_from": "maintenance_team.maintenance_manager",
-   "fieldname": "maintenance_manager", 
-   "fieldtype": "Data", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Maintenance Manager", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "maintenance_manager",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Maintenance Manager",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fetch_from": "maintenance_team.maintenance_manager_name",
-   "fieldname": "maintenance_manager_name", 
-   "fieldtype": "Read Only", 
-   "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": "Maintenance Manager Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "maintenance_manager_name",
+   "fieldtype": "Read Only",
+   "label": "Maintenance Manager Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_8", 
-   "fieldtype": "Section Break", 
-   "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": "Tasks", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
-  }, 
+   "fieldname": "section_break_8",
+   "fieldtype": "Section Break",
+   "label": "Tasks"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "asset_maintenance_tasks", 
-   "fieldtype": "Table", 
-   "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": "Maintenance Tasks", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Asset Maintenance Task", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0,
-   "unique": 0
+   "fieldname": "asset_maintenance_tasks",
+   "fieldtype": "Table",
+   "label": "Maintenance Tasks",
+   "options": "Asset Maintenance Task",
+   "reqd": 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-05-22 17:20:54.711885",
- "modified_by": "Administrator", 
- "module": "Assets", 
- "name": "Asset Maintenance", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2020-05-28 20:28:32.993823",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Maintenance",
+ "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": "Quality Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Quality Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "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": "Manufacturing User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Manufacturing User",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "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
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index 3f04611..d6adde6 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -38,7 +38,7 @@
 
 @frappe.whitelist()
 def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date):
-	team_member = frappe.get_doc('User', assign_to_member).email
+	team_member = frappe.db.get_value('User', assign_to_member, "email")
 	args = {
 		'doctype' : 'Asset Maintenance',
 		'assign_to' : team_member,
@@ -77,7 +77,7 @@
 
 def update_maintenance_log(asset_maintenance, item_code, item_name, task):
 	asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance,
-		"task": task.maintenance_task, "maintenance_status": ('in',['Planned','Overdue'])})
+		"task": task.name, "maintenance_status": ('in',['Planned','Overdue'])})
 
 	if not asset_maintenance_log:
 		asset_maintenance_log = frappe.get_doc({
@@ -86,7 +86,7 @@
 			"asset_name": asset_maintenance,
 			"item_code": item_code,
 			"item_name": item_name,
-			"task": task.maintenance_task,
+			"task": task.name,
 			"has_certificate": task.certificate_required,
 			"description": task.description,
 			"assign_to_name": task.assign_to_name,
diff --git a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json
index 42aecdf..7395bec 100644
--- a/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json
+++ b/erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json
@@ -1,819 +1,210 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "naming_series:", 
- "beta": 0, 
- "creation": "2017-10-23 16:58:44.424309", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2017-10-23 16:58:44.424309",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "asset_maintenance",
+  "naming_series",
+  "asset_name",
+  "column_break_2",
+  "item_code",
+  "item_name",
+  "section_break_5",
+  "task",
+  "task_name",
+  "maintenance_type",
+  "periodicity",
+  "assign_to_name",
+  "column_break_6",
+  "due_date",
+  "completion_date",
+  "maintenance_status",
+  "section_break_12",
+  "has_certificate",
+  "certificate_attachement",
+  "section_break_6",
+  "description",
+  "column_break_9",
+  "actions_performed",
+  "amended_from"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "asset_maintenance", 
-   "fieldtype": "Link", 
-   "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": "Asset Maintenance", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Asset Maintenance", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "asset_maintenance",
+   "fieldtype": "Link",
+   "label": "Asset Maintenance",
+   "options": "Asset Maintenance"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
-   "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": "Series", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "ACC-AML-.YYYY.-", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Series",
+   "options": "ACC-AML-.YYYY.-",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "asset_maintenance.asset_name", 
-   "fieldname": "asset_name", 
-   "fieldtype": "Read Only", 
-   "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": "Asset Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "asset_maintenance.asset_name",
+   "fieldname": "asset_name",
+   "fieldtype": "Read Only",
+   "label": "Asset Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_2", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "asset_maintenance.item_code", 
-   "fieldname": "item_code", 
-   "fieldtype": "Read Only", 
-   "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": "Item Code", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "asset_maintenance.item_code",
+   "fieldname": "item_code",
+   "fieldtype": "Read Only",
+   "label": "Item Code"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "asset_maintenance.item_name", 
-   "fieldname": "item_name", 
-   "fieldtype": "Read Only", 
-   "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": "Item Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "asset_maintenance.item_name",
+   "fieldname": "item_name",
+   "fieldtype": "Read Only",
+   "label": "Item Name"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_5", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "task", 
-   "fieldtype": "Link", 
-   "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": "Task", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Asset Maintenance Task", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "task",
+   "fieldtype": "Link",
+   "label": "Task",
+   "options": "Asset Maintenance Task"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.maintenance_type", 
-   "fieldname": "maintenance_type", 
-   "fieldtype": "Read Only", 
-   "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": "Maintenance Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.maintenance_type",
+   "fieldname": "maintenance_type",
+   "fieldtype": "Read Only",
+   "label": "Maintenance Type"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.periodicity", 
-   "fieldname": "periodicity", 
-   "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": "Periodicity", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.periodicity",
+   "fieldname": "periodicity",
+   "fieldtype": "Data",
+   "label": "Periodicity",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.assign_to_name", 
-   "fieldname": "assign_to_name", 
-   "fieldtype": "Read Only", 
-   "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": "Assign To", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.assign_to_name",
+   "fieldname": "assign_to_name",
+   "fieldtype": "Read Only",
+   "label": "Assign To"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_6", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_6",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.next_due_date", 
-   "fieldname": "due_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Due Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.next_due_date",
+   "fieldname": "due_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Due Date",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "completion_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Completion Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "completion_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Completion Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "maintenance_status", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 1, 
-   "label": "Maintenance Status", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Planned\nCompleted\nCancelled\nOverdue", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "maintenance_status",
+   "fieldtype": "Select",
+   "in_standard_filter": 1,
+   "label": "Maintenance Status",
+   "options": "Planned\nCompleted\nCancelled\nOverdue",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_12", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_12",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.certificate_required", 
-   "fieldname": "has_certificate", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Has Certificate ", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "0",
+   "fetch_from": "task.certificate_required",
+   "fieldname": "has_certificate",
+   "fieldtype": "Check",
+   "label": "Has Certificate "
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.has_certificate", 
-   "fieldname": "certificate_attachement", 
-   "fieldtype": "Attach", 
-   "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": "Certificate", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.has_certificate",
+   "fieldname": "certificate_attachement",
+   "fieldtype": "Attach",
+   "label": "Certificate"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_6", 
-   "fieldtype": "Column Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "section_break_6",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "task.description", 
-   "fieldname": "description", 
-   "fieldtype": "Read Only", 
-   "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": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "task.description",
+   "fieldname": "description",
+   "fieldtype": "Read Only",
+   "label": "Description",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_9", 
-   "fieldtype": "Section Break", 
-   "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, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_9",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 1, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "actions_performed", 
-   "fieldtype": "Text Editor", 
-   "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": "Actions performed", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "allow_on_submit": 1,
+   "fieldname": "actions_performed",
+   "fieldtype": "Text Editor",
+   "label": "Actions performed"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amended_from", 
-   "fieldtype": "Link", 
-   "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": "Amended From", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Asset Maintenance Log", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Asset Maintenance Log",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fetch_from": "task.maintenance_task",
+   "fieldname": "task_name",
+   "fieldtype": "Data",
+   "in_preview": 1,
+   "label": "Task Name",
+   "read_only": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 1, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 14:44:51.457835", 
- "modified_by": "Administrator", 
- "module": "Assets", 
- "name": "Asset Maintenance Log", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-05-28 20:51:48.238397",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Maintenance Log",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 1, 
-   "cancel": 1, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Manufacturing User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 1, 
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Manufacturing User",
+   "share": 1,
+   "submit": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "", 
- "track_changes": 1, 
- "track_seen": 1, 
- "track_views": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 1
 }
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py b/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
index d98cc31..2a5666d 100644
--- a/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
+++ b/erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.py
@@ -7,5 +7,4 @@
 from frappe.model.document import Document
 
 class AssetMaintenanceTask(Document):
-	def autoname(self):
-		self.name = self.maintenance_task
+	pass
diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json
index d31602b..bddb957 100644
--- a/erpnext/buying/desk_page/buying/buying.json
+++ b/erpnext/buying/desk_page/buying/buying.json
@@ -34,9 +34,14 @@
    "hidden": 0,
    "label": "Other Reports",
    "links": "[\n    {\n        \"is_query_report\": true,\n        \"label\": \"Items To Be Requested\",\n        \"name\": \"Items To Be Requested\",\n        \"onboard\": 1,\n        \"reference_doctype\": \"Item\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Item-wise Purchase History\",\n        \"name\": \"Item-wise Purchase History\",\n        \"onboard\": 1,\n        \"reference_doctype\": \"Item\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n        \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n        \"reference_doctype\": \"Purchase Order\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Subcontracted Item To Be Received\",\n        \"name\": \"Subcontracted Item To Be Received\",\n        \"reference_doctype\": \"Purchase Order\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Quoted Item Comparison\",\n        \"name\": \"Quoted Item Comparison\",\n         \"onboard\": 1,\n        \"reference_doctype\": \"Supplier Quotation\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Material Requests for which Supplier Quotations are not created\",\n        \"name\": \"Material Requests for which Supplier Quotations are not created\",\n        \"reference_doctype\": \"Material Request\",\n        \"type\": \"report\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"Supplier Addresses And Contacts\",\n        \"name\": \"Address And Contacts\",\n        \"reference_doctype\": \"Address\",\n        \"route_options\": {\n            \"party_type\": \"Supplier\"\n        },\n        \"type\": \"report\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Regional",
+   "links": "[\n     {\n        \"description\": \"Import Italian Purchase Invoices\",\n        \"label\": \"Import Supplier Invoice\",\n        \"name\": \"Import Supplier Invoice\",\n        \"type\": \"doctype\"\n    }    \n]"
   }
  ],
- "cards_label": "Masters & Reports ",
+ "cards_label": "",
  "category": "Modules",
  "charts": [
   {
@@ -44,7 +49,7 @@
    "label": "Purchase Order Trends"
   }
  ],
- "charts_label": "Buying Dashboard",
+ "charts_label": "",
  "creation": "2020-01-28 11:50:26.195467",
  "developer_mode_only": 0,
  "disable_user_customization": 0,
@@ -55,7 +60,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Buying",
- "modified": "2020-05-27 19:55:22.407528",
+ "modified": "2020-05-28 13:32:49.960574",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Buying",
@@ -104,5 +109,5 @@
    "type": "Dashboard"
   }
  ],
- "shortcuts_label": "Quick Access"
+ "shortcuts_label": ""
 }
\ No newline at end of file
diff --git a/erpnext/config/buying.py b/erpnext/config/buying.py
index 16b49a1..b06bb76 100644
--- a/erpnext/config/buying.py
+++ b/erpnext/config/buying.py
@@ -1,8 +1,9 @@
 from __future__ import unicode_literals
+import frappe
 from frappe import _
 
 def get_data():
-	return [
+	config =  [
 		{
 			"label": _("Purchasing"),
 			"icon": "fa fa-star",
@@ -243,3 +244,21 @@
 		},
 
 	]
+
+	regional = {
+			"label": _("Regional"),
+			"items": [
+				{
+				"type": "doctype",
+				"name": "Import Supplier Invoice",
+				"description": _("Import Italian Supplier Invoice."),
+				"onboard": 1,
+				}
+			]
+		}
+
+	countries = frappe.get_all("Company", fields="country")
+	countries = [country["country"] for country in countries]
+	if "Italy" in countries:
+		config.append(regional)
+	return config
\ No newline at end of file
diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py
index 29f8dd5..50b17ab 100644
--- a/erpnext/controllers/item_variant.py
+++ b/erpnext/controllers/item_variant.py
@@ -70,7 +70,7 @@
 
 		else:
 			attributes_list = attribute_values.get(attribute.lower(), [])
-			validate_item_attribute_value(attributes_list, attribute, value, item.name)
+			validate_item_attribute_value(attributes_list, attribute, value, item.name, from_variant=True)
 
 def validate_is_incremental(numeric_attribute, attribute, value, item):
 	from_range = numeric_attribute.from_range
@@ -93,13 +93,20 @@
 			.format(attribute, from_range, to_range, increment, item),
 			InvalidItemAttributeValueError, title=_('Invalid Attribute'))
 
-def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
+def validate_item_attribute_value(attributes_list, attribute, attribute_value, item, from_variant=True):
 	allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
 	if allow_rename_attribute_value:
 		pass
 	elif attribute_value not in attributes_list:
-		frappe.throw(_("The value {0} is already assigned to an exisiting Item {2}.").format(
-			attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Rename Not Allowed'))
+		if from_variant:
+			frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format(
+				frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value"))
+		else:
+			msg = _("The value {0} is already assigned to an exisiting Item {1}.").format(
+				frappe.bold(attribute_value), frappe.bold(item))
+			msg += "<br>" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value"))
+
+			frappe.throw(msg, InvalidItemAttributeValueError, title=_('Edit Not Allowed'))
 
 def get_attribute_values(item):
 	if not frappe.flags.attribute_values:
diff --git a/erpnext/crm/dashboard_fixtures.py b/erpnext/crm/dashboard_fixtures.py
index 16904b3..0535cbb 100644
--- a/erpnext/crm/dashboard_fixtures.py
+++ b/erpnext/crm/dashboard_fixtures.py
@@ -21,8 +21,8 @@
                 { "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": "Territory Wise Sales", "width": "Full"},
                 { "chart": "Lead Source", "width": "Half"}
             ],
             "cards": [
@@ -59,7 +59,7 @@
         'is_public': 1,
         'timeseries': 1,
         "owner": "Administrator",
-        "filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
+        "filters_json": json.dumps([]),
         "type": "Bar"
     },
     {
@@ -90,7 +90,11 @@
         'timeseries': 1,
         "owner": "Administrator",
         "filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
-        "type": "Pie"
+        "type": "Pie",
+        "custom_options": json.dumps({
+            "truncateLegends": 1,
+            "maxSlices": 8
+        })
     },
     {
         "name": "Won Opportunities",
@@ -123,7 +127,11 @@
             ["Opportunity", "company", "=", company, False]
         ]),
         "owner": "Administrator",
-        "type": "Donut"
+        "type": "Donut",
+        "custom_options": json.dumps({
+            "truncateLegends": 1,
+            "maxSlices": 8
+        })
     },
     {
         "name": "Territory Wise Sales",
@@ -140,7 +148,7 @@
             ["Opportunity", "company", "=", company, False],
             ["Opportunity", "status", "=", "Converted", False]
         ]),
-        "type": "Donut"
+        "type": "Bar"
     },
     {
         "name": "Lead Source",
@@ -152,7 +160,11 @@
         "document_type": "Lead",
         'is_public': 1,
         "owner": "Administrator",
-        "type": "Pie"
+        "type": "Pie",
+        "custom_options": json.dumps({
+            "truncateLegends": 1,
+            "maxSlices": 8
+        })
     }]
 
 def get_number_cards():
diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json
index 2fc4582..eb69dc0 100644
--- a/erpnext/crm/desk_page/crm/crm.json
+++ b/erpnext/crm/desk_page/crm/crm.json
@@ -42,7 +42,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "CRM",
- "modified": "2020-05-20 12:11:36.250491",
+ "modified": "2020-05-28 13:33:52.906750",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "CRM",
@@ -52,6 +52,7 @@
  "pin_to_top": 0,
  "shortcuts": [
   {
+   "color": "#ffe8cd",
    "format": "{} Open",
    "label": "Lead",
    "link_to": "Lead",
@@ -59,6 +60,7 @@
    "type": "DocType"
   },
   {
+   "color": "#cef6d1",
    "format": "{} Assigned",
    "label": "Opportunity",
    "link_to": "Opportunity",
@@ -76,7 +78,7 @@
    "type": "Report"
   },
   {
-   "label": "CRM Dashboard",
+   "label": "Dashboard",
    "link_to": "CRM",
    "type": "Dashboard"
   }
diff --git a/erpnext/crm/module_onboarding/crm/crm.json b/erpnext/crm/module_onboarding/crm/crm.json
index 9b3d91e..44d672a 100644
--- a/erpnext/crm/module_onboarding/crm/crm.json
+++ b/erpnext/crm/module_onboarding/crm/crm.json
@@ -16,7 +16,7 @@
  "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
  "idx": 0,
  "is_complete": 0,
- "modified": "2020-05-27 11:33:09.941263",
+ "modified": "2020-05-28 21:07:41.278784",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "CRM",
@@ -35,8 +35,8 @@
    "step": "Create and Send Quotation"
   }
  ],
- "subtitle": "Lead, Opportunity, Customer and more",
- "success_message": "CRM Module is all setup!",
- "title": "Let's Setup Your CRM",
+ "subtitle": "Lead, Opportunity, Customer and more.",
+ "success_message": "CRM Module is all Set Up!",
+ "title": "Let's Set Up 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
index 9201d77..78f7e4d 100644
--- 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
@@ -8,7 +8,7 @@
  "is_mandatory": 0,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-27 11:30:28.237263",
+ "modified": "2020-05-28 21:07:11.461172",
  "modified_by": "Administrator",
  "name": "Create and Send Quotation",
  "owner": "Administrator",
diff --git a/erpnext/crm/onboarding_step/create_lead/create_lead.json b/erpnext/crm/onboarding_step/create_lead/create_lead.json
index 6ff0bd6..c45e8b0 100644
--- a/erpnext/crm/onboarding_step/create_lead/create_lead.json
+++ b/erpnext/crm/onboarding_step/create_lead/create_lead.json
@@ -8,7 +8,7 @@
  "is_mandatory": 0,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-27 11:30:59.493720",
+ "modified": "2020-05-28 21:07:01.373403",
  "modified_by": "Administrator",
  "name": "Create Lead",
  "owner": "Administrator",
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
index 545a756..fa26921a 100644
--- a/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
+++ b/erpnext/crm/onboarding_step/introduction_to_crm/introduction_to_crm.json
@@ -8,7 +8,7 @@
  "is_mandatory": 0,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-27 11:28:07.452857",
+ "modified": "2020-05-14 17:28:16.448676",
  "modified_by": "Administrator",
  "name": "Introduction to CRM",
  "owner": "Administrator",
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.json b/erpnext/education/doctype/fee_schedule/fee_schedule.json
index 1e98709..7918318 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.json
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2017-07-18 15:21:21.527136",
@@ -7,6 +8,7 @@
  "engine": "InnoDB",
  "field_order": [
   "fee_structure",
+  "posting_date",
   "due_date",
   "naming_series",
   "fee_creation_status",
@@ -259,10 +261,18 @@
   {
    "fieldname": "dimension_col_break",
    "fieldtype": "Column Break"
+  },
+  {
+   "default": "Today",
+   "fieldname": "posting_date",
+   "fieldtype": "Date",
+   "label": "Posting Date",
+   "reqd": 1
   }
  ],
  "is_submittable": 1,
- "modified": "2019-05-26 09:10:34.522409",
+ "links": [],
+ "modified": "2020-05-15 08:39:20.682837",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Fee Schedule",
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py
index a42800a..1543acd 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.py
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.py
@@ -87,6 +87,7 @@
 						}
 					}
 				})
+				fees_doc.posting_date = doc.posting_date
 				fees_doc.student = student.student
 				fees_doc.student_name = student.student_name
 				fees_doc.program = student.program
diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py
index 7046038..d59f909 100644
--- a/erpnext/erpnext_integrations/connectors/shopify_connection.py
+++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py
@@ -241,14 +241,17 @@
 	return taxes
 
 def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings):
+	"""Shipping lines represents the shipping details,
+		each such shipping detail consists of a list of tax_lines"""
 	for shipping_charge in shipping_lines:
-		taxes.append({
-			"charge_type": _("Actual"),
-			"account_head": get_tax_account_head(shipping_charge),
-			"description": shipping_charge["title"],
-			"tax_amount": shipping_charge["price"],
-			"cost_center": shopify_settings.cost_center
-		})
+		for tax in shipping_charge.get("tax_lines"):
+			taxes.append({
+				"charge_type": _("Actual"),
+				"account_head": get_tax_account_head(tax),
+				"description": tax["title"],
+				"tax_amount": tax["price"],
+				"cost_center": shopify_settings.cost_center
+			})
 
 	return taxes
 
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index a706223..c3371ed 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -124,10 +124,11 @@
 
 @frappe.whitelist()
 def sync_transactions(bank, bank_account):
-
-	last_sync_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
-	if last_sync_date:
-		start_date = formatdate(last_sync_date, "YYYY-MM-dd")
+	'''Sync transactions based on the last integration date as the start date, after the sync is completed
+		add the transaction date of the oldest transaction as the last integration date'''
+	last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
+	if last_transaction_date:
+		start_date = formatdate(last_transaction_date, "YYYY-MM-dd")
 	else:
 		start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
 	end_date = formatdate(today(), "YYYY-MM-dd")
@@ -139,12 +140,14 @@
 		for transaction in reversed(transactions):
 			result += new_bank_transaction(transaction)
 
-		frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format(
-			len(result), bank_account, start_date, end_date))
+		if result:
+			last_transaction_date = frappe.db.get_value('Bank Transaction', result.pop(), 'date')
 
-		frappe.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date))
+			frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format(
+				len(result), bank_account, start_date, end_date))
 
-		return result
+			frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date)
+
 	except Exception:
 		frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
 
diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
index d1e5f40..5339c99 100644
--- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
+++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
@@ -258,7 +258,7 @@
   }
  ],
  "issingle": 1,
- "modified": "2019-09-13 12:32:11.384757",
+ "modified": "2020-05-28 12:32:11.384757",
  "modified_by": "umair@erpnext.com",
  "module": "ERPNext Integrations",
  "name": "Shopify Settings",
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
index d84c823..fd16d1e 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
@@ -1,7 +1,9 @@
 // Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on('Tally Migration', {
+frappe.provide("erpnext.tally_migration");
+
+frappe.ui.form.on("Tally Migration", {
 	onload: function (frm) {
 		let reload_status = true;
 		frappe.realtime.on("tally_migration_progress_update", function (data) {
@@ -35,7 +37,17 @@
 			}
 		});
 	},
+
 	refresh: function (frm) {
+		frm.trigger("show_logs_preview");
+		erpnext.tally_migration.failed_import_log = JSON.parse(frm.doc.failed_import_log);
+		erpnext.tally_migration.fixed_errors_log = JSON.parse(frm.doc.fixed_errors_log);
+
+		["default_round_off_account", "default_warehouse", "default_cost_center"].forEach(account => {
+			frm.toggle_reqd(account, frm.doc.is_master_data_imported === 1)
+			frm.toggle_enable(account, frm.doc.is_day_book_data_processed != 1)
+		})
+
 		if (frm.doc.master_data && !frm.doc.is_master_data_imported) {
 			if (frm.doc.is_master_data_processed) {
 				if (frm.doc.status != "Importing Master Data") {
@@ -47,6 +59,7 @@
 				}
 			}
 		}
+
 		if (frm.doc.day_book_data && !frm.doc.is_day_book_data_imported) {
 			if (frm.doc.is_day_book_data_processed) {
 				if (frm.doc.status != "Importing Day Book Data") {
@@ -59,6 +72,17 @@
 			}
 		}
 	},
+
+	erpnext_company: function (frm) {
+		frappe.db.exists("Company", frm.doc.erpnext_company).then(exists => {
+			if (exists) {
+				frappe.msgprint(
+					__("Company {0} already exists. Continuing will overwrite the Company and Chart of Accounts", [frm.doc.erpnext_company]),
+				);
+			}
+		});
+	},
+
 	add_button: function (frm, label, method) {
 		frm.add_custom_button(
 			label,
@@ -71,5 +95,255 @@
 				frm.reload_doc();
 			}
 		);
+	},
+
+	render_html_table(frm, shown_logs, hidden_logs, field) {
+		if (shown_logs && shown_logs.length > 0) {
+			frm.toggle_display(field, true);
+		} else {
+			frm.toggle_display(field, false);
+			return
+		}
+		let rows = erpnext.tally_migration.get_html_rows(shown_logs, field);
+		let rows_head, table_caption;
+
+		let table_footer = (hidden_logs && (hidden_logs.length > 0)) ? `<tr class="text-muted">
+				<td colspan="4">And ${hidden_logs.length} more others</td>
+			</tr>`: "";
+
+		if (field === "fixed_error_log_preview") {
+			rows_head = `<th width="75%">${__("Meta Data")}</th>
+			<th width="10%">${__("Unresolve")}</th>`
+			table_caption = "Resolved Issues"
+		} else {
+			rows_head = `<th width="75%">${__("Error Message")}</th>
+			<th width="10%">${__("Create")}</th>`
+			table_caption = "Error Log"
+		}
+
+		frm.get_field(field).$wrapper.html(`
+			<table class="table table-bordered">
+				<caption>${table_caption}</caption>
+				<tr class="text-muted">
+					<th width="5%">${__("#")}</th>
+					<th width="10%">${__("DocType")}</th>
+					${rows_head}
+				</tr>
+				${rows}
+				${table_footer}
+			</table>
+		`);
+	},
+
+	show_error_summary(frm) {
+		let summary = erpnext.tally_migration.failed_import_log.reduce((summary, row) => {
+			if (row.doc) {
+				if (summary[row.doc.doctype]) {
+					summary[row.doc.doctype] += 1;
+				} else {
+					summary[row.doc.doctype] = 1;
+				}
+			}
+			return summary
+		}, {});
+		console.table(summary);
+	},
+
+	show_logs_preview(frm) {
+		let empty = "[]";
+		let import_log = frm.doc.failed_import_log || empty;
+		let completed_log = frm.doc.fixed_errors_log || empty;
+		let render_section = !(import_log === completed_log && import_log === empty);
+
+		frm.toggle_display("import_log_section", render_section);
+		if (render_section) {
+			frm.trigger("show_error_summary");
+			frm.trigger("show_errored_import_log");
+			frm.trigger("show_fixed_errors_log");
+		}
+	},
+
+	show_errored_import_log(frm) {
+		let import_log = erpnext.tally_migration.failed_import_log;
+		let logs = import_log.slice(0, 20);
+		let hidden_logs = import_log.slice(20);
+
+		frm.events.render_html_table(frm, logs, hidden_logs, "failed_import_preview");
+	},
+
+	show_fixed_errors_log(frm) {
+		let completed_log = erpnext.tally_migration.fixed_errors_log;
+		let logs = completed_log.slice(0, 20);
+		let hidden_logs = completed_log.slice(20);
+
+		frm.events.render_html_table(frm, logs, hidden_logs, "fixed_error_log_preview");
 	}
 });
+
+erpnext.tally_migration.getError = (traceback) => {
+	/* Extracts the Error Message from the Python Traceback or Solved error */
+	let is_multiline = traceback.trim().indexOf("\n") != -1;
+	let message;
+
+	if (is_multiline) {
+		let exc_error_idx = traceback.trim().lastIndexOf("\n") + 1
+		let error_line = traceback.substr(exc_error_idx)
+		let split_str_idx = (error_line.indexOf(':') > 0) ? error_line.indexOf(':') + 1 : 0;
+		message = error_line.slice(split_str_idx).trim();
+	} else {
+		message = traceback;
+	}
+
+	return message
+}
+
+erpnext.tally_migration.cleanDoc = (obj) => {
+	/* Strips all null and empty values of your JSON object */
+	let temp = obj;
+	$.each(temp, function(key, value){
+		if (value === "" || value === null){
+			delete obj[key];
+		} else if (Object.prototype.toString.call(value) === '[object Object]') {
+			erpnext.tally_migration.cleanDoc(value);
+		} else if ($.isArray(value)) {
+			$.each(value, function (k,v) { erpnext.tally_migration.cleanDoc(v); });
+		}
+	});
+	return temp;
+}
+
+erpnext.tally_migration.unresolve = (document) => {
+	/* Mark document migration as unresolved ie. move to failed error log */
+	let frm = cur_frm;
+	let failed_log = erpnext.tally_migration.failed_import_log;
+	let fixed_log = erpnext.tally_migration.fixed_errors_log;
+
+	let modified_fixed_log = fixed_log.filter(row => {
+		if (!frappe.utils.deep_equal(erpnext.tally_migration.cleanDoc(row.doc), document)) {
+			return row
+		}
+	});
+
+	failed_log.push({ doc: document, exc: `Marked unresolved on ${Date()}` });
+
+	frm.doc.failed_import_log = JSON.stringify(failed_log);
+	frm.doc.fixed_errors_log = JSON.stringify(modified_fixed_log);
+
+	frm.dirty();
+	frm.save();
+}
+
+erpnext.tally_migration.resolve = (document) => {
+	/* Mark document migration as resolved ie. move to fixed error log */
+	let frm = cur_frm;
+	let failed_log = erpnext.tally_migration.failed_import_log;
+	let fixed_log = erpnext.tally_migration.fixed_errors_log;
+
+	let modified_failed_log = failed_log.filter(row => {
+		if (!frappe.utils.deep_equal(erpnext.tally_migration.cleanDoc(row.doc), document)) {
+			return row
+		}
+	});
+	fixed_log.push({ doc: document, exc: `Solved on ${Date()}` });
+
+	frm.doc.failed_import_log = JSON.stringify(modified_failed_log);
+	frm.doc.fixed_errors_log = JSON.stringify(fixed_log);
+
+	frm.dirty();
+	frm.save();
+}
+
+erpnext.tally_migration.create_new_doc = (document) => {
+	/* Mark as resolved and create new document */
+	erpnext.tally_migration.resolve(document);
+	return frappe.call({
+		type: "POST",
+		method: 'erpnext.erpnext_integrations.doctype.tally_migration.tally_migration.new_doc',
+		args: {
+			document
+		},
+		freeze: true,
+		callback: function(r) {
+			if(!r.exc) {
+				frappe.model.sync(r.message);
+				frappe.get_doc(r.message.doctype, r.message.name).__run_link_triggers = true;
+				frappe.set_route("Form", r.message.doctype, r.message.name);
+			}
+		}
+	});
+}
+
+erpnext.tally_migration.get_html_rows = (logs, field) => {
+	let index = 0;
+	let rows = logs
+		.map(({ doc, exc }) => {
+			let id = frappe.dom.get_unique_id();
+			let traceback = exc;
+
+			let error_message = erpnext.tally_migration.getError(traceback);
+			index++;
+
+			let show_traceback = `
+				<button class="btn btn-default btn-xs m-3" type="button" data-toggle="collapse" data-target="#${id}-traceback" aria-expanded="false" aria-controls="${id}-traceback">
+					${__("Show Traceback")}
+				</button>
+				<div class="collapse margin-top" id="${id}-traceback">
+					<div class="well">
+						<pre style="font-size: smaller;">${traceback}</pre>
+					</div>
+				</div>`;
+
+			let show_doc = `
+				<button class='btn btn-default btn-xs m-3' type='button' data-toggle='collapse' data-target='#${id}-doc' aria-expanded='false' aria-controls='${id}-doc'>
+					${__("Show Document")}
+				</button>
+				<div class="collapse margin-top" id="${id}-doc">
+					<div class="well">
+						<pre style="font-size: smaller;">${JSON.stringify(erpnext.tally_migration.cleanDoc(doc), null, 1)}</pre>
+					</div>
+				</div>`;
+
+			let create_button = `
+				<button class='btn btn-default btn-xs m-3' type='button' onclick='erpnext.tally_migration.create_new_doc(${JSON.stringify(doc)})'>
+					${__("Create Document")}
+				</button>`
+
+			let mark_as_unresolved = `
+				<button class='btn btn-default btn-xs m-3' type='button' onclick='erpnext.tally_migration.unresolve(${JSON.stringify(doc)})'>
+					${__("Mark as unresolved")}
+				</button>`
+
+			if (field === "fixed_error_log_preview") {
+				return `<tr>
+							<td>${index}</td>
+							<td>
+								<div>${doc.doctype}</div>
+							</td>
+							<td>
+								<div>${error_message}</div>
+								<div>${show_doc}</div>
+							</td>
+							<td>
+								<div>${mark_as_unresolved}</div>
+							</td>
+						</tr>`;
+			} else {
+				return `<tr>
+							<td>${index}</td>
+							<td>
+								<div>${doc.doctype}</div>
+							</td>
+							<td>
+								<div>${error_message}</div>
+								<div>${show_traceback}</div>
+								<div>${show_doc}</div>
+							</td>
+							<td>
+								<div>${create_button}</div>
+							</td>
+						</tr>`;
+			}
+		}).join("");
+
+	return rows
+}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.json b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.json
index dc6f093..417d943 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.json
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.json
@@ -28,14 +28,19 @@
   "vouchers",
   "accounts_section",
   "default_warehouse",
-  "round_off_account",
+  "default_round_off_account",
   "column_break_21",
   "default_cost_center",
   "day_book_section",
   "day_book_data",
   "column_break_27",
   "is_day_book_data_processed",
-  "is_day_book_data_imported"
+  "is_day_book_data_imported",
+  "import_log_section",
+  "failed_import_log",
+  "fixed_errors_log",
+  "failed_import_preview",
+  "fixed_error_log_preview"
  ],
  "fields": [
   {
@@ -57,6 +62,7 @@
    "fieldname": "tally_creditors_account",
    "fieldtype": "Data",
    "label": "Tally Creditors Account",
+   "read_only_depends_on": "eval:doc.is_master_data_processed==1",
    "reqd": 1
   },
   {
@@ -69,6 +75,7 @@
    "fieldname": "tally_debtors_account",
    "fieldtype": "Data",
    "label": "Tally Debtors Account",
+   "read_only_depends_on": "eval:doc.is_master_data_processed==1",
    "reqd": 1
   },
   {
@@ -92,7 +99,7 @@
    "fieldname": "erpnext_company",
    "fieldtype": "Data",
    "label": "ERPNext Company",
-   "read_only_depends_on": "eval:doc.is_master_data_processed == 1"
+   "read_only_depends_on": "eval:doc.is_master_data_processed==1"
   },
   {
    "fieldname": "processed_files_section",
@@ -136,6 +143,7 @@
   },
   {
    "depends_on": "is_master_data_imported",
+   "description": "The accounts are set by the system automatically but do confirm these defaults",
    "fieldname": "accounts_section",
    "fieldtype": "Section Break",
    "label": "Accounts"
@@ -147,12 +155,6 @@
    "options": "Warehouse"
   },
   {
-   "fieldname": "round_off_account",
-   "fieldtype": "Link",
-   "label": "Round Off Account",
-   "options": "Account"
-  },
-  {
    "fieldname": "column_break_21",
    "fieldtype": "Column Break"
   },
@@ -212,11 +214,47 @@
    "fieldname": "default_uom",
    "fieldtype": "Link",
    "label": "Default UOM",
-   "options": "UOM"
+   "options": "UOM",
+   "read_only_depends_on": "eval:doc.is_master_data_imported==1"
+  },
+  {
+   "default": "[]",
+   "fieldname": "failed_import_log",
+   "fieldtype": "Code",
+   "hidden": 1,
+   "options": "JSON"
+  },
+  {
+   "fieldname": "failed_import_preview",
+   "fieldtype": "HTML",
+   "label": "Failed Import Log"
+  },
+  {
+   "fieldname": "import_log_section",
+   "fieldtype": "Section Break",
+   "label": "Import Log"
+  },
+  {
+   "fieldname": "default_round_off_account",
+   "fieldtype": "Link",
+   "label": "Default Round Off Account",
+   "options": "Account"
+  },
+  {
+   "default": "[]",
+   "fieldname": "fixed_errors_log",
+   "fieldtype": "Code",
+   "hidden": 1,
+   "options": "JSON"
+  },
+  {
+   "fieldname": "fixed_error_log_preview",
+   "fieldtype": "HTML",
+   "label": "Fixed Error Log"
   }
  ],
  "links": [],
- "modified": "2020-04-16 13:03:28.894919",
+ "modified": "2020-04-28 00:29:18.039826",
  "modified_by": "Administrator",
  "module": "ERPNext Integrations",
  "name": "Tally Migration",
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
index 13474e1..462685f 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
@@ -6,6 +6,7 @@
 
 import json
 import re
+import sys
 import traceback
 import zipfile
 from decimal import Decimal
@@ -15,18 +16,34 @@
 import frappe
 from erpnext import encode_company_abbr
 from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
+from erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer import unset_existing_data
+
 from frappe import _
 from frappe.custom.doctype.custom_field.custom_field import create_custom_field
 from frappe.model.document import Document
 from frappe.model.naming import getseries, revert_series_if_last
 from frappe.utils.data import format_datetime
 
-
 PRIMARY_ACCOUNT = "Primary"
 VOUCHER_CHUNK_SIZE = 500
 
 
+@frappe.whitelist()
+def new_doc(document):
+	document = json.loads(document)
+	doctype = document.pop("doctype")
+	document.pop("name", None)
+	doc = frappe.new_doc(doctype)
+	doc.update(document)
+
+	return doc
+
 class TallyMigration(Document):
+	def validate(self):
+		failed_import_log = json.loads(self.failed_import_log)
+		sorted_failed_import_log = sorted(failed_import_log, key=lambda row: row["doc"]["creation"])
+		self.failed_import_log = json.dumps(sorted_failed_import_log)
+
 	def autoname(self):
 		if not self.name:
 			self.name = "Tally Migration on " + format_datetime(self.creation)
@@ -65,9 +82,17 @@
 				"attached_to_name": self.name,
 				"content": json.dumps(value),
 				"is_private": True
-			}).insert()
+			})
+			try:
+				f.insert()
+			except frappe.DuplicateEntryError:
+				pass
 			setattr(self, key, f.file_url)
 
+	def set_account_defaults(self):
+		self.default_cost_center, self.default_round_off_account = frappe.db.get_value("Company", self.erpnext_company, ["cost_center", "round_off_account"])
+		self.default_warehouse = frappe.db.get_value("Stock Settings", "Stock Settings", "default_warehouse")
+
 	def _process_master_data(self):
 		def get_company_name(collection):
 			return collection.find_all("REMOTECMPINFO.LIST")[0].REMOTECMPNAME.string.strip()
@@ -84,7 +109,11 @@
 			children, parents = get_children_and_parent_dict(accounts)
 			group_set =  [acc[1] for acc in accounts if acc[2]]
 			children, customers, suppliers = remove_parties(parents, children, group_set)
-			coa = traverse({}, children, roots, roots, group_set)
+
+			try:
+				coa = traverse({}, children, roots, roots, group_set)
+			except RecursionError:
+				self.log(_("Error occured while parsing Chart of Accounts: Please make sure that no two accounts have the same name"))
 
 			for account in coa:
 				coa[account]["root_type"] = root_type_map[account]
@@ -126,14 +155,18 @@
 		def remove_parties(parents, children, group_set):
 			customers, suppliers = set(), set()
 			for account in parents:
+				found = False
 				if self.tally_creditors_account in parents[account]:
-					children.pop(account, None)
+					found = True
 					if account not in group_set:
 						suppliers.add(account)
-				elif self.tally_debtors_account in parents[account]:
-					children.pop(account, None)
+				if self.tally_debtors_account in parents[account]:
+					found = True
 					if account not in group_set:
 						customers.add(account)
+				if found:
+					children.pop(account, None)
+
 			return children, customers, suppliers
 
 		def traverse(tree, children, accounts, roots, group_set):
@@ -151,6 +184,7 @@
 			parties, addresses = [], []
 			for account in collection.find_all("LEDGER"):
 				party_type = None
+				links = []
 				if account.NAME.string.strip() in customers:
 					party_type = "Customer"
 					parties.append({
@@ -161,7 +195,9 @@
 						"territory": "All Territories",
 						"customer_type": "Individual",
 					})
-				elif account.NAME.string.strip() in suppliers:
+					links.append({"link_doctype": party_type, "link_name": account["NAME"]})
+
+				if account.NAME.string.strip() in suppliers:
 					party_type = "Supplier"
 					parties.append({
 						"doctype": party_type,
@@ -170,6 +206,8 @@
 						"supplier_group": "All Supplier Groups",
 						"supplier_type": "Individual",
 					})
+					links.append({"link_doctype": party_type, "link_name": account["NAME"]})
+
 				if party_type:
 					address = "\n".join([a.string.strip() for a in account.find_all("ADDRESS")])
 					addresses.append({
@@ -183,7 +221,7 @@
 						"mobile": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
 						"phone": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
 						"gstin": account.PARTYGSTIN.string.strip() if account.PARTYGSTIN else None,
-						"links": [{"link_doctype": party_type, "link_name": account["NAME"]}],
+						"links": links
 					})
 			return parties, addresses
 
@@ -242,12 +280,18 @@
 		def create_company_and_coa(coa_file_url):
 			coa_file = frappe.get_doc("File", {"file_url": coa_file_url})
 			frappe.local.flags.ignore_chart_of_accounts = True
-			company = frappe.get_doc({
-				"doctype": "Company",
-				"company_name": self.erpnext_company,
-				"default_currency": "INR",
-				"enable_perpetual_inventory": 0,
-			}).insert()
+
+			try:
+				company = frappe.get_doc({
+					"doctype": "Company",
+					"company_name": self.erpnext_company,
+					"default_currency": "INR",
+					"enable_perpetual_inventory": 0,
+				}).insert()
+			except frappe.DuplicateEntryError:
+				company = frappe.get_doc("Company", self.erpnext_company)
+				unset_existing_data(self.erpnext_company)
+
 			frappe.local.flags.ignore_chart_of_accounts = False
 			create_charts(company.name, custom_chart=json.loads(coa_file.get_content()))
 			company.create_default_warehouses()
@@ -256,36 +300,35 @@
 			parties_file = frappe.get_doc("File", {"file_url": parties_file_url})
 			for party in json.loads(parties_file.get_content()):
 				try:
-					frappe.get_doc(party).insert()
+					party_doc = frappe.get_doc(party)
+					party_doc.insert()
 				except:
-					self.log(party)
+					self.log(party_doc)
 			addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
 			for address in json.loads(addresses_file.get_content()):
 				try:
-					frappe.get_doc(address).insert(ignore_mandatory=True)
+					address_doc = frappe.get_doc(address)
+					address_doc.insert(ignore_mandatory=True)
 				except:
-					try:
-						gstin = address.pop("gstin", None)
-						frappe.get_doc(address).insert(ignore_mandatory=True)
-						self.log({"address": address, "message": "Invalid GSTIN: {}. Address was created without GSTIN".format(gstin)})
-					except:
-						self.log(address)
+					self.log(address_doc)
 
 		def create_items_uoms(items_file_url, uoms_file_url):
 			uoms_file = frappe.get_doc("File", {"file_url": uoms_file_url})
 			for uom in json.loads(uoms_file.get_content()):
 				if not frappe.db.exists(uom):
 					try:
-						frappe.get_doc(uom).insert()
+						uom_doc = frappe.get_doc(uom)
+						uom_doc.insert()
 					except:
-						self.log(uom)
+						self.log(uom_doc)
 
 			items_file = frappe.get_doc("File", {"file_url": items_file_url})
 			for item in json.loads(items_file.get_content()):
 				try:
-					frappe.get_doc(item).insert()
+					item_doc = frappe.get_doc(item)
+					item_doc.insert()
 				except:
-					self.log(item)
+					self.log(item_doc)
 
 		try:
 			self.publish("Import Master Data", _("Creating Company and Importing Chart of Accounts"), 1, 4)
@@ -299,10 +342,13 @@
 
 			self.publish("Import Master Data", _("Done"), 4, 4)
 
+			self.set_account_defaults()
 			self.is_master_data_imported = 1
+			frappe.db.commit()
 
 		except:
 			self.publish("Import Master Data", _("Process Failed"), -1, 5)
+			frappe.db.rollback()
 			self.log()
 
 		finally:
@@ -323,7 +369,9 @@
 					processed_voucher = function(voucher)
 					if processed_voucher:
 						vouchers.append(processed_voucher)
+					frappe.db.commit()
 				except:
+					frappe.db.rollback()
 					self.log(voucher)
 			return vouchers
 
@@ -349,6 +397,7 @@
 			journal_entry = {
 				"doctype": "Journal Entry",
 				"tally_guid": voucher.GUID.string.strip(),
+				"tally_voucher_no": voucher.VOUCHERNUMBER.string.strip() if voucher.VOUCHERNUMBER else "",
 				"posting_date": voucher.DATE.string.strip(),
 				"company": self.erpnext_company,
 				"accounts": accounts,
@@ -377,6 +426,7 @@
 				"doctype": doctype,
 				party_field: voucher.PARTYNAME.string.strip(),
 				"tally_guid": voucher.GUID.string.strip(),
+				"tally_voucher_no": voucher.VOUCHERNUMBER.string.strip() if voucher.VOUCHERNUMBER else "",
 				"posting_date": voucher.DATE.string.strip(),
 				"due_date": voucher.DATE.string.strip(),
 				"items": get_voucher_items(voucher, doctype),
@@ -468,14 +518,21 @@
 				oldest_year = new_year
 
 		def create_custom_fields(doctypes):
-			for doctype in doctypes:
-				df = {
-					"fieldtype": "Data",
-					"fieldname": "tally_guid",
-					"read_only": 1,
-					"label": "Tally GUID"
-				}
-				create_custom_field(doctype, df)
+			tally_guid_df = {
+				"fieldtype": "Data",
+				"fieldname": "tally_guid",
+				"read_only": 1,
+				"label": "Tally GUID"
+			}
+			tally_voucher_no_df = {
+				"fieldtype": "Data",
+				"fieldname": "tally_voucher_no",
+				"read_only": 1,
+				"label": "Tally Voucher Number"
+			}
+			for df in [tally_guid_df, tally_voucher_no_df]:
+				for doctype in doctypes:
+					create_custom_field(doctype, df)
 
 		def create_price_list():
 			frappe.get_doc({
@@ -490,7 +547,7 @@
 		try:
 			frappe.db.set_value("Account", encode_company_abbr(self.tally_creditors_account, self.erpnext_company), "account_type", "Payable")
 			frappe.db.set_value("Account", encode_company_abbr(self.tally_debtors_account, self.erpnext_company), "account_type", "Receivable")
-			frappe.db.set_value("Company", self.erpnext_company, "round_off_account", self.round_off_account)
+			frappe.db.set_value("Company", self.erpnext_company, "round_off_account", self.default_round_off_account)
 
 			vouchers_file = frappe.get_doc("File", {"file_url": self.vouchers})
 			vouchers = json.loads(vouchers_file.get_content())
@@ -521,11 +578,14 @@
 
 		for index, voucher in enumerate(chunk, start=start):
 			try:
-				doc = frappe.get_doc(voucher).insert()
-				doc.submit()
+				voucher_doc = frappe.get_doc(voucher)
+				voucher_doc.insert()
+				voucher_doc.submit()
 				self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
+				frappe.db.commit()
 			except:
-				self.log(voucher)
+				frappe.db.rollback()
+				self.log(voucher_doc)
 
 		if is_last:
 			self.status = ""
@@ -551,9 +611,22 @@
 		frappe.enqueue_doc(self.doctype, self.name, "_import_day_book_data", queue="long", timeout=3600)
 
 	def log(self, data=None):
-		data = data or self.status
-		message = "\n".join(["Data:", json.dumps(data, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()])
-		return frappe.log_error(title="Tally Migration Error", message=message)
+		if isinstance(data, frappe.model.document.Document):
+			if sys.exc_info()[1].__class__ != frappe.DuplicateEntryError:
+				failed_import_log = json.loads(self.failed_import_log)
+				doc = data.as_dict()
+				failed_import_log.append({
+					"doc": doc,
+					"exc": traceback.format_exc()
+				})
+				self.failed_import_log = json.dumps(failed_import_log, separators=(',', ':'))
+				self.save()
+				frappe.db.commit()
+
+		else:
+			data = data or self.status
+			message = "\n".join(["Data:", json.dumps(data, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()])
+			return frappe.log_error(title="Tally Migration Error", message=message)
 
 	def set_status(self, status=""):
 		self.status = status
diff --git a/erpnext/healthcare/dashboard_fixtures.py b/erpnext/healthcare/dashboard_fixtures.py
index 967117d..94668a1 100644
--- a/erpnext/healthcare/dashboard_fixtures.py
+++ b/erpnext/healthcare/dashboard_fixtures.py
@@ -71,7 +71,7 @@
 				"chart_name": _("Department wise Patient Appointments"),
 				"chart_type": "Custom",
 				"source": "Department wise Patient Appointments",
-				"filters_json": json.dumps({}),
+				"filters_json": json.dumps([]),
 				'is_public': 1,
 				"owner": "Administrator",
 				"type": "Bar",
@@ -159,7 +159,7 @@
 				"document_type": "Patient Encounter Symptom",
 				"group_by_type": "Count",
 				"group_by_based_on": "complaint",
-				"filters_json": json.dumps({}),
+				"filters_json": json.dumps([]),
 				'is_public': 1,
 				"owner": "Administrator",
 				"type": "Percentage",
@@ -173,7 +173,7 @@
 				"document_type": "Patient Encounter Diagnosis",
 				"group_by_type": "Count",
 				"group_by_based_on": "diagnosis",
-				"filters_json": json.dumps({}),
+				"filters_json": json.dumps([]),
 				'is_public': 1,
 				"owner": "Administrator",
 				"type": "Percentage",
@@ -229,7 +229,7 @@
 		},
 		{
 			"name": "Appointments to Bill",
-			"label": _("Appointments to Bill"),
+			"label": _("Appointments To Bill"),
 			"function": "Count",
 			"doctype": "Number Card",
 			"document_type": "Patient Appointment",
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
index 60b5313..334b655 100644
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json
@@ -64,7 +64,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Healthcare",
- "modified": "2020-05-19 20:57:22.797267",
+ "modified": "2020-05-28 19:02:28.824995",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Healthcare",
@@ -109,7 +109,7 @@
    "type": "Page"
   },
   {
-   "label": "Healthcare Dashboard",
+   "label": "Dashboard",
    "link_to": "Healthcare",
    "type": "Dashboard"
   }
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index ab161aa..9d7cdc2 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -320,8 +320,7 @@
 		"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
 	],
 	"monthly_long": [
-		"erpnext.accounts.deferred_revenue.convert_deferred_revenue_to_income",
-		"erpnext.accounts.deferred_revenue.convert_deferred_expense_to_expense",
+		"erpnext.accounts.deferred_revenue.process_deferred_accounting",
 		"erpnext.hr.utils.allocate_earned_leaves",
 		"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_demand_loans"
 	]
diff --git a/erpnext/hr/dashboard_fixtures.py b/erpnext/hr/dashboard_fixtures.py
index 004477c..6e042ac 100644
--- a/erpnext/hr/dashboard_fixtures.py
+++ b/erpnext/hr/dashboard_fixtures.py
@@ -143,7 +143,7 @@
 
 	number_cards.append(
 		get_number_cards_doc("Employee", "Employees Left (Last year)", filters_json = json.dumps([
-				["Employee", "modified", "Previous", "1 year"],
+				["Employee", "relieving_date", "Previous", "1 year"],
 				["Employee", "status", "=", "Left"]
 			])
 		)
diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json
index 33132a6..7ac000b 100644
--- a/erpnext/hr/desk_page/hr/hr.json
+++ b/erpnext/hr/desk_page/hr/hr.json
@@ -89,10 +89,11 @@
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "HR",
- "modified": "2020-05-23 12:41:52.543438",
+ "modified": "2020-05-28 13:36:07.710600",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "HR",
@@ -102,6 +103,7 @@
  "pin_to_top": 0,
  "shortcuts": [
   {
+   "color": "#cef6d1",
    "format": "{} Active",
    "label": "Employee",
    "link_to": "Employee",
@@ -109,18 +111,20 @@
    "type": "DocType"
   },
   {
-   "label": "Attendance",
-   "link_to": "Attendance",
-   "stats_filter": "",
-   "type": "DocType"
-  },
-  {
+   "color": "#ffe8cd",
+   "format": "{} Open",
    "label": "Leave Application",
    "link_to": "Leave Application",
    "stats_filter": "{\"status\":\"Open\"}",
    "type": "DocType"
   },
   {
+   "label": "Attendance",
+   "link_to": "Attendance",
+   "stats_filter": "",
+   "type": "DocType"
+  },
+  {
    "label": "Salary Structure",
    "link_to": "Payroll Entry",
    "type": "DocType"
@@ -132,7 +136,7 @@
   },
   {
    "format": "{} Open",
-   "label": "HR Dashboard",
+   "label": "Dashboard",
    "link_to": "Human Resource",
    "stats_filter": "{\n    \"status\": \"Open\"\n}",
    "type": "Dashboard"
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index 1f50e27..15ce468 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -38,6 +38,9 @@
 	},
 
 	validate: function(frm) {
+		if (frm.doc.from_date == frm.doc.to_date && frm.doc.half_day == 1){
+			frm.doc.half_day_date = frm.doc.from_date;
+		}
 		frm.toggle_reqd("half_day_date", frm.doc.half_day == 1);
 	},
 
@@ -67,6 +70,13 @@
 				})
 			);
 			frm.dashboard.show();
+			frm.set_query('leave_type', function(){
+				return {
+					filters : [
+						['leave_type_name', 'in', Object.keys(leave_details)]
+					]
+				}
+			});
 		}
 	},
 
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 4499fa6..c2b4cdf 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -33,6 +33,7 @@
 		self.validate_block_days()
 		self.validate_salary_processed_days()
 		self.validate_attendance()
+		self.set_half_day_date()
 		if frappe.db.get_value("Leave Type", self.leave_type, 'is_optional_leave'):
 			self.validate_optional_leave()
 		self.validate_applicable_after()
@@ -290,6 +291,10 @@
 				frappe.throw(_("{0} is not in Optional Holiday List").format(formatdate(day)), NotAnOptionalHoliday)
 			day = add_days(day, 1)
 
+	def set_half_day_date(self):
+		if self.from_date == self.to_date and self.half_day == 1:
+			self.half_day_date = self.from_date
+
 	def notify_employee(self):
 		employee = frappe.get_doc("Employee", self.employee)
 		if not employee.user_id:
diff --git a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
index 295f3b4..d30e3b9 100644
--- a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
+++ b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
@@ -1,5 +1,5 @@
 
-{% if data %}
+{% if not jQuery.isEmptyObject(data) %}
 <h5 style="margin-top: 20px;"> {{ __("Allocated Leaves") }} </h5>
 <table class="table table-bordered small">
 	<thead>
@@ -11,7 +11,6 @@
 			<th style="width: 16%" class="text-right">{{ __("Pending Leaves") }}</th>
 			<th style="width: 16%" class="text-right">{{ __("Available Leaves") }}</th>
 		</tr>
-
 	</thead>
 	<tbody>
 		{% for(const [key, value] of Object.entries(data)) { %}
@@ -26,6 +25,6 @@
 		{% } %}
 	</tbody>
 </table>
-{% } else { %}
+{% else %}
 <p style="margin-top: 30px;"> No Leaves have been allocated. </p>
-{% } %}
\ No newline at end of file
+{% endif %}
\ 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
index 208e394..32472b4 100644
--- a/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
+++ b/erpnext/hr/onboarding_step/create_holiday_list/create_holiday_list.json
@@ -1,6 +1,6 @@
 {
  "action": "Create Entry",
- "creation": "2020-05-27 11:47:34.700174",
+ "creation": "2020-05-28 11:47:34.700174",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
@@ -14,6 +14,6 @@
  "owner": "Administrator",
  "reference_document": "Holiday List",
  "show_full_form": 1,
- "title": "Create Holiday list",
+ "title": "Create Holiday List",
  "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
index a8c96fb..0a1d0ba 100644
--- a/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
+++ b/erpnext/hr/onboarding_step/hr_settings/hr_settings.json
@@ -1,6 +1,6 @@
 {
  "action": "Update Settings",
- "creation": "2020-05-14 13:13:52.427711",
+ "creation": "2020-05-28 13:13:52.427711",
  "docstatus": 0,
  "doctype": "Onboarding Step",
  "idx": 0,
@@ -14,6 +14,6 @@
  "owner": "Administrator",
  "reference_document": "HR Settings",
  "show_full_form": 0,
- "title": "HR settings",
+ "title": "HR Settings",
  "validate_action": 0
 }
\ No newline at end of file
diff --git a/erpnext/loan_management/desk_page/loan_management/loan_management.json b/erpnext/loan_management/desk_page/loan/loan.json
similarity index 75%
rename from erpnext/loan_management/desk_page/loan_management/loan_management.json
rename to erpnext/loan_management/desk_page/loan/loan.json
index d2a1763..48193b0 100644
--- a/erpnext/loan_management/desk_page/loan_management/loan_management.json
+++ b/erpnext/loan_management/desk_page/loan/loan.json
@@ -23,7 +23,7 @@
   {
    "hidden": 0,
    "label": "Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Loan Repayment\"\n        ],\n        \"doctype\": \"Loan Repayment\",\n        \"incomplete_dependencies\": [\n            \"Loan Repayment\"\n        ],\n        \"is_query_report\": true,\n        \"label\": \"Loan Repayment and Closure\",\n        \"name\": \"Loan Repayment and Closure\",\n        \"route\": \"#query-report/Loan Repayment and Closure\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Loan Security Pledge\"\n        ],\n        \"doctype\": \"Loan Security Pledge\",\n        \"incomplete_dependencies\": [\n            \"Loan Security Pledge\"\n        ],\n        \"is_query_report\": true,\n        \"label\": \"Loan Security Status\",\n        \"name\": \"Loan Security Status\",\n        \"route\": \"#query-report/Loan Security Status\",\n        \"type\": \"report\"\n    }\n]"
+   "links": "[\n    {\n        \"doctype\": \"Loan Repayment\",\n        \"is_query_report\": true,\n        \"label\": \"Loan Repayment and Closure\",\n        \"name\": \"Loan Repayment and Closure\",\n        \"route\": \"#query-report/Loan Repayment and Closure\",\n        \"type\": \"report\"\n    },\n    {\n        \"doctype\": \"Loan Security Pledge\",\n        \"is_query_report\": true,\n        \"label\": \"Loan Security Status\",\n        \"name\": \"Loan Security Status\",\n        \"route\": \"#query-report/Loan Security Status\",\n        \"type\": \"report\"\n    }\n]"
   }
  ],
  "category": "Modules",
@@ -37,7 +37,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Loan",
- "modified": "2020-05-22 11:28:51.380509",
+ "modified": "2020-06-07 19:42:14.947902",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan",
@@ -46,8 +46,11 @@
  "pin_to_top": 0,
  "shortcuts": [
   {
+   "color": "#ffe8cd",
+   "format": "{} Open",
    "label": "Loan Application",
    "link_to": "Loan Application",
+   "stats_filter": "{ \"status\": \"Open\" }",
    "type": "DocType"
   },
   {
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index c9e36a8..d44088b 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -27,6 +27,7 @@
 
 	def on_cancel(self):
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def set_missing_values(self):
 		if not self.disbursement_date:
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index 094b9c6..e6ceb55 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -31,6 +31,7 @@
 			self.update_is_accrued()
 
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def update_is_accrued(self):
 		frappe.db.set_value('Repayment Schedule', self.repayment_schedule_name, 'is_accrued', 0)
@@ -176,21 +177,23 @@
 	return term_loans
 
 def make_loan_interest_accrual_entry(args):
-		loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
-		loan_interest_accrual.loan = args.loan
-		loan_interest_accrual.applicant_type = args.applicant_type
-		loan_interest_accrual.applicant = args.applicant
-		loan_interest_accrual.interest_income_account = args.interest_income_account
-		loan_interest_accrual.loan_account = args.loan_account
-		loan_interest_accrual.pending_principal_amount = flt(args.pending_principal_amount, 2)
-		loan_interest_accrual.interest_amount = flt(args.interest_amount, 2)
-		loan_interest_accrual.posting_date = args.posting_date or nowdate()
-		loan_interest_accrual.process_loan_interest_accrual = args.process_loan_interest
-		loan_interest_accrual.repayment_schedule_name = args.repayment_schedule_name
-		loan_interest_accrual.payable_principal_amount = args.payable_principal
+	precision = cint(frappe.db.get_default("currency_precision")) or 2
 
-		loan_interest_accrual.save()
-		loan_interest_accrual.submit()
+	loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
+	loan_interest_accrual.loan = args.loan
+	loan_interest_accrual.applicant_type = args.applicant_type
+	loan_interest_accrual.applicant = args.applicant
+	loan_interest_accrual.interest_income_account = args.interest_income_account
+	loan_interest_accrual.loan_account = args.loan_account
+	loan_interest_accrual.pending_principal_amount = flt(args.pending_principal_amount, precision)
+	loan_interest_accrual.interest_amount = flt(args.interest_amount, precision)
+	loan_interest_accrual.posting_date = args.posting_date or nowdate()
+	loan_interest_accrual.process_loan_interest_accrual = args.process_loan_interest
+	loan_interest_accrual.repayment_schedule_name = args.repayment_schedule_name
+	loan_interest_accrual.payable_principal_amount = args.payable_principal
+
+	loan_interest_accrual.save()
+	loan_interest_accrual.submit()
 
 
 def get_no_of_days_for_interest_accural(loan, posting_date):
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index 2ab668a..c28994e 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -6,7 +6,7 @@
 import frappe, erpnext
 import json
 from frappe import _
-from frappe.utils import flt, getdate
+from frappe.utils import flt, getdate, cint
 from six import iteritems
 from frappe.model.document import Document
 from frappe.utils import date_diff, add_days, getdate, add_months, get_first_day, get_datetime
@@ -29,8 +29,11 @@
 	def on_cancel(self):
 		self.mark_as_unpaid()
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def set_missing_values(self, amounts):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		if not self.posting_date:
 			self.posting_date = get_datetime()
 
@@ -38,24 +41,26 @@
 			self.cost_center = erpnext.get_default_cost_center(self.company)
 
 		if not self.interest_payable:
-			self.interest_payable = flt(amounts['interest_amount'], 2)
+			self.interest_payable = flt(amounts['interest_amount'], precision)
 
 		if not self.penalty_amount:
-			self.penalty_amount = flt(amounts['penalty_amount'], 2)
+			self.penalty_amount = flt(amounts['penalty_amount'], precision)
 
 		if not self.pending_principal_amount:
-			self.pending_principal_amount = flt(amounts['pending_principal_amount'], 2)
+			self.pending_principal_amount = flt(amounts['pending_principal_amount'], precision)
 
 		if not self.payable_principal_amount and self.is_term_loan:
-			self.payable_principal_amount = flt(amounts['payable_principal_amount'], 2)
+			self.payable_principal_amount = flt(amounts['payable_principal_amount'], precision)
 
 		if not self.payable_amount:
-			self.payable_amount = flt(amounts['payable_amount'], 2)
+			self.payable_amount = flt(amounts['payable_amount'], precision)
 
 		if amounts.get('due_date'):
 			self.due_date = amounts.get('due_date')
 
 	def validate_amount(self):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		if not self.amount_paid:
 			frappe.throw(_("Amount paid cannot be zero"))
 
@@ -63,11 +68,13 @@
 			msg = _("Paid amount cannot be less than {0}").format(self.penalty_amount)
 			frappe.throw(msg)
 
-		if self.payment_type == "Loan Closure" and flt(self.amount_paid, 2) < flt(self.payable_amount, 2):
+		if self.payment_type == "Loan Closure" and flt(self.amount_paid, precision) < flt(self.payable_amount, precision):
 			msg = _("Amount of {0} is required for Loan closure").format(self.payable_amount)
 			frappe.throw(msg)
 
 	def update_paid_amount(self):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		loan = frappe.get_doc("Loan", self.against_loan)
 
 		for payment in self.repayment_details:
@@ -75,9 +82,9 @@
 				SET paid_principal_amount = `paid_principal_amount` + %s,
 					paid_interest_amount = `paid_interest_amount` + %s
 				WHERE name = %s""",
-				(flt(payment.paid_principal_amount), flt(payment.paid_interest_amount), payment.loan_interest_accrual))
+				(flt(payment.paid_principal_amount, precision), flt(payment.paid_interest_amount, precision), payment.loan_interest_accrual))
 
-		if flt(loan.total_principal_paid + self.principal_amount_paid, 2) >= flt(loan.total_payment, 2):
+		if flt(loan.total_principal_paid + self.principal_amount_paid, precision) >= flt(loan.total_payment, precision):
 			if loan.is_secured_loan:
 				frappe.db.set_value("Loan", self.against_loan, "status", "Loan Closure Requested")
 			else:
@@ -253,6 +260,7 @@
 # So it pulls all the unpaid Loan Interest Accrual Entries and calculates the penalty if applicable
 
 def get_amounts(amounts, against_loan, posting_date, payment_type):
+	precision = cint(frappe.db.get_default("currency_precision")) or 2
 
 	against_loan_doc = frappe.get_doc("Loan", against_loan)
 	loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
@@ -282,8 +290,8 @@
 		payable_principal_amount += entry.payable_principal_amount
 
 		pending_accrual_entries.setdefault(entry.name, {
-			'interest_amount': flt(entry.interest_amount),
-			'payable_principal_amount': flt(entry.payable_principal_amount)
+			'interest_amount': flt(entry.interest_amount, precision),
+			'payable_principal_amount': flt(entry.payable_principal_amount, precision)
 		})
 
 		if not final_due_date:
@@ -301,11 +309,11 @@
 		per_day_interest = (payable_principal_amount * (loan_type_details.rate_of_interest / 100))/365
 		total_pending_interest += (pending_days * per_day_interest)
 
-	amounts["pending_principal_amount"] = pending_principal_amount
-	amounts["payable_principal_amount"] = payable_principal_amount
-	amounts["interest_amount"] = total_pending_interest
-	amounts["penalty_amount"] = penalty_amount
-	amounts["payable_amount"] = payable_principal_amount + total_pending_interest + penalty_amount
+	amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
+	amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
+	amounts["interest_amount"] = flt(total_pending_interest, precision)
+	amounts["penalty_amount"] = flt(penalty_amount, precision)
+	amounts["payable_amount"] = flt(payable_principal_amount + total_pending_interest + penalty_amount, precision)
 	amounts["pending_accrual_entries"] = pending_accrual_entries
 
 	if final_due_date:
diff --git a/erpnext/loan_management/doctype/loan_type/loan_type.json b/erpnext/loan_management/doctype/loan_type/loan_type.json
index 51c5cb9..1dd3710 100644
--- a/erpnext/loan_management/doctype/loan_type/loan_type.json
+++ b/erpnext/loan_management/doctype/loan_type/loan_type.json
@@ -41,6 +41,7 @@
    "options": "Company:company:default_currency"
   },
   {
+   "default": "0",
    "fieldname": "rate_of_interest",
    "fieldtype": "Percent",
    "label": "Rate of Interest (%) Yearly",
@@ -143,7 +144,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-15 00:24:43.259963",
+ "modified": "2020-06-07 18:55:59.346292",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Type",
diff --git a/erpnext/loan_management/report/loan_security_status/loan_security_status.py b/erpnext/loan_management/report/loan_security_status/loan_security_status.py
index ea6a2ee6..1951855 100644
--- a/erpnext/loan_management/report/loan_security_status/loan_security_status.py
+++ b/erpnext/loan_management/report/loan_security_status/loan_security_status.py
@@ -76,7 +76,8 @@
 			"fieldtype": "Link",
 			"fieldname": "currency",
 			"options": "Currency",
-			"width": 50
+			"width": 50,
+			"hidden": 1
 		}
 	]
 
@@ -84,17 +85,13 @@
 
 def get_data(filters):
 
-	loan_security_price_map = frappe._dict(frappe.get_all("Loan Security",
-		fields=["name", "loan_security_price"], as_list=1
-	))
-
 	data = []
 	conditions = get_conditions(filters)
 
 	loan_security_pledges = frappe.db.sql("""
 		SELECT
 			p.name, p.applicant, p.loan, p.status, p.pledge_time,
-			c.loan_security, c.qty
+			c.loan_security, c.qty, c.loan_security_price, c.amount
 		FROM
 			`tabLoan Security Pledge` p, `tabPledge` c
 		WHERE
@@ -115,8 +112,8 @@
 		row["pledge_time"] = pledge.pledge_time
 		row["loan_security"] = pledge.loan_security
 		row["qty"] = pledge.qty
-		row["loan_security_price"] = loan_security_price_map.get(pledge.loan_security)
-		row["loan_security_value"] = row["loan_security_price"] * pledge.qty
+		row["loan_security_price"] = pledge.loan_security_price
+		row["loan_security_value"] = pledge.amount
 		row["currency"] = default_currency
 
 		data.append(row)
diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
index f2e07bf..763f533 100644
--- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
+++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
@@ -47,7 +47,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Manufacturing",
- "modified": "2020-05-20 11:50:20.029056",
+ "modified": "2020-05-28 13:54:02.048419",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Manufacturing",
@@ -58,6 +58,7 @@
  "restrict_to_domain": "Manufacturing",
  "shortcuts": [
   {
+   "color": "#cef6d1",
    "format": "{} Active",
    "label": "Item",
    "link_to": "Item",
@@ -66,6 +67,7 @@
    "type": "DocType"
   },
   {
+   "color": "#cef6d1",
    "format": "{} Active",
    "label": "BOM",
    "link_to": "BOM",
@@ -74,6 +76,7 @@
    "type": "DocType"
   },
   {
+   "color": "#ffe8cd",
    "format": "{} Open",
    "label": "Work Order",
    "link_to": "Work Order",
@@ -82,6 +85,7 @@
    "type": "DocType"
   },
   {
+   "color": "#ffe8cd",
    "format": "{} Open",
    "label": "Production Plan",
    "link_to": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 1bdac57..2543eec 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -112,8 +112,15 @@
 		if self.routing:
 			self.set("operations", [])
 			for d in frappe.get_all("BOM Operation", fields = ["*"],
-				filters = {'parenttype': 'Routing', 'parent': self.routing}):
-				child = self.append('operations', d)
+				filters = {'parenttype': 'Routing', 'parent': self.routing}, order_by="idx"):
+				child = self.append('operations', {
+					"operation": d.operation,
+					"workstation": d.workstation,
+					"description": d.description,
+					"time_in_mins": d.time_in_mins,
+					"batch_size": d.batch_size,
+					"idx": d.idx
+				})
 				child.hour_rate = flt(d.hour_rate / self.conversion_rate, 2)
 
 	def set_bom_material_details(self):
diff --git a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
index cac8067..2ca9f16 100644
--- a/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
+++ b/erpnext/manufacturing/report/exponential_smoothing_forecasting/exponential_smoothing_forecasting.py
@@ -217,6 +217,8 @@
 		}
 
 	def get_summary_data(self):
+		if not self.data: return
+
 		return [
 			{
 				"value": sum(self.total_demand),
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
index 33953b1..bd68db1 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
@@ -41,7 +41,7 @@
 			reqd: 1
 		},
 		{
-			label: __("To Posting Datetime"),
+			label: __("To Posting Date"),
 			fieldname:"to_date",
 			fieldtype: "Date",
 			default: frappe.defaults.get_user_default("year_end_date"),
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.js b/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
index 2292865..eb23f17 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
@@ -41,7 +41,7 @@
 			reqd: 1
 		},
 		{
-			label: __("To Posting Datetime"),
+			label: __("To Posting Date"),
 			fieldname:"to_date",
 			fieldtype: "Date",
 			default: frappe.defaults.get_user_default("year_end_date"),
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index df19995..4b93242 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -64,9 +64,21 @@
 				}, order_by="creation desc")
 	return frappe.get_doc("Member", members[0]['name'])
 
+def verify_signature(data):
+	signature = frappe.request.headers.get('X-Razorpay-Signature')
+
+	settings = frappe.get_doc("Membership Settings")
+	key = settings.get_webhook_secret()
+
+	controller = frappe.get_doc("Razorpay Settings")
+
+	controller.verify_signature(data, signature, key)
+
+
 @frappe.whitelist(allow_guest=True)
 def trigger_razorpay_subscription(*args, **kwargs):
 	data = frappe.request.get_data()
+	verify_signature(data)
 
 	if isinstance(data, six.string_types):
 		data = json.loads(data)
@@ -113,7 +125,6 @@
 	return True
 
 
-
 def notify_failure(log):
 	try:
 		content = """Dear System Manager,
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.js b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
index c01a0b2..8c0e3a4 100644
--- a/erpnext/non_profit/doctype/membership_settings/membership_settings.js
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
@@ -1,8 +1,30 @@
 // Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on('Membership Settings', {
+frappe.ui.form.on("Membership Settings", {
 	refresh: function(frm) {
+		if (frm.doc.webhook_secret) {
+			frm.add_custom_button(__("Revoke <Key></Key>"), () => {
+				frm.call("revoke_key").then(() => {
+					frm.refresh();
+				})
+			});
+		}
+		frm.trigger("add_generate_button");
+	},
 
-	}
+	add_generate_button: function(frm) {
+		let label;
+
+		if (frm.doc.webhook_secret) {
+			label = __("Regenerate Webhook Secret");
+		} else {
+			label = __("Generate Webhook Secret");
+		}
+		frm.add_custom_button(label, () => {
+			frm.call("generate_webhook_key").then(() => {
+				frm.refresh();
+			});
+		});
+	},
 });
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
index 56b8eac..52b9d01 100644
--- a/erpnext/non_profit/doctype/membership_settings/membership_settings.json
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
@@ -8,7 +8,8 @@
   "enable_razorpay",
   "razorpay_settings_section",
   "billing_cycle",
-  "billing_frequency"
+  "billing_frequency",
+  "webhook_secret"
  ],
  "fields": [
   {
@@ -34,11 +35,17 @@
    "fieldname": "billing_frequency",
    "fieldtype": "Int",
    "label": "Billing Frequency"
+  },
+  {
+   "fieldname": "webhook_secret",
+   "fieldtype": "Password",
+   "label": "Webhook Secret",
+   "read_only": 1
   }
  ],
  "issingle": 1,
  "links": [],
- "modified": "2020-04-07 18:42:51.496807",
+ "modified": "2020-05-22 12:38:27.103759",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Membership Settings",
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.py b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
index 2b8e37f..f3b2eee 100644
--- a/erpnext/non_profit/doctype/membership_settings/membership_settings.py
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
@@ -4,11 +4,27 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.integrations.utils import get_payment_gateway_controller
 from frappe.model.document import Document
 
 class MembershipSettings(Document):
-	pass
+	def generate_webhook_key(self):
+		key = frappe.generate_hash(length=20)
+		self.webhook_secret = key
+		self.save()
+
+		frappe.msgprint(
+			_("Here is your webhook secret, this will be shown to you only once.") + "<br><br>" + key,
+			_("Webhook Secret")
+		);
+
+	def revoke_key(self):
+		self.webhook_secret = None;
+		self.save()
+
+	def get_webhook_secret(self):
+		return self.get_password(fieldname="webhook_secret", raise_exception=False)
 
 @frappe.whitelist()
 def get_plans_for_membership(*args, **kwargs):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b0b224f..b0421f4 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -694,3 +694,4 @@
 execute:frappe.rename_doc("Desk Page", "Loan Management", "Loan", force=True)
 erpnext.patches.v12_0.update_uom_conversion_factor
 erpnext.patches.v13_0.delete_old_purchase_reports
+erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py
index 3c9758e..1ddbae6 100644
--- a/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py
+++ b/erpnext/patches/v12_0/move_bank_account_swift_number_to_bank.py
@@ -4,7 +4,7 @@
 def execute():
 	frappe.reload_doc('accounts', 'doctype', 'bank', force=1)
 
-	if frappe.db.table_exists('Bank') and frappe.db.table_exists('Bank Account'):
+	if frappe.db.table_exists('Bank') and frappe.db.table_exists('Bank Account') and frappe.db.has_column('Bank Account', 'swift_number'):
 		frappe.db.sql("""
 			UPDATE `tabBank` b, `tabBank Account` ba
 			SET b.swift_number = ba.swift_number, b.branch_code = ba.branch_code
@@ -12,4 +12,4 @@
 		""")
 
 	frappe.reload_doc('accounts', 'doctype', 'bank_account')
-	frappe.reload_doc('accounts', 'doctype', 'payment_request')
\ No newline at end of file
+	frappe.reload_doc('accounts', 'doctype', 'payment_request')
diff --git a/erpnext/patches/v12_0/rename_bank_reconciliation.py b/erpnext/patches/v12_0/rename_bank_reconciliation.py
index eda47a9..2efa854 100644
--- a/erpnext/patches/v12_0/rename_bank_reconciliation.py
+++ b/erpnext/patches/v12_0/rename_bank_reconciliation.py
@@ -8,9 +8,6 @@
 	if frappe.db.table_exists("Bank Reconciliation"):
 		frappe.rename_doc('DocType', 'Bank Reconciliation', 'Bank Clearance', force=True)
 		frappe.reload_doc('Accounts', 'doctype', 'Bank Clearance')
-		
+
 		frappe.rename_doc('DocType', 'Bank Reconciliation Detail', 'Bank Clearance Detail', force=True)
 		frappe.reload_doc('Accounts', 'doctype', 'Bank Clearance Detail')
-		
-		frappe.delete_doc("DocType", "Bank Reconciliation")
-		frappe.delete_doc("DocType", "Bank Reconciliation Detail")
diff --git a/erpnext/patches/v12_0/set_italian_import_supplier_invoice_permissions.py b/erpnext/patches/v12_0/set_italian_import_supplier_invoice_permissions.py
new file mode 100644
index 0000000..a6011c4
--- /dev/null
+++ b/erpnext/patches/v12_0/set_italian_import_supplier_invoice_permissions.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from erpnext.regional.italy.setup import add_permissions
+
+def execute():
+	countries = frappe.get_all("Company", fields="country")
+	countries = [country["country"] for country in countries]
+	if "Italy" in countries:
+		add_permissions()
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py b/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
index 6f843cd..52c9a2d 100644
--- a/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
+++ b/erpnext/patches/v12_0/set_purchase_receipt_delivery_note_detail.py
@@ -64,11 +64,13 @@
 
 		return_document_map = make_return_document_map(doctype, return_document_map)
 
+		count = 0
+
 		#iterate through original documents and its return documents
 		for docname in return_document_map:
-			doc_items = frappe.get_doc(doctype, docname).get("items")
+			doc_items = frappe.get_cached_doc(doctype, docname).get("items")
 			for return_doc in return_document_map[docname]:
-				return_doc_items = frappe.get_doc(doctype, return_doc).get("items")
+				return_doc_items = frappe.get_cached_doc(doctype, return_doc).get("items")
 
 				#iterate through return document items and original document items for mapping
 				for return_item in return_doc_items:
@@ -80,9 +82,11 @@
 						else:
 							continue
 
+			# commit after every 100 sql updates
+			count += 1
+			if count%100 == 0:
+				frappe.db.commit()
+
 	set_document_detail_in_return_document("Purchase Receipt")
 	set_document_detail_in_return_document("Delivery Note")
 	frappe.db.commit()
-
-
-
diff --git a/erpnext/patches/v13_0/delete_old_purchase_reports.py b/erpnext/patches/v13_0/delete_old_purchase_reports.py
index 8271d2e..8bdc07e 100644
--- a/erpnext/patches/v13_0/delete_old_purchase_reports.py
+++ b/erpnext/patches/v13_0/delete_old_purchase_reports.py
@@ -12,4 +12,12 @@
 
 	for report in reports_to_delete:
 		if frappe.db.exists("Report", report):
-			frappe.delete_doc("Report", report)
\ No newline at end of file
+			delete_auto_email_reports(report)
+
+			frappe.delete_doc("Report", report)
+
+def delete_auto_email_reports(report):
+	""" Check for one or multiple Auto Email Reports and delete """
+	auto_email_reports = frappe.db.get_values("Auto Email Report", {"report": report}, ["name"])
+	for auto_email_report in auto_email_reports:
+		frappe.delete_doc("Auto Email Report", auto_email_report[0])
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
index ec94cd0..5ade8ca 100644
--- a/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
+++ b/erpnext/patches/v13_0/move_tax_slabs_from_payroll_period_to_income_tax_slab.py
@@ -14,15 +14,21 @@
 		frappe.reload_doc("hr", "doctype", doctype)
 
 
+	standard_tax_exemption_amount_exists = frappe.db.has_column("Payroll Period", "standard_tax_exemption_amount")
+
+	select_fields = "name, start_date, end_date"
+	if standard_tax_exemption_amount_exists:
+		select_fields = "name, start_date, end_date, standard_tax_exemption_amount"
+
 	for company in frappe.get_all("Company"):
 		payroll_periods =  frappe.db.sql("""
 			SELECT
-				name, start_date, end_date, standard_tax_exemption_amount
+				{0}
 			FROM
 				`tabPayroll Period`
 			WHERE company=%s
 			ORDER BY start_date DESC
-		""", company.name, as_dict = 1)
+		""".format(select_fields), company.name, as_dict = 1)
 			
 		for i, period in enumerate(payroll_periods):
 			income_tax_slab = frappe.new_doc("Income Tax Slab")
@@ -36,7 +42,8 @@
 			income_tax_slab.effective_from = period.start_date
 			income_tax_slab.company = company.name
 			income_tax_slab.allow_tax_exemption = 1
-			income_tax_slab.standard_tax_exemption_amount = period.standard_tax_exemption_amount
+			if standard_tax_exemption_amount_exists:
+				income_tax_slab.standard_tax_exemption_amount = period.standard_tax_exemption_amount
 
 			income_tax_slab.flags.ignore_mandatory = True
 			income_tax_slab.submit()
diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json
index fdbe13b..d91fe53 100644
--- a/erpnext/projects/desk_page/projects/projects.json
+++ b/erpnext/projects/desk_page/projects/projects.json
@@ -33,7 +33,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Projects",
- "modified": "2020-05-19 21:09:52.031828",
+ "modified": "2020-05-28 13:38:19.934937",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Projects",
@@ -42,7 +42,7 @@
  "pin_to_top": 0,
  "shortcuts": [
   {
-   "color": "#4d4da8",
+   "color": "#cef6d1",
    "format": "{} Assigned",
    "label": "Task",
    "link_to": "Task",
@@ -50,7 +50,7 @@
    "type": "DocType"
   },
   {
-   "color": "#4d4da8",
+   "color": "#ffe8cd",
    "format": "{} Open",
    "label": "Project",
    "link_to": "Project",
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 524a958..9421668 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -917,7 +917,7 @@
 
 	shipping_rule: function() {
 		var me = this;
-		if(this.frm.doc.shipping_rule && this.frm.doc.shipping_address) {
+		if(this.frm.doc.shipping_rule) {
 			return this.frm.call({
 				doc: this.frm.doc,
 				method: "apply_shipping_rule",
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index cf98b75..d89d471 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -47,6 +47,16 @@
 		// dropdown for links to other financial statements
 		erpnext.financial_statements.filters = get_filters()
 
+		let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
+
+		frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
+			var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
+			frappe.query_report.set_filter_value({
+				period_start_date: fy.year_start_date,
+				period_end_date: fy.year_end_date
+			});
+		});
+
 		report.page.add_inner_button(__("Balance Sheet"), function() {
 			var filters = report.get_values();
 			frappe.set_route('query-report', 'Balance Sheet', {company: filters.company});
@@ -99,7 +109,6 @@
 			"fieldname":"period_start_date",
 			"label": __("Start Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.nowdate(),
 			"hidden": 1,
 			"reqd": 1
 		},
@@ -107,7 +116,6 @@
 			"fieldname":"period_end_date",
 			"label": __("End Date"),
 			"fieldtype": "Date",
-			"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
 			"hidden": 1,
 			"reqd": 1
 		},
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
index 59e955c..c1680c4 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "creation": "2019-10-15 12:33:21.845329",
  "doctype": "DocType",
  "editable_grid": 1,
@@ -92,8 +91,7 @@
    "label": "Upload XML Invoices"
   }
  ],
- "links": [],
- "modified": "2019-12-10 16:37:26.793398",
+ "modified": "2020-05-25 21:32:49.064579",
  "modified_by": "Administrator",
  "module": "Regional",
  "name": "Import Supplier Invoice",
diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
index 6b9567c..31a7545 100644
--- a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
+++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
@@ -64,7 +64,8 @@
 				"buying_price_list": self.default_buying_price_list
 			}
 
-			if not invoices_args.get("invoice_no", ''): return
+			if not invoices_args.get("bill_no", ''):
+				frappe.throw(_("Numero has not set in the XML file"))
 
 			supp_dict = get_supplier_details(file_content)
 			invoices_args["destination_code"] = get_destination_code_from_file(file_content)
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 732780a..3085a31 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -615,8 +615,9 @@
 		data.transDocDate = frappe.utils.formatdate(doc.lr_date, 'dd/mm/yyyy')
 
 	if doc.gst_transporter_id:
-		validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
-		data.transporterId  = doc.gst_transporter_id
+		if doc.gst_transporter_id[0:2] != "88":
+			validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
+		data.transporterId = doc.gst_transporter_id
 
 	return data
 
diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py
index 2d0ad66..6ab7341 100644
--- a/erpnext/regional/italy/setup.py
+++ b/erpnext/regional/italy/setup.py
@@ -7,11 +7,13 @@
 import frappe
 from frappe import _
 from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+from frappe.permissions import add_permission, update_permission_property
 from erpnext.regional.italy import fiscal_regimes, tax_exemption_reasons, mode_of_payment_codes, vat_collectability_options
 
 def setup(company=None, patch=True):
 	make_custom_fields()
 	setup_report()
+	add_permissions()
 
 def make_custom_fields(update=True):
 	invoice_item_fields = [
@@ -200,3 +202,21 @@
 				dict(role='Accounts Manager')
 			]
 		)).insert()
+
+def add_permissions():
+	doctype = 'Import Supplier Invoice'
+	add_permission(doctype, 'All', 0)
+
+	for role in ('Accounts Manager', 'Accounts User','Purchase User', 'Auditor'):
+		add_permission(doctype, role, 0)
+		update_permission_property(doctype, role, 0, 'print', 1)
+		update_permission_property(doctype, role, 0, 'report', 1)
+
+		if role in ('Accounts Manager', 'Accounts User'):
+			update_permission_property(doctype, role, 0, 'write', 1)
+			update_permission_property(doctype, role, 0, 'create', 1)
+
+	update_permission_property(doctype, 'Accounts Manager', 0, 'delete', 1)
+	add_permission(doctype, 'Accounts Manager', 1)
+	update_permission_property(doctype, 'Accounts Manager', 1, 'write', 1)
+	update_permission_property(doctype, 'Accounts Manager', 1, 'create', 1)
\ No newline at end of file
diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json
new file mode 100644
index 0000000..9ec6343
--- /dev/null
+++ b/erpnext/selling/desk_page/selling/selling.json
@@ -0,0 +1,94 @@
+{
+ "cards": [
+  {
+   "hidden": 0,
+   "label": "Items and Pricing",
+   "links": "[\n    {\n        \"description\": \"All Products or Services.\",\n        \"label\": \"Item\",\n        \"name\": \"Item\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Price List\"\n        ],\n        \"description\": \"Multiple Item prices.\",\n        \"label\": \"Item Price\",\n        \"name\": \"Item Price\",\n        \"onboard\": 1,\n        \"route\": \"#Report/Item Price\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Price List master.\",\n        \"label\": \"Price List\",\n        \"name\": \"Price List\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Tree of Item Groups.\",\n        \"icon\": \"fa fa-sitemap\",\n        \"label\": \"Item Group\",\n        \"link\": \"Tree/Item Group\",\n        \"name\": \"Item Group\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"description\": \"Bundle items at time of sale.\",\n        \"label\": \"Product Bundle\",\n        \"name\": \"Product Bundle\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Rules for applying different promotional schemes.\",\n        \"label\": \"Promotional Scheme\",\n        \"name\": \"Promotional Scheme\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"description\": \"Rules for applying pricing and discount.\",\n        \"label\": \"Pricing Rule\",\n        \"name\": \"Pricing Rule\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Rules for adding shipping costs.\",\n        \"label\": \"Shipping Rule\",\n        \"name\": \"Shipping Rule\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Define coupon codes.\",\n        \"label\": \"Coupon Code\",\n        \"name\": \"Coupon Code\",\n        \"type\": \"doctype\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Settings",
+   "links": "[\n    {\n        \"description\": \"Default settings for selling transactions.\",\n        \"label\": \"Selling Settings\",\n        \"name\": \"Selling Settings\",\n        \"settings\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Template of terms or contract.\",\n        \"label\": \"Terms and Conditions Template\",\n        \"name\": \"Terms and Conditions\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Tax template for selling transactions.\",\n        \"label\": \"Sales Taxes and Charges Template\",\n        \"name\": \"Sales Taxes and Charges Template\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Track Leads by Lead Source.\",\n        \"label\": \"Lead Source\",\n        \"name\": \"Lead Source\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Manage Customer Group Tree.\",\n        \"icon\": \"fa fa-sitemap\",\n        \"label\": \"Customer Group\",\n        \"link\": \"Tree/Customer Group\",\n        \"name\": \"Customer Group\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"All Contacts.\",\n        \"label\": \"Contact\",\n        \"name\": \"Contact\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"All Addresses.\",\n        \"label\": \"Address\",\n        \"name\": \"Address\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Manage Territory Tree.\",\n        \"icon\": \"fa fa-sitemap\",\n        \"label\": \"Territory\",\n        \"link\": \"Tree/Territory\",\n        \"name\": \"Territory\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Sales campaigns.\",\n        \"label\": \"Campaign\",\n        \"name\": \"Campaign\",\n        \"type\": \"doctype\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Other Reports",
+   "links": "[\n    {\n        \"dependencies\": [\n            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Lead Details\",\n        \"name\": \"Lead Details\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Address\"\n        ],\n        \"doctype\": \"Address\",\n        \"is_query_report\": true,\n        \"label\": \"Customer Addresses And Contacts\",\n        \"name\": \"Address And Contacts\",\n        \"route_options\": {\n            \"party_type\": \"Customer\"\n        },\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"BOM\"\n        ],\n        \"doctype\": \"BOM\",\n        \"is_query_report\": true,\n        \"label\": \"BOM Search\",\n        \"name\": \"BOM Search\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"doctype\": \"Item\",\n        \"is_query_report\": true,\n        \"label\": \"Available Stock for Packing Items\",\n        \"name\": \"Available Stock for Packing Items\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Pending SO Items For Purchase Request\",\n        \"name\": \"Pending SO Items For Purchase Request\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"is_query_report\": true,\n        \"label\": \"Customer Credit Balance\",\n        \"name\": \"Customer Credit Balance\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"is_query_report\": true,\n        \"label\": \"Customers Without Any Sales Transactions\",\n        \"name\": \"Customers Without Any Sales Transactions\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Partners Commission\",\n        \"name\": \"Sales Partners Commission\",\n        \"type\": \"report\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Sales",
+   "links": "[\n    {\n        \"description\": \"Customer Database.\",\n        \"label\": \"Customer\",\n        \"name\": \"Customer\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Customer\"\n        ],\n        \"description\": \"Quotes to Leads or Customers.\",\n        \"label\": \"Quotation\",\n        \"name\": \"Quotation\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Customer\"\n        ],\n        \"description\": \"Confirmed orders from Customers.\",\n        \"label\": \"Sales Order\",\n        \"name\": \"Sales Order\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Customer\"\n        ],\n        \"description\": \"Invoices for Costumers.\",\n        \"label\": \"Sales Invoice\",\n        \"name\": \"Sales Invoice\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Customer\"\n        ],\n        \"description\": \"Blanket Orders from Costumers.\",\n        \"label\": \"Blanket Order\",\n        \"name\": \"Blanket Order\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"description\": \"Manage Sales Partners.\",\n        \"label\": \"Sales Partner\",\n        \"name\": \"Sales Partner\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\",\n            \"Customer\"\n        ],\n        \"description\": \"Manage Sales Person Tree.\",\n        \"icon\": \"fa fa-sitemap\",\n        \"label\": \"Sales Person\",\n        \"link\": \"Tree/Sales Person\",\n        \"name\": \"Sales Person\",\n        \"type\": \"doctype\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Key Reports",
+   "links": "[\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Analytics\",\n        \"name\": \"Sales Analytics\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"icon\": \"fa fa-bar-chart\",\n        \"label\": \"Sales Funnel\",\n        \"name\": \"sales-funnel\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"dependencies\": [\n            \"Customer\"\n        ],\n        \"doctype\": \"Customer\",\n        \"icon\": \"fa fa-bar-chart\",\n        \"is_query_report\": true,\n        \"label\": \"Customer Acquisition and Loyalty\",\n        \"name\": \"Customer Acquisition and Loyalty\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Inactive Customers\",\n        \"name\": \"Inactive Customers\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Ordered Items To Be Delivered\",\n        \"name\": \"Ordered Items To Be Delivered\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Person-wise Transaction Summary\",\n        \"name\": \"Sales Person-wise Transaction Summary\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Item\"\n        ],\n        \"doctype\": \"Item\",\n        \"is_query_report\": true,\n        \"label\": \"Item-wise Sales History\",\n        \"name\": \"Item-wise Sales History\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Quotation\"\n        ],\n        \"doctype\": \"Quotation\",\n        \"is_query_report\": true,\n        \"label\": \"Quotation Trends\",\n        \"name\": \"Quotation Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Order\"\n        ],\n        \"doctype\": \"Sales Order\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Order Trends\",\n        \"name\": \"Sales Order Trends\",\n        \"type\": \"report\"\n    }\n]"
+  }
+ ],
+ "category": "Modules",
+ "charts": [
+  {
+   "chart_name": "Incoming Bills (Purchase Invoice)",
+   "label": "Income"
+  }
+ ],
+ "creation": "2020-01-28 11:49:12.092882",
+ "developer_mode_only": 0,
+ "disable_user_customization": 0,
+ "docstatus": 0,
+ "doctype": "Desk Page",
+ "extends_another_page": 0,
+ "hide_custom": 1,
+ "idx": 0,
+ "is_standard": 1,
+ "label": "Selling",
+ "modified": "2020-06-03 13:23:24.861706",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Selling",
+ "owner": "Administrator",
+ "pin_to_bottom": 0,
+ "pin_to_top": 0,
+ "shortcuts": [
+  {
+   "color": "#ffe8cd",
+   "format": "{} Draft",
+   "label": "Sales Invoice",
+   "link_to": "Sales Invoice",
+   "stats_filter": "{ \"status\": \"Draft\" }",
+   "type": "DocType"
+  },
+  {
+   "color": "#ffe8cd",
+   "format": "{} To Deliver",
+   "label": "Sales Order",
+   "link_to": "Sales Order",
+   "stats_filter": "{\"Status\": \"To Deliver and Bill\"}",
+   "type": "DocType"
+  },
+  {
+   "color": "#cef6d1",
+   "format": "{} Open",
+   "label": "Quotation",
+   "link_to": "Quotation",
+   "stats_filter": "{ \"Status\": \"Open\" }",
+   "type": "DocType"
+  },
+  {
+   "label": "Delivery Note",
+   "link_to": "Delivery Note",
+   "type": "DocType"
+  },
+  {
+   "label": "Accounts Receivable",
+   "link_to": "Accounts Receivable",
+   "type": "Report"
+  },
+  {
+   "label": "Sales Register",
+   "link_to": "Sales Register",
+   "type": "Report"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
index 88bd9c1..e78d0ff 100644
--- a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
+++ b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
@@ -8,180 +8,180 @@
 from frappe.utils import cint, cstr
 
 def execute(filters=None):
-    common_columns = [
-        {
-            'label': _('New Customers'),
-            'fieldname': 'new_customers',
-            'fieldtype': 'Int',
-            'default': 0,
-            'width': 125
-        },
-        {
-            'label': _('Repeat Customers'),
-            'fieldname': 'repeat_customers',
-            'fieldtype': 'Int',
-            'default': 0,
-            'width': 125
-        },
-        {
-            'label': _('Total'),
-            'fieldname': 'total',
-            'fieldtype': 'Int',
-            'default': 0,
-            'width': 100
-        },
-        {
-            'label': _('New Customer Revenue'),
-            'fieldname': 'new_customer_revenue',
-            'fieldtype': 'Currency',
-            'default': 0.0,
-            'width': 175
-        },
-        {
-            'label': _('Repeat Customer Revenue'),
-            'fieldname': 'repeat_customer_revenue',
-            'fieldtype': 'Currency',
-            'default': 0.0,
-            'width': 175
-        },
-        {
-            'label': _('Total Revenue'),
-            'fieldname': 'total_revenue',
-            'fieldtype': 'Currency',
-            'default': 0.0,
-            'width': 175
-        }
-    ]
-    if filters.get('view_type') == 'Monthly':
-        return get_data_by_time(filters, common_columns)
-    else:
-        return get_data_by_territory(filters, common_columns)
+	common_columns = [
+		{
+			'label': _('New Customers'),
+			'fieldname': 'new_customers',
+			'fieldtype': 'Int',
+			'default': 0,
+			'width': 125
+		},
+		{
+			'label': _('Repeat Customers'),
+			'fieldname': 'repeat_customers',
+			'fieldtype': 'Int',
+			'default': 0,
+			'width': 125
+		},
+		{
+			'label': _('Total'),
+			'fieldname': 'total',
+			'fieldtype': 'Int',
+			'default': 0,
+			'width': 100
+		},
+		{
+			'label': _('New Customer Revenue'),
+			'fieldname': 'new_customer_revenue',
+			'fieldtype': 'Currency',
+			'default': 0.0,
+			'width': 175
+		},
+		{
+			'label': _('Repeat Customer Revenue'),
+			'fieldname': 'repeat_customer_revenue',
+			'fieldtype': 'Currency',
+			'default': 0.0,
+			'width': 175
+		},
+		{
+			'label': _('Total Revenue'),
+			'fieldname': 'total_revenue',
+			'fieldtype': 'Currency',
+			'default': 0.0,
+			'width': 175
+		}
+	]
+	if filters.get('view_type') == 'Monthly':
+		return get_data_by_time(filters, common_columns)
+	else:
+		return get_data_by_territory(filters, common_columns)
 
 def get_data_by_time(filters, common_columns):
-    # key yyyy-mm
-    columns = [
-        {
-            'label': _('Year'),
-            'fieldname': 'year',
-            'fieldtype': 'Data',
-            'width': 100
-        },
-        {
-            'label': _('Month'),
-            'fieldname': 'month',
-            'fieldtype': 'Data',
-            'width': 100
-        },
-    ]
-    columns += common_columns
+	# key yyyy-mm
+	columns = [
+		{
+			'label': _('Year'),
+			'fieldname': 'year',
+			'fieldtype': 'Data',
+			'width': 100
+		},
+		{
+			'label': _('Month'),
+			'fieldname': 'month',
+			'fieldtype': 'Data',
+			'width': 100
+		},
+	]
+	columns += common_columns
 
-    customers_in = get_customer_stats(filters)
+	customers_in = get_customer_stats(filters)
 
-    # time series
-    from_year, from_month, temp = filters.get('from_date').split('-')
-    to_year, to_month, temp = filters.get('to_date').split('-')
+	# time series
+	from_year, from_month, temp = filters.get('from_date').split('-')
+	to_year, to_month, temp = filters.get('to_date').split('-')
 
-    from_year, from_month, to_year, to_month = \
-        cint(from_year), cint(from_month), cint(to_year), cint(to_month)
+	from_year, from_month, to_year, to_month = \
+		cint(from_year), cint(from_month), cint(to_year), cint(to_month)
 
-    out = []
-    for year in range(from_year, to_year+1):
-        for month in range(from_month if year==from_year else 1, (to_month+1) if year==to_year else 13):
-            key = '{year}-{month:02d}'.format(year=year, month=month)
-            data = customers_in.get(key)
-            new = data['new'] if data else [0, 0.0]
-            repeat = data['repeat'] if data else [0, 0.0]
-            out.append({
-                'year': cstr(year),
-                'month': calendar.month_name[month],
-                'new_customers': new[0],
-                'repeat_customers': repeat[0],
-                'total': new[0] + repeat[0],
-                'new_customer_revenue': new[1],
-                'repeat_customer_revenue': repeat[1],
-                'total_revenue': new[1] + repeat[1]
-            })
-    return columns, out
+	out = []
+	for year in range(from_year, to_year+1):
+		for month in range(from_month if year==from_year else 1, (to_month+1) if year==to_year else 13):
+			key = '{year}-{month:02d}'.format(year=year, month=month)
+			data = customers_in.get(key)
+			new = data['new'] if data else [0, 0.0]
+			repeat = data['repeat'] if data else [0, 0.0]
+			out.append({
+				'year': cstr(year),
+				'month': calendar.month_name[month],
+				'new_customers': new[0],
+				'repeat_customers': repeat[0],
+				'total': new[0] + repeat[0],
+				'new_customer_revenue': new[1],
+				'repeat_customer_revenue': repeat[1],
+				'total_revenue': new[1] + repeat[1]
+			})
+	return columns, out
 
 def get_data_by_territory(filters, common_columns):
-    columns = [{
-        'label': 'Territory',
-        'fieldname': 'territory',
-        'fieldtype': 'Link',
-        'options': 'Territory',
-        'width': 150
-    }]
-    columns += common_columns
+	columns = [{
+		'label': 'Territory',
+		'fieldname': 'territory',
+		'fieldtype': 'Link',
+		'options': 'Territory',
+		'width': 150
+	}]
+	columns += common_columns
 
-    customers_in = get_customer_stats(filters, tree_view=True)
+	customers_in = get_customer_stats(filters, tree_view=True)
 
-    territory_dict = {}
-    for t in frappe.db.sql('''SELECT name, lft, parent_territory, is_group FROM `tabTerritory` ORDER BY lft''', as_dict=1):
-        territory_dict.update({
-            t.name: {
-                'parent': t.parent_territory,
-                'is_group': t.is_group
-            }
-        })
+	territory_dict = {}
+	for t in frappe.db.sql('''SELECT name, lft, parent_territory, is_group FROM `tabTerritory` ORDER BY lft''', as_dict=1):
+		territory_dict.update({
+			t.name: {
+				'parent': t.parent_territory,
+				'is_group': t.is_group
+			}
+		})
 
-    depth_map = frappe._dict()
-    for name, info in territory_dict.items():
-        default = depth_map.get(info['parent']) + 1 if info['parent'] else 0
-        depth_map.setdefault(name, default)
+	depth_map = frappe._dict()
+	for name, info in territory_dict.items():
+		default = depth_map.get(info['parent']) + 1 if info['parent'] else 0
+		depth_map.setdefault(name, default)
 
-    data = []
-    for name, indent in depth_map.items():
-        condition = customers_in.get(name)
-        new = customers_in[name]['new'] if condition else [0, 0.0]
-        repeat = customers_in[name]['repeat'] if condition else [0, 0.0]
-        temp = {
-            'territory': name,
-            'parent_territory': territory_dict[name]['parent'],
-            'indent': indent,
-            'new_customers': new[0],
-            'repeat_customers': repeat[0],
-            'total': new[0] + repeat[0],
-            'new_customer_revenue': new[1],
-            'repeat_customer_revenue': repeat[1],
-            'total_revenue': new[1] + repeat[1],
-            'bold': 0 if indent else 1
-        }
-        data.append(temp)
+	data = []
+	for name, indent in depth_map.items():
+		condition = customers_in.get(name)
+		new = customers_in[name]['new'] if condition else [0, 0.0]
+		repeat = customers_in[name]['repeat'] if condition else [0, 0.0]
+		temp = {
+			'territory': name,
+			'parent_territory': territory_dict[name]['parent'],
+			'indent': indent,
+			'new_customers': new[0],
+			'repeat_customers': repeat[0],
+			'total': new[0] + repeat[0],
+			'new_customer_revenue': new[1],
+			'repeat_customer_revenue': repeat[1],
+			'total_revenue': new[1] + repeat[1],
+			'bold': 0 if indent else 1
+		}
+		data.append(temp)
 
-    loop_data = sorted(data, key=lambda k: k['indent'], reverse=True)
+	loop_data = sorted(data, key=lambda k: k['indent'], reverse=True)
 
-    for ld in loop_data:
-        if ld['parent_territory']:
-            parent_data = [x for x in data if x['territory'] == ld['parent_territory']][0]
-            for key in parent_data.keys():
-                if key not in  ['indent', 'territory', 'parent_territory', 'bold']:
-                    parent_data[key] += ld[key]
+	for ld in loop_data:
+		if ld['parent_territory']:
+			parent_data = [x for x in data if x['territory'] == ld['parent_territory']][0]
+			for key in parent_data.keys():
+				if key not in  ['indent', 'territory', 'parent_territory', 'bold']:
+					parent_data[key] += ld[key]
 
-    return columns, data, None, None, None, 1
+	return columns, data, None, None, None, 1
 
 def get_customer_stats(filters, tree_view=False):
-    """ Calculates number of new and repeated customers. """
-    company_condition = ''
-    if filters.get('company'):
-        company_condition = ' and company=%(company)s'
+	""" Calculates number of new and repeated customers. """
+	company_condition = ''
+	if filters.get('company'):
+		company_condition = ' and company=%(company)s'
 
-    customers = []
-    customers_in = {}
+	customers = []
+	customers_in = {}
 
-    for si in frappe.db.sql('''select territory, posting_date, customer, base_grand_total from `tabSales Invoice`
-        where docstatus=1 and posting_date <= %(to_date)s and posting_date >= %(from_date)s
-        {company_condition} order by posting_date'''.format(company_condition=company_condition),
-        filters, as_dict=1):
+	for si in frappe.db.sql('''select territory, posting_date, customer, base_grand_total from `tabSales Invoice`
+		where docstatus=1 and posting_date <= %(to_date)s
+		{company_condition} order by posting_date'''.format(company_condition=company_condition),
+		filters, as_dict=1):
 
-        key = si.territory if tree_view else si.posting_date.strftime('%Y-%m')
-        customers_in.setdefault(key, {'new': [0, 0.0], 'repeat': [0, 0.0]})
+		key = si.territory if tree_view else si.posting_date.strftime('%Y-%m')
+		customers_in.setdefault(key, {'new': [0, 0.0], 'repeat': [0, 0.0]})
 
-        if not si.customer in customers:
-            customers_in[key]['new'][0] += 1
-            customers_in[key]['new'][1] += si.base_grand_total
-            customers.append(si.customer)
-        else:
-            customers_in[key]['repeat'][0] += 1
-            customers_in[key]['repeat'][1] += si.base_grand_total
+		if not si.customer in customers:
+			customers_in[key]['new'][0] += 1
+			customers_in[key]['new'][1] += si.base_grand_total
+			customers.append(si.customer)
+		else:
+			customers_in[key]['repeat'][0] += 1
+			customers_in[key]['repeat'][1] += si.base_grand_total
 
-    return customers_in
+	return customers_in
diff --git a/erpnext/stock/doctype/item_attribute/item_attribute.py b/erpnext/stock/doctype/item_attribute/item_attribute.py
index 71b998f..2f75bbd 100644
--- a/erpnext/stock/doctype/item_attribute/item_attribute.py
+++ b/erpnext/stock/doctype/item_attribute/item_attribute.py
@@ -34,7 +34,7 @@
 			if self.numeric_values:
 				validate_is_incremental(self, self.name, item.value, item.name)
 			else:
-				validate_item_attribute_value(attributes_list, self.name, item.value, item.name)
+				validate_item_attribute_value(attributes_list, self.name, item.value, item.name, from_variant=False)
 
 	def validate_numeric(self):
 		if self.numeric_values:
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 3562181..3a8deb6 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -18,7 +18,7 @@
 
 		// formatter for material request item
 		frm.set_indicator_formatter('item_code',
-			function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange"; });
+			function(doc) { return (doc.stock_qty<=doc.ordered_qty) ? "green" : "orange"; });
 
 		frm.set_query("item_code", "items", function() {
 			return {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index e9568ee..50c18f6 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -25,7 +25,7 @@
 
 		frm.custom_make_buttons = {
 			'Stock Entry': 'Return',
-			'Purchase Invoice': 'Invoice'
+			'Purchase Invoice': 'Purchase Invoice'
 		};
 
 		frm.set_query("expense_account", "items", function() {
diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json
index 596987f..a3fe72d 100644
--- a/erpnext/support/desk_page/support/support.json
+++ b/erpnext/support/desk_page/support/support.json
@@ -2,8 +2,8 @@
  "cards": [
   {
    "hidden": 0,
-   "label": "Service Level Agreement",
-   "links": "[\n    {\n        \"description\": \"Service Level.\",\n        \"label\": \"Service Level\",\n        \"name\": \"Service Level\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Service Level Agreement.\",\n        \"label\": \"Service Level Agreement\",\n        \"name\": \"Service Level Agreement\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Issues",
+   "links": "[\n    {\n        \"description\": \"Support queries from customers.\",\n        \"label\": \"Issue\",\n        \"name\": \"Issue\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Issue Type.\",\n        \"label\": \"Issue Type\",\n        \"name\": \"Issue Type\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Issue Priority.\",\n        \"label\": \"Issue Priority\",\n        \"name\": \"Issue Priority\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -12,8 +12,8 @@
   },
   {
    "hidden": 0,
-   "label": "Issues",
-   "links": "[\n    {\n        \"description\": \"Support queries from customers.\",\n        \"label\": \"Issue\",\n        \"name\": \"Issue\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Issue Type.\",\n        \"label\": \"Issue Type\",\n        \"name\": \"Issue Type\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Issue Priority.\",\n        \"label\": \"Issue Priority\",\n        \"name\": \"Issue Priority\",\n        \"type\": \"doctype\"\n    }\n]"
+   "label": "Service Level Agreement",
+   "links": "[\n    {\n        \"description\": \"Service Level.\",\n        \"label\": \"Service Level\",\n        \"name\": \"Service Level\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Service Level Agreement.\",\n        \"label\": \"Service Level Agreement\",\n        \"name\": \"Service Level Agreement\",\n        \"type\": \"doctype\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -39,11 +39,11 @@
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
- "icon": "",
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "Support",
- "modified": "2020-04-01 11:28:51.120583",
+ "modified": "2020-05-28 13:51:23.869954",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Support",
@@ -52,19 +52,22 @@
  "pin_to_top": 0,
  "shortcuts": [
   {
+   "color": "#ffc4c4",
+   "format": "{} Assigned",
    "label": "Issue",
    "link_to": "Issue",
-   "type": "DocType"
-  },
-  {
-   "label": "Service Level",
-   "link_to": "Service Level",
+   "stats_filter": "{\n    \"_assign\": [\"like\", '%' + frappe.session.user + '%'],\n    \"status\": \"Open\"\n}",
    "type": "DocType"
   },
   {
    "label": "Maintenance Visit",
    "link_to": "Maintenance Visit",
    "type": "DocType"
+  },
+  {
+   "label": "Service Level",
+   "link_to": "Service Level",
+   "type": "DocType"
   }
  ]
 }
\ No newline at end of file