fix: Discount Filters and Web templates
- Fixed discount filters (didn’t work after js render change) - Fix Item Card Group template height and style - Add placeholder to missing images in Product Category Cards template - Code cleanup
This commit is contained in:
parent
03b88bd7b8
commit
b29c5d6e84
@ -115,7 +115,7 @@ def get_next_attribute_and_values(item_code, selected_attributes):
|
||||
next_attribute = attribute
|
||||
break
|
||||
|
||||
valid_options_for_attributes = frappe._dict({})
|
||||
valid_options_for_attributes = frappe._dict()
|
||||
|
||||
for a in attribute_list:
|
||||
valid_options_for_attributes[a] = set()
|
||||
|
@ -12,6 +12,7 @@ erpnext.ProductGrid = class {
|
||||
this.products_section.addClass("hidden");
|
||||
}
|
||||
|
||||
this.products_section.empty();
|
||||
this.make();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ erpnext.ProductList = class {
|
||||
this.products_section.addClass("hidden");
|
||||
}
|
||||
|
||||
this.products_section.empty();
|
||||
this.make();
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class ProductQuery:
|
||||
|
||||
def query_items(self, conditions, or_conditions, substitutions, start=0, with_attributes=False):
|
||||
"""Build a query to fetch Website Items based on field filters."""
|
||||
self.query_fields = (", ").join(self.fields)
|
||||
self.query_fields = ", ".join(self.fields)
|
||||
|
||||
attribute_table = ", `tabItem Variant Attribute` iva" if with_attributes else ""
|
||||
|
||||
@ -119,9 +119,9 @@ class ProductQuery:
|
||||
{conditions}
|
||||
{or_conditions}
|
||||
limit {self.page_length} offset {start}
|
||||
""",
|
||||
tuple(substitutions),
|
||||
as_dict=1)
|
||||
""",
|
||||
tuple(substitutions),
|
||||
as_dict=1)
|
||||
|
||||
def query_items_with_attributes(self, attributes, start=0):
|
||||
"""Build a query to fetch Website Items based on field & attribute filters."""
|
||||
@ -147,7 +147,7 @@ class ProductQuery:
|
||||
|
||||
all_items.append(set(items_dict.keys()))
|
||||
|
||||
result = [items_dict.get(item) for item in list(set.intersection(*all_items))]
|
||||
result = [items_dict.get(item) for item in set.intersection(*all_items)]
|
||||
return result
|
||||
|
||||
def build_fields_filters(self, filters):
|
||||
@ -192,11 +192,8 @@ class ProductQuery:
|
||||
|
||||
# Join the meta fields and default fields set
|
||||
search_fields = default_fields.union(meta_fields)
|
||||
try:
|
||||
if frappe.db.count('Item', cache=True) > 50000:
|
||||
search_fields.remove('description')
|
||||
except KeyError:
|
||||
pass
|
||||
if frappe.db.count('Item', cache=True) > 50000:
|
||||
search_fields.discard('description')
|
||||
|
||||
# Build or filters for query
|
||||
search = '%{}%'.format(search_term)
|
||||
|
@ -6,8 +6,11 @@ erpnext.ProductView = class {
|
||||
*/
|
||||
constructor(options) {
|
||||
Object.assign(this, options);
|
||||
this.preference = "List View";
|
||||
this.preference = this.view_type;
|
||||
this.make();
|
||||
}
|
||||
|
||||
make() {
|
||||
this.products_section.empty();
|
||||
this.prepare_view_toggler();
|
||||
this.get_item_filter_data();
|
||||
@ -22,12 +25,12 @@ erpnext.ProductView = class {
|
||||
}
|
||||
|
||||
get_item_filter_data() {
|
||||
// Get and render all Items related components
|
||||
// Get and render all Product related views
|
||||
let me = this;
|
||||
let args = this.get_query_filters();
|
||||
|
||||
$('#list').prop('disabled', true);
|
||||
$('#image-view').prop('disabled', true);
|
||||
this.disable_view_toggler(true);
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.e_commerce.doctype.website_item.website_item.get_product_filter_data',
|
||||
args: args,
|
||||
@ -55,14 +58,20 @@ erpnext.ProductView = class {
|
||||
me.render_no_products_section();
|
||||
}
|
||||
|
||||
$('#list').prop('disabled', false);
|
||||
$('#image-view').prop('disabled', false);
|
||||
me.disable_view_toggler(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
disable_view_toggler(disable=false) {
|
||||
$('#list').prop('disabled', disable);
|
||||
$('#image-view').prop('disabled', disable);
|
||||
}
|
||||
|
||||
render_filters(filter_data) {
|
||||
this.get_discount_filter_html(filter_data.discount_filters);
|
||||
this.bind_filters();
|
||||
this.restore_filters_state();
|
||||
}
|
||||
|
||||
render_grid_view(items, settings) {
|
||||
@ -226,9 +235,11 @@ erpnext.ProductView = class {
|
||||
html += `
|
||||
<div class="checkbox">
|
||||
<label data-value="${ filter[0] }">
|
||||
<input type="radio" class="product-filter discount-filter"
|
||||
<input type="radio"
|
||||
class="product-filter discount-filter"
|
||||
name="discount" id="${ filter[0] }"
|
||||
data-filter-name="discount" data-filter-value="${ filter[0] }"
|
||||
data-filter-name="discount"
|
||||
data-filter-value="${ filter[0] }"
|
||||
>
|
||||
<span class="label-area" for="${ filter[0] }">
|
||||
${ filter[1] }
|
||||
@ -243,6 +254,97 @@ erpnext.ProductView = class {
|
||||
}
|
||||
}
|
||||
|
||||
bind_filters() {
|
||||
let me = this;
|
||||
this.field_filters = {};
|
||||
this.attribute_filters = {};
|
||||
|
||||
$('.product-filter').on('change', (e) => {
|
||||
const $checkbox = $(e.target);
|
||||
const is_checked = $checkbox.is(':checked');
|
||||
|
||||
if ($checkbox.is('.attribute-filter')) {
|
||||
const {
|
||||
attributeName: attribute_name,
|
||||
attributeValue: attribute_value
|
||||
} = $checkbox.data();
|
||||
|
||||
if (is_checked) {
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
|
||||
this.attribute_filters[attribute_name].push(attribute_value);
|
||||
} else {
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name].filter(v => v !== attribute_value);
|
||||
}
|
||||
|
||||
if (this.attribute_filters[attribute_name].length === 0) {
|
||||
delete this.attribute_filters[attribute_name];
|
||||
}
|
||||
} else if ($checkbox.is('.field-filter') || $checkbox.is('.discount-filter')) {
|
||||
const {
|
||||
filterName: filter_name,
|
||||
filterValue: filter_value
|
||||
} = $checkbox.data();
|
||||
|
||||
if ($checkbox.is('.discount-filter')) {
|
||||
// clear previous discount filter to accomodate new
|
||||
delete this.field_filters["discount"];
|
||||
}
|
||||
if (is_checked) {
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
||||
this.field_filters[filter_name].push(filter_value);
|
||||
} else {
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name].filter(v => v !== filter_value);
|
||||
}
|
||||
|
||||
if (this.field_filters[filter_name].length === 0) {
|
||||
delete this.field_filters[filter_name];
|
||||
}
|
||||
}
|
||||
|
||||
let route_params = frappe.utils.get_query_params();
|
||||
const query_string = get_query_string({
|
||||
start: if_key_exists(route_params.start) || 0,
|
||||
field_filters: JSON.stringify(if_key_exists(this.field_filters)),
|
||||
attribute_filters: JSON.stringify(if_key_exists(this.attribute_filters)),
|
||||
});
|
||||
window.history.pushState('filters', '', `${location.pathname}?` + query_string);
|
||||
|
||||
$('.page_content input').prop('disabled', true);
|
||||
me.make();
|
||||
$('.page_content input').prop('disabled', false);
|
||||
});
|
||||
}
|
||||
|
||||
restore_filters_state() {
|
||||
const filters = frappe.utils.get_query_params();
|
||||
let {field_filters, attribute_filters} = filters;
|
||||
|
||||
if (field_filters) {
|
||||
field_filters = JSON.parse(field_filters);
|
||||
for (let fieldname in field_filters) {
|
||||
const values = field_filters[fieldname];
|
||||
const selector = values.map(value => {
|
||||
return `input[data-filter-name="${fieldname}"][data-filter-value="${value}"]`;
|
||||
}).join(',');
|
||||
$(selector).prop('checked', true);
|
||||
}
|
||||
this.field_filters = field_filters;
|
||||
}
|
||||
if (attribute_filters) {
|
||||
attribute_filters = JSON.parse(attribute_filters);
|
||||
for (let attribute in attribute_filters) {
|
||||
const values = attribute_filters[attribute];
|
||||
const selector = values.map(value => {
|
||||
return `input[data-attribute-name="${attribute}"][data-attribute-value="${value}"]`;
|
||||
}).join(',');
|
||||
$(selector).prop('checked', true);
|
||||
}
|
||||
this.attribute_filters = attribute_filters;
|
||||
}
|
||||
}
|
||||
|
||||
render_no_products_section() {
|
||||
this.products_section.append(`
|
||||
<br><br><br>
|
||||
@ -278,4 +380,26 @@ erpnext.ProductView = class {
|
||||
$("#product-listing").prepend(sub_group_html);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function get_query_string(object) {
|
||||
const url = new URLSearchParams();
|
||||
for (let key in object) {
|
||||
const value = object[key];
|
||||
if (value) {
|
||||
url.append(key, value);
|
||||
}
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function if_key_exists(obj) {
|
||||
let exists = false;
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key) && obj[key]) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return exists ? obj : undefined;
|
||||
}
|
@ -6,8 +6,15 @@
|
||||
}) -%}
|
||||
<div class="card h-100">
|
||||
{% if image %}
|
||||
<img class="card-img-top" src="{{ image }}" alt="{{ title }}">
|
||||
<img class="card-img-top" src="{{ image }}" alt="{{ title }}" style="max-height: 200px;">
|
||||
{% else %}
|
||||
<div class="placeholder-div" style="max-height: 200px;">
|
||||
<span class="placeholder">
|
||||
{{ frappe.utils.get_abbr(title or '') }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card-body text-center text-muted small">
|
||||
{{ title or '' }}
|
||||
</div>
|
||||
|
@ -54,12 +54,12 @@ def execute():
|
||||
for doctype in ("Website Item Group", "Item Website Specification"):
|
||||
web_item, item = website_item.name, item.item_code
|
||||
frappe.db.sql(f"""
|
||||
Update `tab{doctype}`
|
||||
Update
|
||||
`tab{doctype}`
|
||||
set
|
||||
parenttype = 'Website Item',
|
||||
parent = '{web_item}'
|
||||
where
|
||||
parenttype = 'Item'
|
||||
and parent = '{item}'
|
||||
"""
|
||||
)
|
||||
""")
|
@ -84,8 +84,8 @@ $.extend(wishlist, {
|
||||
const $wish_icon = $btn.find('.wish-icon');
|
||||
let me = this;
|
||||
|
||||
if(frappe.session.user==="Guest") {
|
||||
if(localStorage) {
|
||||
if (frappe.session.user==="Guest") {
|
||||
if (localStorage) {
|
||||
localStorage.setItem("last_visited", window.location.pathname);
|
||||
}
|
||||
window.location.href = "/login";
|
||||
@ -137,7 +137,7 @@ $.extend(wishlist, {
|
||||
failure_action: method to execute on failure,
|
||||
async: make call asynchronously (true/false). */
|
||||
if (frappe.session.user==="Guest") {
|
||||
if(localStorage) {
|
||||
if (localStorage) {
|
||||
localStorage.setItem("last_visited", window.location.pathname);
|
||||
}
|
||||
window.location.href = "/login";
|
||||
|
@ -782,3 +782,16 @@ body.product-page {
|
||||
#toggle-view {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.placeholder-div {
|
||||
height:80%;
|
||||
width: -webkit-fill-available;
|
||||
padding: 50px;
|
||||
text-align: center;
|
||||
background-color: #F9FAFA;
|
||||
border-top-left-radius: calc(0.75rem - 1px);
|
||||
border-top-right-radius: calc(0.75rem - 1px);
|
||||
}
|
||||
.placeholder {
|
||||
font-size: 72px;
|
||||
}
|
||||
|
@ -73,10 +73,10 @@
|
||||
|
||||
{% if is_featured %}
|
||||
<div class="col-sm-{{ col_size*2 }} item-card">
|
||||
<div class="card featured-item {{ align_items_class }}">
|
||||
<div class="card featured-item {{ align_items_class }}" style="height: 360px;">
|
||||
{% if image %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-5 ml-4">
|
||||
<img class="card-img" src="{{ image }}" alt="{{ title }}">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
@ -92,7 +92,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-sm-{{ col_size }} item-card">
|
||||
<div class="card {{ align_items_class }}">
|
||||
<div class="card {{ align_items_class }}" style="height: 360px;">
|
||||
{% if image %}
|
||||
<div class="card-img-container">
|
||||
<a href="/{{ item.route or '#' }}" style="text-decoration: none;">
|
||||
@ -119,19 +119,17 @@
|
||||
'text-left': align == 'Left' or is_featured,
|
||||
}) -%}
|
||||
<div class="card-body {{ align_class }}" style="width:100%">
|
||||
<div style="margin-top: 16px; display: flex;">
|
||||
<div class="mt-4">
|
||||
<a href="/{{ item.route or '#' }}">
|
||||
<div class="product-title">
|
||||
{{ title or '' }}
|
||||
{% if item.in_stock %}
|
||||
<span class="indicator {{ item.in_stock }} card-indicator"></span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% if is_featured %}
|
||||
<div class="product-price">{{ item.formatted_price or '' }}</div>
|
||||
<div class="product-description ellipsis">{{ description or '' }}</div>
|
||||
<div class="product-description ellipsis text-muted" style="white-space: normal;">
|
||||
{{ description or '' }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="product-category">{{ item.item_group or '' }}</div>
|
||||
{% endif %}
|
||||
|
@ -1,15 +1,13 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
no_cache = 1
|
||||
|
||||
import frappe
|
||||
from erpnext.e_commerce.doctype.item_review.item_review import get_item_reviews
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
context.full_page = True
|
||||
context.reviews = None
|
||||
|
||||
if frappe.form_dict and frappe.form_dict.get("item_code"):
|
||||
context.item_code = frappe.form_dict.get("item_code")
|
||||
context.web_item = frappe.db.get_value("Website Item", {"item_code": context.item_code}, "name")
|
||||
|
@ -1,9 +1,5 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
no_cache = 1
|
||||
|
||||
import frappe
|
||||
from erpnext.utilities.product import get_price
|
||||
from erpnext.e_commerce.shopping_cart.cart import _set_price_list
|
||||
@ -32,6 +28,7 @@ def get_context(context):
|
||||
|
||||
context.items = items
|
||||
context.settings = settings
|
||||
context.no_cache = 1
|
||||
|
||||
def get_stock_availability(item_code, warehouse):
|
||||
stock_qty = frappe.utils.flt(
|
||||
@ -42,7 +39,7 @@ def get_stock_availability(item_code, warehouse):
|
||||
},
|
||||
"actual_qty")
|
||||
)
|
||||
return True if stock_qty else False
|
||||
return bool(stock_qty)
|
||||
|
||||
def get_wishlist_items():
|
||||
if frappe.db.exists("Wishlist", frappe.session.user):
|
||||
@ -53,5 +50,5 @@ def get_wishlist_items():
|
||||
from
|
||||
`tabWishlist Items`
|
||||
where
|
||||
parent=%(user)s""" % {"user": frappe.db.escape(frappe.session.user)}, as_dict=1)
|
||||
parent=%(user)s""", {"user": frappe.session.user}, as_dict=1)
|
||||
return
|
@ -5,86 +5,18 @@ $(() => {
|
||||
let is_item_group_page = $(".item-group-content").data("item-group");
|
||||
this.item_group = is_item_group_page || null;
|
||||
|
||||
// Render Products and Discount Filters
|
||||
let view_type = "List View";
|
||||
|
||||
// Render Product Views and setup Filters
|
||||
frappe.require('assets/js/e-commerce.min.js', function() {
|
||||
new erpnext.ProductView({
|
||||
view_type: "List",
|
||||
view_type: view_type,
|
||||
products_section: $('#product-listing'),
|
||||
item_group: me.item_group
|
||||
});
|
||||
});
|
||||
|
||||
this.bind_filters();
|
||||
this.bind_card_actions();
|
||||
this.bind_search();
|
||||
this.restore_filters_state();
|
||||
}
|
||||
|
||||
bind_filters() {
|
||||
let me = this;
|
||||
this.field_filters = {};
|
||||
this.attribute_filters = {};
|
||||
|
||||
$('.product-filter').on('change', frappe.utils.debounce((e) => {
|
||||
const $checkbox = $(e.target);
|
||||
const is_checked = $checkbox.is(':checked');
|
||||
|
||||
if ($checkbox.is('.attribute-filter')) {
|
||||
const {
|
||||
attributeName: attribute_name,
|
||||
attributeValue: attribute_value
|
||||
} = $checkbox.data();
|
||||
|
||||
if (is_checked) {
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
|
||||
this.attribute_filters[attribute_name].push(attribute_value);
|
||||
} else {
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name] || [];
|
||||
this.attribute_filters[attribute_name] = this.attribute_filters[attribute_name].filter(v => v !== attribute_value);
|
||||
}
|
||||
|
||||
if (this.attribute_filters[attribute_name].length === 0) {
|
||||
delete this.attribute_filters[attribute_name];
|
||||
}
|
||||
} else if ($checkbox.is('.field-filter') || $checkbox.is('.discount-filter')) {
|
||||
const {
|
||||
filterName: filter_name,
|
||||
filterValue: filter_value
|
||||
} = $checkbox.data();
|
||||
|
||||
if ($checkbox.is('.discount-filter')) {
|
||||
// clear previous discount filter to accomodate new
|
||||
delete this.field_filters["discount"];
|
||||
}
|
||||
if (is_checked) {
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
||||
this.field_filters[filter_name].push(filter_value);
|
||||
} else {
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name] || [];
|
||||
this.field_filters[filter_name] = this.field_filters[filter_name].filter(v => v !== filter_value);
|
||||
}
|
||||
|
||||
if (this.field_filters[filter_name].length === 0) {
|
||||
delete this.field_filters[filter_name];
|
||||
}
|
||||
}
|
||||
|
||||
const query_string = get_query_string({
|
||||
field_filters: JSON.stringify(if_key_exists(this.field_filters)),
|
||||
attribute_filters: JSON.stringify(if_key_exists(this.attribute_filters)),
|
||||
});
|
||||
window.history.pushState('filters', '', `${location.pathname}?` + query_string);
|
||||
|
||||
$('.page_content input').prop('disabled', true);
|
||||
frappe.require('assets/js/e-commerce.min.js', function() {
|
||||
new erpnext.ProductView({
|
||||
view_type: "List",
|
||||
products_section: $('#product-listing'),
|
||||
item_group: me.item_group
|
||||
});
|
||||
$('.page_content input').prop('disabled', false);
|
||||
});
|
||||
}, 1000));
|
||||
}
|
||||
|
||||
bind_card_actions() {
|
||||
@ -92,70 +24,20 @@ $(() => {
|
||||
e_commerce.wishlist.bind_wishlist_action();
|
||||
}
|
||||
|
||||
bind_search() {
|
||||
$('input[type=search]').on('keydown', (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
// Enter
|
||||
const value = e.target.value;
|
||||
if (value) {
|
||||
window.location.search = 'search=' + e.target.value;
|
||||
} else {
|
||||
window.location.search = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
restore_filters_state() {
|
||||
const filters = frappe.utils.get_query_params();
|
||||
let {field_filters, attribute_filters} = filters;
|
||||
|
||||
if (field_filters) {
|
||||
field_filters = JSON.parse(field_filters);
|
||||
for (let fieldname in field_filters) {
|
||||
const values = field_filters[fieldname];
|
||||
const selector = values.map(value => {
|
||||
return `input[data-filter-name="${fieldname}"][data-filter-value="${value}"]`;
|
||||
}).join(',');
|
||||
$(selector).prop('checked', true);
|
||||
}
|
||||
this.field_filters = field_filters;
|
||||
}
|
||||
if (attribute_filters) {
|
||||
attribute_filters = JSON.parse(attribute_filters);
|
||||
for (let attribute in attribute_filters) {
|
||||
const values = attribute_filters[attribute];
|
||||
const selector = values.map(value => {
|
||||
return `input[data-attribute-name="${attribute}"][data-attribute-value="${value}"]`;
|
||||
}).join(',');
|
||||
$(selector).prop('checked', true);
|
||||
}
|
||||
this.attribute_filters = attribute_filters;
|
||||
}
|
||||
}
|
||||
// bind_search() {
|
||||
// $('input[type=search]').on('keydown', (e) => {
|
||||
// if (e.keyCode === 13) {
|
||||
// // Enter
|
||||
// const value = e.target.value;
|
||||
// if (value) {
|
||||
// window.location.search = 'search=' + e.target.value;
|
||||
// } else {
|
||||
// window.location.search = '';
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
new ProductListing();
|
||||
|
||||
function get_query_string(object) {
|
||||
const url = new URLSearchParams();
|
||||
for (let key in object) {
|
||||
const value = object[key];
|
||||
if (value) {
|
||||
url.append(key, value);
|
||||
}
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function if_key_exists(obj) {
|
||||
let exists = false;
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key) && obj[key]) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return exists ? obj : undefined;
|
||||
}
|
||||
});
|
||||
|
@ -11,18 +11,6 @@
|
||||
width: 300px !important;
|
||||
margin: 30px !important;
|
||||
}
|
||||
.placeholder-div {
|
||||
height:80%;
|
||||
width: -webkit-fill-available;
|
||||
padding: 50px;
|
||||
text-align: center;
|
||||
background-color: #F9FAFA;
|
||||
border-top-left-radius: calc(0.75rem - 1px);
|
||||
border-top-right-radius: calc(0.75rem - 1px);
|
||||
}
|
||||
.placeholder {
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -4,7 +4,7 @@ from frappe import _
|
||||
sitemap = 1
|
||||
|
||||
def get_context(context):
|
||||
settings = frappe.get_doc("E Commerce Settings")
|
||||
settings = frappe.get_cached_doc("E Commerce Settings")
|
||||
context.categories_enabled = settings.enable_field_filters
|
||||
|
||||
if context.categories_enabled:
|
||||
@ -23,9 +23,9 @@ def get_slideshow(slideshow):
|
||||
'rounded': 1,
|
||||
'slider_name': "Categories"
|
||||
}
|
||||
slideshow = frappe.get_doc("Website Slideshow", slideshow)
|
||||
slideshow = frappe.get_cached_doc("Website Slideshow", slideshow)
|
||||
slides = slideshow.get({"doctype": "Website Slideshow Item"})
|
||||
for index, slide in enumerate(slides):
|
||||
for index, slide in enumerate(slides, start=1):
|
||||
values[f"slide_{index + 1}_image"] = slide.image
|
||||
values[f"slide_{index + 1}_title"] = slide.heading
|
||||
values[f"slide_{index + 1}_subtitle"] = slide.description
|
||||
@ -41,7 +41,7 @@ def get_tabs(categories):
|
||||
}
|
||||
|
||||
categorical_data = get_category_records(categories)
|
||||
for index, tab in enumerate(categorical_data):
|
||||
for index, tab in enumerate(categorical_data, start=1):
|
||||
tab_values[f"tab_{index + 1}_title"] = frappe.unscrub(tab)
|
||||
# pre-render cards for each tab
|
||||
tab_values[f"tab_{index + 1}_content"] = frappe.render_template(
|
||||
@ -55,19 +55,24 @@ def get_category_records(categories):
|
||||
for category in categories:
|
||||
if category == "item_group":
|
||||
categorical_data["item_group"] = frappe.db.sql("""
|
||||
Select name, parent_item_group, is_group, image, route
|
||||
from `tabItem Group`
|
||||
where parent_item_group='All Item Groups'
|
||||
and show_in_website=1""", as_dict=1)
|
||||
Select
|
||||
name, parent_item_group, is_group, image, route
|
||||
from
|
||||
`tabItem Group`
|
||||
where
|
||||
parent_item_group = 'All Item Groups'
|
||||
and show_in_website = 1
|
||||
""",
|
||||
as_dict=1)
|
||||
else:
|
||||
doctype = frappe.unscrub(category)
|
||||
fields = ["name"]
|
||||
if frappe.get_meta(doctype, cached=True).get_field("image"):
|
||||
fields += ["image"]
|
||||
|
||||
categorical_data[category] = frappe.db.sql("""
|
||||
Select {fields}
|
||||
from `tab{doctype}`""".format(doctype=doctype, fields=",".join(fields)), as_dict=1)
|
||||
categorical_data[category] = frappe.db.sql(f"""
|
||||
Select {",".join(fields)}
|
||||
from `tab{doctype}`""", as_dict=1)
|
||||
|
||||
return categorical_data
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user