Merge branch 'develop' into navbar_links
diff --git a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
index 3a0d416..340b9dd 100644
--- a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
+++ b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
@@ -9,6 +9,8 @@
 from erpnext.stock.get_item_details import get_item_details
 from frappe.test_runner import make_test_objects
 
+test_dependencies = ['Item']
+
 def test_create_test_data():
 	frappe.set_user("Administrator")
 	# create test item
@@ -95,7 +97,6 @@
 		})
 		coupon_code.insert()
 
-
 class TestCouponCode(unittest.TestCase):
 	def setUp(self):
 		test_create_test_data()
diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
index 8a4050c..edf8659 100644
--- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
@@ -8,6 +8,8 @@
 from erpnext.stock.get_item_details import get_pos_profile
 from erpnext.accounts.doctype.pos_profile.pos_profile import get_child_nodes
 
+test_dependencies = ['Item']
+
 class TestPOSProfile(unittest.TestCase):
 	def test_pos_profile(self):
 		make_pos_profile()
@@ -88,7 +90,7 @@
 		"write_off_account":  args.write_off_account or "_Test Write Off - _TC",
 		"write_off_cost_center":  args.write_off_cost_center or "_Test Write Off Cost Center - _TC"
 	})
-	
+
 	payments = [{
 		'mode_of_payment': 'Cash',
 		'default': 1
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index cff7d5b..aa6194c 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -1,5 +1,4 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
 
 # For license information, please see license.txt
 
@@ -208,7 +207,7 @@
 
 def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
 	from erpnext.accounts.doctype.pricing_rule.utils import (get_pricing_rules,
-		get_applied_pricing_rules, get_pricing_rule_items, get_product_discount_rule)
+			get_applied_pricing_rules, get_pricing_rule_items, get_product_discount_rule)
 
 	if isinstance(doc, string_types):
 		doc = json.loads(doc)
@@ -237,7 +236,7 @@
 
 	update_args_for_pricing_rule(args)
 
-	pricing_rules = (get_applied_pricing_rules(args)
+	pricing_rules = (get_applied_pricing_rules(args.get('pricing_rules'))
 		if for_validate and args.get("pricing_rules") else get_pricing_rules(args, doc))
 
 	if pricing_rules:
@@ -365,8 +364,9 @@
 			item_details.rate = rate
 
 def remove_pricing_rule_for_item(pricing_rules, item_details, item_code=None):
-	from erpnext.accounts.doctype.pricing_rule.utils import get_pricing_rule_items
-	for d in json.loads(pricing_rules):
+	from erpnext.accounts.doctype.pricing_rule.utils import (get_applied_pricing_rules,
+		get_pricing_rule_items)
+	for d in get_applied_pricing_rules(pricing_rules):
 		if not d or not frappe.db.exists("Pricing Rule", d): continue
 		pricing_rule = frappe.get_cached_doc('Pricing Rule', d)
 
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 3fd316f..53b0cf7b 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -447,9 +447,14 @@
 				apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
 				doc.set_missing_values()
 
-def get_applied_pricing_rules(item_row):
-	return (json.loads(item_row.get("pricing_rules"))
-		if item_row.get("pricing_rules") else [])
+def get_applied_pricing_rules(pricing_rules):
+	if pricing_rules:
+		if pricing_rules.startswith('['):
+			return json.loads(pricing_rules)
+		else:
+			return pricing_rules.split(',')
+
+	return []
 
 def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
 	free_item = pricing_rule.free_item
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 31613e5..2397b7d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -447,7 +447,7 @@
   {
    "allow_on_submit": 1,
    "fieldname": "po_no",
-   "fieldtype": "Small Text",
+   "fieldtype": "Data",
    "hide_days": 1,
    "hide_seconds": 1,
    "label": "Customer's Purchase Order",
@@ -1946,7 +1946,7 @@
  "idx": 181,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-08-03 23:31:12.675040",
+ "modified": "2020-08-27 01:56:28.532140",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
index f106928..2980213 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_dashboard.py
@@ -13,7 +13,8 @@
 			'Auto Repeat': 'reference_document',
 		},
 		'internal_links': {
-			'Sales Order': ['items', 'sales_order']
+			'Sales Order': ['items', 'sales_order'],
+			'Delivery Note': ['items', 'delivery_note']
 		},
 		'transactions': [
 			{
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
index 53ee08a..d0904ee 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js
@@ -3,6 +3,22 @@
 
 frappe.ui.form.on('Shipping Rule', {
 	refresh: function(frm) {
+		frm.set_query("cost_center", function() {
+			return {
+				filters: {
+					company: frm.doc.company
+				}
+			}
+		})
+
+		frm.set_query("account", function() {
+			return {
+				filters: {
+					company: frm.doc.company
+				}
+			}
+		})
+
 		frm.trigger('toggle_reqd');
 	},
 	calculate_based_on: function(frm) {
@@ -12,4 +28,4 @@
 		frm.toggle_reqd("shipping_amount", frm.doc.calculate_based_on === 'Fixed');
 		frm.toggle_reqd("conditions", frm.doc.calculate_based_on !== 'Fixed');
 	}
-});
\ No newline at end of file
+});
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index c2c7207..219871b 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -378,7 +378,7 @@
 		if filters and filters.get('presentation_currency') != d.default_currency:
 			currency_info['company'] = d.name
 			currency_info['company_currency'] = d.default_currency
-			convert_to_presentation_currency(gl_entries, currency_info)
+			convert_to_presentation_currency(gl_entries, currency_info, filters.get('company'))
 
 		for entry in gl_entries:
 			key = entry.account_number or entry.account_name
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index d5b8cdb..1b65a31 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -423,7 +423,7 @@
 				distributed_cost_center_query=distributed_cost_center_query), gl_filters, as_dict=True) #nosec
 
 		if filters and filters.get('presentation_currency'):
-			convert_to_presentation_currency(gl_entries, get_currency(filters))
+			convert_to_presentation_currency(gl_entries, get_currency(filters), filters.get('company'))
 
 		for entry in gl_entries:
 			gl_entries_by_account.setdefault(entry.account, []).append(entry)
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 1fc0f79..fb0d359 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -147,6 +147,12 @@
 			}
 		},
 		{
+			"fieldname": "include_dimensions",
+			"label": __("Consider Accounting Dimensions"),
+			"fieldtype": "Check",
+			"default": 0
+		},
+		{
 			"fieldname": "show_opening_entries",
 			"label": __("Show Opening Entries"),
 			"fieldtype": "Check"
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index fcd36e4..0599707 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -106,15 +106,20 @@
 	return filters
 
 def get_result(filters, account_details):
-	gl_entries = get_gl_entries(filters)
+	accounting_dimensions = []
+	if filters.get("include_dimensions"):
+		accounting_dimensions = get_accounting_dimensions()
 
-	data = get_data_with_opening_closing(filters, account_details, gl_entries)
+	gl_entries = get_gl_entries(filters, accounting_dimensions)
+
+	data = get_data_with_opening_closing(filters, account_details,
+		accounting_dimensions, gl_entries)
 
 	result = get_result_as_list(data, filters)
 
 	return result
 
-def get_gl_entries(filters):
+def get_gl_entries(filters, accounting_dimensions):
 	currency_map = get_currency(filters)
 	select_fields = """, debit, credit, debit_in_account_currency,
 		credit_in_account_currency """
@@ -128,6 +133,10 @@
 		filters['company_fb'] = frappe.db.get_value("Company",
 			filters.get("company"), 'default_finance_book')
 
+	dimension_fields = ""
+	if accounting_dimensions:
+		dimension_fields = ', '.join(accounting_dimensions) + ','
+
 	distributed_cost_center_query = ""
 	if filters and filters.get('cost_center'):
 		select_fields_with_percentage = """, debit*(DCC_allocation.percentage_allocation/100) as debit, credit*(DCC_allocation.percentage_allocation/100) as credit, debit_in_account_currency*(DCC_allocation.percentage_allocation/100) as debit_in_account_currency,
@@ -141,7 +150,7 @@
 			party_type,
 			party,
 			voucher_type,
-			voucher_no,
+			voucher_no, {dimension_fields}
 			cost_center, project,
 			against_voucher_type,
 			against_voucher,
@@ -160,13 +169,14 @@
 		{conditions}
 		AND posting_date <= %(to_date)s
 		AND cost_center = DCC_allocation.parent
-		""".format(select_fields_with_percentage=select_fields_with_percentage, conditions=get_conditions(filters).replace("and cost_center in %(cost_center)s ", ''))
+		""".format(dimension_fields=dimension_fields,select_fields_with_percentage=select_fields_with_percentage, conditions=get_conditions(filters).replace("and cost_center in %(cost_center)s ", ''))
 
 	gl_entries = frappe.db.sql(
 		"""
 		select
 			name as gl_entry, posting_date, account, party_type, party,
-			voucher_type, voucher_no, cost_center, project,
+			voucher_type, voucher_no, {dimension_fields}
+			cost_center, project,
 			against_voucher_type, against_voucher, account_currency,
 			remarks, against, is_opening, creation {select_fields}
 		from `tabGL Entry`
@@ -174,13 +184,13 @@
 		{distributed_cost_center_query}
 		{order_by_statement}
 		""".format(
-			select_fields=select_fields, conditions=get_conditions(filters), distributed_cost_center_query=distributed_cost_center_query,
+			dimension_fields=dimension_fields, select_fields=select_fields, conditions=get_conditions(filters), distributed_cost_center_query=distributed_cost_center_query,
 			order_by_statement=order_by_statement
 		),
 		filters, as_dict=1)
 
 	if filters.get('presentation_currency'):
-		return convert_to_presentation_currency(gl_entries, currency_map)
+		return convert_to_presentation_currency(gl_entries, currency_map, filters.get('company'))
 	else:
 		return gl_entries
 
@@ -247,12 +257,12 @@
 	return "and {}".format(" and ".join(conditions)) if conditions else ""
 
 
-def get_data_with_opening_closing(filters, account_details, gl_entries):
+def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries):
 	data = []
 
 	gle_map = initialize_gle_map(gl_entries, filters)
 
-	totals, entries = get_accountwise_gle(filters, gl_entries, gle_map)
+	totals, entries = get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map)
 
 	# Opening for filtered account
 	data.append(totals.opening)
@@ -318,7 +328,7 @@
 	return gle_map
 
 
-def get_accountwise_gle(filters, gl_entries, gle_map):
+def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
 	totals = get_totals_dict()
 	entries = []
 	consolidated_gle = OrderedDict()
@@ -350,8 +360,11 @@
 			if filters.get("group_by") != _('Group by Voucher (Consolidated)'):
 				gle_map[gle.get(group_by)].entries.append(gle)
 			elif filters.get("group_by") == _('Group by Voucher (Consolidated)'):
-				key = (gle.get("voucher_type"), gle.get("voucher_no"),
-					gle.get("account"), gle.get("cost_center"))
+				keylist = [gle.get("voucher_type"), gle.get("voucher_no"), gle.get("account")]
+				for dim in accounting_dimensions:
+					keylist.append(gle.get(dim))
+				keylist.append(gle.get("cost_center"))
+				key = tuple(keylist)
 				if key not in consolidated_gle:
 					consolidated_gle.setdefault(key, gle)
 				else:
@@ -478,7 +491,19 @@
 			"options": "Project",
 			"fieldname": "project",
 			"width": 100
-		},
+		}
+	])
+
+	if filters.get("include_dimensions"):
+		for dim in get_accounting_dimensions(as_list = False):
+			columns.append({
+				"label": _(dim.label),
+				"options": dim.label,
+				"fieldname": dim.fieldname,
+				"width": 100
+			})
+
+	columns.extend([
 		{
 			"label": _("Cost Center"),
 			"options": "Cost Center",
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index 4a9af49..9de8d19 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -6,10 +6,6 @@
 from frappe.utils import cint, get_datetime_str, formatdate, flt
 
 __exchange_rates = {}
-P_OR_L_ACCOUNTS = list(
-	sum(frappe.get_list('Account', fields=['name'], or_filters=[{'root_type': 'Income'}, {'root_type': 'Expense'}], as_list=True), ())
-)
-
 
 def get_currency(filters):
 	"""
@@ -73,18 +69,7 @@
 
 	return rate
 
-
-def is_p_or_l_account(account_name):
-	"""
-	Check if the given `account name` is an `Account` with `root_type` of either 'Income'
-	or 'Expense'.
-	:param account_name:
-	:return: Boolean
-	"""
-	return account_name in P_OR_L_ACCOUNTS
-
-
-def convert_to_presentation_currency(gl_entries, currency_info):
+def convert_to_presentation_currency(gl_entries, currency_info, company):
 	"""
 	Take a list of GL Entries and change the 'debit' and 'credit' values to currencies
 	in `currency_info`.
@@ -96,6 +81,9 @@
 	presentation_currency = currency_info['presentation_currency']
 	company_currency = currency_info['company_currency']
 
+	pl_accounts = [d.name for d in frappe.get_list('Account',
+		filters={'report_type': 'Profit and Loss', 'company': company})]
+
 	for entry in gl_entries:
 		account = entry['account']
 		debit = flt(entry['debit'])
@@ -107,7 +95,7 @@
 		if account_currency != presentation_currency:
 			value = debit or credit
 
-			date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']
+			date = entry['posting_date'] if account in pl_accounts else currency_info['report_date']
 			converted_value = convert(value, presentation_currency, company_currency, date)
 
 			if entry.get('debit'):
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 3091193..d61e44b 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -325,7 +325,7 @@
 				apply_pricing_rule_for_free_items(self, pricing_rule_args.get('free_item_data'))
 
 		elif pricing_rule_args.get("validate_applied_rule"):
-			for pricing_rule in get_applied_pricing_rules(item):
+			for pricing_rule in get_applied_pricing_rules(item.get('pricing_rules')):
 				pricing_rule_doc = frappe.get_cached_doc("Pricing Rule", pricing_rule)
 				for field in ['discount_percentage', 'discount_amount', 'rate']:
 					if item.get(field) < pricing_rule_doc.get(field):
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 2a14be8..92cfdb7 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -9,6 +9,7 @@
 from erpnext.controllers.accounts_controller import validate_conversion_rate, \
 	validate_taxes_and_charges, validate_inclusive_tax
 from erpnext.stock.get_item_details import _get_item_tax_template
+from erpnext.accounts.doctype.pricing_rule.utils import get_applied_pricing_rules
 
 class calculate_taxes_and_totals(object):
 	def __init__(self, doc):
@@ -209,7 +210,7 @@
 			elif tax.charge_type == "On Previous Row Total":
 				current_tax_fraction = (tax_rate / 100.0) * \
 					self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_fraction_for_current_item
-			
+
 			elif tax.charge_type == "On Item Quantity":
 				inclusive_tax_amount_per_qty = flt(tax_rate)
 
@@ -607,7 +608,7 @@
 		base_rate_with_margin = 0.0
 		if item.price_list_rate:
 			if item.pricing_rules and not self.doc.ignore_pricing_rule:
-				for d in json.loads(item.pricing_rules):
+				for d in get_applied_pricing_rules(item.pricing_rules):
 					pricing_rule = frappe.get_cached_doc('Pricing Rule', d)
 
 					if (pricing_rule.margin_type == 'Amount' and pricing_rule.currency == self.doc.currency)\
diff --git a/erpnext/crm/doctype/social_media_post/social_media_post.js b/erpnext/crm/doctype/social_media_post/social_media_post.js
index 3a14f2d..0ce8b44 100644
--- a/erpnext/crm/doctype/social_media_post/social_media_post.js
+++ b/erpnext/crm/doctype/social_media_post/social_media_post.js
@@ -30,14 +30,14 @@
                 let color = frm.doc.twitter_post_id ? "green" : "red";
                 let status = frm.doc.twitter_post_id ? "Posted" : "Not Posted";
                 html += `<div class="col-xs-6">
-                            <span class="indicator whitespace-nowrap ${color}"><span class="hidden-xs">Twitter : ${status} </span></span>
+                            <span class="indicator whitespace-nowrap ${color}"><span>Twitter : ${status} </span></span>
                         </div>` ;
             }
             if (frm.doc.linkedin){
                 let color = frm.doc.linkedin_post_id ? "green" : "red";
                 let status = frm.doc.linkedin_post_id ? "Posted" : "Not Posted";
                 html += `<div class="col-xs-6">
-                            <span class="indicator whitespace-nowrap ${color}"><span class="hidden-xs">LinkedIn : ${status} </span></span>
+                            <span class="indicator whitespace-nowrap ${color}"><span>LinkedIn : ${status} </span></span>
                         </div>` ;
             }
             html = `<div class="row">${html}</div>`;
diff --git a/erpnext/crm/report/lead_details/lead_details.js b/erpnext/crm/report/lead_details/lead_details.js
new file mode 100644
index 0000000..f92070d
--- /dev/null
+++ b/erpnext/crm/report/lead_details/lead_details.js
@@ -0,0 +1,52 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Lead Details"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -12),
+			"reqd": 1
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1
+		},
+		{
+			"fieldname":"status",
+			"label": __("Status"),
+			"fieldtype": "Select",
+			options: [
+				{ "value": "Lead", "label": __("Lead") },
+				{ "value": "Open", "label": __("Open") },
+				{ "value": "Replied", "label": __("Replied") },
+				{ "value": "Opportunity", "label": __("Opportunity") },
+				{ "value": "Quotation", "label": __("Quotation") },
+				{ "value": "Lost Quotation", "label": __("Lost Quotation") },
+				{ "value": "Interested", "label": __("Interested") },
+				{ "value": "Converted", "label": __("Converted") },
+				{ "value": "Do Not Contact", "label": __("Do Not Contact") },
+			],
+		},
+		{
+			"fieldname":"territory",
+			"label": __("Territory"),
+			"fieldtype": "Link",
+			"options": "Territory",
+		}
+	]
+};
\ No newline at end of file
diff --git a/erpnext/crm/report/lead_details/lead_details.json b/erpnext/crm/report/lead_details/lead_details.json
index cdeb6bb..7871d08 100644
--- a/erpnext/crm/report/lead_details/lead_details.json
+++ b/erpnext/crm/report/lead_details/lead_details.json
@@ -7,16 +7,15 @@
  "doctype": "Report",
  "idx": 3,
  "is_standard": "Yes",
- "modified": "2020-01-22 16:51:56.591110",
+ "modified": "2020-07-26 23:59:49.897577",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Lead Details",
  "owner": "Administrator",
  "prepared_report": 0,
- "query": "SELECT\n    `tabLead`.name as \"Lead Id:Link/Lead:120\",\n    `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n\t`tabLead`.notes as \"Notes::360\",\n    `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabDynamic Link` on (\n\t\t`tabDynamic Link`.link_name=`tabLead`.name \n\t\tand `tabDynamic Link`.parenttype = 'Address'\n\t)\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.name=`tabDynamic Link`.parent\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
  "ref_doctype": "Lead",
  "report_name": "Lead Details",
- "report_type": "Query Report",
+ "report_type": "Script Report",
  "roles": [
   {
    "role": "Sales User"
diff --git a/erpnext/crm/report/lead_details/lead_details.py b/erpnext/crm/report/lead_details/lead_details.py
new file mode 100644
index 0000000..eeaaec2
--- /dev/null
+++ b/erpnext/crm/report/lead_details/lead_details.py
@@ -0,0 +1,158 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe import _
+import frappe
+
+def execute(filters=None):
+	columns, data = get_columns(), get_data(filters)
+	return columns, data
+
+def get_columns():
+	columns = [
+		{
+			"label": _("Lead"),
+			"fieldname": "name",
+			"fieldtype": "Link",
+			"options": "Lead",
+			"width": 150,
+		},
+		{
+			"label": _("Lead Name"),
+			"fieldname": "lead_name",
+			"fieldtype": "Data",
+			"width": 120
+		},
+		{
+			"fieldname":"status",
+			"label": _("Status"),
+			"fieldtype": "Data",
+			"width": 100
+		},
+		{
+			"fieldname":"lead_owner",
+			"label": _("Lead Owner"),
+			"fieldtype": "Link",
+			"options": "User",
+			"width": 100
+		},
+		{
+			"label": _("Territory"),
+			"fieldname": "territory",
+			"fieldtype": "Link",
+			"options": "Territory",
+			"width": 100
+		},
+		{
+			"label": _("Source"),
+			"fieldname": "source",
+			"fieldtype": "Data",
+			"width": 120
+		},
+		{
+			"label": _("Email"),
+			"fieldname": "email_id",
+			"fieldtype": "Data",
+			"width": 120
+		},
+		{
+			"label": _("Mobile"),
+			"fieldname": "mobile_no",
+			"fieldtype": "Data",
+			"width": 120
+		},
+		{
+			"label": _("Phone"),
+			"fieldname": "phone",
+			"fieldtype": "Data",
+			"width": 120
+		},
+		{
+			"label": _("Owner"),
+			"fieldname": "owner",
+			"fieldtype": "Link",
+			"options": "user",
+			"width": 120
+		},
+		{
+			"label": _("Company"),
+			"fieldname": "company",
+			"fieldtype": "Link",
+			"options": "Company",
+			"width": 120
+		},
+		{
+			"fieldname":"address",
+			"label": _("Address"),
+			"fieldtype": "Data",
+			"width": 130
+		},
+		{
+			"fieldname":"state",
+			"label": _("State"),
+			"fieldtype": "Data",
+			"width": 100
+		},
+		{
+			"fieldname":"pincode",
+			"label": _("Postal Code"),
+			"fieldtype": "Data",
+			"width": 90
+		},
+		{
+			"fieldname":"country",
+			"label": _("Country"),
+			"fieldtype": "Link",
+			"options": "Country",
+			"width": 100
+		},
+		
+	]
+	return columns
+
+def get_data(filters):
+	return frappe.db.sql("""
+		SELECT
+			`tabLead`.name,
+			`tabLead`.lead_name,
+			`tabLead`.status,
+			`tabLead`.lead_owner,
+			`tabLead`.territory,
+			`tabLead`.source,
+			`tabLead`.email_id,
+			`tabLead`.mobile_no,
+			`tabLead`.phone,
+			`tabLead`.owner,
+			`tabLead`.company,
+			concat_ws(', ',
+				trim(',' from `tabAddress`.address_line1),
+				trim(',' from tabAddress.address_line2)
+			) AS address,
+			`tabAddress`.state,
+			`tabAddress`.pincode,
+			`tabAddress`.country
+		FROM
+			`tabLead` left join `tabDynamic Link` on (
+			`tabLead`.name = `tabDynamic Link`.link_name and
+			`tabDynamic Link`.parenttype = 'Address')
+			left join `tabAddress` on (
+			`tabAddress`.name=`tabDynamic Link`.parent)
+		WHERE
+			company = %(company)s
+			AND `tabLead`.creation BETWEEN %(from_date)s AND %(to_date)s
+			{conditions}
+		ORDER BY 
+			`tabLead`.creation asc """.format(conditions=get_conditions(filters)), filters, as_dict=1)
+
+def get_conditions(filters) :
+	conditions = []
+
+	if filters.get("territory"):
+		conditions.append(" and `tabLead`.territory=%(territory)s")
+
+	if filters.get("status"):
+		conditions.append(" and `tabLead`.status=%(status)s")
+	
+	return " ".join(conditions) if conditions else ""
+
diff --git a/erpnext/crm/report/lost_opportunity/lost_opportunity.js b/erpnext/crm/report/lost_opportunity/lost_opportunity.js
new file mode 100644
index 0000000..d79f8c8
--- /dev/null
+++ b/erpnext/crm/report/lost_opportunity/lost_opportunity.js
@@ -0,0 +1,67 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Lost Opportunity"] = {
+	"filters": [
+		{
+			"fieldname":"company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"default": frappe.defaults.get_user_default("Company"),
+			"reqd": 1
+		},
+		{
+			"fieldname":"from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -12),
+			"reqd": 1
+		},
+		{
+			"fieldname":"to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"default": frappe.datetime.get_today(),
+			"reqd": 1
+		},
+		{
+			"fieldname":"lost_reason",
+			"label": __("Lost Reason"),
+			"fieldtype": "Link",
+			"options": "Opportunity Lost Reason"
+		},
+		{
+			"fieldname":"territory",
+			"label": __("Territory"),
+			"fieldtype": "Link",
+			"options": "Territory"
+		},
+		{
+			"fieldname":"opportunity_from",
+			"label": __("Opportunity From"),
+			"fieldtype": "Link",
+			"options": "DocType",
+			"get_query": function() {
+				return {
+					"filters": {
+						"name": ["in", ["Customer", "Lead"]],
+					}
+				}
+			}
+		},
+		{
+			"fieldname":"party_name",
+			"label": __("Party"),
+			"fieldtype": "Dynamic Link",
+			"options": "opportunity_from"
+		},
+		{
+			"fieldname":"contact_by",
+			"label": __("Next Contact By"),
+			"fieldtype": "Link",
+			"options": "User"
+		},
+	]
+};
\ No newline at end of file
diff --git a/erpnext/crm/report/lost_opportunity/lost_opportunity.json b/erpnext/crm/report/lost_opportunity/lost_opportunity.json
index e7c5068..e7a8e12 100644
--- a/erpnext/crm/report/lost_opportunity/lost_opportunity.json
+++ b/erpnext/crm/report/lost_opportunity/lost_opportunity.json
@@ -1,13 +1,14 @@
 {
  "add_total_row": 0,
  "creation": "2018-12-31 16:30:57.188837",
+ "disable_prepared_report": 0,
  "disabled": 0,
  "docstatus": 0,
  "doctype": "Report",
  "idx": 0,
  "is_standard": "Yes",
  "json": "{\"order_by\": \"`tabOpportunity`.`modified` desc\", \"filters\": [[\"Opportunity\", \"status\", \"=\", \"Lost\"]], \"fields\": [[\"name\", \"Opportunity\"], [\"opportunity_from\", \"Opportunity\"], [\"party_name\", \"Opportunity\"], [\"customer_name\", \"Opportunity\"], [\"opportunity_type\", \"Opportunity\"], [\"status\", \"Opportunity\"], [\"contact_by\", \"Opportunity\"], [\"docstatus\", \"Opportunity\"], [\"lost_reason\", \"Lost Reason Detail\"]], \"add_totals_row\": 0, \"add_total_row\": 0, \"page_length\": 20}",
- "modified": "2019-06-26 16:33:08.083618",
+ "modified": "2020-07-29 15:49:02.848845",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Lost Opportunity",
@@ -15,7 +16,7 @@
  "prepared_report": 0,
  "ref_doctype": "Opportunity",
  "report_name": "Lost Opportunity",
- "report_type": "Report Builder",
+ "report_type": "Script Report",
  "roles": [
   {
    "role": "Sales User"
diff --git a/erpnext/crm/report/lost_opportunity/lost_opportunity.py b/erpnext/crm/report/lost_opportunity/lost_opportunity.py
new file mode 100644
index 0000000..1aa4afe
--- /dev/null
+++ b/erpnext/crm/report/lost_opportunity/lost_opportunity.py
@@ -0,0 +1,131 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe import _
+import frappe
+
+def execute(filters=None):
+	columns, data = get_columns(), get_data(filters)
+	return columns, data
+
+def get_columns():
+	columns = [
+		{
+			"label": _("Opportunity"),
+			"fieldname": "name",
+			"fieldtype": "Link",
+			"options": "Opportunity",
+			"width": 170,
+		},
+		{
+			"label": _("Opportunity From"),
+			"fieldname": "opportunity_from",
+			"fieldtype": "Link",
+			"options": "DocType",
+			"width": 130
+		},
+		{
+			"label": _("Party"),
+			"fieldname":"party_name",
+			"fieldtype": "Dynamic Link",
+			"options": "opportunity_from",
+			"width": 160
+		},
+		{
+			"label": _("Customer/Lead Name"),
+			"fieldname":"customer_name",
+			"fieldtype": "Data",
+			"width": 150
+		},
+		{
+			"label": _("Opportunity Type"),
+			"fieldname": "opportunity_type",
+			"fieldtype": "Data",
+			"width": 130
+		},
+		{
+			"label": _("Lost Reasons"),
+			"fieldname": "lost_reason",
+			"fieldtype": "Data",
+			"width": 220
+		},
+		{
+			"label": _("Sales Stage"),
+			"fieldname": "sales_stage",
+			"fieldtype": "Link",
+			"options": "Sales Stage",
+			"width": 150
+		},
+		{
+			"label": _("Territory"),
+			"fieldname": "territory",
+			"fieldtype": "Link",
+			"options": "Territory",
+			"width": 150
+		},
+		{
+			"label": _("Next Contact By"),
+			"fieldname": "contact_by",
+			"fieldtype": "Link",
+			"options": "User",
+			"width": 150
+		}
+	]
+	return columns
+
+def get_data(filters):
+	return frappe.db.sql("""
+		SELECT
+			`tabOpportunity`.name,
+			`tabOpportunity`.opportunity_from,
+			`tabOpportunity`.party_name,
+			`tabOpportunity`.customer_name,
+			`tabOpportunity`.opportunity_type,
+			`tabOpportunity`.contact_by,
+			GROUP_CONCAT(`tabOpportunity Lost Reason Detail`.lost_reason separator ', ') lost_reason,
+			`tabOpportunity`.sales_stage,
+			`tabOpportunity`.territory
+		FROM
+			`tabOpportunity` 
+			{join}
+		WHERE
+			`tabOpportunity`.status = 'Lost' and `tabOpportunity`.company = %(company)s
+			AND `tabOpportunity`.modified BETWEEN %(from_date)s AND %(to_date)s 
+			{conditions} 
+		GROUP BY 
+			`tabOpportunity`.name 
+		ORDER BY 
+			`tabOpportunity`.creation asc  """.format(conditions=get_conditions(filters), join=get_join(filters)), filters, as_dict=1)
+		
+
+def get_conditions(filters):
+	conditions = []
+
+	if filters.get("territory"):
+		conditions.append(" and `tabOpportunity`.territory=%(territory)s")
+
+	if filters.get("opportunity_from"):
+		conditions.append(" and `tabOpportunity`.opportunity_from=%(opportunity_from)s")
+
+	if filters.get("party_name"):
+		conditions.append(" and `tabOpportunity`.party_name=%(party_name)s")
+
+	if filters.get("contact_by"):
+		conditions.append(" and `tabOpportunity`.contact_by=%(contact_by)s")
+
+	return " ".join(conditions) if conditions else ""
+
+def get_join(filters):
+	join = """LEFT JOIN `tabOpportunity Lost Reason Detail` 
+			ON `tabOpportunity Lost Reason Detail`.parenttype = 'Opportunity' and 
+			`tabOpportunity Lost Reason Detail`.parent = `tabOpportunity`.name"""
+
+	if filters.get("lost_reason"):
+		join = """JOIN `tabOpportunity Lost Reason Detail` 
+			ON `tabOpportunity Lost Reason Detail`.parenttype = 'Opportunity' and 
+			`tabOpportunity Lost Reason Detail`.parent = `tabOpportunity`.name and
+			`tabOpportunity Lost Reason Detail`.lost_reason = '{0}'
+			""".format(filters.get("lost_reason"))
+	
+	return join
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
index 207351f..4ee5f6b 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
@@ -7,6 +7,8 @@
 import frappe
 from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_clinical_procedure_template
 
+test_dependencies = ['Item']
+
 class TestClinicalProcedure(unittest.TestCase):
 	def test_procedure_template_item(self):
 		patient, medical_department, practitioner = create_healthcare_docs()
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index f7ed31b..2d6b645 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -226,7 +226,9 @@
 			primary_action_label: __('Book'),
 			primary_action: function() {
 				frm.set_value('appointment_time', selected_slot);
-				frm.set_value('duration', duration);
+				if (!frm.doc.duration) {
+					frm.set_value('duration', duration);
+				}
 				frm.set_value('practitioner', d.get_value('practitioner'));
 				frm.set_value('department', d.get_value('department'));
 				frm.set_value('appointment_date', d.get_value('appointment_date'));
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index db1d191..1b92358 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -132,6 +132,9 @@
 	if filters.get('employee'):
 		conditions['name'] = filters.get('employee')
 
+	if filters.get('company'):
+		conditions['company'] = filters.get('company')
+
 	return conditions
 
 def get_department_leave_approver_map(department=None):
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index c51f655..3189433 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -494,7 +494,7 @@
 					'image'			: d.image,
 					'stock_uom'		: d.stock_uom,
 					'stock_qty'		: flt(d.stock_qty),
-					'rate'			: flt(d.base_rate) / flt(d.conversion_factor),
+					'rate'			: flt(d.base_rate) / (flt(d.conversion_factor) or 1.0),
 					'include_item_in_manufacturing': d.include_item_in_manufacturing
 				}))
 
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index e6c10ad..742d18c 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -90,6 +90,7 @@
 		update_cost()
 
 def replace_bom(args):
+	frappe.db.auto_commit_on_many_writes = 1
 	args = frappe._dict(args)
 
 	doc = frappe.get_doc("BOM Update Tool")
@@ -97,6 +98,8 @@
 	doc.new_bom = args.new_bom
 	doc.replace_bom()
 
+	frappe.db.auto_commit_on_many_writes = 0
+
 def update_cost():
 	frappe.db.auto_commit_on_many_writes = 1
 	bom_list = get_boms_in_bottom_up_order()
diff --git a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py
index 43bd0cc..7feaffd 100644
--- a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py
+++ b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py
@@ -7,6 +7,7 @@
 	frappe.reload_doc('accounts', 'doctype', 'allowed_to_transact_with', force=True)
 	frappe.reload_doc('accounts', 'doctype', 'pricing_rule_detail', force=True)
 	frappe.reload_doc('crm', 'doctype', 'lost_reason_detail', force=True)
+	frappe.reload_doc('setup', 'doctype', 'quotation_lost_reason_detail', force=True)
 
 	company = frappe.get_all('Company', filters = {'country': 'United States'})
 	if not company:
diff --git a/erpnext/patches/v12_0/rename_lost_reason_detail.py b/erpnext/patches/v12_0/rename_lost_reason_detail.py
index 044d023..d0dc356 100644
--- a/erpnext/patches/v12_0/rename_lost_reason_detail.py
+++ b/erpnext/patches/v12_0/rename_lost_reason_detail.py
@@ -3,6 +3,7 @@
 
 def execute():
     if frappe.db.exists("DocType", "Lost Reason Detail"):
+        frappe.reload_doc("crm", "doctype", "opportunity_lost_reason")
         frappe.reload_doc("crm", "doctype", "opportunity_lost_reason_detail")
         frappe.reload_doc("setup", "doctype", "quotation_lost_reason_detail")
 
@@ -10,8 +11,8 @@
 
         frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason Detail` SELECT * FROM `tabLost Reason Detail` WHERE `parenttype` = 'Quotation'""")
 
-        frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason` (`name`, `creation`, `modified`, `modified_by`, `owner`, `docstatus`, `parent`, `parentfield`, `parenttype`, `idx`, `_comments`, `_assign`, `_user_tags`, `_liked_by`, `order_lost_reason`) 
-            SELECT o.`name`, o.`creation`, o.`modified`, o.`modified_by`, o.`owner`, o.`docstatus`, o.`parent`, o.`parentfield`, o.`parenttype`, o.`idx`, o.`_comments`, o.`_assign`, o.`_user_tags`, o.`_liked_by`, o.`lost_reason` 
+        frappe.db.sql("""INSERT INTO `tabQuotation Lost Reason` (`name`, `creation`, `modified`, `modified_by`, `owner`, `docstatus`, `parent`, `parentfield`, `parenttype`, `idx`, `_comments`, `_assign`, `_user_tags`, `_liked_by`, `order_lost_reason`)
+            SELECT o.`name`, o.`creation`, o.`modified`, o.`modified_by`, o.`owner`, o.`docstatus`, o.`parent`, o.`parentfield`, o.`parenttype`, o.`idx`, o.`_comments`, o.`_assign`, o.`_user_tags`, o.`_liked_by`, o.`lost_reason`
             FROM `tabOpportunity Lost Reason` o LEFT JOIN `tabQuotation Lost Reason` q ON q.name = o.name WHERE q.name IS NULL""")
-        
+
         frappe.delete_doc("DocType", "Lost Reason Detail")
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py
index 7c07b98..0f521cb 100644
--- a/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py
+++ b/erpnext/patches/v13_0/update_start_end_date_for_old_shift_assignment.py
@@ -7,4 +7,7 @@
 
 def execute():
     frappe.reload_doc('hr', 'doctype', 'shift_assignment')
-    frappe.db.sql("update `tabShift Assignment` set end_date=date, start_date=date where date IS NOT NULL and start_date IS NULL and end_date IS NULL;")
+    if frappe.db.has_column('Shift Assignment', 'date'):
+        frappe.db.sql("""update `tabShift Assignment`
+            set end_date=date, start_date=date
+            where date IS NOT NULL and start_date IS NULL and end_date IS NULL;""")
diff --git a/erpnext/portal/doctype/homepage/homepage.js b/erpnext/portal/doctype/homepage/homepage.js
index ca34d69..c7c66e0 100644
--- a/erpnext/portal/doctype/homepage/homepage.js
+++ b/erpnext/portal/doctype/homepage/homepage.js
@@ -21,34 +21,6 @@
 });
 
 frappe.ui.form.on('Homepage Featured Product', {
-	item_code: function(frm, cdt, cdn) {
-		var featured_product = frappe.model.get_doc(cdt, cdn);
-		if (featured_product.item_code) {
-			frappe.call({
-				method: 'frappe.client.get_value',
-				args: {
-					'doctype': 'Item',
-					'filters': {'name': featured_product.item_code},
-					'fieldname': [
-						'item_name',
-						'web_long_description',
-						'description',
-						'image',
-						'thumbnail'
-					]
-				},
-				callback: function(r) {
-					if (!r.exc) {
-						$.extend(featured_product, r.message);
-						if (r.message.web_long_description) {
-							featured_product.description = r.message.web_long_description;
-						}
-						frm.refresh_field('products');
-					}
-				}
-			});
-		}
-	},
 
 	view: function(frm, cdt, cdn){
 		var child= locals[cdt][cdn]
diff --git a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json
index c8b4ae9..01c32ef 100644
--- a/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json
+++ b/erpnext/portal/doctype/homepage_featured_product/homepage_featured_product.json
@@ -1,301 +1,116 @@
 {
- "allow_copy": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "hash", 
- "beta": 0, 
- "creation": "2016-04-22 05:57:06.261401", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 1, 
+ "actions": [],
+ "autoname": "hash",
+ "creation": "2016-04-22 05:57:06.261401",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "item_code",
+  "col_break1",
+  "item_name",
+  "view",
+  "section_break_5",
+  "description",
+  "column_break_7",
+  "image",
+  "thumbnail",
+  "route"
+ ],
  "fields": [
   {
-   "allow_on_submit": 0, 
-   "bold": 1, 
-   "collapsible": 0, 
-   "fieldname": "item_code", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 1, 
-   "label": "Item Code", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "item_code", 
-   "oldfieldtype": "Link", 
-   "options": "Item", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "print_width": "150px", 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 1, 
-   "set_only_once": 0, 
-   "unique": 0, 
+   "bold": 1,
+   "fieldname": "item_code",
+   "fieldtype": "Link",
+   "in_filter": 1,
+   "in_list_view": 1,
+   "label": "Item Code",
+   "oldfieldname": "item_code",
+   "oldfieldtype": "Link",
+   "options": "Item",
+   "print_width": "150px",
+   "reqd": 1,
+   "search_index": 1,
    "width": "150px"
-  }, 
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "col_break1", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "col_break1",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "item_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "Item Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "item_name", 
-   "oldfieldtype": "Data", 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "print_width": "150", 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0, 
+   "fetch_from": "item_code.item_name",
+   "fetch_if_empty": 1,
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Item Name",
+   "oldfieldname": "item_name",
+   "oldfieldtype": "Data",
+   "print_hide": 1,
+   "print_width": "150",
+   "read_only": 1,
+   "reqd": 1,
    "width": "150"
-  }, 
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "view", 
-   "fieldtype": "Button", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 1, 
-   "label": "View", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "view",
+   "fieldtype": "Button",
+   "in_list_view": 1,
+   "label": "View"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "fieldname": "section_break_5", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "collapsible": 1,
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break",
+   "label": "Description"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "description", 
-   "fieldtype": "Text Editor", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 1, 
-   "in_list_view": 1, 
-   "label": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "description", 
-   "oldfieldtype": "Small Text", 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "print_width": "300px", 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0, 
+   "fetch_from": "item_code.web_long_description",
+   "fieldname": "description",
+   "fieldtype": "Text Editor",
+   "in_filter": 1,
+   "in_list_view": 1,
+   "label": "Description",
+   "oldfieldname": "description",
+   "oldfieldtype": "Small Text",
+   "print_width": "300px",
    "width": "300px"
-  }, 
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "column_break_7", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_7",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Image", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "item_code.website_image",
+   "fetch_if_empty": 1,
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "label": "Image"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "thumbnail", 
-   "fieldtype": "Attach Image", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Thumbnail", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "thumbnail",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Thumbnail"
+  },
   {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "route", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "route", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "route",
+   "fieldtype": "Small Text",
+   "label": "route",
+   "read_only": 1
   }
- ], 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
-
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2016-08-09 06:09:34.731971", 
- "modified_by": "Administrator", 
- "module": "Portal", 
- "name": "Homepage Featured Product", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_seen": 0
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2020-08-25 15:27:49.573537",
+ "modified_by": "Administrator",
+ "module": "Portal",
+ "name": "Homepage Featured Product",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
 }
\ No newline at end of file
diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json
index 7b30af2..581e14c 100644
--- a/erpnext/selling/desk_page/retail/retail.json
+++ b/erpnext/selling/desk_page/retail/retail.json
@@ -3,7 +3,7 @@
   {
    "hidden": 0,
    "label": "Retail Operations",
-   "links": "[\n    {\n        \"description\": \"Setup default values for POS Invoices\",\n        \"label\": \"Point-of-Sale Profile\",\n        \"name\": \"POS Profile\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"POS Profile\"\n        ],\n        \"description\": \"Point of Sale\",\n        \"label\": \"POS\",\n        \"name\": \"pos\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"description\": \"Cashier Closing\",\n        \"label\": \"Cashier Closing\",\n        \"name\": \"Cashier Closing\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Setup mode of POS (Online / Offline)\",\n        \"label\": \"POS Settings\",\n        \"name\": \"POS Settings\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To make Customer based incentive schemes.\",\n        \"label\": \"Loyalty Program\",\n        \"name\": \"Loyalty Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n        \"label\": \"Loyalty Point Entry\",\n        \"name\": \"Loyalty Point Entry\",\n        \"type\": \"doctype\"\n    }\n]"
+   "links": "[\n    {\n        \"description\": \"Setup default values for POS Invoices\",\n        \"label\": \"Point of Sale Profile\",\n        \"name\": \"POS Profile\",\n        \"onboard\": 1,\n        \"type\": \"doctype\"\n    },\n    {\n        \"dependencies\": [\n            \"POS Profile\"\n        ],\n        \"description\": \"Point of Sale\",\n        \"label\": \"Point of Sale\",\n        \"name\": \"point-of-sale\",\n        \"onboard\": 1,\n        \"type\": \"page\"\n    },\n    {\n        \"description\": \"Setup mode of POS (Online / Offline)\",\n        \"label\": \"POS Settings\",\n        \"name\": \"POS Settings\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"Cashier Closing\",\n        \"label\": \"Cashier Closing\",\n        \"name\": \"Cashier Closing\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To make Customer based incentive schemes.\",\n        \"label\": \"Loyalty Program\",\n        \"name\": \"Loyalty Program\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"description\": \"To view logs of Loyalty Points assigned to a Customer.\",\n        \"label\": \"Loyalty Point Entry\",\n        \"name\": \"Loyalty Point Entry\",\n        \"type\": \"doctype\"\n    }\n]"
   }
  ],
  "category": "Domains",
@@ -14,10 +14,11 @@
  "docstatus": 0,
  "doctype": "Desk Page",
  "extends_another_page": 0,
+ "hide_custom": 0,
  "idx": 0,
  "is_standard": 1,
  "label": "Retail",
- "modified": "2020-04-26 22:42:39.346750",
+ "modified": "2020-08-20 18:00:07.515691",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Retail",
@@ -25,5 +26,27 @@
  "pin_to_bottom": 0,
  "pin_to_top": 0,
  "restrict_to_domain": "Retail",
- "shortcuts": []
+ "shortcuts": [
+  {
+   "color": "#9deca2",
+   "doc_view": "",
+   "format": "{} Active",
+   "label": "Point of Sale Profile",
+   "link_to": "POS Profile",
+   "stats_filter": "{\n    \"disabled\": 0\n}",
+   "type": "DocType"
+  },
+  {
+   "doc_view": "",
+   "label": "Point of Sale",
+   "link_to": "point-of-sale",
+   "type": "Page"
+  },
+  {
+   "doc_view": "",
+   "label": "POS Settings",
+   "link_to": "POS Settings",
+   "type": "DocType"
+  }
+ ]
 }
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py
index 09e474d..532c11b 100644
--- a/erpnext/selling/doctype/customer/customer_dashboard.py
+++ b/erpnext/selling/doctype/customer/customer_dashboard.py
@@ -33,7 +33,7 @@
 			},
 			{
 				'label': _('Support'),
-				'items': ['Issue']
+				'items': ['Issue', 'Maintenance Visit', 'Installation Note', 'Warranty Claim']
 			},
 			{
 				'label': _('Projects'),
diff --git a/erpnext/selling/doctype/sales_order/sales_order_dashboard.py b/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
index 4126bc6..05a760d 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
+++ b/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
@@ -10,6 +10,7 @@
 			'Payment Entry': 'reference_name',
 			'Payment Request': 'reference_name',
 			'Auto Repeat': 'reference_document',
+			'Maintenance Visit': 'prevdoc_docname'
 		},
 		'internal_links': {
 			'Quotation': ['items', 'prevdoc_docname']
@@ -17,7 +18,7 @@
 		'transactions': [
 			{
 				'label': _('Fulfillment'),
-				'items': ['Sales Invoice', 'Pick List', 'Delivery Note']
+				'items': ['Sales Invoice', 'Pick List', 'Delivery Note', 'Maintenance Visit']
 			},
 			{
 				'label': _('Purchasing'),
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index 8ecc13b..c94831e 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -26,7 +26,8 @@
 		tabDocField where fieldtype='Link' and options='Company'"""):
 		if doctype not in ("Account", "Cost Center", "Warehouse", "Budget",
 			"Party Account", "Employee", "Sales Taxes and Charges Template",
-			"Purchase Taxes and Charges Template", "POS Profile", 'BOM'):
+			"Purchase Taxes and Charges Template", "POS Profile", "BOM",
+			"Company", "Bank Account"):
 				delete_for_doctype(doctype, company_name)
 
 	# reset company values
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d209f48..d22fda8 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -111,6 +111,7 @@
 		self.synced_with_hub = 0
 
 		self.validate_has_variants()
+		self.validate_attributes_in_variants()
 		self.validate_stock_exists_for_template_item()
 		self.validate_attributes()
 		self.validate_variant_attributes()
@@ -806,6 +807,77 @@
 			if frappe.db.exists("Item", {"variant_of": self.name}):
 				frappe.throw(_("Item has variants."))
 
+	def validate_attributes_in_variants(self):
+		if not self.has_variants or self.get("__islocal"):
+			return
+
+		old_doc = self.get_doc_before_save()
+		old_doc_attributes = set([attr.attribute for attr in old_doc.attributes])
+		own_attributes = [attr.attribute for attr in self.attributes]
+
+		# Check if old attributes were removed from the list
+		# Is old_attrs is a subset of new ones
+		# that means we need not check any changes
+		if old_doc_attributes.issubset(set(own_attributes)):
+			return
+
+		from collections import defaultdict
+
+		# get all item variants
+		items = [item["name"] for item in frappe.get_all("Item", {"variant_of": self.name})]
+
+		# get all deleted attributes
+		deleted_attribute = list(old_doc_attributes.difference(set(own_attributes)))
+
+		# fetch all attributes of these items
+		item_attributes = frappe.get_all(
+			"Item Variant Attribute",
+			filters={
+				"parent": ["in", items],
+				"attribute": ["in", deleted_attribute]
+			},
+			fields=["attribute", "parent"]
+		)
+		not_included = defaultdict(list)
+
+		for attr in item_attributes:
+			if attr["attribute"] not in own_attributes:
+				not_included[attr["parent"]].append(attr["attribute"])
+
+		if not len(not_included):
+			return
+
+		def body(docnames):
+			docnames.sort()
+			return "<br>".join(docnames)
+
+		def table_row(title, body):
+			return """<tr>
+				<td>{0}</td>
+				<td>{1}</td>
+			</tr>""".format(title, body)
+
+		rows = ''
+		for docname, attr_list in not_included.items():
+			link = "<a href='#Form/Item/{0}'>{0}</a>".format(frappe.bold(_(docname)))
+			rows += table_row(link, body(attr_list))
+
+		error_description = _('The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template.')
+
+		message = """
+			<div>{0}</div><br>
+			<table class="table">
+				<thead>
+					<td>{1}</td>
+					<td>{2}</td>
+				</thead>
+				{3}
+			</table>
+		""".format(error_description, _('Variant Items'), _('Attributes'), rows)
+
+		frappe.throw(message, title=_("Variant Attribute Error"), is_minimizable=True, wide=True)
+
+
 	def validate_stock_exists_for_template_item(self):
 		if self.stock_ledger_created() and self._doc_before_save:
 			if (cint(self._doc_before_save.has_variants) != cint(self.has_variants)
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index d0ba001..4e173ff 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -227,6 +227,14 @@
 					if not stock_value_diff:
 						continue
 
+					# If PR is sub-contracted and fg item rate is zero
+					# in that case if account for shource and target warehouse are same,
+					# then GL entries should not be posted
+					if flt(stock_value_diff) == flt(d.rm_supp_cost) \
+						and warehouse_account.get(self.supplier_warehouse) \
+						and warehouse_account[d.warehouse]["account"] == warehouse_account[self.supplier_warehouse]["account"]:
+							continue
+
 					gl_entries.append(self.get_gl_dict({
 						"account": warehouse_account[d.warehouse]["account"],
 						"against": stock_rbnb,
@@ -242,16 +250,16 @@
 
 					credit_amount = flt(d.base_net_amount, d.precision("base_net_amount")) \
 						if credit_currency == self.company_currency else flt(d.net_amount, d.precision("net_amount"))
-
-					gl_entries.append(self.get_gl_dict({
-						"account":  warehouse_account[d.from_warehouse]['account'] \
-							if d.from_warehouse else stock_rbnb,
-						"against": warehouse_account[d.warehouse]["account"],
-						"cost_center": d.cost_center,
-						"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
-						"debit": -1 * flt(d.base_net_amount, d.precision("base_net_amount")),
-						"debit_in_account_currency": -1 * credit_amount
-					}, credit_currency, item=d))
+					if credit_amount:
+						gl_entries.append(self.get_gl_dict({
+							"account":  warehouse_account[d.from_warehouse]['account'] \
+								if d.from_warehouse else stock_rbnb,
+							"against": warehouse_account[d.warehouse]["account"],
+							"cost_center": d.cost_center,
+							"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
+							"debit": -1 * flt(d.base_net_amount, d.precision("base_net_amount")),
+							"debit_in_account_currency": -1 * credit_amount
+						}, credit_currency, item=d))
 
 					negative_expense_to_be_booked += flt(d.item_tax_amount)
 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index d97b9e8..4a8236d 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -18,6 +18,28 @@
 		set_perpetual_inventory(0)
 		frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
 
+	def test_reverse_purchase_receipt_sle(self):
+
+		frappe.db.set_value('UOM', '_Test UOM', 'must_be_whole_number', 0)
+
+		pr = make_purchase_receipt(qty=0.5)
+
+		sl_entry = frappe.db.get_all("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
+			"voucher_no": pr.name}, ['actual_qty'])
+
+		self.assertEqual(len(sl_entry), 1)
+		self.assertEqual(sl_entry[0].actual_qty, 0.5)
+
+		pr.cancel()
+
+		sl_entry_cancelled = frappe.db.get_all("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
+			"voucher_no": pr.name}, ['actual_qty'], order_by='creation')
+
+		self.assertEqual(len(sl_entry_cancelled), 2)
+		self.assertEqual(sl_entry_cancelled[1].actual_qty, -0.5)
+
+		frappe.db.set_value('UOM', '_Test UOM', 'must_be_whole_number', 1)
+
 	def test_make_purchase_invoice(self):
 		pr = make_purchase_receipt(do_not_save=True)
 		self.assertRaises(frappe.ValidationError, make_purchase_invoice, pr.name)
@@ -121,6 +143,22 @@
 		rm_supp_cost = sum([d.amount for d in pr.get("supplied_items")])
 		self.assertEqual(pr.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
 
+	def test_subcontracting_gle_fg_item_rate_zero(self):
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+		set_perpetual_inventory()
+		frappe.db.set_value("Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", "BOM")
+		make_stock_entry(item_code="_Test Item", target="Work In Progress - TCP1", qty=100, basic_rate=100, company="_Test Company with perpetual inventory")
+		make_stock_entry(item_code="_Test Item Home Desktop 100", target="Work In Progress - TCP1",
+			qty=100, basic_rate=100, company="_Test Company with perpetual inventory")
+		pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=0, is_subcontracted="Yes",
+			company="_Test Company with perpetual inventory", warehouse='Stores - TCP1', supplier_warehouse='Work In Progress - TCP1')
+		
+		gl_entries = get_gl_entries("Purchase Receipt", pr.name)
+
+		self.assertFalse(gl_entries)
+
+		set_perpetual_inventory(0)
+
 	def test_serial_no_supplier(self):
 		pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1)
 		self.assertEqual(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"),
@@ -688,7 +726,7 @@
 		"received_qty": received_qty,
 		"rejected_qty": rejected_qty,
 		"rejected_warehouse": args.rejected_warehouse or "_Test Rejected Warehouse - _TC" if rejected_qty != 0 else "",
-		"rate": args.rate or 50,
+		"rate": args.rate if args.rate != None else 50,
 		"conversion_factor": args.conversion_factor or 1.0,
 		"serial_no": args.serial_no,
 		"stock_uom": args.stock_uom or "_Test UOM",
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index e1b3730..f4490f1 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -31,7 +31,7 @@
 				sle['posting_time'] = now_datetime().strftime('%H:%M:%S.%f')
 
 				if cancel:
-					sle['actual_qty'] = -flt(sle.get('actual_qty'), 0)
+					sle['actual_qty'] = -flt(sle.get('actual_qty'))
 
 					if sle['actual_qty'] < 0 and not sle.get('outgoing_rate'):
 						sle['outgoing_rate'] = get_incoming_outgoing_rate_for_cancel(sle.item_code,
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 9e15757..858564a 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -209,11 +209,11 @@
 
 	frm.dashboard.set_headline_alert(
 		'<div class="row">' +
-			'<div class="col-xs-6">' +
-				'<span class="indicator whitespace-nowrap '+ time_to_respond.indicator +'"><span class="hidden-xs">Time to Respond: '+ time_to_respond.diff_display +'</span></span> ' +
+			'<div class="col-xs-12 col-sm-6">' +
+				'<span class="indicator whitespace-nowrap '+ time_to_respond.indicator +'"><span>Time to Respond: '+ time_to_respond.diff_display +'</span></span> ' +
 			'</div>' +
-			'<div class="col-xs-6">' +
-				'<span class="indicator whitespace-nowrap '+ time_to_resolve.indicator +'"><span class="hidden-xs">Time to Resolve: '+ time_to_resolve.diff_display +'</span></span> ' +
+			'<div class="col-xs-12 col-sm-6">' +
+				'<span class="indicator whitespace-nowrap '+ time_to_resolve.indicator +'"><span>Time to Resolve: '+ time_to_resolve.diff_display +'</span></span> ' +
 			'</div>' +
 		'</div>'
 	);
diff --git a/erpnext/templates/generators/item/item_inquiry.js b/erpnext/templates/generators/item/item_inquiry.js
index 52ddae2..e7db3a3 100644
--- a/erpnext/templates/generators/item/item_inquiry.js
+++ b/erpnext/templates/generators/item/item_inquiry.js
@@ -22,6 +22,13 @@
 			},
 			{
 				fieldtype: 'Data',
+				label: __('Phone Number'),
+				fieldname: 'phone',
+				options: 'Phone',
+				reqd: 1
+			},
+			{
+				fieldtype: 'Data',
 				label: __('Subject'),
 				fieldname: 'subject',
 				reqd: 1