From 666e8cd07657b92d9198c699f74a63396e23324d Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Tue, 14 Sep 2021 11:41:19 +0530 Subject: [PATCH 1/3] perf: Optimize get_attribute_filters (#26729) * perf: Optimize get_attribute_filters * fix: handle when filter attributes are undefined * chore: unused imports Co-authored-by: Ankush Menat --- .../e_commerce/product_data_engine/filters.py | 56 +++++++++---------- erpnext/templates/includes/macros.html | 8 +-- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py index f9e3b6ae32e0..ba1b2ea9a563 100644 --- a/erpnext/e_commerce/product_data_engine/filters.py +++ b/erpnext/e_commerce/product_data_engine/filters.py @@ -96,38 +96,32 @@ def get_attribute_filters(self): return attributes = [row.attribute for row in self.doc.filter_attributes] - attribute_docs = [ - frappe.get_doc('Item Attribute', attribute) for attribute in attributes - ] - - valid_attributes = [] - - for attr_doc in attribute_docs: - selected_attributes = [] - for attr in attr_doc.item_attribute_values: - or_filters = [] - filters= [ - ["Item Variant Attribute", "attribute", "=", attr.parent], - ["Item Variant Attribute", "attribute_value", "=", attr.attribute_value] - ] - if self.item_group: - or_filters.extend([ - ["item_group", "=", self.item_group], - ["Website Item Group", "item_group", "=", self.item_group] - ]) - - if frappe.db.get_all("Item", filters, or_filters=or_filters, limit=1): - selected_attributes.append(attr) - - if selected_attributes: - valid_attributes.append( - _dict( - item_attribute_values=selected_attributes, - name=attr_doc.name - ) - ) - return valid_attributes + if not attributes: + return [] + + result = frappe.db.sql( + """ + select + distinct attribute, attribute_value + from + `tabItem Variant Attribute` + where + attribute in %(attributes)s + and attribute_value is not null + """, + {"attributes": attributes}, + as_dict=1, + ) + + attribute_value_map = {} + for d in result: + attribute_value_map.setdefault(d.attribute, []).append(d.attribute_value) + + out = [] + for name, values in attribute_value_map.items(): + out.append(frappe._dict(name=name, item_attribute_values=values)) + return out def get_discount_filters(self, discounts): discount_filters = [] diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html index 889cf1ab38d1..892d62513e22 100644 --- a/erpnext/templates/includes/macros.html +++ b/erpnext/templates/includes/macros.html @@ -339,15 +339,15 @@

{% for attr_value in attribute.item_attribute_values %}
-
{% endfor %} From 71e517f04348099f42cb4583b18a49d6d1e6d494 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Oct 2021 10:55:11 +0530 Subject: [PATCH 2/3] test: fix get_attribute_filter test The function returns strings directly instead of objects now. --- .../product_data_engine/test_product_data_engine.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py index 925e6e7be3cd..b52e140fcc46 100644 --- a/erpnext/e_commerce/product_data_engine/test_product_data_engine.py +++ b/erpnext/e_commerce/product_data_engine/test_product_data_engine.py @@ -175,9 +175,7 @@ def test_product_list_attribute_filter_builder(self): filter_engine = ProductFiltersBuilder() attribute_filter = filter_engine.get_attribute_filters()[0] - attributes = attribute_filter.item_attribute_values - - attribute_values = [d.attribute_value for d in attributes] + attribute_values = attribute_filter.item_attribute_values self.assertEqual(attribute_filter.name, "Test Size") self.assertGreater(len(attribute_values), 0) @@ -349,4 +347,4 @@ def create_variant_web_item(): variant.save() if not frappe.db.exists("Website Item", {"variant_of": "Test Web Item"}): - make_website_item(variant, save=True) \ No newline at end of file + make_website_item(variant, save=True) From 5ed32b59953d117041e55209066aab2666c8f9ff Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 21 Oct 2021 11:04:40 +0530 Subject: [PATCH 3/3] fix: unused imports --- erpnext/e_commerce/product_data_engine/filters.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/e_commerce/product_data_engine/filters.py b/erpnext/e_commerce/product_data_engine/filters.py index ba1b2ea9a563..6d44b2cb9772 100644 --- a/erpnext/e_commerce/product_data_engine/filters.py +++ b/erpnext/e_commerce/product_data_engine/filters.py @@ -1,7 +1,6 @@ # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt import frappe -from frappe import _dict from frappe.utils import floor @@ -141,4 +140,4 @@ def get_discount_filters(self, discounts): label = f"{discount}% and below" discount_filters.append([discount, label]) - return discount_filters \ No newline at end of file + return discount_filters