fix: Hide Attribute filters if 'Hide Variants' is enabled in E Commerce Settings

- Hide Attribute filters if 'Hide Variants' is enabled in E Commerce Settings
- Consider 'Hide Variants' in ProductQuery Engine
- Added docstrings
- Remove `get_e_commerce_settings`, redundant
diff --git a/erpnext/e_commerce/doctype/website_item/website_item.py b/erpnext/e_commerce/doctype/website_item/website_item.py
index 53ed5e8..6465571 100644
--- a/erpnext/e_commerce/doctype/website_item/website_item.py
+++ b/erpnext/e_commerce/doctype/website_item/website_item.py
@@ -326,6 +326,7 @@
 				row.description = desc
 
 def invalidate_cache_for_web_item(doc):
+	"""Invalidate Website Item Group cache and rebuild ItemVariantsCacheManager."""
 	from erpnext.stock.doctype.item.item import invalidate_item_variants_cache_for_website
 
 	invalidate_cache_for(doc, doc.item_group)
diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py
index 0de9729..7ce8f80 100644
--- a/erpnext/portal/product_configurator/utils.py
+++ b/erpnext/portal/product_configurator/utils.py
@@ -138,15 +138,3 @@
 
 	return attributes
 
-def get_html_for_items(items):
-	html = []
-	for item in items:
-		html.append(frappe.render_template('erpnext/www/all-products/item_row.html', {
-			'item': item
-		}))
-	return html
-
-def get_e_commerce_settings():
-	doc = frappe.get_cached_doc('E Commerce Settings')
-	doc.products_per_page = doc.products_per_page or 20
-	return doc
diff --git a/erpnext/shopping_cart/filters.py b/erpnext/shopping_cart/filters.py
index 4fe346b..f074081 100644
--- a/erpnext/shopping_cart/filters.py
+++ b/erpnext/shopping_cart/filters.py
@@ -1,8 +1,6 @@
-# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
-
 import frappe
 
 
@@ -16,6 +14,8 @@
 		self.item_group = item_group
 
 	def get_field_filters(self):
+		if not self.doc.enable_field_filters: return
+
 		filter_fields = [row.fieldname for row in self.doc.filter_fields]
 
 		meta = frappe.get_meta('Item')
@@ -56,6 +56,8 @@
 		return filter_data
 
 	def get_attribute_filters(self):
+		if not self.doc.enable_attribute_filters: return
+
 		attributes = [row.attribute for row in self.doc.filter_attributes]
 
 		if not attributes:
diff --git a/erpnext/shopping_cart/product_query.py b/erpnext/shopping_cart/product_query.py
index 140e1c6..a2d2994 100644
--- a/erpnext/shopping_cart/product_query.py
+++ b/erpnext/shopping_cart/product_query.py
@@ -42,6 +42,9 @@
 		if fields: self.build_fields_filters(fields)
 		if search_term: self.build_search_filters(search_term)
 
+		if self.settings.hide_variants:
+			self.conditions += " and wi.variant_of is null"
+
 		result = []
 		website_item_groups = []
 
@@ -53,7 +56,6 @@
 				filters=[["Website Item Group", "item_group", "=", item_group]]
 			)
 
-		self.query_fields = (", ").join(self.fields)
 		if attributes:
 			result = self.query_items_with_attributes(attributes, start)
 		else:
@@ -70,6 +72,8 @@
 
 	def query_items(self, conditions, or_conditions, substitutions, start=0):
 		"""Build a query to fetch Website Items based on field filters."""
+		self.query_fields = (", ").join(self.fields)
+
 		return frappe.db.sql("""
 			select distinct {query_fields}
 			from
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index ebc3276..2185694 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -23,7 +23,6 @@
 from frappe.utils.html_utils import clean_html
 from frappe.website.utils import clear_cache
 from frappe.model.document import Document
-from frappe.website.website_generator import WebsiteGenerator
 
 import erpnext
 from erpnext.controllers.item_variant import (
@@ -858,6 +857,7 @@
 
 
 def invalidate_cache_for_item(doc):
+	"""Invalidate Item Group cache and rebuild ItemVariantsCacheManager."""
 	invalidate_cache_for(doc, doc.item_group)
 
 	if doc.get("old_item_group") and doc.get("old_item_group") != doc.item_group:
@@ -867,6 +867,7 @@
 
 
 def invalidate_item_variants_cache_for_website(doc):
+	"""Rebuild ItemVariantsCacheManager via Item or Website Item."""
 	from erpnext.portal.product_configurator.item_variants_cache import ItemVariantsCacheManager
 
 	item_code = None
diff --git a/erpnext/www/all-products/index.html b/erpnext/www/all-products/index.html
index a7838ee..d32ef62 100644
--- a/erpnext/www/all-products/index.html
+++ b/erpnext/www/all-products/index.html
@@ -53,68 +53,72 @@
 				<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
 				<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
 			</div>
-			{% for field_filter in field_filters %}
-				{%- set item_field =  field_filter[0] %}
-				{%- set values =  field_filter[1] %}
-				<div class="mb-4 filter-block pb-5">
-					<div class="filter-label mb-3">{{ item_field.label }}</div>
+			{% if field_filters %}
+				{% for field_filter in field_filters %}
+					{%- set item_field =  field_filter[0] %}
+					{%- set values =  field_filter[1] %}
+					<div class="mb-4 filter-block pb-5">
+						<div class="filter-label mb-3">{{ item_field.label }}</div>
 
-					{% if values | len > 20 %}
-					<!-- show inline filter if values more than 20 -->
-					<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
-					{% endif %}
+						{% if values | len > 20 %}
+						<!-- show inline filter if values more than 20 -->
+						<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
+						{% endif %}
 
-					{% if values %}
-					<div class="filter-options">
-						{% for value in values %}
-						<div class="checkbox" data-value="{{ value }}">
-							<label for="{{value}}">
-								<input type="checkbox"
-									class="product-filter field-filter"
-									id="{{value}}"
-									data-filter-name="{{ item_field.fieldname }}"
-									data-filter-value="{{ value }}"
-								>
-								<span class="label-area">{{ value }}</span>
-							</label>
+						{% if values %}
+						<div class="filter-options">
+							{% for value in values %}
+							<div class="checkbox" data-value="{{ value }}">
+								<label for="{{value}}">
+									<input type="checkbox"
+										class="product-filter field-filter"
+										id="{{value}}"
+										data-filter-name="{{ item_field.fieldname }}"
+										data-filter-value="{{ value }}"
+									>
+									<span class="label-area">{{ value }}</span>
+								</label>
+							</div>
+							{% endfor %}
 						</div>
-						{% endfor %}
+						{% else %}
+						<i class="text-muted">{{ _('No values') }}</i>
+						{% endif %}
 					</div>
-					{% else %}
-					<i class="text-muted">{{ _('No values') }}</i>
-					{% endif %}
-				</div>
-			{% endfor %}
+				{% endfor %}
+			{% endif %}
 
-			{% for attribute in attribute_filters %}
-				<div class="mb-4 filter-block pb-5">
-					<div class="filter-label mb-3">{{ attribute.name}}</div>
-					{% if values | len > 20 %}
-					<!-- show inline filter if values more than 20 -->
-					<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
-					{% endif %}
+			{% if attribute_filters %}
+				{% for attribute in attribute_filters %}
+					<div class="mb-4 filter-block pb-5">
+						<div class="filter-label mb-3">{{ attribute.name}}</div>
+						{% if values | len > 20 %}
+						<!-- show inline filter if values more than 20 -->
+						<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
+						{% endif %}
 
-					{% if attribute.item_attribute_values %}
-					<div class="filter-options">
-						{% for attr_value in attribute.item_attribute_values %}
-						<div class="checkbox">
-							<label>
-								<input type="checkbox"
-									class="product-filter attribute-filter"
-									id="{{attr_value}}"
-									data-attribute-name="{{ attribute.name }}"
-									data-attribute-value="{{ attr_value }}"
-									{% if attr_value.checked %} checked {% endif %}>
-									<span class="label-area">{{ attr_value }}</span>
-							</label>
+						{% if attribute.item_attribute_values %}
+						<div class="filter-options">
+							{% for attr_value in attribute.item_attribute_values %}
+							<div class="checkbox">
+								<label data-value="{{ value }}">
+									<input type="checkbox"
+										class="product-filter attribute-filter"
+										id="{{attr_value.name}}"
+										data-attribute-name="{{ attribute.name }}"
+										data-attribute-value="{{ attr_value.attribute_value }}"
+										{% if attr_value.checked %} checked {% endif %}>
+										<span class="label-area">{{ attr_value.attribute_value }}</span>
+								</label>
+							</div>
+							{% endfor %}
 						</div>
-						{% endfor %}
+						{% else %}
+						<i class="text-muted">{{ _('No values') }}</i>
+						{% endif %}
 					</div>
-					{% else %}
-					<i class="text-muted">{{ _('No values') }}</i>
-					{% endif %}
-				</div>
-			{% endfor %}
+				{% endfor %}
+			{% endif %}
 		</div>
 
 		<script>