Merge branch 'develop' of https://github.com/frappe/erpnext into tax_fetch_quote
diff --git a/README.md b/README.md
index 80ebdb6..0f6a521 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
 ERPNext as a monolith includes the following areas for managing businesses:
 
 1. [Accounting](https://erpnext.com/open-source-accounting)
-1. [Inventory](https://erpnext.com/distribution/inventory-management-system)
+1. [Warehouse Management](https://erpnext.com/distribution/warehouse-management-system)
 1. [CRM](https://erpnext.com/open-source-crm)
 1. [Sales](https://erpnext.com/open-source-sales-purchase)
 1. [Purchase](https://erpnext.com/open-source-sales-purchase)
diff --git a/erpnext/accounts/doctype/item_tax_template/item_tax_template.json b/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
index 856c371..8915f79 100644
--- a/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
+++ b/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
@@ -38,8 +38,8 @@
    "reqd": 1
   }
  ],
- "modified": "2020-06-18 20:27:42.615842",
- "modified_by": "ahmad@havenir.com",
+ "modified": "2020-09-18 17:26:09.703215",
+ "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Item Tax Template",
  "owner": "Administrator",
diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json
index f3df1f0..50fc3bb 100644
--- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json
+++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json
@@ -45,11 +45,11 @@
  ],
  "icon": "fa fa-credit-card",
  "idx": 1,
- "modified": "2019-08-14 14:58:42.079115",
- "modified_by": "sammish.thundiyil@gmail.com",
+ "modified": "2020-09-18 17:26:09.703215",
+ "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Mode of Payment",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 9fc44bc..e117471 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -12,9 +12,10 @@
 
 	setup: function(frm) {
 		frm.set_query("paid_from", function() {
+			frm.events.validate_company(frm);
+
 			var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
 				["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
-
 			return {
 				filters: {
 					"account_type": ["in", account_types],
@@ -23,13 +24,16 @@
 				}
 			}
 		});
+
 		frm.set_query("party_type", function() {
+			frm.events.validate_company(frm);
 			return{
 				filters: {
 					"name": ["in", Object.keys(frappe.boot.party_account_types)],
 				}
 			}
 		});
+
 		frm.set_query("party_bank_account", function() {
 			return {
 				filters: {
@@ -39,6 +43,7 @@
 				}
 			}
 		});
+
 		frm.set_query("bank_account", function() {
 			return {
 				filters: {
@@ -47,6 +52,7 @@
 				}
 			}
 		});
+
 		frm.set_query("contact_person", function() {
 			if (frm.doc.party) {
 				return {
@@ -58,10 +64,12 @@
 				};
 			}
 		});
+
 		frm.set_query("paid_to", function() {
+			frm.events.validate_company(frm);
+
 			var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
 				["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
-
 			return {
 				filters: {
 					"account_type": ["in", account_types],
@@ -150,6 +158,12 @@
 		frm.events.show_general_ledger(frm);
 	},
 
+	validate_company: (frm) => {
+		if (!frm.doc.company){
+			frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
+		}
+	},
+
 	company: function(frm) {
 		frm.events.hide_unhide_fields(frm);
 		frm.events.set_dynamic_labels(frm);
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 9979377..72149a6 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2016-06-01 14:38:51.012597",
@@ -63,6 +64,7 @@
   "cost_center",
   "section_break_12",
   "status",
+  "custom_remarks",
   "remarks",
   "column_break_16",
   "letter_head",
@@ -462,7 +464,8 @@
    "fieldname": "remarks",
    "fieldtype": "Small Text",
    "label": "Remarks",
-   "no_copy": 1
+   "no_copy": 1,
+   "read_only_depends_on": "eval:doc.custom_remarks == 0"
   },
   {
    "fieldname": "column_break_16",
@@ -573,10 +576,18 @@
    "label": "Status",
    "options": "\nDraft\nSubmitted\nCancelled",
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "custom_remarks",
+   "fieldtype": "Check",
+   "label": "Custom Remarks"
   }
  ],
+ "index_web_pages_for_search": 1,
  "is_submittable": 1,
- "modified": "2019-12-08 13:02:30.016610",
+ "links": [],
+ "modified": "2020-09-02 13:39:43.383705",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index bb312bf..11ab020 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -453,7 +453,7 @@
 				frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
 
 	def set_remarks(self):
-		if self.remarks: return
+		if self.custom_remarks: return
 
 		if self.payment_type=="Internal Transfer":
 			remarks = [_("Amount {0} {1} transferred from {2} to {3}")
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
index d04f25b..47546c0 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
@@ -291,11 +291,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 16:15:49.089450", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Period Closing Voucher", 
- "owner": "jai@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 1, 
diff --git a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
index 15f23b6..b9e07b8 100644
--- a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
+++ b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
@@ -5,13 +5,14 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import cint
+from frappe.utils import cint, get_link_to_form
 from frappe.model.document import Document
 from erpnext.controllers.status_updater import StatusUpdater
 
 class POSOpeningEntry(StatusUpdater):
 	def validate(self):
 		self.validate_pos_profile_and_cashier()
+		self.validate_payment_method_account()
 		self.set_status()
 
 	def validate_pos_profile_and_cashier(self):
@@ -20,6 +21,14 @@
 
 		if not cint(frappe.db.get_value("User", self.user, "enabled")):
 			frappe.throw(_("User {} has been disabled. Please select valid user/cashier".format(self.user)))
+	
+	def validate_payment_method_account(self):
+		for d in self.balance_details:
+			account = frappe.db.get_value("Mode of Payment Account", 
+				{"parent": d.mode_of_payment, "company": self.company}, "default_account")
+			if not account:
+				frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
+					.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
 
 	def on_submit(self):
 		self.set_status(update=True)
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py
index 789b4c3..1386b70 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import msgprint, _
-from frappe.utils import cint, now
+from frappe.utils import cint, now, get_link_to_form
 from six import iteritems
 from frappe.model.document import Document
 
@@ -13,7 +13,7 @@
 		self.validate_default_profile()
 		self.validate_all_link_fields()
 		self.validate_duplicate_groups()
-		self.check_default_payment()
+		self.validate_payment_methods()
 
 	def validate_default_profile(self):
 		for row in self.applicable_for_users:
@@ -52,14 +52,23 @@
 		if len(customer_groups) != len(set(customer_groups)):
 			frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
 
-	def check_default_payment(self):
-		if self.payments:
-			default_mode_of_payment = [d.default for d in self.payments if d.default]
-			if not default_mode_of_payment:
-				frappe.throw(_("Set default mode of payment"))
+	def validate_payment_methods(self):
+		if not self.payments:
+			frappe.throw(_("Payment methods are mandatory. Please add at least one payment method."))
 
-			if len(default_mode_of_payment) > 1:
-				frappe.throw(_("Multiple default mode of payment is not allowed"))
+		default_mode_of_payment = [d.default for d in self.payments if d.default]
+		if not default_mode_of_payment:
+			frappe.throw(_("Please select a default mode of payment"))
+
+		if len(default_mode_of_payment) > 1:
+			frappe.throw(_("You can only select one mode of payment as default"))
+		
+		for d in self.payments:
+			account = frappe.db.get_value("Mode of Payment Account", 
+				{"parent": d.mode_of_payment, "company": self.company}, "default_account")
+			if not account:
+				frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
+					.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
 
 	def on_update(self):
 		self.set_defaults()
diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.js b/erpnext/accounts/doctype/pos_settings/pos_settings.js
index 504941d..05cb7f0 100644
--- a/erpnext/accounts/doctype/pos_settings/pos_settings.js
+++ b/erpnext/accounts/doctype/pos_settings/pos_settings.js
@@ -7,10 +7,10 @@
 	},
 
 	get_invoice_fields: function(frm) {
-		frappe.model.with_doctype("Sales Invoice", () => {
-			var fields = $.map(frappe.get_doc("DocType", "Sales Invoice").fields, function(d) {
+		frappe.model.with_doctype("POS Invoice", () => {
+			var fields = $.map(frappe.get_doc("DocType", "POS Invoice").fields, function(d) {
 				if (frappe.model.no_value_type.indexOf(d.fieldtype) === -1 ||
-					d.fieldtype === 'Table') {
+					['Table', 'Button'].includes(d.fieldtype)) {
 					return { label: d.label + ' (' + d.fieldtype + ')', value: d.fieldname };
 				} else {
 					return null;
@@ -25,7 +25,7 @@
 frappe.ui.form.on("POS Field", {
 	fieldname: function(frm, doctype, name) {
 		var doc = frappe.get_doc(doctype, name);
-		var df = $.map(frappe.get_doc("DocType", "Sales Invoice").fields, function(d) {
+		var df = $.map(frappe.get_doc("DocType", "POS Invoice").fields, function(d) {
 			return doc.fieldname == d.fieldname ? d : null;
 		})[0];
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 2bfa4a5..fe5301d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -28,7 +28,7 @@
 
 		// Trigger supplier event on load if supplier is available
 		// The reason for this is PI can be created from PR or PO and supplier is pre populated
-		if (this.frm.doc.supplier) {
+		if (this.frm.doc.supplier && this.frm.doc.__islocal) {
 			this.frm.trigger('supplier');
 		}
 	},
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
index 0e748f8..f9fdc4b 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
@@ -210,7 +210,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-03-12 14:53:47.679439",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Taxes and Charges",
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.json b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.json
index a18fec6..b46d2e3 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.json
@@ -78,7 +78,7 @@
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Taxes and Charges Template",
- "owner": "wasim@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "email": 1,
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 71f2e12..92e49d5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe, erpnext
 import frappe.defaults
-from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr, nowdate
+from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr, nowdate, get_link_to_form
 from frappe import _, msgprint, throw
 from erpnext.accounts.party import get_party_account, get_due_date
 from frappe.model.mapper import get_mapped_doc
@@ -1372,7 +1372,7 @@
 		{"parent": mode_of_payment, "company": company}, "default_account")
 	if not account:
 		frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
-			.format(mode_of_payment))
+			.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
 	return {
 		"account": account
 	}
@@ -1612,18 +1612,16 @@
 		payment.type = payment_mode.type
 
 	doc.set('payments', [])
-	if not pos_profile or not pos_profile.get('payments'):
-		for payment_mode in get_all_mode_of_payments(doc):
-			append_payment(payment_mode)
-		return
-
 	for pos_payment_method in pos_profile.get('payments'):
 		pos_payment_method = pos_payment_method.as_dict()
 
 		payment_mode = get_mode_of_payment_info(pos_payment_method.mode_of_payment, doc.company)
-		if payment_mode:
-			payment_mode[0].default = pos_payment_method.default
-			append_payment(payment_mode[0])
+		if not payment_mode:
+			frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
+				.format(get_link_to_form("Mode of Payment", pos_payment_method.mode_of_payment)), title=_("Missing Account"))
+
+		payment_mode[0].default = pos_payment_method.default
+		append_payment(payment_mode[0])
 
 def get_all_mode_of_payments(doc):
 	return frappe.db.sql("""
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 01d3903..c12e006d 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -320,7 +320,6 @@
 
 			entry['remarks'] = "On cancellation of " + entry['voucher_no']
 			entry['is_cancelled'] = 1
-			entry['posting_date'] = today()
 
 			if entry['debit'] or entry['credit']:
 				make_entry(entry, adv_adj, "Yes")
diff --git a/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js b/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js
index efc76f9..9703527 100644
--- a/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js
+++ b/erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js
@@ -72,7 +72,7 @@
 	check_plaid_status() {
 		const me = this;
 		frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
-			if (r && r.enabled == "1") {
+			if (r && r.enabled === "1") {
 				me.plaid_status = "active"
 			} else {
 				me.plaid_status = "inactive"
@@ -139,7 +139,7 @@
 	}
 
 	make() {
-		const me = this;	
+		const me = this;
 		new frappe.ui.FileUploader({
 			method: 'erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.upload_bank_statement',
 			allow_multiple: 0,
@@ -214,31 +214,35 @@
 
 	init_config() {
 		const me = this;
-		frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.plaid_configuration')
-		.then(result => {
-			me.plaid_env = result.plaid_env;
-			me.plaid_public_key = result.plaid_public_key;
-			me.client_name = result.client_name;
-			me.sync_transactions()
-		})
+		frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_plaid_configuration')
+			.then(result => {
+				me.plaid_env = result.plaid_env;
+				me.client_name = result.client_name;
+				me.link_token = result.link_token;
+				me.sync_transactions();
+			})
 	}
 
 	sync_transactions() {
 		const me = this;
-		frappe.db.get_value("Bank Account", me.parent.bank_account, "bank", (v) => {
+		frappe.db.get_value("Bank Account", me.parent.bank_account, "bank", (r) => {
 			frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions', {
-				bank: v['bank'],
+				bank: r.bank,
 				bank_account: me.parent.bank_account,
 				freeze: true
 			})
 			.then((result) => {
-				let result_title = (result.length > 0) ? __("{0} bank transaction(s) created", [result.length]) : __("This bank account is already synchronized")
+				let result_title = (result && result.length > 0)
+					? __("{0} bank transaction(s) created", [result.length])
+					: __("This bank account is already synchronized");
+
 				let result_msg = `
-					<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
-						<h5 class="text-muted">${result_title}</h5>
-					</div>`
+				<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
+					<h5 class="text-muted">${result_title}</h5>
+				</div>`
+
 				this.parent.$main_section.append(result_msg)
-				frappe.show_alert({message:__("Bank account '{0}' has been synchronized", [me.parent.bank_account]), indicator:'green'});
+				frappe.show_alert({ message: __("Bank account '{0}' has been synchronized", [me.parent.bank_account]), indicator: 'green' });
 			})
 		})
 	}
@@ -384,7 +388,7 @@
 		})
 
 		frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.get_linked_payments',
-			{bank_transaction: data, freeze:true, freeze_message:__("Finding linked payments")}
+			{ bank_transaction: data, freeze: true, freeze_message: __("Finding linked payments") }
 		).then((result) => {
 			me.make_dialog(result)
 		})
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index c999eb9..29c4f7d 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -34,7 +34,7 @@
 					filters: {
 						'company': company
 					}
-				}
+				};
 			}
 		},
 		{
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 59117c8..044fc1d 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -617,9 +617,19 @@
 		elif party_type_field=="supplier":
 			self.add_supplier_filters(conditions, values)
 
+		if self.filters.cost_center:
+			self.get_cost_center_conditions(conditions)
+
 		self.add_accounting_dimensions_filters(conditions, values)
 		return " and ".join(conditions), values
 
+	def get_cost_center_conditions(self, conditions):
+		lft, rgt = frappe.db.get_value("Cost Center", self.filters.cost_center, ["lft", "rgt"])
+		cost_center_list = [center.name for center in frappe.get_list("Cost Center", filters = {'lft': (">=", lft), 'rgt': ("<=", rgt)})]
+
+		cost_center_string = '", "'.join(cost_center_list)
+		conditions.append('cost_center in ("{0}")'.format(cost_center_string))
+
 	def get_order_by_condition(self):
 		if self.filters.get('group_by_party'):
 			return "order by party, posting_date"
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 2563b66..84c7454 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -268,9 +268,9 @@
 	def get_last_purchase_rate(self, item_code, row):
 		condition = ''
 		if row.project:
-			condition += " AND a.project='%s'" % (row.project)
+			condition += " AND a.project=%s" % (frappe.db.escape(row.project))
 		elif row.cost_center:
-			condition += " AND a.cost_center='%s'" % (row.cost_center)
+			condition += " AND a.cost_center=%s" % (frappe.db.escape(row.cost_center))
 		if self.filters.to_date:
 			condition += " AND modified='%s'" % (self.filters.to_date)
 
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index fba20c0..7ad164a 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -252,13 +252,6 @@
 		})
 	},
 
-	available_for_use_date: function(frm) {
-		$.each(frm.doc.finance_books || [], function(i, d) {
-			if(!d.depreciation_start_date) d.depreciation_start_date = frm.doc.available_for_use_date;
-		});
-		refresh_field("finance_books");
-	},
-
 	is_existing_asset: function(frm) {
 		frm.trigger("toggle_reference_doc");
 		// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
@@ -438,6 +431,15 @@
 		}
 
 		frappe.flags.dont_change_rate = false;
+	},
+
+	depreciation_start_date: function(frm, cdt, cdn) {
+		const book = locals[cdt][cdn];
+		if (frm.doc.available_for_use_date && book.depreciation_start_date == frm.doc.available_for_use_date) {
+			frappe.msgprint(__(`Depreciation Posting Date should not be equal to Available for Use Date.`));
+			book.depreciation_start_date = "";
+			frm.refresh_field("finance_books");
+		}
 	}
 });
 
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 9d08d92..efdbdb1 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -6,7 +6,7 @@
 import frappe, erpnext, math, json
 from frappe import _
 from six import string_types
-from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days
+from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days, get_last_day, get_datetime
 from frappe.model.document import Document
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
 from erpnext.assets.doctype.asset.depreciation \
@@ -83,6 +83,11 @@
 		if not self.available_for_use_date:
 			frappe.throw(_("Available for use date is required"))
 
+		for d in self.finance_books:
+			if d.depreciation_start_date == self.available_for_use_date:
+				frappe.throw(_("Row #{}: Depreciation Posting Date should not be equal to Available for Use Date.").format(d.idx),
+					title=_("Incorrect Date"))
+
 	def set_missing_values(self):
 		if not self.asset_category:
 			self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
@@ -135,6 +140,10 @@
 	def make_asset_movement(self):
 		reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
 		reference_docname = self.purchase_receipt or self.purchase_invoice
+		transaction_date = getdate(self.purchase_date)
+		if reference_docname:
+			posting_date, posting_time = frappe.db.get_value(reference_doctype, reference_docname, ["posting_date", "posting_time"])
+			transaction_date = get_datetime("{} {}".format(posting_date, posting_time))
 		assets = [{
 			'asset': self.name,
 			'asset_name': self.asset_name,
@@ -146,7 +155,7 @@
 			'assets': assets,
 			'purpose': 'Receipt',
 			'company': self.company,
-			'transaction_date': getdate(self.purchase_date),
+			'transaction_date': transaction_date,
 			'reference_doctype': reference_doctype,
 			'reference_name': reference_docname
 		}).insert()
@@ -294,7 +303,7 @@
 		if not row.depreciation_start_date:
 			if not self.available_for_use_date:
 				frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
-			row.depreciation_start_date = self.available_for_use_date
+			row.depreciation_start_date = get_last_day(self.available_for_use_date)
 
 		if not self.is_existing_asset:
 			self.opening_accumulated_depreciation = 0
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index aed78e7..52039c1 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -371,19 +371,18 @@
 		asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
 		asset = frappe.get_doc('Asset', asset_name)
 		asset.calculate_depreciation = 1
-		asset.available_for_use_date = nowdate()
-		asset.purchase_date = nowdate()
+		asset.available_for_use_date = '2020-01-01'
+		asset.purchase_date = '2020-01-01'
 		asset.append("finance_books", {
 			"expected_value_after_useful_life": 10000,
 			"depreciation_method": "Straight Line",
-			"total_number_of_depreciations": 3,
-			"frequency_of_depreciation": 10,
-			"depreciation_start_date": nowdate()
+			"total_number_of_depreciations": 10,
+			"frequency_of_depreciation": 1
 		})
 		asset.insert()
 		asset.submit()
 
-		post_depreciation_entries(date=add_months(nowdate(), 10))
+		post_depreciation_entries(date=add_months('2020-01-01', 4))
 
 		scrap_asset(asset.name)
 
@@ -392,9 +391,9 @@
 		self.assertTrue(asset.journal_entry_for_scrap)
 
 		expected_gle = (
-			("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
+			("_Test Accumulated Depreciations - _TC", 36000.0, 0.0),
 			("_Test Fixed Asset - _TC", 0.0, 100000.0),
-			("_Test Gain/Loss on Asset Disposal - _TC", 70000.0, 0.0)
+			("_Test Gain/Loss on Asset Disposal - _TC", 64000.0, 0.0)
 		)
 
 		gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
@@ -466,8 +465,7 @@
 			"expected_value_after_useful_life": 10000,
 			"depreciation_method": "Straight Line",
 			"total_number_of_depreciations": 3,
-			"frequency_of_depreciation": 10,
-			"depreciation_start_date": "2020-06-06"
+			"frequency_of_depreciation": 10
 		})
 		asset.insert()
 		accumulated_depreciation_after_full_schedule = \
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
index c80f95e..79fcb95 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
@@ -1,347 +1,99 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "beta": 0, 
- "creation": "2018-05-08 14:44:37.095570", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2018-05-08 14:44:37.095570",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "finance_book",
+  "depreciation_method",
+  "total_number_of_depreciations",
+  "column_break_5",
+  "frequency_of_depreciation",
+  "depreciation_start_date",
+  "expected_value_after_useful_life",
+  "value_after_depreciation",
+  "rate_of_depreciation"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "", 
-   "fetch_if_empty": 0, 
-   "fieldname": "finance_book", 
-   "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": "Finance Book", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Finance Book", 
-   "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": "finance_book",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Finance Book",
+   "options": "Finance Book"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "depreciation_method", 
-   "fieldtype": "Select", 
-   "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": "Depreciation Method", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual", 
-   "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": "depreciation_method",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Depreciation Method",
+   "options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "total_number_of_depreciations", 
-   "fieldtype": "Int", 
-   "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": "Total Number of Depreciations", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "total_number_of_depreciations",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Total Number of Depreciations",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "column_break_5", 
-   "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, 
-   "label": "", 
-   "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_5",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "frequency_of_depreciation", 
-   "fieldtype": "Int", 
-   "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": "Frequency of Depreciation (Months)", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "frequency_of_depreciation",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Frequency of Depreciation (Months)",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:parent.doctype == 'Asset'", 
-   "fetch_if_empty": 0, 
-   "fieldname": "depreciation_start_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": "Depreciation Start 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
-  }, 
+   "depends_on": "eval:parent.doctype == 'Asset'",
+   "fieldname": "depreciation_start_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Depreciation Posting Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "0", 
-   "depends_on": "eval:parent.doctype == 'Asset'", 
-   "fetch_if_empty": 0, 
-   "fieldname": "expected_value_after_useful_life", 
-   "fieldtype": "Currency", 
-   "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": "Expected Value After Useful Life", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Company:company:default_currency", 
-   "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",
+   "depends_on": "eval:parent.doctype == 'Asset'",
+   "fieldname": "expected_value_after_useful_life",
+   "fieldtype": "Currency",
+   "label": "Expected Value After Useful Life",
+   "options": "Company:company:default_currency"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_if_empty": 0, 
-   "fieldname": "value_after_depreciation", 
-   "fieldtype": "Currency", 
-   "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": "Value After Depreciation", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "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": "value_after_depreciation",
+   "fieldtype": "Currency",
+   "hidden": 1,
+   "label": "Value After Depreciation",
+   "no_copy": 1,
+   "options": "Company:company:default_currency",
+   "print_hide": 1,
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.depreciation_method == 'Written Down Value'", 
-   "description": "In Percentage", 
-   "fetch_if_empty": 0, 
-   "fieldname": "rate_of_depreciation", 
-   "fieldtype": "Percent", 
-   "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": "Rate of Depreciation", 
-   "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.depreciation_method == 'Written Down Value'",
+   "description": "In Percentage",
+   "fieldname": "rate_of_depreciation",
+   "fieldtype": "Percent",
+   "label": "Rate of Depreciation"
   }
- ], 
- "has_web_view": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2019-04-09 19:45:14.523488", 
- "modified_by": "Administrator", 
- "module": "Assets", 
- "name": "Asset Finance Book", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2020-09-16 12:11:30.631788",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Finance Book",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_movement/test_asset_movement.py b/erpnext/assets/doctype/asset_movement/test_asset_movement.py
index c3755a3..cddee5f 100644
--- a/erpnext/assets/doctype/asset_movement/test_asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/test_asset_movement.py
@@ -32,8 +32,7 @@
 			"next_depreciation_date": "2020-12-31",
 			"depreciation_method": "Straight Line",
 			"total_number_of_depreciations": 3,
-			"frequency_of_depreciation": 10,
-			"depreciation_start_date": "2020-06-06"
+			"frequency_of_depreciation": 10
 		})
 
 		if asset.docstatus == 0:
@@ -82,8 +81,7 @@
 			"next_depreciation_date": "2020-12-31",
 			"depreciation_method": "Straight Line",
 			"total_number_of_depreciations": 3,
-			"frequency_of_depreciation": 10,
-			"depreciation_start_date": "2020-06-06"
+			"frequency_of_depreciation": 10
 		})
 		if asset.docstatus == 0:
 			asset.submit()
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index 69817a4..158799c 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -202,6 +202,53 @@
 		self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
 		frappe.set_user("Administrator")
 
+	def test_update_child_with_tax_template(self):
+		tax_template = "_Test Account Excise Duty @ 10"
+		item =  "_Test Item Home Desktop 100"
+
+		if not frappe.db.exists("Item Tax", {"parent":item, "item_tax_template":tax_template}):
+			item_doc = frappe.get_doc("Item", item)
+			item_doc.append("taxes", {
+				"item_tax_template": tax_template,
+				"valid_from": nowdate()
+			})
+			item_doc.save()
+		else:
+			# update valid from
+			frappe.db.sql("""UPDATE `tabItem Tax` set valid_from = CURDATE()
+				where parent = %(item)s and item_tax_template = %(tax)s""",
+					{"item": item, "tax": tax_template})
+
+		po = create_purchase_order(item_code=item, qty=1, do_not_save=1)
+
+		po.append("taxes", {
+			"account_head": "_Test Account Excise Duty - _TC",
+			"charge_type": "On Net Total",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Excise Duty",
+			"doctype": "Purchase Taxes and Charges",
+			"rate": 10
+		})
+		po.insert()
+		po.submit()
+
+		self.assertEqual(po.taxes[0].tax_amount, 50)
+		self.assertEqual(po.taxes[0].total, 550)
+
+		items = json.dumps([
+			{'item_code' : item, 'rate' : 500, 'qty' : 1, 'docname': po.items[0].name},
+			{'item_code' : item, 'rate' : 100, 'qty' : 1} # added item
+		])
+		update_child_qty_rate('Purchase Order', items, po.name)
+
+		po.reload()
+		self.assertEqual(po.taxes[0].tax_amount, 60)
+		self.assertEqual(po.taxes[0].total, 660)
+
+		frappe.db.sql("""UPDATE `tabItem Tax` set valid_from = NULL
+				where parent = %(item)s and item_tax_template = %(tax)s""",
+					{"item": item, "tax": tax_template})
+
 	def test_update_child_uom_conv_factor_change(self):
 		po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
 		total_reqd_qty = sum([d.get("required_qty") for d in po.as_dict().get("supplied_items")])
diff --git a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
index c3e1bf5..d7ea9c1 100644
--- a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
@@ -148,11 +148,11 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-03-12 15:43:53.862897",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item Supplied",
- "owner": "dhanalekshmi@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC"
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
index ea58630..dc00bca 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
@@ -188,11 +188,11 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-10 18:09:33.997618",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Receipt Item Supplied",
- "owner": "wasim@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
index af109ba..e956afd 100644
--- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
+++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
@@ -178,6 +178,7 @@
 			period_card = make_supplier_scorecard(docname, None)
 			period_card.start_date = start_date
 			period_card.end_date = end_date
+			period_card.insert(ignore_permissions=True)
 			period_card.submit()
 			scp_count = scp_count + 1
 			if start_date < first_start_date:
diff --git a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
index 87f1033..9938710 100644
--- a/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
+++ b/erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.py
@@ -106,7 +106,7 @@
 			"doctype": "Supplier Scorecard Scoring Criteria",
 			"postprocess": update_criteria_fields,
 		}
-	}, target_doc, post_process)
+	}, target_doc, post_process, ignore_permissions=True)
 
 	return doc
 
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 9093cd5..90c466b 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -20,7 +20,7 @@
 from erpnext.exceptions import InvalidCurrency
 from six import text_type
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
-from erpnext.stock.get_item_details import get_item_warehouse
+from erpnext.stock.get_item_details import get_item_warehouse, _get_item_tax_template, get_item_tax_map
 from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
 
 force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
@@ -1158,6 +1158,18 @@
 	}
 	return info
 
+def set_child_tax_template_and_map(item, child_item, parent_doc):
+	args = {
+			'item_code': item.item_code,
+			'posting_date': parent_doc.transaction_date,
+			'tax_category': parent_doc.get('tax_category'),
+			'company': parent_doc.get('company')
+		}
+
+	child_item.item_tax_template = _get_item_tax_template(args, item.taxes)
+	if child_item.get("item_tax_template"):
+		child_item.item_tax_rate = get_item_tax_map(parent_doc.get('company'), child_item.item_tax_template, as_json=True)
+
 def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
 	"""
 	Returns a Sales Order Item child item containing the default values
@@ -1172,6 +1184,7 @@
 	child_item.uom = trans_item.get("uom") or item.stock_uom
 	conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
 	child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
+	set_child_tax_template_and_map(item, child_item, p_doc)
 	child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
 	if not child_item.warehouse:
 		frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
@@ -1195,6 +1208,7 @@
 	child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
 	child_item.base_rate = 1 # Initiallize value will update in parent validation
 	child_item.base_amount = 1 # Initiallize value will update in parent validation
+	set_child_tax_template_and_map(item, child_item, p_doc)
 	return child_item
 
 def validate_and_delete_children(parent, data):
@@ -1232,7 +1246,7 @@
 
 			frappe.throw(_("You do not have permissions to {} items in a {}.")
 				.format(actions[perm_type], parent_doctype), title=_("Insufficient Permissions"))
-	
+
 	def validate_workflow_conditions(doc):
 		workflow = get_workflow_name(doc.doctype)
 		if not workflow:
@@ -1250,7 +1264,10 @@
 				transitions.append(transition.as_dict())
 
 		if not transitions:
-			frappe.throw(_("You do not have workflow access to update this document."), title=_("Insufficient Workflow Permissions"))
+			frappe.throw(
+				_("You are not allowed to update as per the conditions set in {} Workflow.").format(get_link_to_form("Workflow", workflow)),
+				title=_("Insufficient Permissions")
+			)
 
 	def get_new_child_item(item_row):
 		new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
@@ -1267,7 +1284,7 @@
 
 	sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
 	parent = frappe.get_doc(parent_doctype, parent_doctype_name)
-	
+
 	check_doc_permissions(parent, 'cancel')
 	validate_and_delete_children(parent, data)
 
@@ -1315,7 +1332,7 @@
 				child_item.conversion_factor = 1
 			else:
 				child_item.conversion_factor = flt(d.get('conversion_factor'))
-		
+
 		if d.get("uom"):
 			child_item.uom = d.get("uom")
 			conversion_factor = flt(get_conversion_factor(child_item.item_code, child_item.uom).get("conversion_factor"))
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index c88bf66..efd4944 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -165,9 +165,14 @@
 				AND company = %(company)s
 				AND account_currency = %(currency)s
 				AND `{searchfield}` LIKE %(txt)s
+				{mcond}
 			ORDER BY idx DESC, name
 			LIMIT %(offset)s, %(limit)s
-		""".format(account_type_condition=account_type_condition, searchfield=searchfield),
+		""".format(
+				account_type_condition=account_type_condition,
+				searchfield=searchfield,
+				mcond=get_match_cond(doctype)
+			),
 			dict(
 				account_types=filters.get("account_type"),
 				company=filters.get("company"),
@@ -359,9 +364,21 @@
 	if filters.get("is_return"):
 		having_clause = ""
 
+	meta = frappe.get_meta("Batch", cached=True)
+	searchfields = meta.get_search_fields()
+
+	search_columns = ''
+	if searchfields:
+		search_columns = ", " + ", ".join(searchfields)
+
 	if args.get('warehouse'):
+		searchfields = ['batch.' + field for field in searchfields]
+		if searchfields:
+			search_columns = ", " + ", ".join(searchfields)
+
 		batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom,
 				concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date)
+				{search_columns}
 			from `tabStock Ledger Entry` sle
 				INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
 			where
@@ -377,6 +394,7 @@
 			group by batch_no {having_clause}
 			order by batch.expiry_date, sle.batch_no desc
 			limit %(start)s, %(page_len)s""".format(
+				search_columns = search_columns,
 				cond=cond,
 				match_conditions=get_match_cond(doctype),
 				having_clause = having_clause
@@ -384,7 +402,9 @@
 
 		return batch_nos
 	else:
-		return frappe.db.sql("""select name, concat('MFG-', manufacturing_date), concat('EXP-',expiry_date) from `tabBatch` batch
+		return frappe.db.sql("""select name, concat('MFG-', manufacturing_date), concat('EXP-',expiry_date)
+			{search_columns}
+			from `tabBatch` batch
 			where batch.disabled = 0
 			and item = %(item_code)s
 			and (name like %(txt)s
@@ -394,7 +414,7 @@
 			{0}
 			{match_conditions}
 			order by expiry_date, name desc
-			limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args)
+			limit %(start)s, %(page_len)s""".format(cond, search_columns = search_columns, match_conditions=get_match_cond(doctype)), args)
 
 
 @frappe.whitelist()
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 6fd1319..0ae1759 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -82,6 +82,7 @@
 			party_details = _get_party_details(customer,
 				ignore_permissions=self.flags.ignore_permissions,
 				doctype=self.doctype, company=self.company,
+				posting_date=self.get('posting_date'),
 				fetch_payment_terms_template=fetch_payment_terms_template,
 				party_address=self.customer_address, shipping_address=self.shipping_address_name)
 			if not self.meta.get_field("sales_team"):
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index ecf041e..801c405 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -25,7 +25,7 @@
 
 	if not filters: filters = []
 
-	if doctype in ['Supplier Quotation', 'Purchase Invoice']:
+	if doctype in ['Supplier Quotation', 'Purchase Invoice', 'Quotation']:
 		filters.append((doctype, 'docstatus', '<', 2))
 	else:
 		filters.append((doctype, 'docstatus', '=', 1))
diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json
index eb69dc0..d974beb 100644
--- a/erpnext/crm/desk_page/crm/crm.json
+++ b/erpnext/crm/desk_page/crm/crm.json
@@ -8,7 +8,7 @@
   {
    "hidden": 0,
    "label": "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        \"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            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Prospects Engaged But Not Converted\",\n        \"name\": \"Prospects Engaged But Not Converted\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Opportunity\"\n        ],\n        \"doctype\": \"Opportunity\",\n        \"is_query_report\": true,\n        \"label\": \"Minutes to First Response for Opportunity\",\n        \"name\": \"Minutes to First Response for Opportunity\",\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            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Campaign Efficiency\",\n        \"name\": \"Campaign Efficiency\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Lead Owner Efficiency\",\n        \"name\": \"Lead Owner Efficiency\",\n        \"type\": \"report\"\n    }\n]"
+   "links": "[\n    {\n        \"dependencies\": [\n            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Lead Details\",\n        \"name\": \"Lead Details\",\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            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Prospects Engaged But Not Converted\",\n        \"name\": \"Prospects Engaged But Not Converted\",\n        \"onboard\": 1,\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Opportunity\"\n        ],\n        \"doctype\": \"Opportunity\",\n        \"is_query_report\": true,\n        \"label\": \"First Response Time for Opportunity\",\n        \"name\": \"First Response Time for Opportunity\",\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            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Campaign Efficiency\",\n        \"name\": \"Campaign Efficiency\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Lead\"\n        ],\n        \"doctype\": \"Lead\",\n        \"is_query_report\": true,\n        \"label\": \"Lead Owner Efficiency\",\n        \"name\": \"Lead Owner Efficiency\",\n        \"type\": \"report\"\n    }\n]"
   },
   {
    "hidden": 0,
@@ -42,7 +42,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "CRM",
- "modified": "2020-05-28 13:33:52.906750",
+ "modified": "2020-08-11 18:55:18.238900",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "CRM",
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 315d298..99fa703 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -27,9 +27,6 @@
 
 	def after_insert(self):
 		self.update_links()
-		# after the address and contact are created, flush the field values
-		# to avoid inconsistent reporting in case the documents are changed
-		self.flush_address_and_contact_fields()
 
 	def validate(self):
 		self.set_lead_name()
@@ -210,14 +207,6 @@
 			})
 			self.contact_doc.save()
 
-	def flush_address_and_contact_fields(self):
-		fields = ['address_type', 'address_line1', 'address_line2', 'address_title',
-			'city', 'county', 'country', 'fax', 'pincode', 'state']
-
-		for field in fields:
-			self.set(field, None)
-
-
 @frappe.whitelist()
 def make_customer(source_name, target_doc=None):
 	return _make_customer(source_name, target_doc)
@@ -376,3 +365,8 @@
 	lead = leads[0].name if leads else None
 
 	return lead
+
+def daily_open_lead():
+	leads = frappe.get_all("Lead", filters = [["contact_date", "Between", [nowdate(), nowdate()]]])
+	for lead in leads:
+		frappe.db.set_value("Lead", lead.name, "status", "Open")
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index b61cad3..eee13f7 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -24,7 +24,7 @@
   "converted_by",
   "sales_stage",
   "order_lost_reason",
-  "mins_to_first_response",
+  "first_response_time",
   "expected_closing",
   "next_contact",
   "contact_by",
@@ -153,13 +153,6 @@
    "read_only": 1
   },
   {
-   "bold": 1,
-   "fieldname": "mins_to_first_response",
-   "fieldtype": "Float",
-   "label": "Mins to first response",
-   "read_only": 1
-  },
-  {
    "fieldname": "expected_closing",
    "fieldtype": "Date",
    "label": "Expected Closing Date"
@@ -419,12 +412,19 @@
    "fieldtype": "Link",
    "label": "Converted By",
    "options": "User"
+  },
+  {
+   "bold": 1,
+   "fieldname": "first_response_time",
+   "fieldtype": "Duration",
+   "label": "First Response Time",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-info-sign",
  "idx": 195,
  "links": [],
- "modified": "2020-08-11 17:34:35.066961",
+ "modified": "2020-08-12 17:34:35.066961",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Opportunity",
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py b/erpnext/crm/report/first_response_time_for_opportunity/__init__.py
similarity index 100%
rename from erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py
rename to erpnext/crm/report/first_response_time_for_opportunity/__init__.py
diff --git a/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.js b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.js
new file mode 100644
index 0000000..3f5c95a
--- /dev/null
+++ b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.js
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["First Response Time for Opportunity"] = {
+	"filters": [
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default": frappe.datetime.nowdate()
+		},
+	],
+	get_chart_data: function (_columns, result) {
+		return {
+			data: {
+				labels: result.map(d => d[0]),
+				datasets: [{
+					name: "First Response Time",
+					values: result.map(d => d[1])
+				}]
+			},
+			type: "line",
+			tooltipOptions: {
+				formatTooltipY: d => {
+					let duration_options = {
+						hide_days: 0,
+						hide_seconds: 0
+					};
+					value = frappe.utils.get_formatted_duration(d, duration_options);
+					return value;
+				}
+			}
+		}
+	}
+};
diff --git a/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.json b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.json
new file mode 100644
index 0000000..1b3184f
--- /dev/null
+++ b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.json
@@ -0,0 +1,28 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-08-10 18:34:19.083872",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Test 2",
+ "modified": "2020-08-10 18:34:19.083872",
+ "modified_by": "Administrator",
+ "module": "CRM",
+ "name": "First Response Time for Opportunity",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Opportunity",
+ "report_name": "First Response Time for Opportunity",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Sales User"
+  },
+  {
+   "role": "Sales Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.py b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.py
new file mode 100644
index 0000000..2ffbc3e
--- /dev/null
+++ b/erpnext/crm/report/first_response_time_for_opportunity/first_response_time_for_opportunity.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute(filters=None):
+	columns = [
+		{
+			'fieldname': 'creation_date',
+			'label': 'Date',
+			'fieldtype': 'Date',
+			'width': 300
+		},
+		{
+			'fieldname': 'first_response_time',
+			'fieldtype': 'Duration',
+			'label': 'First Response Time',
+			'width': 300
+		},
+	]
+
+	data = frappe.db.sql('''
+		SELECT
+			date(creation) as creation_date,
+			avg(first_response_time) as avg_response_time
+		FROM tabOpportunity
+		WHERE
+			date(creation) between %s and %s
+			and first_response_time > 0
+		GROUP BY creation_date
+		ORDER BY creation_date desc
+	''', (filters.from_date, filters.to_date))
+
+	return columns, data
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.js b/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.js
deleted file mode 100644
index 92d026a..0000000
--- a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.query_reports["Minutes to First Response for Opportunity"] = {
-	"filters": [
-		{
-			"fieldname": "from_date",
-			"label": __("From Date"),
-			"fieldtype": "Date",
-			'reqd': 1,
-			"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
-		},
-		{
-			"fieldname": "to_date",
-			"label": __("To Date"),
-			"fieldtype": "Date",
-			'reqd': 1,
-			"default": frappe.datetime.nowdate()
-		},
-	],
-	get_chart_data: function (columns, result) {
-		return {
-			data: {
-				labels: result.map(d => d[0]),
-				datasets: [{
-					name: 'Mins to first response',
-					values: result.map(d => d[1])
-				}]
-			},
-			type: 'line',
-		}
-	}
-}
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.json b/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.json
deleted file mode 100644
index bcd092b..0000000
--- a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "add_total_row": 0, 
- "apply_user_permissions": 0, 
- "creation": "2016-06-17 11:28:25.867258", 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 2, 
- "is_standard": "Yes", 
- "modified": "2017-02-24 20:06:08.801109", 
- "modified_by": "Administrator", 
- "module": "CRM", 
- "name": "Minutes to First Response for Opportunity", 
- "owner": "Administrator", 
- "ref_doctype": "Opportunity", 
- "report_name": "Minutes to First Response for Opportunity", 
- "report_type": "Script Report", 
- "roles": [
-  {
-   "role": "Sales User"
-  }, 
-  {
-   "role": "Sales Manager"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.py b/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.py
deleted file mode 100644
index 54e3a60..0000000
--- a/erpnext/crm/report/minutes_to_first_response_for_opportunity/minutes_to_first_response_for_opportunity.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-def execute(filters=None):
-	columns = [
-		{
-			'fieldname': 'creation_date',
-			'label': 'Date',
-			'fieldtype': 'Date'
-		},
-		{
-			'fieldname': 'mins',
-			'fieldtype': 'Float',
-			'label': 'Mins to First Response'
-		},
-	]
-
-	data = frappe.db.sql('''select date(creation) as creation_date,
-		avg(mins_to_first_response) as mins
-		from tabOpportunity
-			where date(creation) between %s and %s
-			and mins_to_first_response > 0
-		group by creation_date order by creation_date desc''', (filters.from_date, filters.to_date))
-
-	return columns, data
diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json
index b3a161d..e396760 100644
--- a/erpnext/education/doctype/question/question.json
+++ b/erpnext/education/doctype/question/question.json
@@ -13,7 +13,7 @@
  "fields": [
   {
    "fieldname": "question",
-   "fieldtype": "Small Text",
+   "fieldtype": "Text Editor",
    "in_list_view": 1,
    "label": "Question",
    "reqd": 1
@@ -34,7 +34,7 @@
    "read_only": 1
   }
  ],
- "modified": "2019-05-30 18:39:21.880974",
+ "modified": "2020-09-24 18:39:21.880974",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Question",
@@ -77,4 +77,4 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json
index 0564482..aab07a3 100644
--- a/erpnext/education/doctype/quiz_question/quiz_question.json
+++ b/erpnext/education/doctype/quiz_question/quiz_question.json
@@ -20,14 +20,14 @@
   {
    "fetch_from": "question_link.question",
    "fieldname": "question",
-   "fieldtype": "Data",
+   "fieldtype": "Text Editor",
    "in_list_view": 1,
    "label": "Question",
    "read_only": 1
   }
  ],
  "istable": 1,
- "modified": "2019-06-12 12:24:02.312577",
+ "modified": "2020-09-24 12:24:02.312577",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Quiz Question",
@@ -37,4 +37,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py
index 532e19c..a033a2a 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py
@@ -2,81 +2,90 @@
 # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
-from __future__ import unicode_literals
-from frappe import _
-from frappe.utils.password import get_decrypted_password
-from plaid import Client
-from plaid.errors import APIError, ItemError
+import plaid
+import requests
+from plaid.errors import APIError, ItemError, InvalidRequestError
 
 import frappe
-import requests
+from frappe import _
+
 
 class PlaidConnector():
 	def __init__(self, access_token=None):
-
-		plaid_settings = frappe.get_single("Plaid Settings")
-
-		self.config = {
-			"plaid_client_id": plaid_settings.plaid_client_id,
-			"plaid_secret": get_decrypted_password("Plaid Settings", "Plaid Settings", 'plaid_secret'),
-			"plaid_public_key": plaid_settings.plaid_public_key,
-			"plaid_env": plaid_settings.plaid_env
-		}
-
-		self.client = Client(client_id=self.config.get("plaid_client_id"),
-			secret=self.config.get("plaid_secret"),
-			public_key=self.config.get("plaid_public_key"),
-			environment=self.config.get("plaid_env")
-			)
-
 		self.access_token = access_token
+		self.settings = frappe.get_single("Plaid Settings")
+		self.products = ["auth", "transactions"]
+		self.client_name = frappe.local.site
+		self.client = plaid.Client(
+			client_id=self.settings.plaid_client_id,
+			secret=self.settings.get_password("plaid_secret"),
+			environment=self.settings.plaid_env,
+			api_version="2019-05-29"
+		)
 
 	def get_access_token(self, public_token):
 		if public_token is None:
 			frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error"))
-
 		response = self.client.Item.public_token.exchange(public_token)
-		access_token = response['access_token']
-
+		access_token = response["access_token"]
 		return access_token
 
+	def get_link_token(self):
+		token_request = {
+			"client_name": self.client_name,
+			"client_id": self.settings.plaid_client_id,
+			"secret": self.settings.plaid_secret,
+			"products": self.products,
+			# only allow Plaid-supported languages and countries (LAST: Sep-19-2020)
+			"language": frappe.local.lang if frappe.local.lang in ["en", "fr", "es", "nl"] else "en",
+			"country_codes": ["US", "CA", "FR", "IE", "NL", "ES", "GB"],
+			"user": {
+				"client_user_id": frappe.generate_hash(frappe.session.user, length=32)
+			}
+		}
+
+		try:
+			response = self.client.LinkToken.create(token_request)
+		except InvalidRequestError:
+			frappe.log_error(frappe.get_traceback(), _("Plaid invalid request error"))
+			frappe.msgprint(_("Please check your Plaid client ID and secret values"))
+		except APIError as e:
+			frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
+			frappe.throw(_(str(e)), title=_("Authentication Failed"))
+		else:
+			return response["link_token"]
+
 	def auth(self):
 		try:
 			self.client.Auth.get(self.access_token)
-			print("Authentication successful.....")
 		except ItemError as e:
-			if e.code == 'ITEM_LOGIN_REQUIRED':
-				pass
-			else:
+			if e.code == "ITEM_LOGIN_REQUIRED":
 				pass
 		except APIError as e:
-			if e.code == 'PLANNED_MAINTENANCE':
-				pass
-			else:
+			if e.code == "PLANNED_MAINTENANCE":
 				pass
 		except requests.Timeout:
 			pass
 		except Exception as e:
-			print(e)
 			frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
-			frappe.msgprint({"title": _("Authentication Failed"), "message":e, "raise_exception":1, "indicator":'red'})
+			frappe.throw(_(str(e)), title=_("Authentication Failed"))
 
 	def get_transactions(self, start_date, end_date, account_id=None):
+		self.auth()
+		kwargs = dict(
+			access_token=self.access_token,
+			start_date=start_date,
+			end_date=end_date
+		)
+		if account_id:
+			kwargs.update(dict(account_ids=[account_id]))
+
 		try:
-			self.auth()
-			if account_id:
-				account_ids = [account_id]
-
-				response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, account_ids=account_ids)
-
-			else:
-				response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date)
-
-			transactions = response['transactions']
-
-			while len(transactions) < response['total_transactions']:
+			response = self.client.Transactions.get(**kwargs)
+			transactions = response["transactions"]
+			while len(transactions) < response["total_transactions"]:
 				response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
-				transactions.extend(response['transactions'])
+				transactions.extend(response["transactions"])
 			return transactions
 		except Exception:
 			frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js
index 0ffbb87..22a4004 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js
@@ -4,14 +4,14 @@
 frappe.provide("erpnext.integrations");
 
 frappe.ui.form.on('Plaid Settings', {
-	enabled: function(frm) {
+	enabled: function (frm) {
 		frm.toggle_reqd('plaid_client_id', frm.doc.enabled);
 		frm.toggle_reqd('plaid_secret', frm.doc.enabled);
-		frm.toggle_reqd('plaid_public_key', frm.doc.enabled);
 		frm.toggle_reqd('plaid_env', frm.doc.enabled);
 	},
-	refresh: function(frm) {
-		if(frm.doc.enabled) {
+
+	refresh: function (frm) {
+		if (frm.doc.enabled) {
 			frm.add_custom_button('Link a new bank account', () => {
 				new erpnext.integrations.plaidLink(frm);
 			});
@@ -22,17 +22,16 @@
 erpnext.integrations.plaidLink = class plaidLink {
 	constructor(parent) {
 		this.frm = parent;
-		this.product = ["transactions", "auth"];
 		this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
 		this.init_config();
 	}
 
-	init_config() {
-		const me = this;
-		me.plaid_env = me.frm.doc.plaid_env;
-		me.plaid_public_key = me.frm.doc.plaid_public_key;
-		me.client_name = frappe.boot.sitename;
-		me.init_plaid();
+	async init_config() {
+		this.product = ["auth", "transactions"];
+		this.plaid_env = this.frm.doc.plaid_env;
+		this.client_name = frappe.boot.sitename;
+		this.token = await this.frm.call("get_link_token").then(resp => resp.message);
+		this.init_plaid();
 	}
 
 	init_plaid() {
@@ -69,17 +68,17 @@
 	}
 
 	onScriptLoaded(me) {
-		me.linkHandler = window.Plaid.create({
+		me.linkHandler = Plaid.create({
 			clientName: me.client_name,
+			product: me.product,
 			env: me.plaid_env,
-			key: me.plaid_public_key,
-			onSuccess: me.plaid_success,
-			product: me.product
+			token: me.token,
+			onSuccess: me.plaid_success
 		});
 	}
 
 	onScriptError(error) {
-		frappe.msgprint('There was an issue loading the link-initialize.js script');
+		frappe.msgprint("There was an issue connecting to Plaid's authentication server");
 		frappe.msgprint(error);
 	}
 
@@ -87,21 +86,25 @@
 		const me = this;
 
 		frappe.prompt({
-			fieldtype:"Link",
+			fieldtype: "Link",
 			options: "Company",
-			label:__("Company"),
-			fieldname:"company",
-			reqd:1
+			label: __("Company"),
+			fieldname: "company",
+			reqd: 1
 		}, (data) => {
 			me.company = data.company;
-			frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {token: token, response: response})
-				.then((result) => {
-					frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {response: response,
-						bank: result, company: me.company});
-				})
-				.then(() => {
-					frappe.show_alert({message:__("Bank accounts added"), indicator:'green'});
+			frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {
+				token: token,
+				response: response
+			}).then((result) => {
+				frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {
+					response: response,
+					bank: result,
+					company: me.company
 				});
+			}).then(() => {
+				frappe.show_alert({ message: __("Bank accounts added"), indicator: 'green' });
+			});
 		}, __("Select a company"), __("Continue"));
 	}
 };
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
index d8203d7..2706217 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "creation": "2018-10-25 10:02:48.656165",
  "doctype": "DocType",
  "editable_grid": 1,
@@ -12,7 +11,6 @@
   "plaid_client_id",
   "plaid_secret",
   "column_break_7",
-  "plaid_public_key",
   "plaid_env"
  ],
  "fields": [
@@ -42,12 +40,6 @@
    "label": "Plaid Secret"
   },
   {
-   "fieldname": "plaid_public_key",
-   "fieldtype": "Data",
-   "in_list_view": 1,
-   "label": "Plaid Public Key"
-  },
-  {
    "fieldname": "plaid_env",
    "fieldtype": "Select",
    "in_list_view": 1,
@@ -69,8 +61,7 @@
   }
  ],
  "issingle": 1,
- "links": [],
- "modified": "2020-02-07 15:21:11.616231",
+ "modified": "2020-09-12 02:31:44.542385",
  "modified_by": "Administrator",
  "module": "ERPNext Integrations",
  "name": "Plaid Settings",
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index c3371ed..e535e81 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -2,30 +2,36 @@
 # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
-from __future__ import unicode_literals
-import frappe
 import json
-from frappe import _
-from frappe.model.document import Document
+
+import frappe
 from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
 from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector
-from frappe.utils import getdate, formatdate, today, add_months
+from frappe import _
 from frappe.desk.doctype.tag.tag import add_tag
+from frappe.model.document import Document
+from frappe.utils import add_months, formatdate, getdate, today
+
 
 class PlaidSettings(Document):
-	pass
+	@staticmethod
+	def get_link_token():
+		plaid = PlaidConnector()
+		return plaid.get_link_token()
+
 
 @frappe.whitelist()
-def plaid_configuration():
+def get_plaid_configuration():
 	if frappe.db.get_single_value("Plaid Settings", "enabled"):
 		plaid_settings = frappe.get_single("Plaid Settings")
 		return {
-			"plaid_public_key": plaid_settings.plaid_public_key,
 			"plaid_env": plaid_settings.plaid_env,
+			"link_token": plaid_settings.get_link_token(),
 			"client_name": frappe.local.site
 		}
-	else:
-		return "disabled"
+
+	return "disabled"
+
 
 @frappe.whitelist()
 def add_institution(token, response):
@@ -33,6 +39,7 @@
 
 	plaid = PlaidConnector()
 	access_token = plaid.get_access_token(token)
+	bank = None
 
 	if not frappe.db.exists("Bank", response["institution"]["name"]):
 		try:
@@ -44,7 +51,6 @@
 			bank.insert()
 		except Exception:
 			frappe.throw(frappe.get_traceback())
-
 	else:
 		bank = frappe.get_doc("Bank", response["institution"]["name"])
 		bank.plaid_access_token = access_token
@@ -52,6 +58,7 @@
 
 	return bank
 
+
 @frappe.whitelist()
 def add_bank_accounts(response, bank, company):
 	try:
@@ -92,9 +99,8 @@
 				new_account.insert()
 
 				result.append(new_account.name)
-
 			except frappe.UniqueValidationError:
-				frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(new_account.account_name))
+				frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(account["name"]))
 			except Exception:
 				frappe.throw(frappe.get_traceback())
 
@@ -103,6 +109,7 @@
 
 	return result
 
+
 def add_account_type(account_type):
 	try:
 		frappe.get_doc({
@@ -122,10 +129,11 @@
 	except Exception:
 		frappe.throw(frappe.get_traceback())
 
+
 @frappe.whitelist()
 def sync_transactions(bank, bank_account):
-	'''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'''
+	"""Sync transactions based on the last integration date as the start date, after 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")
@@ -147,10 +155,10 @@
 				len(result), bank_account, start_date, end_date))
 
 			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"))
 
+
 def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
 	access_token = None
 
@@ -168,6 +176,7 @@
 
 	return transactions
 
+
 def new_bank_transaction(transaction):
 	result = []
 
@@ -182,8 +191,8 @@
 
 	status = "Pending" if transaction["pending"] == "True" else "Settled"
 
+	tags = []
 	try:
-		tags  = []
 		tags += transaction["category"]
 		tags += ["Plaid Cat. {}".format(transaction["category_id"])]
 	except KeyError:
@@ -216,6 +225,7 @@
 
 	return result
 
+
 def automatic_synchronization():
 	settings = frappe.get_doc("Plaid Settings", "Plaid Settings")
 
@@ -223,4 +233,8 @@
 		plaid_accounts = frappe.get_all("Bank Account", filters={"integration_id": ["!=", ""]}, fields=["name", "bank"])
 
 		for plaid_account in plaid_accounts:
-			frappe.enqueue("erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions", bank=plaid_account.bank, bank_account=plaid_account.name)
+			frappe.enqueue(
+				"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions",
+				bank=plaid_account.bank,
+				bank_account=plaid_account.name
+			)
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
index 1a063d6..3c90637 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
@@ -1,14 +1,17 @@
 # -*- coding: utf-8 -*-
 # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
-from __future__ import unicode_literals
 
-import unittest
-import frappe
-from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import plaid_configuration, add_account_type, add_account_subtype, new_bank_transaction, add_bank_accounts
 import json
-from frappe.utils.response import json_handler
+import unittest
+
+import frappe
 from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
+from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import (
+	add_account_subtype, add_account_type, add_bank_accounts,
+	new_bank_transaction, get_plaid_configuration)
+from frappe.utils.response import json_handler
+
 
 class TestPlaidSettings(unittest.TestCase):
 	def setUp(self):
@@ -31,7 +34,7 @@
 
 	def test_plaid_disabled(self):
 		frappe.db.set_value("Plaid Settings", None, "enabled", 0)
-		self.assertTrue(plaid_configuration() == "disabled")
+		self.assertTrue(get_plaid_configuration() == "disabled")
 
 	def test_add_account_type(self):
 		add_account_type("brokerage")
@@ -64,7 +67,7 @@
 				'mask': '0000',
 				'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
 				'name': 'Plaid Checking'
-				}],
+			}],
 			'institution': {
 				'institution_id': 'ins_6',
 				'name': 'Citi'
@@ -100,7 +103,7 @@
 				'mask': '0000',
 				'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
 				'name': 'Plaid Checking'
-				}],
+			}],
 			'institution': {
 				'institution_id': 'ins_6',
 				'name': 'Citi'
@@ -152,4 +155,4 @@
 
 		new_bank_transaction(transactions)
 
-		self.assertTrue(len(frappe.get_all("Bank Transaction")) == 1)
\ No newline at end of file
+		self.assertTrue(len(frappe.get_all("Bank Transaction")) == 1)
diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
index 5339c99..2e10751 100644
--- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
+++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.json
@@ -258,8 +258,8 @@
   }
  ],
  "issingle": 1,
- "modified": "2020-05-28 12:32:11.384757",
- "modified_by": "umair@erpnext.com",
+ "modified": "2020-09-18 17:26:09.703215",
+ "modified_by": "Administrator",
  "module": "ERPNext Integrations",
  "name": "Shopify Settings",
  "owner": "Administrator",
diff --git a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
index 9faa5b2..cf54e82 100644
--- a/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
+++ b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
@@ -117,12 +117,12 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-05-08 13:45:57.226530", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Healthcare Schedule Time Slot", 
  "name_case": "", 
- "owner": "rmehta@gmail.com", 
+ "owner": "Administrator", 
  "permissions": [], 
  "quick_entry": 1, 
  "read_only": 0, 
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 512fb48..e685b20 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -6,7 +6,7 @@
 import frappe
 from frappe.model.document import Document
 import json
-from frappe.utils import getdate, get_time
+from frappe.utils import getdate, get_time, flt
 from frappe.model.mapper import get_mapped_doc
 from frappe import _
 import datetime
@@ -45,7 +45,7 @@
 
 	def validate_overlaps(self):
 		end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) \
-			 + datetime.timedelta(minutes=float(self.duration))
+			 + datetime.timedelta(minutes=flt(self.duration))
 
 		overlaps = frappe.db.sql("""
 		select
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
index cff100c..a21825e 100644
--- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
@@ -44,11 +44,11 @@
   }
  ],
  "links": [],
- "modified": "2020-01-31 12:21:45.975488",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Practitioner Schedule",
- "owner": "rmehta@gmail.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 463ad6c..4e05076 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -282,6 +282,11 @@
 ]
 
 scheduler_events = {
+	"cron": {
+		"0/30 * * * *": [
+			"erpnext.utilities.doctype.video.video.update_youtube_data",
+		]
+	},
 	"all": [
 		"erpnext.projects.doctype.project.project.project_status_update_reminder",
 		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
@@ -331,7 +336,8 @@
 		"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
 		"erpnext.hr.utils.generate_leave_encashment",
 		"erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.create_process_loan_security_shortfall",
-		"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
+		"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans",
+		"erpnext.crm.doctype.lead.lead.daily_open_lead"
 	],
 	"monthly_long": [
 		"erpnext.accounts.deferred_revenue.process_deferred_accounting",
diff --git a/erpnext/hr/doctype/appraisal/appraisal.json b/erpnext/hr/doctype/appraisal/appraisal.json
index 4f6da97..91201d4 100644
--- a/erpnext/hr/doctype/appraisal/appraisal.json
+++ b/erpnext/hr/doctype/appraisal/appraisal.json
@@ -696,11 +696,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2019-01-30 11:28:08.401459", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Appraisal", 
- "owner": "ashwini@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 0, 
diff --git a/erpnext/hr/doctype/appraisal_goal/appraisal_goal.json b/erpnext/hr/doctype/appraisal_goal/appraisal_goal.json
index f22969b..b8ec5a8 100644
--- a/erpnext/hr/doctype/appraisal_goal/appraisal_goal.json
+++ b/erpnext/hr/doctype/appraisal_goal/appraisal_goal.json
@@ -207,11 +207,11 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:27:57.897071", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Appraisal Goal", 
- "owner": "ashwini@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [], 
  "quick_entry": 0, 
  "read_only": 0, 
diff --git a/erpnext/hr/doctype/appraisal_template/appraisal_template.json b/erpnext/hr/doctype/appraisal_template/appraisal_template.json
index ac6e400..7329c35 100644
--- a/erpnext/hr/doctype/appraisal_template/appraisal_template.json
+++ b/erpnext/hr/doctype/appraisal_template/appraisal_template.json
@@ -113,11 +113,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-12-13 12:37:56.937023", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Appraisal Template", 
- "owner": "ashwini@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 0, 
diff --git a/erpnext/hr/doctype/appraisal_template_goal/appraisal_template_goal.json b/erpnext/hr/doctype/appraisal_template_goal/appraisal_template_goal.json
index 34ea5d8..2858419 100644
--- a/erpnext/hr/doctype/appraisal_template_goal/appraisal_template_goal.json
+++ b/erpnext/hr/doctype/appraisal_template_goal/appraisal_template_goal.json
@@ -78,11 +78,11 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:27:57.979215", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Appraisal Template Goal", 
- "owner": "ashwini@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [], 
  "quick_entry": 0, 
  "read_only": 0, 
diff --git a/erpnext/hr/doctype/attendance/attendance.json b/erpnext/hr/doctype/attendance/attendance.json
index a656a7e..134098f 100644
--- a/erpnext/hr/doctype/attendance/attendance.json
+++ b/erpnext/hr/doctype/attendance/attendance.json
@@ -205,11 +205,11 @@
  "idx": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-05-29 13:51:37.177231",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Attendance",
- "owner": "ashwini@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "cancel": 1,
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index fa28470..e3e6e80 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -371,12 +371,12 @@
  "idx": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-06-15 12:43:04.099803",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim",
  "name_case": "Title Case",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "amend": 1,
diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
index 3cce50e..70a48f9 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -120,11 +120,11 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-05-11 18:54:35.601592",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim Detail",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC"
diff --git a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
index cf2cbb4..02ab4cb 100644
--- a/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
+++ b/erpnext/hr/doctype/expense_claim_type/expense_claim_type.json
@@ -48,11 +48,11 @@
  "icon": "fa fa-flag",
  "idx": 1,
  "links": [],
- "modified": "2019-12-11 13:38:59.534034",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Expense Claim Type",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.json b/erpnext/hr/doctype/upload_attendance/upload_attendance.json
index 16b7a83..a1451fd 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.json
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.json
@@ -229,11 +229,11 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 1, 
- "modified": "2017-11-14 12:51:34.980103", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Upload Attendance", 
- "owner": "harshada@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 0, 
diff --git a/erpnext/hub_node/data_migration_mapping/company_to_hub_company/company_to_hub_company.json b/erpnext/hub_node/data_migration_mapping/company_to_hub_company/company_to_hub_company.json
index ae0d492..b1e421d 100644
--- a/erpnext/hub_node/data_migration_mapping/company_to_hub_company/company_to_hub_company.json
+++ b/erpnext/hub_node/data_migration_mapping/company_to_hub_company/company_to_hub_company.json
@@ -40,8 +40,8 @@
  "mapping_name": "Company to Hub Company",
  "mapping_type": "Push",
  "migration_id_field": "hub_sync_id",
- "modified": "2018-02-14 15:57:05.571142",
- "modified_by": "achilles@erpnext.com",
+ "modified": "2020-09-18 17:26:09.703215",
+ "modified_by": "Administrator",
  "name": "Company to Hub Company",
  "owner": "Administrator",
  "page_length": 10,
diff --git a/erpnext/hub_node/data_migration_mapping/hub_message_to_lead/hub_message_to_lead.json b/erpnext/hub_node/data_migration_mapping/hub_message_to_lead/hub_message_to_lead.json
index d2af755..d11abeb 100644
--- a/erpnext/hub_node/data_migration_mapping/hub_message_to_lead/hub_message_to_lead.json
+++ b/erpnext/hub_node/data_migration_mapping/hub_message_to_lead/hub_message_to_lead.json
@@ -21,10 +21,10 @@
  "mapping_name": "Hub Message to Lead",
  "mapping_type": "Pull",
  "migration_id_field": "hub_sync_id",
- "modified": "2018-02-14 15:57:05.606597",
- "modified_by": "achilles@erpnext.com",
+ "modified": "2020-09-18 17:26:09.703215",
+ "modified_by": "Administrator",
  "name": "Hub Message to Lead",
- "owner": "frappetest@gmail.com",
+ "owner": "Administrator",
  "page_length": 10,
  "remote_objectname": "Hub Message",
  "remote_primary_key": "name"
diff --git a/erpnext/hub_node/doctype/hub_user/hub_user.json b/erpnext/hub_node/doctype/hub_user/hub_user.json
index a660022..f51ffb4 100644
--- a/erpnext/hub_node/doctype/hub_user/hub_user.json
+++ b/erpnext/hub_node/doctype/hub_user/hub_user.json
@@ -121,8 +121,8 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-09-01 13:56:07.816894", 
- "modified_by": "netchamp@rawcoderz.com", 
+ "modified": "2020-09-18 17:26:09.703215", 
+ "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Hub User", 
  "name_case": "", 
diff --git a/erpnext/hub_node/doctype/hub_users/hub_users.json b/erpnext/hub_node/doctype/hub_users/hub_users.json
index 2027e72..d42f3fd 100644
--- a/erpnext/hub_node/doctype/hub_users/hub_users.json
+++ b/erpnext/hub_node/doctype/hub_users/hub_users.json
@@ -54,12 +54,12 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2018-03-06 04:41:17.916243", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Hub Users", 
  "name_case": "", 
- "owner": "test1@example.com", 
+ "owner": "Administrator", 
  "permissions": [], 
  "quick_entry": 1, 
  "read_only": 0, 
diff --git a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
index 4b49f19..e784f68 100644
--- a/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
+++ b/erpnext/hub_node/doctype/marketplace_settings/marketplace_settings.json
@@ -352,12 +352,12 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2019-02-01 14:21:16.729848", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Marketplace Settings", 
  "name_case": "", 
- "owner": "netchamp@rawcoderz.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 0, 
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
index 3788bc3..606d22f 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
@@ -813,7 +813,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-08-21 14:44:33.670332", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Maintenance", 
  "name": "Maintenance Schedule", 
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json
index 1192568..32bfa0e 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json
@@ -1001,11 +1001,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2020-07-15 14:44:44.911402", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Maintenance", 
  "name": "Maintenance Visit", 
- "owner": "ashwini@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 1, 
diff --git a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json
index 84dc72c..467441d 100644
--- a/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json
+++ b/erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json
@@ -125,11 +125,11 @@
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-10-03 14:55:52.786805",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Maintenance",
  "name": "Maintenance Visit Purpose",
- "owner": "ashwini@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
diff --git a/erpnext/non_profit/doctype/donor/donor.json b/erpnext/non_profit/doctype/donor/donor.json
index 7e24dac..9639265 100644
--- a/erpnext/non_profit/doctype/donor/donor.json
+++ b/erpnext/non_profit/doctype/donor/donor.json
@@ -1,336 +1,105 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 1, 
- "autoname": "field:email", 
- "beta": 0, 
- "creation": "2017-09-19 16:20:27.510196", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:email",
+ "creation": "2017-09-19 16:20:27.510196",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "donor_name",
+  "column_break_5",
+  "donor_type",
+  "email",
+  "image",
+  "address_contacts",
+  "address_html",
+  "column_break_9",
+  "contact_html"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "donor_name", 
-   "fieldtype": "Data", 
-   "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": "Donor Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "donor_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Donor Name",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_5", 
-   "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, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_5",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "donor_type", 
-   "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": "Donor Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Donor Type", 
-   "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, 
-   "unique": 0
-  }, 
+   "fieldname": "donor_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Donor Type",
+   "options": "Donor Type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "email", 
-   "fieldtype": "Data", 
-   "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": "Email", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "email",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Email",
+   "reqd": 1,
+   "unique": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "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": "Image", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "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, 
-   "unique": 0
-  }, 
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image",
+   "no_copy": 1,
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_contacts", 
-   "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": "Address and Contact", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "fa fa-map-marker", 
-   "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, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:!doc.__islocal;",
+   "fieldname": "address_contacts",
+   "fieldtype": "Section Break",
+   "label": "Address and Contact",
+   "options": "fa fa-map-marker"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_html", 
-   "fieldtype": "HTML", 
-   "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": "Address HTML", 
-   "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, 
-   "unique": 0
-  }, 
+   "fieldname": "address_html",
+   "fieldtype": "HTML",
+   "label": "Address HTML"
+  },
   {
-   "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, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "contact_html", 
-   "fieldtype": "HTML", 
-   "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": "Contact HTML", 
-   "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, 
-   "unique": 0
+   "fieldname": "contact_html",
+   "fieldtype": "HTML",
+   "label": "Contact HTML"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_field": "image", 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-01-22 15:53:35.059946", 
- "modified_by": "Administrator", 
- "module": "Non Profit", 
- "name": "Donor", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-09-16 23:46:04.083274",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Donor",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 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": "Non Profit Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Non Profit", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "donor_name", 
- "track_changes": 1, 
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "donor_name",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json
index 77cdb94..992ef16 100644
--- a/erpnext/non_profit/doctype/member/member.json
+++ b/erpnext/non_profit/doctype/member/member.json
@@ -111,6 +111,7 @@
    "options": "Supplier"
   },
   {
+   "depends_on": "eval:!doc.__islocal;",
    "fieldname": "address_contacts",
    "fieldtype": "Section Break",
    "label": "Address and Contact",
@@ -177,7 +178,7 @@
  ],
  "image_field": "image",
  "links": [],
- "modified": "2020-08-06 10:06:01.153564",
+ "modified": "2020-09-16 23:44:13.596948",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Member",
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
index 95bb3a5..7f21896 100644
--- a/erpnext/non_profit/doctype/membership/membership.json
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -90,9 +90,9 @@
   },
   {
    "fieldname": "currency",
-   "fieldtype": "Select",
+   "fieldtype": "Link",
    "label": "Currency",
-   "options": "USD\nINR"
+   "options": "Currency"
   },
   {
    "fieldname": "amount",
@@ -126,7 +126,7 @@
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-07-31 13:57:02.328995",
+ "modified": "2020-09-19 14:28:11.532696",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Membership",
@@ -161,4 +161,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/non_profit/doctype/volunteer/volunteer.json b/erpnext/non_profit/doctype/volunteer/volunteer.json
index 052b288..08b7f87 100644
--- a/erpnext/non_profit/doctype/volunteer/volunteer.json
+++ b/erpnext/non_profit/doctype/volunteer/volunteer.json
@@ -1,580 +1,148 @@
 {
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 1, 
- "autoname": "field:email", 
- "beta": 0, 
- "creation": "2017-09-19 16:16:45.676019", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:email",
+ "creation": "2017-09-19 16:16:45.676019",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "volunteer_name",
+  "column_break_5",
+  "volunteer_type",
+  "email",
+  "image",
+  "address_contacts",
+  "address_html",
+  "column_break_9",
+  "contact_html",
+  "volunteer_availability_and_skills_details",
+  "availability",
+  "availability_timeslot",
+  "column_break_12",
+  "volunteer_skills",
+  "section_break_15",
+  "note"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "volunteer_name", 
-   "fieldtype": "Data", 
-   "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": "Volunteer Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "volunteer_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Volunteer Name",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_5", 
-   "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_5",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "volunteer_type", 
-   "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": "Volunteer Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Volunteer Type", 
-   "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": "volunteer_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Volunteer Type",
+   "options": "Volunteer Type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "email", 
-   "fieldtype": "Data", 
-   "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": "Email", 
-   "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": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
+   "fieldname": "email",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Email",
+   "reqd": 1,
    "unique": 1
-  }, 
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "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": "Image", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "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": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image",
+   "no_copy": 1,
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_contacts", 
-   "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": "Address and Contact", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "fa fa-map-marker", 
-   "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.__islocal;",
+   "fieldname": "address_contacts",
+   "fieldtype": "Section Break",
+   "label": "Address and Contact",
+   "options": "fa fa-map-marker"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_html", 
-   "fieldtype": "HTML", 
-   "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": "Address HTML", 
-   "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": "address_html",
+   "fieldtype": "HTML",
+   "label": "Address HTML"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 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
-  }, 
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "contact_html", 
-   "fieldtype": "HTML", 
-   "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": "Contact HTML", 
-   "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": "contact_html",
+   "fieldtype": "HTML",
+   "label": "Contact HTML"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "volunteer_availability_and_skills_details", 
-   "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": "Availability and Skills", 
-   "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": "volunteer_availability_and_skills_details",
+   "fieldtype": "Section Break",
+   "label": "Availability and Skills"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "availability", 
-   "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": "Availability", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nWeekly\nWeekdays\nWeekends", 
-   "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": "availability",
+   "fieldtype": "Select",
+   "label": "Availability",
+   "options": "\nWeekly\nWeekdays\nWeekends"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "availability_timeslot", 
-   "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": "Availability Timeslot", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "\nMorning\nAfternoon\nEvening\nAnytime", 
-   "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": "availability_timeslot",
+   "fieldtype": "Select",
+   "label": "Availability Timeslot",
+   "options": "\nMorning\nAfternoon\nEvening\nAnytime"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_12", 
-   "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_12",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "volunteer_skills", 
-   "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": "Volunteer Skills", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Volunteer Skill", 
-   "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": "volunteer_skills",
+   "fieldtype": "Table",
+   "label": "Volunteer Skills",
+   "options": "Volunteer Skill"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "section_break_15", 
-   "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_15",
+   "fieldtype": "Section Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "note", 
-   "fieldtype": "Long 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": "Note", 
-   "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": "note",
+   "fieldtype": "Long Text",
+   "label": "Note"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_field": "image", 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-11-04 03:36:25.776211", 
- "modified_by": "Administrator", 
- "module": "Non Profit", 
- "name": "Volunteer", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-09-16 23:45:15.595952",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Volunteer",
+ "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": "Non Profit Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Non Profit", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "volunteer_name", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "volunteer_name",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9ce570e..6087ce2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -690,6 +690,7 @@
 erpnext.patches.v13_0.update_old_loans
 erpnext.patches.v12_0.set_serial_no_status #2020-05-21
 erpnext.patches.v12_0.update_price_list_currency_in_bom
+execute:frappe.reload_doctype('Dashboard')
 execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
 erpnext.patches.v13_0.update_actual_start_and_end_date_in_wo
 erpnext.patches.v13_0.set_company_field_in_healthcare_doctypes #2020-05-25
@@ -725,4 +726,6 @@
 erpnext.patches.v13_0.drop_razorpay_payload_column
 erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
 erpnext.patches.v13_0.setting_custom_roles_for_some_regional_reports
+erpnext.patches.v13_0.rename_issue_doctype_fields
 erpnext.patches.v13_0.change_default_pos_print_format
+erpnext.patches.v13_0.set_youtube_video_id
diff --git a/erpnext/patches/v12_0/move_plaid_settings_to_doctype.py b/erpnext/patches/v12_0/move_plaid_settings_to_doctype.py
index 8e60d33..d2bcb12 100644
--- a/erpnext/patches/v12_0/move_plaid_settings_to_doctype.py
+++ b/erpnext/patches/v12_0/move_plaid_settings_to_doctype.py
@@ -4,17 +4,16 @@
 from __future__ import unicode_literals
 import frappe
 
+
 def execute():
 	frappe.reload_doc("erpnext_integrations", "doctype", "plaid_settings")
 	plaid_settings = frappe.get_single("Plaid Settings")
 	if plaid_settings.enabled:
-		if not (frappe.conf.plaid_client_id and frappe.conf.plaid_env \
-			and frappe.conf.plaid_public_key and frappe.conf.plaid_secret):
+		if not (frappe.conf.plaid_client_id and frappe.conf.plaid_env and frappe.conf.plaid_secret):
 			plaid_settings.enabled = 0
 		else:
 			plaid_settings.update({
 				"plaid_client_id": frappe.conf.plaid_client_id,
-				"plaid_public_key": frappe.conf.plaid_public_key,
 				"plaid_env": frappe.conf.plaid_env,
 				"plaid_secret": frappe.conf.plaid_secret
 			})
diff --git a/erpnext/patches/v13_0/rename_issue_doctype_fields.py b/erpnext/patches/v13_0/rename_issue_doctype_fields.py
new file mode 100644
index 0000000..5bd6596
--- /dev/null
+++ b/erpnext/patches/v13_0/rename_issue_doctype_fields.py
@@ -0,0 +1,65 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+	if frappe.db.exists('DocType', 'Issue'):
+		issues = frappe.db.get_all('Issue', fields=['name', 'response_by_variance', 'resolution_by_variance', 'mins_to_first_response'],
+			 order_by='creation desc')
+		frappe.reload_doc('support', 'doctype', 'issue')
+
+		# rename fields
+		rename_map = {
+			'agreement_fulfilled': 'agreement_status',
+			'mins_to_first_response': 'first_response_time'
+		}
+		for old, new in rename_map.items():
+			rename_field('Issue', old, new)
+
+		# change fieldtype to duration
+		count = 0
+		for entry in issues:
+			response_by_variance = convert_to_seconds(entry.response_by_variance, 'Hours')
+			resolution_by_variance = convert_to_seconds(entry.resolution_by_variance, 'Hours')
+			mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes')
+			frappe.db.set_value('Issue', entry.name, {
+				'response_by_variance': response_by_variance,
+				'resolution_by_variance': resolution_by_variance,
+				'first_response_time': mins_to_first_response
+			})
+			# commit after every 100 updates
+			count += 1
+			if count%100 == 0:
+				frappe.db.commit()
+
+	if frappe.db.exists('DocType', 'Opportunity'):
+		opportunities = frappe.db.get_all('Opportunity', fields=['name', 'mins_to_first_response'], order_by='creation desc')
+		frappe.reload_doc('crm', 'doctype', 'opportunity')
+		rename_field('Opportunity', 'mins_to_first_response', 'first_response_time')
+
+		# change fieldtype to duration
+		count = 0
+		for entry in opportunities:
+			mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes')
+			frappe.db.set_value('Opportunity', entry.name, 'first_response_time', mins_to_first_response)
+			# commit after every 100 updates
+			count += 1
+			if count%100 == 0:
+				frappe.db.commit()
+
+	# renamed reports from "Minutes to First Response for Issues" to "First Response Time for Issues". Same for Opportunity
+	for report in ['Minutes to First Response for Issues', 'Minutes to First Response for Opportunity']:
+		if frappe.db.exists('Report', report):
+			frappe.delete_doc('Report', report)
+
+
+def convert_to_seconds(value, unit):
+	seconds = 0
+	if unit == 'Hours':
+		seconds = value * 3600
+	if unit == 'Minutes':
+		seconds = value * 60
+	return seconds
diff --git a/erpnext/patches/v13_0/set_youtube_video_id.py b/erpnext/patches/v13_0/set_youtube_video_id.py
new file mode 100644
index 0000000..c3b49eb
--- /dev/null
+++ b/erpnext/patches/v13_0/set_youtube_video_id.py
@@ -0,0 +1,10 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.utilities.doctype.video.video import get_id_from_url
+
+def execute():
+	frappe.reload_doc("utilities", "doctype","video")
+
+	for video in frappe.get_all("Video", fields=["name", "url", "youtube_video_id"]):
+		if video.url and not video.youtube_video_id:
+			frappe.db.set_value("Video", video.name, "youtube_video_id", get_id_from_url(video.url))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/dependent_task/dependent_task.json b/erpnext/projects/doctype/dependent_task/dependent_task.json
index e00a2b2..858a554 100644
--- a/erpnext/projects/doctype/dependent_task/dependent_task.json
+++ b/erpnext/projects/doctype/dependent_task/dependent_task.json
@@ -48,8 +48,8 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-10-26 17:37:25.638190", 
- "modified_by": "rohitw1991@gmail.com", 
+ "modified": "2020-09-18 17:26:09.703215", 
+ "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Dependent Task", 
  "name_case": "", 
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 2af9140..eb709e5 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -11,7 +11,9 @@
 	"Territory": "Selling",
 	"Sales Person": "Selling",
 	"Sales Partner": "Selling",
-	"Brand": "Stock"
+	"Brand": "Stock",
+	"Maintenance Schedule": "Support",
+	"Maintenance Visit": "Support"
 });
 
 $.extend(frappe.breadcrumbs.module_map, {
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index f4eaad5..6e97d81 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -120,7 +120,7 @@
 
 var get_payment_mode_account = function(frm, mode_of_payment, callback) {
 	if(!frm.doc.company) {
-		frappe.throw(__("Please select the Company first"));
+		frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
 	}
 
 	if(!mode_of_payment) {
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 6d58fd2..be30086 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -595,7 +595,7 @@
 			$.each(actual_taxes_dict, function(key, value) {
 				if (value) total_actual_tax += value;
 			});
-			
+
 			return flt(this.frm.doc.grand_total - total_actual_tax, precision("grand_total"));
 		}
 	},
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 792235f..3391179 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -417,7 +417,7 @@
 		var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
 			me.frm.doc.name);
 
-		if (!this.frm.doc.taxes_and_charges && this.frm.doc.taxes) {
+		if (!this.frm.doc.taxes_and_charges && this.frm.doc.taxes && this.frm.doc.taxes.length > 0) {
 			return;
 		}
 
diff --git a/erpnext/public/js/education/lms/quiz.js b/erpnext/public/js/education/lms/quiz.js
index 91cbbf4..4a9d1e3 100644
--- a/erpnext/public/js/education/lms/quiz.js
+++ b/erpnext/public/js/education/lms/quiz.js
@@ -140,7 +140,7 @@
 	make_question() {
 		let question_wrapper = document.createElement('h5');
 		question_wrapper.classList.add('mt-3');
-		question_wrapper.innerText = this.question;
+		question_wrapper.innerHTML = this.question;
 		this.wrapper.appendChild(question_wrapper);
 	}
 
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 87982f1..9ed5009 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -480,7 +480,7 @@
 				callback: r => {
 					if(!r.exc) {
 						if (this.doc.conversion_factor == r.message.conversion_factor) return;
-						
+
 						const docname = this.doc.docname;
 						dialog.fields_dict.trans_items.df.data.some(doc => {
 							if (doc.docname == docname) {
@@ -677,6 +677,7 @@
 			date_field: opts.date_field || undefined,
 			setters: opts.setters,
 			get_query: opts.get_query,
+			add_filters_group: 1,
 			action: function(selections, args) {
 				let values = selections;
 				if(values.length === 0){
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index 0653267..44e75ae 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -224,6 +224,10 @@
 		party = frm.doc.party_name;
 	}
 
+	if (!frm.doc.company) {
+		frappe.throw(__("Kindly select the company first"));
+	}
+
 	frappe.call({
 		method: "erpnext.accounts.party.set_taxes",
 		args: {
@@ -292,4 +296,4 @@
 	} else {
 		frappe.msgprint(__("Select company first"));
 	}
-}
\ No newline at end of file
+}
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/__init__.py b/erpnext/regional/germany/utils/__init__.py
similarity index 100%
copy from erpnext/support/report/minutes_to_first_response_for_issues/__init__.py
copy to erpnext/regional/germany/utils/__init__.py
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py b/erpnext/regional/germany/utils/datev/__init__.py
similarity index 100%
copy from erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py
copy to erpnext/regional/germany/utils/datev/__init__.py
diff --git a/erpnext/regional/report/datev/datev_constants.py b/erpnext/regional/germany/utils/datev/datev_constants.py
similarity index 89%
rename from erpnext/regional/report/datev/datev_constants.py
rename to erpnext/regional/germany/utils/datev/datev_constants.py
index e063703..63f9a77 100644
--- a/erpnext/regional/report/datev/datev_constants.py
+++ b/erpnext/regional/germany/utils/datev/datev_constants.py
@@ -460,80 +460,8 @@
 	"Sprach-ID"
 ]
 
-QUERY_REPORT_COLUMNS = [
-	{
-		"label": "Umsatz (ohne Soll/Haben-Kz)",
-		"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
-		"fieldtype": "Currency",
-		"width": 100
-	},
-	{
-		"label": "Soll/Haben-Kennzeichen",
-		"fieldname": "Soll/Haben-Kennzeichen",
-		"fieldtype": "Data",
-		"width": 100
-	},
-	{
-		"label": "Konto",
-		"fieldname": "Konto",
-		"fieldtype": "Data",
-		"width": 100
-	},
-	{
-		"label": "Gegenkonto (ohne BU-Schlüssel)",
-		"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
-		"fieldtype": "Data",
-		"width": 100
-	},
-	{
-		"label": "Belegdatum",
-		"fieldname": "Belegdatum",
-		"fieldtype": "Date",
-		"width": 100
-	},
-	{
-		"label": "Belegfeld 1",
-		"fieldname": "Belegfeld 1",
-		"fieldtype": "Data",
-		"width": 150
-	},
-	{
-		"label": "Buchungstext",
-		"fieldname": "Buchungstext",
-		"fieldtype": "Text",
-		"width": 300
-	},
-	{
-		"label": "Beleginfo - Art 1",
-		"fieldname": "Beleginfo - Art 1",
-		"fieldtype": "Link",
-		"options": "DocType",
-		"width": 100
-	},
-	{
-		"label": "Beleginfo - Inhalt 1",
-		"fieldname": "Beleginfo - Inhalt 1",
-		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 1",
-		"width": 150
-	},
-	{
-		"label": "Beleginfo - Art 2",
-		"fieldname": "Beleginfo - Art 2",
-		"fieldtype": "Link",
-		"options": "DocType",
-		"width": 100
-	},
-	{
-		"label": "Beleginfo - Inhalt 2",
-		"fieldname": "Beleginfo - Inhalt 2",
-		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 2",
-		"width": 150
-	}
-]
-
 class DataCategory():
+
 	"""Field of the CSV Header."""
 
 	DEBTORS_CREDITORS = "16"
@@ -542,6 +470,7 @@
 	POSTING_TEXT_CONSTANTS = "67"
 
 class FormatName():
+
 	"""Field of the CSV Header, corresponds to DataCategory."""
 
 	DEBTORS_CREDITORS = "Debitoren/Kreditoren"
diff --git a/erpnext/regional/germany/utils/datev/datev_csv.py b/erpnext/regional/germany/utils/datev/datev_csv.py
new file mode 100644
index 0000000..aae734f
--- /dev/null
+++ b/erpnext/regional/germany/utils/datev/datev_csv.py
@@ -0,0 +1,174 @@
+# coding: utf-8
+from __future__ import unicode_literals
+
+import datetime
+import zipfile
+from csv import QUOTE_NONNUMERIC
+from six import BytesIO
+
+import six
+import frappe
+import pandas as pd
+from frappe import _
+from .datev_constants import DataCategory
+
+
+def get_datev_csv(data, filters, csv_class):
+	"""
+	Fill in missing columns and return a CSV in DATEV Format.
+
+	For automatic processing, DATEV requires the first line of the CSV file to
+	hold meta data such as the length of account numbers oder the category of
+	the data.
+
+	Arguments:
+	data -- array of dictionaries
+	filters -- dict
+	csv_class -- defines DATA_CATEGORY, FORMAT_NAME and COLUMNS
+	"""
+	empty_df = pd.DataFrame(columns=csv_class.COLUMNS)
+	data_df = pd.DataFrame.from_records(data)
+	result = empty_df.append(data_df, sort=True)
+
+	if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS:
+		result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
+
+	if csv_class.DATA_CATEGORY == DataCategory.ACCOUNT_NAMES:
+		result['Sprach-ID'] = 'de-DE'
+
+	data = result.to_csv(
+		# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
+		sep=str(';'),
+		# European decimal seperator
+		decimal=',',
+		# Windows "ANSI" encoding
+		encoding='latin_1',
+		# format date as DDMM
+		date_format='%d%m',
+		# Windows line terminator
+		line_terminator='\r\n',
+		# Do not number rows
+		index=False,
+		# Use all columns defined above
+		columns=csv_class.COLUMNS,
+		# Quote most fields, even currency values with "," separator
+		quoting=QUOTE_NONNUMERIC
+	)
+
+	if not six.PY2:
+		data = data.encode('latin_1')
+
+	header = get_header(filters, csv_class)
+	header = ';'.join(header).encode('latin_1')
+
+	# 1st Row: Header with meta data
+	# 2nd Row: Data heading (Überschrift der Nutzdaten), included in `data` here.
+	# 3rd - nth Row: Data (Nutzdaten)
+	return header + b'\r\n' + data
+
+
+def get_header(filters, csv_class):
+	description = filters.get('voucher_type', csv_class.FORMAT_NAME)
+	company = filters.get('company')
+	datev_settings = frappe.get_doc('DATEV Settings', {'client': company})
+	default_currency = frappe.get_value('Company', company, 'default_currency')
+	coa = frappe.get_value('Company', company, 'chart_of_accounts')
+	coa_short_code = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
+
+	header = [
+		# DATEV format
+		#	"DTVF" = created by DATEV software,
+		#	"EXTF" = created by other software
+		'"EXTF"',
+		# version of the DATEV format
+		#	141 = 1.41, 
+		#	510 = 5.10,
+		#	720 = 7.20
+		'700',
+		csv_class.DATA_CATEGORY,
+		'"%s"' % csv_class.FORMAT_NAME,
+		# Format version (regarding format name)
+		csv_class.FORMAT_VERSION,
+		# Generated on
+		datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '000',
+		# Imported on -- stays empty
+		'',
+		# Origin. Any two symbols, will be replaced by "SV" on import.
+		'"EN"',
+		# I = Exported by
+		'"%s"' % frappe.session.user,
+		# J = Imported by -- stays empty
+		'',
+		# K = Tax consultant number (Beraternummer)
+		datev_settings.get('consultant_number', '0000000'),
+		# L = Tax client number (Mandantennummer)
+		datev_settings.get('client_number', '00000'),
+		# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
+		frappe.utils.formatdate(frappe.defaults.get_user_default('year_start_date'), 'yyyyMMdd'),
+		# N = Length of account numbers (Sachkontenlänge)
+		datev_settings.get('account_number_length', '4'),
+		# O = Transaction batch start date (YYYYMMDD)
+		frappe.utils.formatdate(filters.get('from_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# P = Transaction batch end date (YYYYMMDD)
+		frappe.utils.formatdate(filters.get('to_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# Q = Description (for example, "Sales Invoice") Max. 30 chars
+		'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# R = Diktatkürzel
+		'',
+		# S = Buchungstyp
+		#	1 = Transaction batch (Finanzbuchführung),
+		#	2 = Annual financial statement (Jahresabschluss)
+		'1' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# T = Rechnungslegungszweck
+		#	0 oder leer = vom Rechnungslegungszweck unabhängig
+		#	50 = Handelsrecht
+		#	30 = Steuerrecht
+		#	64 = IFRS
+		#	40 = Kalkulatorik
+		#	11 = Reserviert
+		#	12 = Reserviert
+		'0' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# U = Festschreibung
+		# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
+		'0',
+		# V = Default currency, for example, "EUR"
+		'"%s"' % default_currency if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
+		# reserviert
+		'',
+		# Derivatskennzeichen
+		'',
+		# reserviert
+		'',
+		# reserviert
+		'',
+		# SKR
+		'"%s"' % coa_short_code,
+		# Branchen-Lösungs-ID
+		'',
+		# reserviert
+		'',
+		# reserviert
+		'',
+		# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
+		''
+	]
+	return header
+
+
+def download_csv_files_as_zip(csv_data_list):
+	"""
+	Put CSV files in a zip archive and send that to the client.
+
+	Params:
+	csv_data_list -- list of dicts [{'file_name': 'EXTF_Buchunsstapel.zip', 'csv_data': get_datev_csv()}]
+	"""
+	zip_buffer = BytesIO()
+
+	datev_zip = zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
+	for csv_file in csv_data_list:
+		datev_zip.writestr(csv_file.get('file_name'), csv_file.get('csv_data'))
+	datev_zip.close()
+
+	frappe.response['filecontent'] = zip_buffer.getvalue()
+	frappe.response['filename'] = 'DATEV.zip'
+	frappe.response['type'] = 'binary'
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
index 7fec94e..dd818e6 100644
--- a/erpnext/regional/report/datev/datev.py
+++ b/erpnext/regional/report/datev/datev.py
@@ -9,31 +9,91 @@
 """
 from __future__ import unicode_literals
 
-import datetime
 import json
-import zipfile
-import six
 import frappe
-import pandas as pd
-
 from frappe import _
-from csv import QUOTE_NONNUMERIC
-from six import BytesIO
 from six import string_types
-from .datev_constants import DataCategory
-from .datev_constants import Transactions
-from .datev_constants import DebtorsCreditors
-from .datev_constants import AccountNames
-from .datev_constants import QUERY_REPORT_COLUMNS
+from erpnext.regional.germany.utils.datev.datev_csv import download_csv_files_as_zip, get_datev_csv
+from erpnext.regional.germany.utils.datev.datev_constants import Transactions, DebtorsCreditors, AccountNames
+
+COLUMNS = [
+	{
+		"label": "Umsatz (ohne Soll/Haben-Kz)",
+		"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
+		"fieldtype": "Currency",
+		"width": 100
+	},
+	{
+		"label": "Soll/Haben-Kennzeichen",
+		"fieldname": "Soll/Haben-Kennzeichen",
+		"fieldtype": "Data",
+		"width": 100
+	},
+	{
+		"label": "Konto",
+		"fieldname": "Konto",
+		"fieldtype": "Data",
+		"width": 100
+	},
+	{
+		"label": "Gegenkonto (ohne BU-Schlüssel)",
+		"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
+		"fieldtype": "Data",
+		"width": 100
+	},
+	{
+		"label": "Belegdatum",
+		"fieldname": "Belegdatum",
+		"fieldtype": "Date",
+		"width": 100
+	},
+	{
+		"label": "Belegfeld 1",
+		"fieldname": "Belegfeld 1",
+		"fieldtype": "Data",
+		"width": 150
+	},
+	{
+		"label": "Buchungstext",
+		"fieldname": "Buchungstext",
+		"fieldtype": "Text",
+		"width": 300
+	},
+	{
+		"label": "Beleginfo - Art 1",
+		"fieldname": "Beleginfo - Art 1",
+		"fieldtype": "Link",
+		"options": "DocType",
+		"width": 100
+	},
+	{
+		"label": "Beleginfo - Inhalt 1",
+		"fieldname": "Beleginfo - Inhalt 1",
+		"fieldtype": "Dynamic Link",
+		"options": "Beleginfo - Art 1",
+		"width": 150
+	},
+	{
+		"label": "Beleginfo - Art 2",
+		"fieldname": "Beleginfo - Art 2",
+		"fieldtype": "Link",
+		"options": "DocType",
+		"width": 100
+	},
+	{
+		"label": "Beleginfo - Inhalt 2",
+		"fieldname": "Beleginfo - Inhalt 2",
+		"fieldtype": "Dynamic Link",
+		"options": "Beleginfo - Art 2",
+		"width": 150
+	}
+]
 
 
 def execute(filters=None):
 	"""Entry point for frappe."""
 	validate(filters)
-	result = get_transactions(filters, as_dict=0)
-	columns = QUERY_REPORT_COLUMNS
-
-	return columns, result
+	return COLUMNS, get_transactions(filters, as_dict=0)
 
 
 def validate(filters):
@@ -240,146 +300,8 @@
 	""", filters, as_dict=1)
 
 
-def get_datev_csv(data, filters, csv_class):
-	"""
-	Fill in missing columns and return a CSV in DATEV Format.
-
-	For automatic processing, DATEV requires the first line of the CSV file to
-	hold meta data such as the length of account numbers oder the category of
-	the data.
-
-	Arguments:
-	data -- array of dictionaries
-	filters -- dict
-	csv_class -- defines DATA_CATEGORY, FORMAT_NAME and COLUMNS
-	"""
-	empty_df = pd.DataFrame(columns=csv_class.COLUMNS)
-	data_df = pd.DataFrame.from_records(data)
-
-	result = empty_df.append(data_df, sort=True)
-
-	if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS:
-		result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
-
-	if csv_class.DATA_CATEGORY == DataCategory.ACCOUNT_NAMES:
-		result['Sprach-ID'] = 'de-DE'
-
-	data = result.to_csv(
-		# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
-		sep=str(';'),
-		# European decimal seperator
-		decimal=',',
-		# Windows "ANSI" encoding
-		encoding='latin_1',
-		# format date as DDMM
-		date_format='%d%m',
-		# Windows line terminator
-		line_terminator='\r\n',
-		# Do not number rows
-		index=False,
-		# Use all columns defined above
-		columns=csv_class.COLUMNS,
-		# Quote most fields, even currency values with "," separator
-		quoting=QUOTE_NONNUMERIC
-	)
-
-	if not six.PY2:
-		data = data.encode('latin_1')
-
-	header = get_header(filters, csv_class)
-	header = ';'.join(header).encode('latin_1')
-
-	# 1st Row: Header with meta data
-	# 2nd Row: Data heading (Überschrift der Nutzdaten), included in `data` here.
-	# 3rd - nth Row: Data (Nutzdaten)
-	return header + b'\r\n' + data
-
-
-def get_header(filters, csv_class):
-	description = filters.get('voucher_type', csv_class.FORMAT_NAME)
-
-	header = [
-		# DATEV format
-		#	"DTVF" = created by DATEV software,
-		#	"EXTF" = created by other software
-		'"EXTF"',
-		# version of the DATEV format
-		#	141 = 1.41, 
-		#	510 = 5.10,
-		#	720 = 7.20
-		'700',
-		csv_class.DATA_CATEGORY,
-		'"%s"' % csv_class.FORMAT_NAME,
-		# Format version (regarding format name)
-		csv_class.FORMAT_VERSION,
-		# Generated on
-		datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '000',
-		# Imported on -- stays empty
-		'',
-		# Origin. Any two symbols, will be replaced by "SV" on import.
-		'"EN"',
-		# I = Exported by
-		'"%s"' % frappe.session.user,
-		# J = Imported by -- stays empty
-		'',
-		# K = Tax consultant number (Beraternummer)
-		filters.get('consultant_number', '0000000'),
-		# L = Tax client number (Mandantennummer)
-		filters.get('client_number', '00000'),
-		# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
-		frappe.utils.formatdate(frappe.defaults.get_user_default("year_start_date"), "yyyyMMdd"),
-		# N = Length of account numbers (Sachkontenlänge)
-		'%d' % filters.get('acc_len', 4),
-		# O = Transaction batch start date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# P = Transaction batch end date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# Q = Description (for example, "Sales Invoice") Max. 30 chars
-		'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# R = Diktatkürzel
-		'',
-		# S = Buchungstyp
-		#	1 = Transaction batch (Finanzbuchführung),
-		#	2 = Annual financial statement (Jahresabschluss)
-		'1' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# T = Rechnungslegungszweck
-		#	0 oder leer = vom Rechnungslegungszweck unabhängig
-		#	50 = Handelsrecht
-		#	30 = Steuerrecht
-		#	64 = IFRS
-		#	40 = Kalkulatorik
-		#	11 = Reserviert
-		#	12 = Reserviert
-		'0' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# U = Festschreibung
-		# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
-		'0',
-		# V = Default currency, for example, "EUR"
-		'"%s"' % filters.get('default_currency', 'EUR') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
-		# reserviert
-		'',
-		# Derivatskennzeichen
-		'',
-		# reserviert
-		'',
-		# reserviert
-		'',
-		# SKR
-		'"%s"' % filters.get('skr', '04'),
-		# Branchen-Lösungs-ID
-		'',
-		# reserviert
-		'',
-		# reserviert
-		'',
-		# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
-		''
-	]
-	return header
-
-
 @frappe.whitelist()
-def download_datev_csv(filters=None):
+def download_datev_csv(filters):
 	"""
 	Provide accounting entries for download in DATEV format.
 
@@ -400,38 +322,26 @@
 	coa = frappe.get_value('Company', filters.get('company'), 'chart_of_accounts')
 	filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
 
-	# set account number length
-	account_numbers = frappe.get_list('Account', fields=['account_number'], filters={'is_group': 0, 'account_number': ('!=', '')})
-	filters['acc_len'] = max([len(a.account_number) for a in account_numbers])
-
-	filters['consultant_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'consultant_number')
-	filters['client_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'client_number')
-	filters['default_currency'] = frappe.get_value('Company', filters.get('company'), 'default_currency')
-
-	# This is where my zip will be written
-	zip_buffer = BytesIO()
-	# This is my zip file
-	datev_zip = zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
-
 	transactions = get_transactions(filters)
-	transactions_csv = get_datev_csv(transactions, filters, csv_class=Transactions)
-	datev_zip.writestr('EXTF_Buchungsstapel.csv', transactions_csv)
-
 	account_names = get_account_names(filters)
-	account_names_csv = get_datev_csv(account_names, filters, csv_class=AccountNames)
-	datev_zip.writestr('EXTF_Kontenbeschriftungen.csv', account_names_csv)
-
 	customers = get_customers(filters)
-	customers_csv = get_datev_csv(customers, filters, csv_class=DebtorsCreditors)
-	datev_zip.writestr('EXTF_Kunden.csv', customers_csv)
-
 	suppliers = get_suppliers(filters)
-	suppliers_csv = get_datev_csv(suppliers, filters, csv_class=DebtorsCreditors)
-	datev_zip.writestr('EXTF_Lieferanten.csv', suppliers_csv)
-	
-	# You must call close() before exiting your program or essential records will not be written.
-	datev_zip.close()
 
-	frappe.response['filecontent'] = zip_buffer.getvalue()
-	frappe.response['filename'] = 'DATEV.zip'
-	frappe.response['type'] = 'binary'
+	download_csv_files_as_zip([
+		{
+			'file_name': 'EXTF_Buchungsstapel.csv',
+			'csv_data': get_datev_csv(transactions, filters, csv_class=Transactions)
+		},
+		{
+			'file_name': 'EXTF_Kontenbeschriftungen.csv',
+			'csv_data': get_datev_csv(account_names, filters, csv_class=AccountNames)
+		},
+		{
+			'file_name': 'EXTF_Kunden.csv',
+			'csv_data': get_datev_csv(customers, filters, csv_class=DebtorsCreditors)
+		},
+		{
+			'file_name': 'EXTF_Lieferanten.csv',
+			'csv_data': get_datev_csv(suppliers, filters, csv_class=DebtorsCreditors)
+		},
+	])
diff --git a/erpnext/regional/report/datev/test_datev.py b/erpnext/regional/report/datev/test_datev.py
index eed62a8..9529923 100644
--- a/erpnext/regional/report/datev/test_datev.py
+++ b/erpnext/regional/report/datev/test_datev.py
@@ -1,32 +1,22 @@
 # coding=utf-8
 from __future__ import unicode_literals
 
-import os
-import json
 import zipfile
+import frappe
 from six import BytesIO
 from unittest import TestCase
-
-import frappe
-from frappe.utils import getdate, today, now_datetime, cstr
-from frappe.test_runner import make_test_objects
+from frappe.utils import today, now_datetime, cstr
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
-from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
 
 from erpnext.regional.report.datev.datev import validate
 from erpnext.regional.report.datev.datev import get_transactions
 from erpnext.regional.report.datev.datev import get_customers
 from erpnext.regional.report.datev.datev import get_suppliers
 from erpnext.regional.report.datev.datev import get_account_names
-from erpnext.regional.report.datev.datev import get_datev_csv
-from erpnext.regional.report.datev.datev import get_header
 from erpnext.regional.report.datev.datev import download_datev_csv
 
-from erpnext.regional.report.datev.datev_constants import DataCategory
-from erpnext.regional.report.datev.datev_constants import Transactions
-from erpnext.regional.report.datev.datev_constants import DebtorsCreditors
-from erpnext.regional.report.datev.datev_constants import AccountNames
-from erpnext.regional.report.datev.datev_constants import QUERY_REPORT_COLUMNS
+from erpnext.regional.germany.utils.datev.datev_csv import get_datev_csv, get_header
+from erpnext.regional.germany.utils.datev.datev_constants import Transactions, DebtorsCreditors, AccountNames
 
 def make_company(company_name, abbr):
 	if not frappe.db.exists("Company", company_name):
diff --git a/erpnext/selling/doctype/industry_type/industry_type.json b/erpnext/selling/doctype/industry_type/industry_type.json
index f4fcae4..6c49f0f 100644
--- a/erpnext/selling/doctype/industry_type/industry_type.json
+++ b/erpnext/selling/doctype/industry_type/industry_type.json
@@ -49,11 +49,11 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-25 05:24:25.881361", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Industry Type", 
- "owner": "harshada@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [
   {
    "amend": 0, 
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.json b/erpnext/selling/doctype/product_bundle/product_bundle.json
index b63fb4b..56155fb 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.json
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.json
@@ -238,8 +238,8 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-10-18 14:23:06.538568", 
- "modified_by": "tundebabzy@gmail.com", 
+ "modified": "2020-09-18 17:26:09.703215", 
+ "modified_by": "Administrator", 
  "module": "Selling", 
  "name": "Product Bundle", 
  "owner": "Administrator", 
diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js
index e1c54f6..7f0cabe 100644
--- a/erpnext/selling/page/point_of_sale/pos_payment.js
+++ b/erpnext/selling/page/point_of_sale/pos_payment.js
@@ -70,13 +70,23 @@
 				this.$invoice_fields.append(
 					`<div class="invoice_detail_field ${df.fieldname}-field" data-fieldname="${df.fieldname}"></div>`
 				);
+				let df_events = {
+					onchange: function() { frm.set_value(this.df.fieldname, this.value); }
+				}
+				if (df.fieldtype == "Button") {
+					df_events = {
+						click: function() {
+							if (frm.script_manager.has_handlers(df.fieldname, frm.doc.doctype)) {
+								frm.script_manager.trigger(df.fieldname, frm.doc.doctype, frm.doc.docname);
+							}
+						}
+					}
+				}
 
 				this[`${df.fieldname}_field`] = frappe.ui.form.make_control({
 					df: { 
 						...df,
-						onchange: function() {
-							frm.set_value(this.df.fieldname, this.value);
-						}
+						...df_events
 					},
 					parent: this.$invoice_fields.find(`.${df.fieldname}-field`),
 					render_input: true,
diff --git a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py
index 0a70b97..c716aa9 100644
--- a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py
+++ b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py
@@ -188,7 +188,7 @@
 		conditions += "AND so.transaction_date <= '%s'" %filters.to_date
 
 	if filters.get("item_code"):
-		conditions += "AND so_item.item_code = '%s'" %frappe.db.escape(filters.item_code)
+		conditions += "AND so_item.item_code = %s" %frappe.db.escape(filters.item_code)
 
 	if filters.get("customer"):
 		conditions += "AND so.customer = %s" %frappe.db.escape(filters.customer)
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js
index 80874c1..0e565a3 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.js
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.js
@@ -8,7 +8,7 @@
 			fieldname: "tree_type",
 			label: __("Tree Type"),
 			fieldtype: "Select",
-			options: ["Customer Group","Customer","Item Group","Item","Territory","Order Type"],
+			options: ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Order Type", "Project"],
 			default: "Customer",
 			reqd: 1
 		},
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index 4d113c8..d036a1c 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -34,7 +34,7 @@
 
 	def get_columns(self):
 		self.columns = [{
-				"label": _(self.filters.tree_type + " ID"),
+				"label": _(self.filters.tree_type),
 				"options": self.filters.tree_type if self.filters.tree_type != "Order Type" else "",
 				"fieldname": "entity",
 				"fieldtype": "Link" if self.filters.tree_type != "Order Type" else "Data",
@@ -97,6 +97,10 @@
 			self.get_sales_transactions_based_on_order_type()
 			self.get_rows_by_group()
 
+		elif self.filters.tree_type == "Project":
+			self.get_sales_transactions_based_on_project()
+			self.get_rows()
+
 	def get_sales_transactions_based_on_order_type(self):
 		if self.filters["value_quantity"] == 'Value':
 			value_field = "base_net_total"
@@ -198,6 +202,24 @@
 
 		self.get_groups()
 
+	def get_sales_transactions_based_on_project(self):
+		if self.filters["value_quantity"] == 'Value':
+			value_field = "base_net_total as value_field"
+		else:
+			value_field = "total_qty as value_field"
+
+		entity = "project as entity"
+
+		self.entries = frappe.get_all(self.filters.doc_type,
+			fields=[entity, value_field, self.date_field],
+			filters={
+				"docstatus": 1,
+				"company": self.filters.company,
+				"project": ["!=", ""],
+				self.date_field: ('between', [self.filters.from_date, self.filters.to_date])
+			}
+		)
+
 	def get_rows(self):
 		self.data = []
 		self.get_periodic_data()
@@ -205,7 +227,7 @@
 		for entity, period_data in iteritems(self.entity_periodic_data):
 			row = {
 				"entity": entity,
-				"entity_name": self.entity_names.get(entity)
+				"entity_name": self.entity_names.get(entity) if hasattr(self, 'entity_names') else None
 			}
 			total = 0
 			for end_date in self.periodic_daterange:
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index a7e8388..0ccc025 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -96,7 +96,9 @@
 def request_for_quotation():
 	quotation = _get_cart_quotation()
 	quotation.flags.ignore_permissions = True
-	quotation.submit()
+	quotation.save()
+	if not get_shopping_cart_settings().save_quotations_as_draft:
+		quotation.submit()
 	return quotation.name
 
 @frappe.whitelist()
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index 32004ef..9d61e7d 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -27,6 +27,7 @@
   "enable_checkout",
   "payment_success_url",
   "column_break_11",
+  "save_quotations_as_draft",
   "payment_gateway_account"
  ],
  "fields": [
@@ -166,13 +167,20 @@
    "fieldname": "enable_variants",
    "fieldtype": "Check",
    "label": "Enable Variants"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval: doc.enable_checkout == 0",
+   "fieldname": "save_quotations_as_draft",
+   "fieldtype": "Check",
+   "label": "Save Quotations as Draft"
   }
  ],
  "icon": "fa fa-shopping-cart",
  "idx": 1,
  "issingle": 1,
  "links": [],
- "modified": "2020-08-02 18:21:43.873303",
+ "modified": "2020-09-24 16:28:07.192525",
  "modified_by": "Administrator",
  "module": "Shopping Cart",
  "name": "Shopping Cart Settings",
diff --git a/erpnext/stock/doctype/batch/batch.json b/erpnext/stock/doctype/batch/batch.json
index 1eb4577..943cb34 100644
--- a/erpnext/stock/doctype/batch/batch.json
+++ b/erpnext/stock/doctype/batch/batch.json
@@ -166,11 +166,11 @@
  "idx": 1,
  "image_field": "image",
  "max_attachments": 5,
- "modified": "2019-10-03 22:38:45.104056",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Batch",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 38e5fe5..faeeb57 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -26,19 +26,19 @@
 
 	refresh: function(frm) {
 		if (frm.doc.is_stock_item) {
-			frm.add_custom_button(__("Balance"), function() {
+			frm.add_custom_button(__("Stock Balance"), function() {
 				frappe.route_options = {
 					"item_code": frm.doc.name
 				}
 				frappe.set_route("query-report", "Stock Balance");
 			}, __("View"));
-			frm.add_custom_button(__("Ledger"), function() {
+			frm.add_custom_button(__("Stock Ledger"), function() {
 				frappe.route_options = {
 					"item_code": frm.doc.name
 				}
 				frappe.set_route("query-report", "Stock Ledger");
 			}, __("View"));
-			frm.add_custom_button(__("Projected"), function() {
+			frm.add_custom_button(__("Stock Projected Qty"), function() {
 				frappe.route_options = {
 					"item_code": frm.doc.name
 				}
diff --git a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
index 90a392c..b24d621 100644
--- a/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
+++ b/erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
@@ -133,11 +133,11 @@
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-11-12 15:41:21.053462",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Landed Cost Item",
- "owner": "wasim@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC"
diff --git a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
index f49c147..9b2b5da 100644
--- a/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
+++ b/erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
@@ -173,11 +173,11 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-20 10:49:34.228751", 
+ "modified": "2020-09-18 17:26:09.703215", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Landed Cost Purchase Receipt", 
- "owner": "wasim@webnotestech.com", 
+ "owner": "Administrator", 
  "permissions": [], 
  "quick_entry": 0, 
  "read_only": 0, 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 67161aa..1e7153e 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -494,8 +494,7 @@
 			"expected_value_after_useful_life": 10,
 			"depreciation_method": "Straight Line",
 			"total_number_of_depreciations": 3,
-			"frequency_of_depreciation": 1,
-			"depreciation_start_date": frappe.utils.nowdate()
+			"frequency_of_depreciation": 1
 		})
 		asset.submit()
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 9845bc2..39fd029 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -23,6 +23,24 @@
 			}
 		});
 
+		frm.set_query('source_warehouse_address', function() {
+			return {
+				filters: {
+					link_doctype: 'Warehouse',
+					link_name: frm.doc.from_warehouse
+				}
+			}
+		});
+
+		frm.set_query('target_warehouse_address', function() {
+			return {
+				filters: {
+					link_doctype: 'Warehouse',
+					link_name: frm.doc.to_warehouse
+				}
+			}
+		});
+
 		frappe.db.get_value('Stock Settings', {name: 'Stock Settings'}, 'sample_retention_warehouse', (r) => {
 			if (r.sample_retention_warehouse) {
 				var filters = [
@@ -138,6 +156,7 @@
 						mr_item.item_code = item.item_code;
 						mr_item.item_name = item.item_name;
 						mr_item.uom = item.uom;
+						mr_item.stock_uom = item.stock_uom;
 						mr_item.conversion_factor = item.conversion_factor;
 						mr_item.item_group = item.item_group;
 						mr_item.description = item.description;
diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js
index 23700c9..2499c80 100644
--- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js
+++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js
@@ -9,13 +9,15 @@
 			"fieldtype": "Date",
 			"width": "80",
 			"default": frappe.sys_defaults.year_start_date,
+			"reqd": 1
 		},
 		{
 			"fieldname":"to_date",
 			"label": __("To Date"),
 			"fieldtype": "Date",
 			"width": "80",
-			"default": frappe.datetime.get_today()
+			"default": frappe.datetime.get_today(),
+			"reqd": 1
 		},
 		{
 			"fieldname": "item",
diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
index 2c95084..8f3e246 100644
--- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
+++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
@@ -11,6 +11,9 @@
 def execute(filters=None):
 	if not filters: filters = {}
 
+	if filters.from_date > filters.to_date:
+		frappe.throw(_("From Date must be before To Date"))
+
 	float_precision = cint(frappe.db.get_default("float_precision")) or 3
 
 	columns = get_columns(filters)
diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json
index b1ad7c8..28410f3 100644
--- a/erpnext/support/desk_page/support/support.json
+++ b/erpnext/support/desk_page/support/support.json
@@ -28,7 +28,7 @@
   {
    "hidden": 0,
    "label": "Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Issue\"\n        ],\n        \"doctype\": \"Issue\",\n        \"is_query_report\": true,\n        \"label\": \"Minutes to First Response for Issues\",\n        \"name\": \"Minutes to First Response for Issues\",\n        \"type\": \"report\"\n    }\n]"
+   "links": "[\n    {\n        \"dependencies\": [\n            \"Issue\"\n        ],\n        \"doctype\": \"Issue\",\n        \"is_query_report\": true,\n        \"label\": \"First Response Time for Issues\",\n        \"name\": \"First Response Time for Issues\",\n        \"type\": \"report\"\n    }\n]"
   }
  ],
  "category": "Modules",
@@ -43,7 +43,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Support",
- "modified": "2020-06-04 11:54:56.124219",
+ "modified": "2020-08-11 15:49:34.307341",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Support",
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 858564a..fe01d4b 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -2,10 +2,14 @@
 	onload: function(frm) {
 		frm.email_field = "raised_by";
 
-		frappe.db.get_value("Support Settings", {name: "Support Settings"}, "allow_resetting_service_level_agreement", (r) => {
-			if (!r.allow_resetting_service_level_agreement) {
-				frm.set_df_property("reset_service_level_agreement", "hidden", 1) ;
-			}
+		frappe.db.get_value("Support Settings", {name: "Support Settings"},
+			["allow_resetting_service_level_agreement", "track_service_level_agreement"], (r) => {
+				if (r && r.track_service_level_agreement == "0") {
+					frm.set_df_property("service_level_section", "hidden", 1);
+				}
+				if (r && r.allow_resetting_service_level_agreement == "0") {
+					frm.set_df_property("reset_service_level_agreement", "hidden", 1);
+				}
 		});
 
 		if (frm.doc.service_level_agreement) {
@@ -38,7 +42,7 @@
 	},
 
 	refresh: function (frm) {
-		if (frm.doc.status !== "Closed" && frm.doc.agreement_fulfilled === "Ongoing") {
+		if (frm.doc.status !== "Closed" && frm.doc.agreement_status === "Ongoing") {
 			if (frm.doc.service_level_agreement) {
 				frappe.call({
 					'method': 'frappe.client.get',
@@ -85,14 +89,14 @@
 			if (frm.doc.service_level_agreement) {
 				frm.dashboard.clear_headline();
 
-				let agreement_fulfilled = (frm.doc.agreement_fulfilled == "Fulfilled") ?
+				let agreement_status = (frm.doc.agreement_status == "Fulfilled") ?
 					{"indicator": "green", "msg": "Service Level Agreement has been fulfilled"} :
 					{"indicator": "red", "msg": "Service Level Agreement Failed"};
 
 				frm.dashboard.set_headline_alert(
 					'<div class="row">' +
 						'<div class="col-xs-12">' +
-							'<span class="indicator whitespace-nowrap '+ agreement_fulfilled.indicator +'"><span class="hidden-xs">'+ agreement_fulfilled.msg +'</span></span> ' +
+							'<span class="indicator whitespace-nowrap '+ agreement_status.indicator +'"><span class="hidden-xs">'+ agreement_status.msg +'</span></span> ' +
 						'</div>' +
 					'</div>'
 				);
@@ -198,13 +202,13 @@
 	frm.dashboard.clear_headline();
 
 	var time_to_respond = get_status(frm.doc.response_by_variance);
-	if (!frm.doc.first_responded_on && frm.doc.agreement_fulfilled === "Ongoing") {
-		time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
+	if (!frm.doc.first_responded_on && frm.doc.agreement_status === "Ongoing") {
+		time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_status);
 	}
 
 	var time_to_resolve = get_status(frm.doc.resolution_by_variance);
-	if (!frm.doc.resolution_date && frm.doc.agreement_fulfilled === "Ongoing") {
-		time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
+	if (!frm.doc.resolution_date && frm.doc.agreement_status === "Ongoing") {
+		time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_status);
 	}
 
 	frm.dashboard.set_headline_alert(
@@ -219,10 +223,10 @@
 	);
 }
 
-function get_time_left(timestamp, agreement_fulfilled) {
+function get_time_left(timestamp, agreement_status) {
 	const diff = moment(timestamp).diff(moment());
 	const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : "Failed";
-	let indicator = (diff_display == 'Failed' && agreement_fulfilled != "Fulfilled") ? "red" : "green";
+	let indicator = (diff_display == 'Failed' && agreement_status != "Fulfilled") ? "red" : "green";
 	return {"diff_display": diff_display, "indicator": indicator};
 }
 
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 6525ab2..a43381c 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -27,17 +27,25 @@
   "response_by_variance",
   "reset_service_level_agreement",
   "cb",
-  "agreement_fulfilled",
+  "agreement_status",
   "resolution_by",
   "resolution_by_variance",
   "service_level_agreement_creation",
   "on_hold_since",
   "total_hold_time",
   "response",
-  "mins_to_first_response",
+  "first_response_time",
   "first_responded_on",
   "column_break_26",
   "avg_response_time",
+  "section_break_19",
+  "resolution_details",
+  "column_break1",
+  "opening_date",
+  "opening_time",
+  "resolution_date",
+  "resolution_time",
+  "user_resolution_time",
   "additional_info",
   "lead",
   "contact",
@@ -46,23 +54,14 @@
   "customer_name",
   "project",
   "company",
-  "section_break_19",
-  "resolution_details",
-  "column_break1",
-  "opening_date",
-  "opening_time",
-  "resolution_date",
-  "content_type",
-  "attachment",
   "via_customer_portal",
-  "resolution_time",
-  "user_resolution_time"
+  "attachment",
+  "content_type"
  ],
  "fields": [
   {
    "fieldname": "subject_section",
    "fieldtype": "Section Break",
-   "label": "Subject",
    "options": "fa fa-flag"
   },
   {
@@ -158,7 +157,7 @@
    "collapsible": 1,
    "fieldname": "service_level_section",
    "fieldtype": "Section Break",
-   "label": "Service Level"
+   "label": "Service Level Agreement Details"
   },
   {
    "fieldname": "service_level_agreement",
@@ -191,14 +190,7 @@
    "collapsible": 1,
    "fieldname": "response",
    "fieldtype": "Section Break",
-   "label": "Response"
-  },
-  {
-   "bold": 1,
-   "fieldname": "mins_to_first_response",
-   "fieldtype": "Float",
-   "label": "Mins to First Response",
-   "read_only": 1
+   "label": "Response Details"
   },
   {
    "fieldname": "first_responded_on",
@@ -261,7 +253,7 @@
    "collapsible": 1,
    "fieldname": "section_break_19",
    "fieldtype": "Section Break",
-   "label": "Resolution"
+   "label": "Resolution Details"
   },
   {
    "depends_on": "eval:!doc.__islocal",
@@ -327,27 +319,18 @@
    "label": "Via Customer Portal"
   },
   {
-   "default": "Ongoing",
-   "depends_on": "eval: doc.service_level_agreement",
-   "fieldname": "agreement_fulfilled",
-   "fieldtype": "Select",
-   "label": "Service Level Agreement Fulfilled",
-   "options": "Ongoing\nFulfilled\nFailed",
-   "read_only": 1
-  },
-  {
    "depends_on": "eval: doc.service_level_agreement && doc.status != 'Replied';",
-   "description": "in hours",
    "fieldname": "response_by_variance",
-   "fieldtype": "Float",
+   "fieldtype": "Duration",
+   "hide_seconds": 1,
    "label": "Response By Variance",
    "read_only": 1
   },
   {
    "depends_on": "eval: doc.service_level_agreement && doc.status != 'Replied';",
-   "description": "in hours",
    "fieldname": "resolution_by_variance",
-   "fieldtype": "Float",
+   "fieldtype": "Duration",
+   "hide_seconds": 1,
    "label": "Resolution By Variance",
    "read_only": 1
   },
@@ -406,12 +389,28 @@
    "fieldtype": "Duration",
    "label": "Total Hold Time",
    "read_only": 1
+  },
+  {
+   "default": "Ongoing",
+   "depends_on": "eval: doc.service_level_agreement",
+   "fieldname": "agreement_status",
+   "fieldtype": "Select",
+   "label": "Service Level Agreement Status",
+   "options": "Ongoing\nFulfilled\nFailed",
+   "read_only": 1
+  },
+  {
+   "bold": 1,
+   "fieldname": "first_response_time",
+   "fieldtype": "Duration",
+   "label": "First Response Time",
+   "read_only": 1
   }
  ],
  "icon": "fa fa-ticket",
  "idx": 7,
  "links": [],
- "modified": "2020-06-10 12:47:37.146914",
+ "modified": "2020-08-11 18:49:07.574769",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Issue",
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 87168e1..920c13c 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -61,7 +61,7 @@
 
 		if self.status in ["Closed", "Resolved"] and status not in ["Resolved", "Closed"]:
 			self.resolution_date = frappe.flags.current_time or now_datetime()
-			if frappe.db.get_value("Issue", self.name, "agreement_fulfilled") == "Ongoing":
+			if frappe.db.get_value("Issue", self.name, "agreement_status") == "Ongoing":
 				set_service_level_agreement_variance(issue=self.name)
 				self.update_agreement_status()
 			set_resolution_time(issue=self)
@@ -72,7 +72,7 @@
 			self.resolution_date = None
 			self.reset_issue_metrics()
 			# enable SLA and variance on Reopen
-			self.agreement_fulfilled = "Ongoing"
+			self.agreement_status = "Ongoing"
 			set_service_level_agreement_variance(issue=self.name)
 
 		self.handle_hold_time(status)
@@ -113,39 +113,39 @@
 					if not self.first_responded_on:
 						response_by = get_expected_time_for(parameter="response", service_level=priority, start_date_time=start_date_time)
 						response_by = add_to_date(response_by, seconds=round(last_hold_time))
-						response_by_variance = round(time_diff_in_hours(response_by, now_time))
+						response_by_variance = round(time_diff_in_seconds(response_by, now_time))
 						update_values['response_by'] = response_by
-						update_values['response_by_variance'] = response_by_variance + (last_hold_time // 3600)
+						update_values['response_by_variance'] = response_by_variance + last_hold_time
 
 					resolution_by = get_expected_time_for(parameter="resolution", service_level=priority, start_date_time=start_date_time)
 					resolution_by = add_to_date(resolution_by, seconds=round(last_hold_time))
-					resolution_by_variance = round(time_diff_in_hours(resolution_by, now_time))
+					resolution_by_variance = round(time_diff_in_seconds(resolution_by, now_time))
 					update_values['resolution_by'] = resolution_by
-					update_values['resolution_by_variance'] = resolution_by_variance + (last_hold_time // 3600)
+					update_values['resolution_by_variance'] = resolution_by_variance + last_hold_time
 					update_values['on_hold_since'] = None
 
 				self.db_set(update_values)
 
 	def update_agreement_status(self):
-		if self.service_level_agreement and self.agreement_fulfilled == "Ongoing":
+		if self.service_level_agreement and self.agreement_status == "Ongoing":
 			if frappe.db.get_value("Issue", self.name, "response_by_variance") < 0 or \
 				frappe.db.get_value("Issue", self.name, "resolution_by_variance") < 0:
 
-				self.agreement_fulfilled = "Failed"
+				self.agreement_status = "Failed"
 			else:
-				self.agreement_fulfilled = "Fulfilled"
+				self.agreement_status = "Fulfilled"
 
-	def update_agreement_fulfilled_on_custom_status(self):
+	def update_agreement_status_on_custom_status(self):
 		"""
 			Update Agreement Fulfilled status using Custom Scripts for Custom Issue Status
 		"""
 		if not self.first_responded_on: # first_responded_on set when first reply is sent to customer
-			self.response_by_variance = round(time_diff_in_hours(self.response_by, now_datetime()), 2)
+			self.response_by_variance = round(time_diff_in_seconds(self.response_by, now_datetime()), 2)
 
 		if not self.resolution_date: # resolution_date set when issue has been closed
-			self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime()), 2)
+			self.resolution_by_variance = round(time_diff_in_seconds(self.resolution_by, now_datetime()), 2)
 
-		self.agreement_fulfilled = "Fulfilled" if self.response_by_variance > 0 and self.resolution_by_variance > 0 else "Failed"
+		self.agreement_status = "Fulfilled" if self.response_by_variance > 0 and self.resolution_by_variance > 0 else "Failed"
 
 	def create_communication(self):
 		communication = frappe.new_doc("Communication")
@@ -172,7 +172,7 @@
 		replicated_issue = deepcopy(self)
 		replicated_issue.subject = subject
 		replicated_issue.issue_split_from = self.name
-		replicated_issue.mins_to_first_response = 0
+		replicated_issue.first_response_time = 0
 		replicated_issue.first_responded_on = None
 		replicated_issue.creation = now_datetime()
 
@@ -180,7 +180,7 @@
 		if replicated_issue.service_level_agreement:
 			replicated_issue.service_level_agreement_creation = now_datetime()
 			replicated_issue.service_level_agreement = None
-			replicated_issue.agreement_fulfilled = "Ongoing"
+			replicated_issue.agreement_status = "Ongoing"
 			replicated_issue.response_by = None
 			replicated_issue.response_by_variance = None
 			replicated_issue.resolution_by = None
@@ -241,8 +241,8 @@
 		self.response_by = get_expected_time_for(parameter="response", service_level=priority, start_date_time=start_date_time)
 		self.resolution_by = get_expected_time_for(parameter="resolution", service_level=priority, start_date_time=start_date_time)
 
-		self.response_by_variance = round(time_diff_in_hours(self.response_by, now_datetime()))
-		self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime()))
+		self.response_by_variance = round(time_diff_in_seconds(self.response_by, now_datetime()))
+		self.resolution_by_variance = round(time_diff_in_seconds(self.resolution_by, now_datetime()))
 
 	def change_service_level_agreement_and_priority(self):
 		if self.service_level_agreement and frappe.db.exists("Issue", self.name) and \
@@ -271,7 +271,7 @@
 
 		self.service_level_agreement_creation = now_datetime()
 		self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
-		self.agreement_fulfilled = "Ongoing"
+		self.agreement_status = "Ongoing"
 		self.save()
 
 	def reset_issue_metrics(self):
@@ -347,7 +347,7 @@
 def set_service_level_agreement_variance(issue=None):
 	current_time = frappe.flags.current_time or now_datetime()
 
-	filters = {"status": "Open", "agreement_fulfilled": "Ongoing"}
+	filters = {"status": "Open", "agreement_status": "Ongoing"}
 	if issue:
 		filters = {"name": issue}
 
@@ -358,13 +358,13 @@
 			variance = round(time_diff_in_hours(doc.response_by, current_time), 2)
 			frappe.db.set_value(dt="Issue", dn=doc.name, field="response_by_variance", val=variance, update_modified=False)
 			if variance < 0:
-				frappe.db.set_value(dt="Issue", dn=doc.name, field="agreement_fulfilled", val="Failed", update_modified=False)
+				frappe.db.set_value(dt="Issue", dn=doc.name, field="agreement_status", val="Failed", update_modified=False)
 
 		if not doc.resolution_date: # resolution_date set when issue has been closed
 			variance = round(time_diff_in_hours(doc.resolution_by, current_time), 2)
 			frappe.db.set_value(dt="Issue", dn=doc.name, field="resolution_by_variance", val=variance, update_modified=False)
 			if variance < 0:
-				frappe.db.set_value(dt="Issue", dn=doc.name, field="agreement_fulfilled", val="Failed", update_modified=False)
+				frappe.db.set_value(dt="Issue", dn=doc.name, field="agreement_status", val="Failed", update_modified=False)
 
 
 def set_resolution_time(issue):
diff --git a/erpnext/support/doctype/issue/test_issue.py b/erpnext/support/doctype/issue/test_issue.py
index fb8ceb5..c962dc6 100644
--- a/erpnext/support/doctype/issue/test_issue.py
+++ b/erpnext/support/doctype/issue/test_issue.py
@@ -73,7 +73,7 @@
 		issue.status = 'Closed'
 		issue.save()
 
-		self.assertEqual(issue.agreement_fulfilled, 'Fulfilled')
+		self.assertEqual(issue.agreement_status, 'Fulfilled')
 
 	def test_issue_metrics(self):
 		creation = datetime.datetime(2020, 3, 4, 4, 0)
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.json b/erpnext/support/doctype/warranty_claim/warranty_claim.json
index ae1a7a5..88ee4a3 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.json
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.json
@@ -361,11 +361,11 @@
  ],
  "icon": "fa fa-bug",
  "idx": 1,
- "modified": "2019-05-24 10:56:30.626200",
+ "modified": "2020-09-18 17:26:09.703215",
  "modified_by": "Administrator",
  "module": "Support",
  "name": "Warranty Claim",
- "owner": "harshada@webnotestech.com",
+ "owner": "Administrator",
  "permissions": [
   {
    "create": 1,
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/__init__.py b/erpnext/support/report/first_response_time_for_issues/__init__.py
similarity index 100%
rename from erpnext/support/report/minutes_to_first_response_for_issues/__init__.py
rename to erpnext/support/report/first_response_time_for_issues/__init__.py
diff --git a/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.js b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.js
new file mode 100644
index 0000000..576e0b7
--- /dev/null
+++ b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.js
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["First Response Time for Issues"] = {
+	"filters": [
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default":frappe.datetime.nowdate()
+		}
+	],
+	get_chart_data: function(_columns, result) {
+		return {
+			data: {
+				labels: result.map(d => d[0]),
+				datasets: [{
+					name: 'First Response Time',
+					values: result.map(d => d[1])
+				}]
+			},
+			type: "line",
+			tooltipOptions: {
+				formatTooltipY: d => {
+					let duration_options = {
+						hide_days: 0,
+						hide_seconds: 0
+					};
+					value = frappe.utils.get_formatted_duration(d, duration_options);
+					return value;
+				}
+			}
+		}
+	}
+};
diff --git a/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.json b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.json
new file mode 100644
index 0000000..c4fe6f5
--- /dev/null
+++ b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.json
@@ -0,0 +1,26 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-08-10 18:12:42.391224",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Test 2",
+ "modified": "2020-08-10 18:12:42.391224",
+ "modified_by": "Administrator",
+ "module": "Support",
+ "name": "First Response Time for Issues",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "query": "select date(creation) as creation_date, avg(mins_to_first_response) from tabIssue where creation > '2016-05-01' group by date(creation) order by creation_date;",
+ "ref_doctype": "Issue",
+ "report_name": "First Response Time for Issues",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "Support Team"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.py b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.py
new file mode 100644
index 0000000..922da2b
--- /dev/null
+++ b/erpnext/support/report/first_response_time_for_issues/first_response_time_for_issues.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute(filters=None):
+	columns = [
+		{
+			'fieldname': 'creation_date',
+			'label': 'Date',
+			'fieldtype': 'Date',
+			'width': 300
+		},
+		{
+			'fieldname': 'first_response_time',
+			'fieldtype': 'Duration',
+			'label': 'First Response Time',
+			'width': 300
+		},
+	]
+
+	data = frappe.db.sql('''
+		SELECT
+			date(creation) as creation_date,
+			avg(first_response_time) as avg_response_time
+		FROM tabIssue
+		WHERE
+			date(creation) between %s and %s
+			and first_response_time > 0
+		GROUP BY creation_date
+		ORDER BY creation_date desc
+	''', (filters.from_date, filters.to_date))
+
+	return columns, data
\ No newline at end of file
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.js b/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.js
deleted file mode 100644
index 034e777..0000000
--- a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.js
+++ /dev/null
@@ -1,30 +0,0 @@
-frappe.query_reports["Minutes to First Response for Issues"] = {
-	"filters": [
-		{
-			"fieldname":"from_date",
-			"label": __("From Date"),
-			"fieldtype": "Date",
-			'reqd': 1,
-			"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
-		},
-		{
-			"fieldname":"to_date",
-			"label": __("To Date"),
-			"fieldtype": "Date",
-			'reqd': 1,
-			"default":frappe.datetime.nowdate()
-		},
-	],
-	get_chart_data: function(columns, result) {
-		return {
-			data: {
-				labels: result.map(d => d[0]),
-				datasets: [{
-					name: 'Mins to first response',
-					values: result.map(d => d[1])
-				}]
-			},
-			type: 'line',
-		}
-	}
-}
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.json b/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.json
deleted file mode 100644
index 539d3d9..0000000
--- a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "add_total_row": 0, 
- "apply_user_permissions": 1, 
- "creation": "2016-06-14 17:44:26.034112", 
- "disabled": 0, 
- "docstatus": 0, 
- "doctype": "Report", 
- "idx": 2, 
- "is_standard": "Yes", 
- "modified": "2017-02-24 20:06:18.391100", 
- "modified_by": "Administrator", 
- "module": "Support", 
- "name": "Minutes to First Response for Issues", 
- "owner": "Administrator", 
- "query": "select date(creation) as creation_date, avg(mins_to_first_response) from tabIssue where creation > '2016-05-01' group by date(creation) order by creation_date;", 
- "ref_doctype": "Issue", 
- "report_name": "Minutes to First Response for Issues", 
- "report_type": "Script Report", 
- "roles": [
-  {
-   "role": "Support Team"
-  }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.py b/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.py
deleted file mode 100644
index 57c2d44..0000000
--- a/erpnext/support/report/minutes_to_first_response_for_issues/minutes_to_first_response_for_issues.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-
-def execute(filters=None):
-	columns = [
-		{
-			'fieldname': 'creation_date',
-			'label': 'Date',
-			'fieldtype': 'Date'
-		},
-		{
-			'fieldname': 'mins',
-			'fieldtype': 'Float',
-			'label': 'Mins to First Response'
-		},
-	]
-
-	data = frappe.db.sql('''select date(creation) as creation_date,
-		avg(mins_to_first_response) as mins
-		from tabIssue
-			where date(creation) between %s and %s
-			and mins_to_first_response > 0
-		group by creation_date order by creation_date desc''', (filters.from_date, filters.to_date))
-
-	return columns, data
diff --git a/erpnext/templates/generators/item/item_add_to_cart.html b/erpnext/templates/generators/item/item_add_to_cart.html
index 40bc0c7..dbf15de 100644
--- a/erpnext/templates/generators/item/item_add_to_cart.html
+++ b/erpnext/templates/generators/item/item_add_to_cart.html
@@ -10,7 +10,10 @@
 			{{ product_info.price.formatted_price_sales_uom }}
 			<small class="text-muted">({{ product_info.price.formatted_price }} / {{ product_info.uom }})</small>
 		</h4>
+		{% else %}
+			{{ _("Unit of Measurement") }} : {{ product_info.uom }}
 		{% endif %}
+
 		{% if cart_settings.show_stock_availability %}
 		<div>
 			{% if product_info.in_stock == 0 %}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
index 80a542f..fd4835e 100644
--- a/erpnext/templates/includes/transaction_row.html
+++ b/erpnext/templates/includes/transaction_row.html
@@ -14,7 +14,11 @@
 			</div>
 		</div>
 		<div class="col-sm-3 text-right bold">
-			{{ doc.get_formatted("grand_total") }}
+			{% if doc.doctype == "Quotation" and not doc.docstatus %}
+				{{ _("Pending") }}
+			{% else %}
+				{{ doc.get_formatted("grand_total") }}
+			{% endif %}
 		</div>
 	</div>
 	<a class="transaction-item-link" href="/{{ pathname }}/{{ doc.name }}">Link</a>
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
index 9e3c58b..01b5f6d 100644
--- a/erpnext/templates/pages/order.html
+++ b/erpnext/templates/pages/order.html
@@ -12,22 +12,21 @@
 {% endblock %}
 
 {% block header_actions %}
-<div class="dropdown">
-	<button class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
-		<span>{{ _('Actions') }}</span>
-		<b class="caret"></b>
-	</button>
-	<ul class="dropdown-menu dropdown-menu-right" role="menu">
-		{% if doc.doctype == 'Purchase Order' %}
-		<a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
-		{% endif %}
-		<a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'
-			target="_blank" rel="noopener noreferrer">
-			{{ _("Print") }}
-		</a>
-	</ul>
-</div>
-
+	<div class="dropdown">
+		<button class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+			<span>{{ _('Actions') }}</span>
+			<b class="caret"></b>
+		</button>
+		<ul class="dropdown-menu dropdown-menu-right" role="menu">
+			{% if doc.doctype == 'Purchase Order' %}
+			<a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
+			{% endif %}
+			<a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'
+				target="_blank" rel="noopener noreferrer">
+				{{ _("Print") }}
+			</a>
+		</ul>
+	</div>
 {% endblock %}
 
 {% block page_content %}
@@ -35,7 +34,11 @@
 <div class="row transaction-subheading">
 	<div class="col-6">
 		<span class="indicator {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "darkgrey") }}">
-			{{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
+			{% if doc.doctype == "Quotation" and not doc.docstatus %}
+				{{ _("Pending") }}
+			{% else %}
+				{{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
+			{% endif %}
 		</span>
 	</div>
 	<div class="col-6 text-muted text-right small">
@@ -95,7 +98,6 @@
 		</div>
 		{% endfor %}
 	</div>
-
 	<!-- taxes -->
 	<div class="order-taxes d-flex justify-content-end">
 		<table>
diff --git a/erpnext/utilities/activation.py b/erpnext/utilities/activation.py
index 63c36b3..7b17c8c 100644
--- a/erpnext/utilities/activation.py
+++ b/erpnext/utilities/activation.py
@@ -11,8 +11,39 @@
 	activation_level = 0
 	sales_data = []
 	min_count = 0
-	doctypes = {"Item": 5, "Customer": 5, "Sales Order": 2, "Sales Invoice": 2, "Purchase Order": 2, "Employee": 3, "Lead": 3, "Quotation": 3,
-					"Payment Entry": 2, "User": 5, "Student": 5, "Instructor": 5, "BOM": 3, "Journal Entry": 3, "Stock Entry": 3}
+	doctypes = {
+		"Asset": 5,
+		"BOM": 3, 
+		"Customer": 5, 
+		"Delivery Note": 5,
+		"Employee": 3, 
+		"Instructor": 5, 
+		"Instructor": 5, 
+		"Issue": 5,
+		"Item": 5, 
+		"Journal Entry": 3, 
+		"Lead": 3,
+		"Leave Application": 5,
+		"Material Request": 5,
+		"Opportunity": 5, 
+		"Payment Entry": 2, 
+		"Project": 5,
+		"Purchase Order": 2, 
+		"Purchase Invoice": 5,
+		"Purchase Receipt": 5,
+		"Quotation": 3,
+		"Salary Slip": 5,
+		"Salary Structure": 5,
+		"Sales Order": 2, 
+		"Sales Invoice": 2, 
+		"Stock Entry": 3,
+		"Student": 5, 
+		"Supplier": 5,
+		"Task": 5,
+		"User": 5, 
+		"Work Order": 5
+	}
+
 	for doctype, min_count in iteritems(doctypes):
 		count = frappe.db.count(doctype)
 		if count > min_count:
diff --git a/erpnext/utilities/desk_page/utilities/utilities.json b/erpnext/utilities/desk_page/utilities/utilities.json
new file mode 100644
index 0000000..591eab5
--- /dev/null
+++ b/erpnext/utilities/desk_page/utilities/utilities.json
@@ -0,0 +1,29 @@
+{
+ "cards": [
+  {
+   "hidden": 0,
+   "label": "Video",
+   "links": "[\n    {\n        \"description\": \"Video\",\n        \"label\": \"Video\",\n        \"name\": \"Video\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Video settings\",\n        \"label\": \"Video Settings\",\n        \"name\": \"Video Settings\",\n        \"type\": \"doctype\"\n    }\n]"
+  }
+ ],
+ "category": "Modules",
+ "charts": [],
+ "creation": "2020-09-10 12:21:22.335307",
+ "developer_mode_only": 0,
+ "disable_user_customization": 0,
+ "docstatus": 0,
+ "doctype": "Desk Page",
+ "extends_another_page": 0,
+ "hide_custom": 0,
+ "idx": 0,
+ "is_standard": 1,
+ "label": "Utilities",
+ "modified": "2020-09-10 12:33:30.089853",
+ "modified_by": "user@erpnext.com",
+ "module": "Utilities",
+ "name": "Utilities",
+ "owner": "user@erpnext.com",
+ "pin_to_bottom": 1,
+ "pin_to_top": 0,
+ "shortcuts": []
+}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/video/video.js b/erpnext/utilities/doctype/video/video.js
index 056bd3c..9cb5a15 100644
--- a/erpnext/utilities/doctype/video/video.js
+++ b/erpnext/utilities/doctype/video/video.js
@@ -2,7 +2,16 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Video', {
-	// refresh: function(frm) {
+	refresh: function (frm) {
+		frm.events.toggle_youtube_statistics_section(frm);
+		frm.add_custom_button("Watch Video", () => frappe.help.show_video(frm.doc.url, frm.doc.title));
+	},
 
-	// }
+	toggle_youtube_statistics_section: (frm) => {
+		if (frm.doc.provider === "YouTube") {
+			frappe.db.get_single_value("Video Settings", "enable_youtube_tracking").then( val => {
+				frm.toggle_display("youtube_tracking_section", val);
+			});
+		}
+	}
 });
diff --git a/erpnext/utilities/doctype/video/video.json b/erpnext/utilities/doctype/video/video.json
index 5d2cc13..2a82db2 100644
--- a/erpnext/utilities/doctype/video/video.json
+++ b/erpnext/utilities/doctype/video/video.json
@@ -11,11 +11,19 @@
   "title",
   "provider",
   "url",
+  "youtube_video_id",
   "column_break_4",
   "publish_date",
   "duration",
+  "youtube_tracking_section",
+  "like_count",
+  "view_count",
+  "col_break",
+  "dislike_count",
+  "comment_count",
   "section_break_7",
-  "description"
+  "description",
+  "image"
  ],
  "fields": [
   {
@@ -37,7 +45,6 @@
   {
    "fieldname": "url",
    "fieldtype": "Data",
-   "in_list_view": 1,
    "label": "URL",
    "reqd": 1
   },
@@ -48,11 +55,12 @@
   {
    "fieldname": "publish_date",
    "fieldtype": "Date",
+   "in_list_view": 1,
    "label": "Publish Date"
   },
   {
    "fieldname": "duration",
-   "fieldtype": "Data",
+   "fieldtype": "Duration",
    "label": "Duration"
   },
   {
@@ -62,13 +70,67 @@
   {
    "fieldname": "description",
    "fieldtype": "Text Editor",
-   "in_list_view": 1,
    "label": "Description",
    "reqd": 1
+  },
+  {
+   "fieldname": "like_count",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Likes",
+   "no_copy": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "view_count",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Views",
+   "no_copy": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "col_break",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "dislike_count",
+   "fieldtype": "Float",
+   "label": "Dislikes",
+   "no_copy": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "comment_count",
+   "fieldtype": "Float",
+   "label": "Comments",
+   "no_copy": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image",
+   "no_copy": 1
+  },
+  {
+   "depends_on": "eval:doc.provider==\"YouTube\"",
+   "fieldname": "youtube_tracking_section",
+   "fieldtype": "Section Break",
+   "label": "Youtube Statistics"
+  },
+  {
+   "fieldname": "youtube_video_id",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Youtube ID",
+   "read_only": 1
   }
  ],
+ "image_field": "image",
  "links": [],
- "modified": "2020-07-21 19:29:46.603734",
+ "modified": "2020-09-07 17:02:20.185794",
  "modified_by": "Administrator",
  "module": "Utilities",
  "name": "Video",
diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py
index 3c17b56..c2e414e 100644
--- a/erpnext/utilities/doctype/video/video.py
+++ b/erpnext/utilities/doctype/video/video.py
@@ -3,8 +3,144 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-# import frappe
+import frappe
+import re
+import pytz
 from frappe.model.document import Document
+from frappe import _
+from datetime import datetime
+from six import string_types
+from pyyoutube import Api
 
 class Video(Document):
-	pass
+	def validate(self):
+		if self.provider == "YouTube" and is_tracking_enabled():
+			self.set_video_id()
+			self.set_youtube_statistics()
+
+	def set_video_id(self):
+		if self.url and not self.get("youtube_video_id"):
+			self.youtube_video_id = get_id_from_url(self.url)
+
+	def set_youtube_statistics(self):
+		api_key = frappe.db.get_single_value("Video Settings", "api_key")
+		api = Api(api_key=api_key)
+
+		try:
+			video = api.get_video_by_id(video_id=self.youtube_video_id)
+			video_stats = video.items[0].to_dict().get('statistics')
+
+			self.like_count = video_stats.get('likeCount')
+			self.view_count = video_stats.get('viewCount')
+			self.dislike_count = video_stats.get('dislikeCount')
+			self.comment_count = video_stats.get('commentCount')
+
+		except Exception:
+			title = "Failed to Update YouTube Statistics for Video: {0}".format(self.name)
+			frappe.log_error(title + "\n\n" +  frappe.get_traceback(), title=title)
+
+def is_tracking_enabled():
+	return frappe.db.get_single_value("Video Settings", "enable_youtube_tracking")
+
+
+def get_frequency(value):
+	# Return numeric value from frequency field, return 1 as fallback default value: 1 hour
+	if value != "Daily":
+		return frappe.utils.cint(value[:2].strip())
+	elif value:
+		return 24
+	return 1
+
+
+def update_youtube_data():
+	# Called every 30 minutes via hooks
+	enable_youtube_tracking, frequency = frappe.db.get_value("Video Settings", "Video Settings", ["enable_youtube_tracking", "frequency"])
+
+	if not enable_youtube_tracking:
+		return
+
+	frequency = get_frequency(frequency)
+	time = datetime.now()
+	timezone = pytz.timezone(frappe.utils.get_time_zone())
+	site_time = time.astimezone(timezone)
+
+	if frequency == 30:
+		batch_update_youtube_data()
+	elif site_time.hour % frequency == 0 and site_time.minute < 15:
+		# make sure it runs within the first 15 mins of the hour
+		batch_update_youtube_data()
+
+
+def get_formatted_ids(video_list):
+	# format ids to comma separated string for bulk request
+	ids = []
+	for video in video_list:
+		ids.append(video.youtube_video_id)
+
+	return ','.join(ids)
+
+
+@frappe.whitelist()
+def get_id_from_url(url):
+	"""
+		Returns video id from url
+		:param youtube url: String URL
+	"""
+	if not isinstance(url, string_types):
+		frappe.throw(_("URL can only be a string"), title=_("Invalid URL"))
+
+	pattern = re.compile(r'[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/|.+\?v=)?([^"&?\s]{11})?')
+	id = pattern.match(url)
+	return id.groups()[-1]
+
+
+@frappe.whitelist()
+def batch_update_youtube_data():
+	def get_youtube_statistics(video_ids):
+		api_key = frappe.db.get_single_value("Video Settings", "api_key")
+		api = Api(api_key=api_key)
+		try:
+			video = api.get_video_by_id(video_id=video_ids)
+			video_stats = video.items
+			return video_stats
+		except Exception:
+			title = "Failed to Update YouTube Statistics"
+			frappe.log_error(title + "\n\n" +  frappe.get_traceback(), title=title)
+
+	def prepare_and_set_data(video_list):
+		video_ids = get_formatted_ids(video_list)
+		stats = get_youtube_statistics(video_ids)
+		set_youtube_data(stats)
+
+	def set_youtube_data(entries):
+		for entry in entries:
+			video_stats = entry.to_dict().get('statistics')
+			video_id = entry.to_dict().get('id')
+			stats = {
+				'like_count' : video_stats.get('likeCount'),
+				'view_count' : video_stats.get('viewCount'),
+				'dislike_count' : video_stats.get('dislikeCount'),
+				'comment_count' : video_stats.get('commentCount'),
+				'video_id': video_id
+			}
+
+			frappe.db.sql("""
+				UPDATE `tabVideo`
+				SET
+					like_count  = %(like_count)s,
+					view_count = %(view_count)s,
+					dislike_count = %(dislike_count)s,
+					comment_count = %(comment_count)s
+				WHERE youtube_video_id = %(video_id)s""", stats)
+
+	video_list = frappe.get_all("Video", fields=["youtube_video_id"])
+	if len(video_list) > 50:
+		# Update in batches of 50
+		start, end = 0, 50
+		while start < len(video_list):
+			batch = video_list[start:end]
+			prepare_and_set_data(batch)
+			start += 50
+			end += 50
+	else:
+		prepare_and_set_data(video_list)
diff --git a/erpnext/utilities/doctype/video/video_list.js b/erpnext/utilities/doctype/video/video_list.js
new file mode 100644
index 0000000..8273a4a
--- /dev/null
+++ b/erpnext/utilities/doctype/video/video_list.js
@@ -0,0 +1,7 @@
+frappe.listview_settings["Video"] = {
+	onload: (listview) => {
+		listview.page.add_menu_item(__("Video Settings"), function() {
+			frappe.set_route("Form","Video Settings", "Video Settings");
+		});
+	}
+}
\ No newline at end of file
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/__init__.py b/erpnext/utilities/doctype/video_settings/__init__.py
similarity index 100%
copy from erpnext/support/report/minutes_to_first_response_for_issues/__init__.py
copy to erpnext/utilities/doctype/video_settings/__init__.py
diff --git a/erpnext/utilities/doctype/video_settings/test_video_settings.py b/erpnext/utilities/doctype/video_settings/test_video_settings.py
new file mode 100644
index 0000000..b217afe
--- /dev/null
+++ b/erpnext/utilities/doctype/video_settings/test_video_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestVideoSettings(unittest.TestCase):
+	pass
diff --git a/erpnext/utilities/doctype/video_settings/video_settings.js b/erpnext/utilities/doctype/video_settings/video_settings.js
new file mode 100644
index 0000000..9ac8b9e
--- /dev/null
+++ b/erpnext/utilities/doctype/video_settings/video_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Video Settings', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/utilities/doctype/video_settings/video_settings.json b/erpnext/utilities/doctype/video_settings/video_settings.json
new file mode 100644
index 0000000..fb3274d
--- /dev/null
+++ b/erpnext/utilities/doctype/video_settings/video_settings.json
@@ -0,0 +1,60 @@
+{
+ "actions": [],
+ "creation": "2020-08-02 03:50:21.339609",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "enable_youtube_tracking",
+  "api_key",
+  "frequency"
+ ],
+ "fields": [
+  {
+   "default": "0",
+   "fieldname": "enable_youtube_tracking",
+   "fieldtype": "Check",
+   "label": "Enable YouTube Tracking"
+  },
+  {
+   "depends_on": "eval:doc.enable_youtube_tracking",
+   "fieldname": "api_key",
+   "fieldtype": "Data",
+   "label": "API Key",
+   "mandatory_depends_on": "eval:doc.enable_youtube_tracking"
+  },
+  {
+   "default": "1 hr",
+   "depends_on": "eval:doc.enable_youtube_tracking",
+   "fieldname": "frequency",
+   "fieldtype": "Select",
+   "label": "Frequency",
+   "mandatory_depends_on": "eval:doc.enable_youtube_tracking",
+   "options": "30 mins\n1 hr\n6 hrs\nDaily"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "issingle": 1,
+ "links": [],
+ "modified": "2020-09-07 16:09:00.360668",
+ "modified_by": "Administrator",
+ "module": "Utilities",
+ "name": "Video Settings",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/video_settings/video_settings.py b/erpnext/utilities/doctype/video_settings/video_settings.py
new file mode 100644
index 0000000..36fb54f
--- /dev/null
+++ b/erpnext/utilities/doctype/video_settings/video_settings.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.model.document import Document
+from apiclient.discovery import build
+
+class VideoSettings(Document):
+	def validate(self):
+		self.validate_youtube_api_key()
+
+	def validate_youtube_api_key(self):
+		if self.enable_youtube_tracking and self.api_key:
+			try:
+				build("youtube", "v3", developerKey=self.api_key)
+			except Exception:
+				title = _("Failed to Authenticate the API key.")
+				frappe.log_error(title + "\n\n" +  frappe.get_traceback(), title=title)
+				frappe.throw(title + " Please check the error logs.", title=_("Invalid Credentials"))
\ No newline at end of file
diff --git a/erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py b/erpnext/utilities/report/__init__.py
similarity index 100%
copy from erpnext/crm/report/minutes_to_first_response_for_opportunity/__init__.py
copy to erpnext/utilities/report/__init__.py
diff --git a/erpnext/support/report/minutes_to_first_response_for_issues/__init__.py b/erpnext/utilities/report/youtube_interactions/__init__.py
similarity index 100%
copy from erpnext/support/report/minutes_to_first_response_for_issues/__init__.py
copy to erpnext/utilities/report/youtube_interactions/__init__.py
diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.js b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js
new file mode 100644
index 0000000..6e3e4e6
--- /dev/null
+++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["YouTube Interactions"] = {
+	"filters": [
+		{
+			fieldname: "from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.add_months(frappe.datetime.now_date(), -12),
+		},
+		{
+			fieldname:"to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+			default: frappe.datetime.now_date(),
+		}
+	]
+};
diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.json b/erpnext/utilities/report/youtube_interactions/youtube_interactions.json
new file mode 100644
index 0000000..a40247b
--- /dev/null
+++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.json
@@ -0,0 +1,27 @@
+{
+ "add_total_row": 0,
+ "creation": "2020-08-02 05:05:00.457093",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-08-02 05:05:00.457093",
+ "modified_by": "Administrator",
+ "module": "Utilities",
+ "name": "YouTube Interactions",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Video",
+ "report_name": "YouTube Interactions",
+ "report_type": "Script Report",
+ "roles": [
+  {
+   "role": "All"
+  },
+  {
+   "role": "System Manager"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.py b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py
new file mode 100644
index 0000000..3516a35
--- /dev/null
+++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py
@@ -0,0 +1,113 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import flt
+
+def execute(filters=None):
+	if not frappe.db.get_single_value("Video Settings", "enable_youtube_tracking") or not filters:
+		return [], []
+
+	columns = get_columns()
+	data = get_data(filters)
+	chart_data, summary = get_chart_summary_data(data)
+	return columns, data, None, chart_data, summary
+
+def get_columns():
+	return [
+		{
+			"label": _("Published Date"),
+			"fieldname": "publish_date",
+			"fieldtype": "Date",
+			"width": 100
+		},
+		{
+			"label": _("Title"),
+			"fieldname": "title",
+			"fieldtype": "Data",
+			"width": 200
+		},
+		{
+			"label": _("Duration"),
+			"fieldname": "duration",
+			"fieldtype": "Duration",
+			"width": 100
+		},
+		{
+			"label": _("Views"),
+			"fieldname": "view_count",
+			"fieldtype": "Float",
+			"width": 200
+		},
+		{
+			"label": _("Likes"),
+			"fieldname": "like_count",
+			"fieldtype": "Float",
+			"width": 200
+		},
+		{
+			"label": _("Dislikes"),
+			"fieldname": "dislike_count",
+			"fieldtype": "Float",
+			"width": 100
+		},
+		{
+			"label": _("Comments"),
+			"fieldname": "comment_count",
+			"fieldtype": "Float",
+			"width": 100
+		}
+	]
+
+def get_data(filters):
+	return frappe.db.sql("""
+		SELECT
+			publish_date, title, provider, duration,
+			view_count, like_count, dislike_count, comment_count
+		FROM `tabVideo`
+		WHERE view_count is not null
+			and publish_date between %(from_date)s and %(to_date)s
+		ORDER BY view_count desc""", filters, as_dict=1)
+
+def get_chart_summary_data(data):
+	labels, likes, views = [], [], []
+	total_views = 0
+
+	for row in data:
+		labels.append(row.get('title'))
+		likes.append(row.get('like_count'))
+		views.append(row.get('view_count'))
+		total_views += flt(row.get('view_count'))
+
+
+	chart_data = {
+		"data" : {
+			"labels" : labels,
+			"datasets" : [
+				{
+					"name" : "Likes",
+					"values" : likes
+				},
+				{
+					"name" : "Views",
+					"values" : views
+				}
+			]
+		},
+		"type": "bar",
+		"barOptions": {
+			"stacked": 1
+		},
+	}
+
+	summary = [
+		{
+			"value": total_views,
+			"indicator": "Blue",
+			"label": "Total Views",
+			"datatype": "Float",
+		}
+	]
+	return chart_data, summary
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 912d61f..c4f9171 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,10 +3,11 @@
 gocardless-pro==1.11.0
 googlemaps==3.1.1
 pandas==1.0.5
-plaid-python==3.4.0
+plaid-python==6.0.0
 pycountry==19.8.18
 PyGithub==1.44.1
 python-stdnum==1.12
+python-youtube==0.6.0
 taxjar==1.9.0
 tweepy==3.8.0
 Unidecode==1.1.1