Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Optimize get_attribute_filters (#26729) #27931

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 26 additions & 33 deletions erpnext/e_commerce/product_data_engine/filters.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down Expand Up @@ -96,38 +95,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 = []
Expand All @@ -147,4 +140,4 @@ def get_discount_filters(self, discounts):
label = f"{discount}% and below"
discount_filters.append([discount, label])

return discount_filters
return discount_filters
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
make_website_item(variant, save=True)
8 changes: 4 additions & 4 deletions erpnext/templates/includes/macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,15 @@ <h2 style="font-size: 2rem;">
<div class="filter-options">
{% for attr_value in attribute.item_attribute_values %}
<div class="checkbox">
<label data-value="{{ attr_value }}">
<label>
<input type="checkbox"
class="product-filter attribute-filter"
id="{{attr_value.name}}"
id="{{ attr_value }}"
data-attribute-name="{{ attribute.name }}"
data-attribute-value="{{ attr_value.attribute_value }}"
data-attribute-value="{{ attr_value }}"
style="width: 14px !important"
{% if attr_value.checked %} checked {% endif %}>
<span class="label-area">{{ attr_value.attribute_value }}</span>
<span class="label-area">{{ attr_value }}</span>
</label>
</div>
{% endfor %}
Expand Down