Merge branch 'develop' of https://github.com/frappe/erpnext into sla_fix
diff --git a/erpnext/portal/product_configurator/item_variants_cache.py b/erpnext/portal/product_configurator/item_variants_cache.py
index 0e0b8c9..f33c8d6 100644
--- a/erpnext/portal/product_configurator/item_variants_cache.py
+++ b/erpnext/portal/product_configurator/item_variants_cache.py
@@ -66,15 +66,14 @@
 			as_list=1
 		)
 
-		disabled_items = [i.name for i in frappe.db.get_all('Item', {'disabled': 1})]
+		disabled_items = set([i.name for i in frappe.db.get_all('Item', {'disabled': 1})])
 
 		attribute_value_item_map = frappe._dict({})
 		item_attribute_value_map = frappe._dict({})
 
+		item_variants_data = [r for r in item_variants_data if r[0] not in disabled_items]
 		for row in item_variants_data:
 			item_code, attribute, attribute_value = row
-			if item_code in disabled_items:
-				continue
 			# (attr, value) => [item1, item2]
 			attribute_value_item_map.setdefault((attribute, attribute_value), []).append(item_code)
 			# item => {attr1: value1, attr2: value2}
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index 405a6d8..15d5e9f 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -257,7 +257,8 @@
 
 	items = []
 	for attribute, value in selected_attributes.items():
-		items.append(set(attribute_value_item_map[(attribute, value)]))
+		filtered_items = attribute_value_item_map.get((attribute, value), [])
+		items.append(set(filtered_items))
 
 	return set.intersection(*items)
 
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index 6de6454..528c7cd 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -109,6 +109,18 @@
 			}
 		});
 	},
+
+	status: function(frm) {
+		if (frm.doc.status === 'Cancelled') {
+			frappe.confirm(__('Set tasks in this project as cancelled?'), () => {
+				frm.doc.tasks = frm.doc.tasks.map(task => {
+					task.status = 'Cancelled';
+					return task;
+				});
+				frm.refresh_field('tasks');
+			});
+		}
+	}
 });
 
 frappe.ui.form.on("Project Task", {
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 39222ac..61db3e1 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -35,6 +35,9 @@
 
 	def load_tasks(self):
 		"""Load `tasks` from the database"""
+		if frappe.flags.in_import:
+			return
+
 		self.tasks = []
 		for task in self.get_tasks():
 			task_map = {
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 84ee715..fa9a5a5 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -105,7 +105,7 @@
 
 	def update_project(self):
 		if self.project and not self.flags.from_project:
-			frappe.get_doc("Project", self.project).update_project()
+			frappe.get_cached_doc("Project", self.project).update_project()
 
 	def check_recursion(self):
 		if self.flags.ignore_recursion_check: return
@@ -150,7 +150,7 @@
 
 	def populate_depends_on(self):
 		if self.parent_task:
-			parent = frappe.get_doc('Task', self.parent_task)
+			parent = frappe.get_cached_doc('Task', self.parent_task)
 			if not self.name in [row.task for row in parent.depends_on]:
 				parent.append("depends_on", {
 					"doctype": "Task Depends On",