feat: Discount Filters
- Discount filters in filters section - Code cleanup
This commit is contained in:
@@ -75,4 +75,4 @@ def get_customer():
|
|||||||
if customer:
|
if customer:
|
||||||
return frappe.db.get_value("Customer", customer)
|
return frappe.db.get_value("Customer", customer)
|
||||||
else:
|
else:
|
||||||
frappe.throw("You are not verified to write a review yet. Please contact us for verification.")
|
frappe.throw(_("You are not verified to write a review yet. Please contact us for verification."))
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _dict
|
from frappe import _dict
|
||||||
|
from frappe.utils import floor, ceil, flt
|
||||||
|
|
||||||
class ProductFiltersBuilder:
|
class ProductFiltersBuilder:
|
||||||
def __init__(self, item_group=None):
|
def __init__(self, item_group=None):
|
||||||
@@ -88,3 +89,19 @@ class ProductFiltersBuilder:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return valid_attributes
|
return valid_attributes
|
||||||
|
|
||||||
|
def get_discount_filters(self, discounts):
|
||||||
|
discount_filters = []
|
||||||
|
|
||||||
|
# [25.89, 60.5]
|
||||||
|
min_discount, max_discount = discounts[0], discounts[1]
|
||||||
|
# [25, 60]
|
||||||
|
min_range_absolute, max_range_absolute = floor(min_discount), floor(max_discount)
|
||||||
|
min_range = int(min_discount - (min_range_absolute%10)) # 20
|
||||||
|
max_range = int(max_discount - (max_range_absolute%10)) # 60
|
||||||
|
|
||||||
|
for discount in range(min_range, (max_range + 1), 10):
|
||||||
|
label = f"{discount}% and above"
|
||||||
|
discount_filters.append([discount, label])
|
||||||
|
|
||||||
|
return discount_filters
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
|
from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
class ProductQuery:
|
class ProductQuery:
|
||||||
"""Query engine for product listing
|
"""Query engine for product listing
|
||||||
@@ -37,16 +38,15 @@ class ProductQuery:
|
|||||||
Returns:
|
Returns:
|
||||||
list: List of results with set fields
|
list: List of results with set fields
|
||||||
"""
|
"""
|
||||||
|
result, discount_list = [], []
|
||||||
|
|
||||||
if fields:
|
if fields:
|
||||||
self.build_fields_filters(fields)
|
self.build_fields_filters(fields)
|
||||||
if search_term:
|
if search_term:
|
||||||
self.build_search_filters(search_term)
|
self.build_search_filters(search_term)
|
||||||
|
|
||||||
if self.settings.hide_variants:
|
if self.settings.hide_variants:
|
||||||
self.conditions += " and wi.variant_of is null"
|
self.conditions += " and wi.variant_of is null"
|
||||||
|
|
||||||
result = []
|
|
||||||
|
|
||||||
if attributes:
|
if attributes:
|
||||||
result = self.query_items_with_attributes(attributes, start)
|
result = self.query_items_with_attributes(attributes, start)
|
||||||
else:
|
else:
|
||||||
@@ -56,33 +56,50 @@ class ProductQuery:
|
|||||||
# add price and availability info in results
|
# add price and availability info in results
|
||||||
for item in result:
|
for item in result:
|
||||||
product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info')
|
product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info')
|
||||||
|
|
||||||
if product_info and product_info['price']:
|
if product_info and product_info['price']:
|
||||||
item.formatted_mrp = product_info['price'].get('formatted_mrp')
|
self.get_price_discount_info(item, product_info['price'], discount_list)
|
||||||
item.formatted_price = product_info['price'].get('formatted_price')
|
|
||||||
if item.formatted_mrp:
|
|
||||||
item.discount = product_info['price'].get('formatted_discount_percent') or \
|
|
||||||
product_info['price'].get('formatted_discount_rate')
|
|
||||||
item.price = product_info['price'].get('price_list_rate')
|
|
||||||
|
|
||||||
if self.settings.show_stock_availability:
|
if self.settings.show_stock_availability:
|
||||||
if item.get("website_warehouse"):
|
self.get_stock_availability(item)
|
||||||
stock_qty = frappe.utils.flt(
|
|
||||||
frappe.db.get_value("Bin",
|
|
||||||
{
|
|
||||||
"item_code": item.item_code,
|
|
||||||
"warehouse": item.get("website_warehouse")
|
|
||||||
},
|
|
||||||
"actual_qty")
|
|
||||||
)
|
|
||||||
item.in_stock = "green" if stock_qty else "red"
|
|
||||||
elif not frappe.db.get_value("Item", item.item_code, "is_stock_item"):
|
|
||||||
item.in_stock = "green" # non-stock item will always be available
|
|
||||||
|
|
||||||
item.wished = False
|
item.wished = False
|
||||||
if frappe.db.exists("Wishlist Items", {"item_code": item.item_code, "parent": frappe.session.user}):
|
if frappe.db.exists("Wishlist Items", {"item_code": item.item_code, "parent": frappe.session.user}):
|
||||||
item.wished = True
|
item.wished = True
|
||||||
|
|
||||||
return result
|
discounts = []
|
||||||
|
if discount_list:
|
||||||
|
discounts = [min(discount_list), max(discount_list)]
|
||||||
|
|
||||||
|
if fields and "discount" in fields:
|
||||||
|
discount_percent = frappe.utils.flt(fields["discount"][0])
|
||||||
|
result = [row for row in result if row.get("discount_percent") and row.discount_percent >= discount_percent]
|
||||||
|
|
||||||
|
return result, discounts
|
||||||
|
|
||||||
|
def get_price_discount_info(self, item, price_object, discount_list):
|
||||||
|
"""Modify item object and add price details."""
|
||||||
|
item.formatted_mrp = price_object.get('formatted_mrp')
|
||||||
|
item.formatted_price = price_object.get('formatted_price')
|
||||||
|
|
||||||
|
if price_object.get('discount_percent'):
|
||||||
|
item.discount_percent = flt(price_object.discount_percent)
|
||||||
|
discount_list.append(price_object.discount_percent)
|
||||||
|
|
||||||
|
if item.formatted_mrp:
|
||||||
|
item.discount = price_object.get('formatted_discount_percent') or \
|
||||||
|
price_object.get('formatted_discount_rate')
|
||||||
|
item.price = price_object.get('price_list_rate')
|
||||||
|
|
||||||
|
def get_stock_availability(self, item):
|
||||||
|
"""Modify item object and add stock details."""
|
||||||
|
if item.get("website_warehouse"):
|
||||||
|
stock_qty = frappe.utils.flt(
|
||||||
|
frappe.db.get_value("Bin", {"item_code": item.item_code, "warehouse": item.get("website_warehouse")},
|
||||||
|
"actual_qty"))
|
||||||
|
item.in_stock = "green" if stock_qty else "red"
|
||||||
|
elif not frappe.db.get_value("Item", item.item_code, "is_stock_item"):
|
||||||
|
item.in_stock = "green" # non-stock item will always be available
|
||||||
|
|
||||||
def query_items(self, conditions, or_conditions, substitutions, start=0):
|
def query_items(self, conditions, or_conditions, substitutions, start=0):
|
||||||
"""Build a query to fetch Website Items based on field filters."""
|
"""Build a query to fetch Website Items based on field filters."""
|
||||||
@@ -139,7 +156,7 @@ class ProductQuery:
|
|||||||
filters (dict): Filters
|
filters (dict): Filters
|
||||||
"""
|
"""
|
||||||
for field, values in filters.items():
|
for field, values in filters.items():
|
||||||
if not values:
|
if not values or field == "discount":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if isinstance(values, list):
|
if isinstance(values, list):
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ $.extend(wishlist, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let success_action = function() {
|
let success_action = function() {
|
||||||
const $card_wrapper = $move_to_cart_btn.closest(".item-card");
|
const $card_wrapper = $move_to_cart_btn.closest(".wishlist-card");
|
||||||
$card_wrapper.addClass("wish-removed");
|
$card_wrapper.addClass("wish-removed");
|
||||||
};
|
};
|
||||||
let args = { item_code: item_code };
|
let args = { item_code: item_code };
|
||||||
@@ -63,7 +63,7 @@ $.extend(wishlist, {
|
|||||||
let item_code = $remove_wish_btn.data("item-code");
|
let item_code = $remove_wish_btn.data("item-code");
|
||||||
|
|
||||||
let success_action = function() {
|
let success_action = function() {
|
||||||
const $card_wrapper = $remove_wish_btn.closest(".item-card");
|
const $card_wrapper = $remove_wish_btn.closest(".wishlist-card");
|
||||||
$card_wrapper.addClass("wish-removed");
|
$card_wrapper.addClass("wish-removed");
|
||||||
};
|
};
|
||||||
let args = { item_code: item_code };
|
let args = { item_code: item_code };
|
||||||
|
|||||||
@@ -90,12 +90,14 @@ class ItemGroup(NestedSet, WebsiteGenerator):
|
|||||||
field_filters['item_group'] = self.name
|
field_filters['item_group'] = self.name
|
||||||
|
|
||||||
engine = ProductQuery()
|
engine = ProductQuery()
|
||||||
context.items = engine.query(attribute_filters, field_filters, search, start)
|
context.items, discounts = engine.query(attribute_filters, field_filters, search, start)
|
||||||
|
|
||||||
filter_engine = ProductFiltersBuilder(self.name)
|
filter_engine = ProductFiltersBuilder(self.name)
|
||||||
|
|
||||||
context.field_filters = filter_engine.get_field_filters()
|
context.field_filters = filter_engine.get_field_filters()
|
||||||
context.attribute_filters = filter_engine.get_attribute_filters()
|
context.attribute_filters = filter_engine.get_attribute_filters()
|
||||||
|
if discounts:
|
||||||
|
context.discount_filters = filter_engine.get_discount_filters(discounts)
|
||||||
|
|
||||||
context.update({
|
context.update({
|
||||||
"parents": get_parent_item_groups(self.parent_item_group),
|
"parents": get_parent_item_groups(self.parent_item_group),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% from "erpnext/templates/includes/macros.html" import field_filter_section, attribute_filter_section, discount_range_filters %}
|
||||||
{% extends "templates/web.html" %}
|
{% extends "templates/web.html" %}
|
||||||
|
|
||||||
{% block header %}
|
{% block header %}
|
||||||
@@ -63,69 +64,17 @@
|
|||||||
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
||||||
<a class="mb-4 clear-filters" href="/{{ doc.route }}">{{ _('Clear All') }}</a>
|
<a class="mb-4 clear-filters" href="/{{ doc.route }}">{{ _('Clear All') }}</a>
|
||||||
</div>
|
</div>
|
||||||
{% for field_filter in field_filters %}
|
<!-- field filters -->
|
||||||
{%- set item_field = field_filter[0] %}
|
{{ field_filter_section(field_filters) }}
|
||||||
{%- 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 %}
|
<!-- attribute filters -->
|
||||||
<!-- show inline filter if values more than 20 -->
|
{{ attribute_filter_section(attribute_filters) }}
|
||||||
<input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if values %}
|
<!-- discount filters -->
|
||||||
<div class="filter-options">
|
{% if discount_filters %}
|
||||||
{% for value in values %}
|
{{ discount_range_filters(discount_filters) }}
|
||||||
<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>
|
|
||||||
{% else %}
|
|
||||||
<i class="text-muted">{{ _('No values') }}</i>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% 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 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>
|
|
||||||
{% else %}
|
|
||||||
<i class="text-muted">{{ _('No values') }}</i>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
|
|||||||
@@ -315,3 +315,91 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{%- macro field_filter_section(filters)-%}
|
||||||
|
{% for field_filter in 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 %}
|
||||||
|
<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>
|
||||||
|
{% else %}
|
||||||
|
<i class="text-muted">{{ _('No values') }}</i>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{%- macro attribute_filter_section(filters)-%}
|
||||||
|
{% for attribute in 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 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>
|
||||||
|
{% else %}
|
||||||
|
<i class="text-muted">{{ _('No values') }}</i>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{%- macro discount_range_filters(filters)-%}
|
||||||
|
<div class="mb-4 filter-block pb-5">
|
||||||
|
<div class="filter-label mb-3">{{ _("Discounts") }}</div>
|
||||||
|
<div class="filter-options">
|
||||||
|
{% for entry in filters %}
|
||||||
|
<div class="checkbox">
|
||||||
|
<label data-value="{{ entry[0] }}">
|
||||||
|
<input type="radio" class="product-filter discount-filter"
|
||||||
|
name="discount" id="{{ entry[0] }}"
|
||||||
|
data-filter-name="discount" data-filter-value="{{ entry[0] }}"
|
||||||
|
>
|
||||||
|
<span class="label-area" for="{{ entry[0] }}">
|
||||||
|
{{ entry[1] }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{%- endmacro -%}
|
||||||
@@ -98,6 +98,7 @@ def get_price(item_code, price_list, customer_group, company, qty=1):
|
|||||||
mrp = price_obj.price_list_rate or 0
|
mrp = price_obj.price_list_rate or 0
|
||||||
|
|
||||||
if pricing_rule.pricing_rule_for == "Discount Percentage":
|
if pricing_rule.pricing_rule_for == "Discount Percentage":
|
||||||
|
price_obj.discount_percent = pricing_rule.discount_percentage
|
||||||
price_obj.formatted_discount_percent = str(flt(pricing_rule.discount_percentage, 0)) + "%"
|
price_obj.formatted_discount_percent = str(flt(pricing_rule.discount_percentage, 0)) + "%"
|
||||||
price_obj.price_list_rate = flt(price_obj.price_list_rate * (1.0 - (flt(pricing_rule.discount_percentage) / 100.0)))
|
price_obj.price_list_rate = flt(price_obj.price_list_rate * (1.0 - (flt(pricing_rule.discount_percentage) / 100.0)))
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
{% from "erpnext/templates/includes/macros.html" import attribute_filter_section, field_filter_section, discount_range_filters %}
|
||||||
{% extends "templates/web.html" %}
|
{% extends "templates/web.html" %}
|
||||||
|
|
||||||
{% block title %}{{ _('Products') }}{% endblock %}
|
{% block title %}{{ _('Products') }}{% endblock %}
|
||||||
{% block header %}
|
{% block header %}
|
||||||
<div class="mb-6">{{ _('Products') }}</div>
|
<div class="mb-6">{{ _('Products') }}</div>
|
||||||
@@ -53,71 +55,19 @@
|
|||||||
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
||||||
<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
|
<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- field filters -->
|
||||||
{% if field_filters %}
|
{% if field_filters %}
|
||||||
{% for field_filter in field_filters %}
|
{{ field_filter_section(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 %}
|
|
||||||
<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>
|
|
||||||
{% else %}
|
|
||||||
<i class="text-muted">{{ _('No values') }}</i>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- attribute filters -->
|
||||||
{% if attribute_filters %}
|
{% if attribute_filters %}
|
||||||
{% for attribute in attribute_filters %}
|
{{ attribute_filter_section(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 %}
|
{% endif %}
|
||||||
|
|
||||||
{% if attribute.item_attribute_values %}
|
<!-- discount filters -->
|
||||||
<div class="filter-options">
|
{% if discount_filters %}
|
||||||
{% for attr_value in attribute.item_attribute_values %}
|
{{ discount_range_filters(discount_filters) }}
|
||||||
<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>
|
|
||||||
{% else %}
|
|
||||||
<i class="text-muted">{{ _('No values') }}</i>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,16 @@ $(() => {
|
|||||||
if (this.attribute_filters[attribute_name].length === 0) {
|
if (this.attribute_filters[attribute_name].length === 0) {
|
||||||
delete this.attribute_filters[attribute_name];
|
delete this.attribute_filters[attribute_name];
|
||||||
}
|
}
|
||||||
} else if ($checkbox.is('.field-filter')) {
|
} else if ($checkbox.is('.field-filter') || $checkbox.is('.discount-filter')) {
|
||||||
const {
|
const {
|
||||||
filterName: filter_name,
|
filterName: filter_name,
|
||||||
filterValue: filter_value
|
filterValue: filter_value
|
||||||
} = $checkbox.data();
|
} = $checkbox.data();
|
||||||
|
|
||||||
|
if ($checkbox.is('.discount-filter')) {
|
||||||
|
// clear previous discount filter to accomodate new
|
||||||
|
delete this.field_filters["discount"];
|
||||||
|
}
|
||||||
if (is_checked) {
|
if (is_checked) {
|
||||||
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
||||||
this.field_filters[filter_name].push(filter_value);
|
this.field_filters[filter_name].push(filter_value);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ def get_context(context):
|
|||||||
start = 0
|
start = 0
|
||||||
|
|
||||||
engine = ProductQuery()
|
engine = ProductQuery()
|
||||||
context.items = engine.query(attribute_filters, field_filters, search, start)
|
context.items, discounts = engine.query(attribute_filters, field_filters, search, start)
|
||||||
|
|
||||||
# Add homepage as parent
|
# Add homepage as parent
|
||||||
context.parents = [{"name": frappe._("Home"), "route":"/"}]
|
context.parents = [{"name": frappe._("Home"), "route":"/"}]
|
||||||
@@ -26,6 +26,8 @@ def get_context(context):
|
|||||||
|
|
||||||
context.field_filters = filter_engine.get_field_filters()
|
context.field_filters = filter_engine.get_field_filters()
|
||||||
context.attribute_filters = filter_engine.get_attribute_filters()
|
context.attribute_filters = filter_engine.get_attribute_filters()
|
||||||
|
if discounts:
|
||||||
|
context.discount_filters = filter_engine.get_discount_filters(discounts)
|
||||||
|
|
||||||
context.e_commerce_settings = engine.settings
|
context.e_commerce_settings = engine.settings
|
||||||
context.page_length = engine.settings.products_per_page or 20
|
context.page_length = engine.settings.products_per_page or 20
|
||||||
@@ -39,12 +41,13 @@ def get_products_html_for_website(field_filters=None, attribute_filters=None):
|
|||||||
attribute_filters = frappe.parse_json(attribute_filters)
|
attribute_filters = frappe.parse_json(attribute_filters)
|
||||||
|
|
||||||
engine = ProductQuery()
|
engine = ProductQuery()
|
||||||
items = engine.query(attribute_filters, field_filters, search_term=None, start=0)
|
items, discounts = engine.query(attribute_filters, field_filters, search_term=None, start=0)
|
||||||
|
|
||||||
item_html = []
|
item_html = []
|
||||||
for item in items:
|
for item in items:
|
||||||
item_html.append(frappe.render_template('erpnext/www/all-products/item_row.html', {
|
item_html.append(frappe.render_template('erpnext/www/all-products/item_row.html', {
|
||||||
'item': item
|
'item': item,
|
||||||
|
'e_commerce_settings': None
|
||||||
}))
|
}))
|
||||||
html = ''.join(item_html)
|
html = ''.join(item_html)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user