mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 08:54:45 +00:00
fix: Sider and Tests
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
from frappe import _
|
from frappe import _, msgprint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import get_datetime, get_datetime_str, now_datetime
|
from frappe.utils import get_datetime, get_datetime_str, now_datetime
|
||||||
|
|
||||||
@@ -30,7 +30,8 @@ class ECommerceSettings(Document):
|
|||||||
frappe.clear_document_cache("E Commerce Settings", "E Commerce Settings")
|
frappe.clear_document_cache("E Commerce Settings", "E Commerce Settings")
|
||||||
|
|
||||||
def validate_field_filters(self):
|
def validate_field_filters(self):
|
||||||
if not (self.enable_field_filters and self.filter_fields): return
|
if not (self.enable_field_filters and self.filter_fields):
|
||||||
|
return
|
||||||
|
|
||||||
item_meta = frappe.get_meta("Item")
|
item_meta = frappe.get_meta("Item")
|
||||||
valid_fields = [df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]]
|
valid_fields = [df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]]
|
||||||
@@ -40,7 +41,8 @@ class ECommerceSettings(Document):
|
|||||||
frappe.throw(_("Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type 'Link' or 'Table MultiSelect'").format(f.idx, f.fieldname))
|
frappe.throw(_("Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type 'Link' or 'Table MultiSelect'").format(f.idx, f.fieldname))
|
||||||
|
|
||||||
def validate_attribute_filters(self):
|
def validate_attribute_filters(self):
|
||||||
if not (self.enable_attribute_filters and self.filter_attributes): return
|
if not (self.enable_attribute_filters and self.filter_attributes):
|
||||||
|
return
|
||||||
|
|
||||||
# if attribute filters are enabled, hide_variants should be disabled
|
# if attribute filters are enabled, hide_variants should be disabled
|
||||||
self.hide_variants = 0
|
self.hide_variants = 0
|
||||||
|
|||||||
@@ -4,9 +4,6 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from six import string_types
|
|
||||||
import json
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.contacts.doctype.contact.contact import get_contact_name
|
from frappe.contacts.doctype.contact.contact import get_contact_name
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class WebsiteItem(WebsiteGenerator):
|
|||||||
self.update_template_item()
|
self.update_template_item()
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
|
super(WebsiteItem, self).on_trash()
|
||||||
self.publish_unpublish_desk_item(publish=False)
|
self.publish_unpublish_desk_item(publish=False)
|
||||||
|
|
||||||
def validate_duplicate_website_item(self):
|
def validate_duplicate_website_item(self):
|
||||||
@@ -169,8 +170,8 @@ class WebsiteItem(WebsiteGenerator):
|
|||||||
|
|
||||||
context.parents = get_parent_item_groups(self.item_group, from_item=True)
|
context.parents = get_parent_item_groups(self.item_group, from_item=True)
|
||||||
self.attributes = frappe.get_all("Item Variant Attribute",
|
self.attributes = frappe.get_all("Item Variant Attribute",
|
||||||
fields=["attribute", "attribute_value"],
|
fields=["attribute", "attribute_value"],
|
||||||
filters={"parent": self.item_code})
|
filters={"parent": self.item_code})
|
||||||
self.set_variant_context(context)
|
self.set_variant_context(context)
|
||||||
self.set_attribute_context(context)
|
self.set_attribute_context(context)
|
||||||
self.set_disabled_attributes(context)
|
self.set_disabled_attributes(context)
|
||||||
@@ -181,7 +182,7 @@ class WebsiteItem(WebsiteGenerator):
|
|||||||
|
|
||||||
context.wished = False
|
context.wished = False
|
||||||
if frappe.db.exists("Wishlist Items", {"item_code": self.item_code, "parent": frappe.session.user}):
|
if frappe.db.exists("Wishlist Items", {"item_code": self.item_code, "parent": frappe.session.user}):
|
||||||
context.wished = True
|
context.wished = True
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@@ -192,8 +193,8 @@ class WebsiteItem(WebsiteGenerator):
|
|||||||
# load variants
|
# load variants
|
||||||
# also used in set_attribute_context
|
# also used in set_attribute_context
|
||||||
context.variants = frappe.get_all("Item",
|
context.variants = frappe.get_all("Item",
|
||||||
filters={"variant_of": self.name, "show_variant_in_website": 1},
|
filters={"variant_of": self.name, "show_variant_in_website": 1},
|
||||||
order_by="name asc")
|
order_by="name asc")
|
||||||
|
|
||||||
variant = frappe.form_dict.variant
|
variant = frappe.form_dict.variant
|
||||||
if not variant and context.variants:
|
if not variant and context.variants:
|
||||||
@@ -227,8 +228,8 @@ class WebsiteItem(WebsiteGenerator):
|
|||||||
# load attributes
|
# load attributes
|
||||||
for v in context.variants:
|
for v in context.variants:
|
||||||
v.attributes = frappe.get_all("Item Variant Attribute",
|
v.attributes = frappe.get_all("Item Variant Attribute",
|
||||||
fields=["attribute", "attribute_value"],
|
fields=["attribute", "attribute_value"],
|
||||||
filters={"parent": v.name})
|
filters={"parent": v.name})
|
||||||
# make a map for easier access in templates
|
# make a map for easier access in templates
|
||||||
v.attribute_map = frappe._dict({})
|
v.attribute_map = frappe._dict({})
|
||||||
for attr in v.attributes:
|
for attr in v.attributes:
|
||||||
@@ -380,7 +381,8 @@ def invalidate_cache_for_web_item(doc):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_website_item(doc, save=True):
|
def make_website_item(doc, save=True):
|
||||||
if not doc: return
|
if not doc:
|
||||||
|
return
|
||||||
|
|
||||||
if isinstance(doc, string_types):
|
if isinstance(doc, string_types):
|
||||||
doc = json.loads(doc)
|
doc = json.loads(doc)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def remove_from_wishlist(item_code):
|
|||||||
delete
|
delete
|
||||||
from `tabWishlist Items`
|
from `tabWishlist Items`
|
||||||
where item_code=%(item_code)s
|
where item_code=%(item_code)s
|
||||||
"""%{"item_code": frappe.db.escape(item_code)})
|
""" % {"item_code": frappe.db.escape(item_code)})
|
||||||
|
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ class ProductFiltersBuilder:
|
|||||||
self.item_group = item_group
|
self.item_group = item_group
|
||||||
|
|
||||||
def get_field_filters(self):
|
def get_field_filters(self):
|
||||||
if not self.item_group and not self.doc.enable_field_filters: return
|
if not self.item_group and not self.doc.enable_field_filters:
|
||||||
|
return
|
||||||
|
|
||||||
filter_fields = [row.fieldname for row in self.doc.filter_fields]
|
filter_fields = [row.fieldname for row in self.doc.filter_fields]
|
||||||
|
|
||||||
@@ -46,7 +47,8 @@ class ProductFiltersBuilder:
|
|||||||
values = [d.name for d in frappe.get_all(doctype, filters)]
|
values = [d.name for d in frappe.get_all(doctype, filters)]
|
||||||
|
|
||||||
# Remove None
|
# Remove None
|
||||||
if None in values: values.remove(None)
|
if None in values:
|
||||||
|
values.remove(None)
|
||||||
|
|
||||||
if values:
|
if values:
|
||||||
filter_data.append([df, values])
|
filter_data.append([df, values])
|
||||||
@@ -54,7 +56,8 @@ class ProductFiltersBuilder:
|
|||||||
return filter_data
|
return filter_data
|
||||||
|
|
||||||
def get_attribute_filters(self):
|
def get_attribute_filters(self):
|
||||||
if not self.item_group and not self.doc.enable_attribute_filters: return
|
if not self.item_group and not self.doc.enable_attribute_filters:
|
||||||
|
return
|
||||||
|
|
||||||
attributes = [row.attribute for row in self.doc.filter_attributes]
|
attributes = [row.attribute for row in self.doc.filter_attributes]
|
||||||
attribute_docs = [
|
attribute_docs = [
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import frappe, unittest
|
import frappe, unittest
|
||||||
from frappe.utils import set_request, get_html_for_route
|
from frappe.utils import get_html_for_route
|
||||||
from frappe.website.render import render
|
|
||||||
from erpnext.e_commerce.product_query import ProductQuery
|
from erpnext.e_commerce.product_query import ProductQuery
|
||||||
from erpnext.stock.doctype.item.test_item import make_item_variant
|
|
||||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||||
|
|
||||||
test_dependencies = ["Item"]
|
test_dependencies = ["Item"]
|
||||||
@@ -84,7 +82,7 @@ class TestProductConfigurator(unittest.TestCase):
|
|||||||
|
|
||||||
def publish_items_on_website(self):
|
def publish_items_on_website(self):
|
||||||
if frappe.db.exists("Item", "_Test Item") and not frappe.db.exists("Website Item", {"item_code": "_Test Item"}):
|
if frappe.db.exists("Item", "_Test Item") and not frappe.db.exists("Website Item", {"item_code": "_Test Item"}):
|
||||||
make_website_item(frappe.get_cached_doc("Item", "_Test Item"))
|
make_website_item(frappe.get_cached_doc("Item", "_Test Item"))
|
||||||
|
|
||||||
if frappe.db.exists("Item", "_Test Variant Item") and not frappe.db.exists("Website Item", {"item_code": "_Test Variant Item"}):
|
if frappe.db.exists("Item", "_Test Variant Item") and not frappe.db.exists("Website Item", {"item_code": "_Test Variant Item"}):
|
||||||
make_website_item(frappe.get_cached_doc("Item", "_Test Variant Item"))
|
make_website_item(frappe.get_cached_doc("Item", "_Test Variant Item"))
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ def get_item_codes_by_attributes(attribute_filters, template_item_code=None):
|
|||||||
if not isinstance(attribute_values, list):
|
if not isinstance(attribute_values, list):
|
||||||
attribute_values = [attribute_values]
|
attribute_values = [attribute_values]
|
||||||
|
|
||||||
if not attribute_values: continue
|
if not attribute_values:
|
||||||
|
continue
|
||||||
|
|
||||||
wheres = []
|
wheres = []
|
||||||
query_values = []
|
query_values = []
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ class ProductQuery:
|
|||||||
"""Query engine for product listing
|
"""Query engine for product listing
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
fields (list): Fields to fetch in query
|
fields (list): Fields to fetch in query
|
||||||
conditions (string): Conditions for query building
|
conditions (string): Conditions for query building
|
||||||
or_conditions (string): Search conditions
|
or_conditions (string): Search conditions
|
||||||
page_length (Int): Length of page for the query
|
page_length (Int): Length of page for the query
|
||||||
settings (Document): E Commerce Settings DocType
|
settings (Document): E Commerce Settings DocType
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -29,16 +29,18 @@ class ProductQuery:
|
|||||||
"""Summary
|
"""Summary
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
attributes (dict, optional): Item Attribute filters
|
attributes (dict, optional): Item Attribute filters
|
||||||
fields (dict, optional): Field level filters
|
fields (dict, optional): Field level filters
|
||||||
search_term (str, optional): Search term to lookup
|
search_term (str, optional): Search term to lookup
|
||||||
start (int, optional): Page start
|
start (int, optional): Page start
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: List of results with set fields
|
list: List of results with set fields
|
||||||
"""
|
"""
|
||||||
if fields: self.build_fields_filters(fields)
|
if fields:
|
||||||
if search_term: self.build_search_filters(search_term)
|
self.build_fields_filters(fields)
|
||||||
|
if 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"
|
||||||
@@ -61,13 +63,13 @@ class ProductQuery:
|
|||||||
if self.settings.show_stock_availability:
|
if self.settings.show_stock_availability:
|
||||||
if item.get("website_warehouse"):
|
if item.get("website_warehouse"):
|
||||||
stock_qty = frappe.utils.flt(
|
stock_qty = frappe.utils.flt(
|
||||||
frappe.db.get_value("Bin",
|
frappe.db.get_value("Bin",
|
||||||
{
|
{
|
||||||
"item_code": item.item_code,
|
"item_code": item.item_code,
|
||||||
"warehouse": item.get("website_warehouse")
|
"warehouse": item.get("website_warehouse")
|
||||||
},
|
},
|
||||||
"actual_qty")
|
"actual_qty")
|
||||||
)
|
)
|
||||||
item.in_stock = "green" if stock_qty else "red"
|
item.in_stock = "green" if stock_qty else "red"
|
||||||
elif not frappe.db.get_value("Item", item.item_code, "is_stock_item"):
|
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.in_stock = "green" # non-stock item will always be available
|
||||||
@@ -106,7 +108,8 @@ class ProductQuery:
|
|||||||
self.conditions += " and iva.parent = wi.item_code"
|
self.conditions += " and iva.parent = wi.item_code"
|
||||||
|
|
||||||
for attribute, values in attributes.items():
|
for attribute, values in attributes.items():
|
||||||
if not isinstance(values, list): values = [values]
|
if not isinstance(values, list):
|
||||||
|
values = [values]
|
||||||
|
|
||||||
conditions_copy = self.conditions
|
conditions_copy = self.conditions
|
||||||
substitutions_copy = self.substitutions.copy()
|
substitutions_copy = self.substitutions.copy()
|
||||||
@@ -129,7 +132,7 @@ class ProductQuery:
|
|||||||
"""Build filters for field values
|
"""Build filters for field values
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filters (dict): Filters
|
filters (dict): Filters
|
||||||
"""
|
"""
|
||||||
for field, values in filters.items():
|
for field, values in filters.items():
|
||||||
if not values:
|
if not values:
|
||||||
@@ -147,7 +150,7 @@ class ProductQuery:
|
|||||||
"""Query search term in specified fields
|
"""Query search term in specified fields
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
search_term (str): Search candidate
|
search_term (str): Search candidate
|
||||||
"""
|
"""
|
||||||
# Default fields to search from
|
# Default fields to search from
|
||||||
default_fields = {'name', 'item_name', 'description', 'item_group'}
|
default_fields = {'name', 'item_name', 'description', 'item_group'}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ def execute():
|
|||||||
|
|
||||||
for row in homepage.products:
|
for row in homepage.products:
|
||||||
web_item = frappe.db.get_value("Website Item", {"item_code": row.item_code}, "name")
|
web_item = frappe.db.get_value("Website Item", {"item_code": row.item_code}, "name")
|
||||||
if not web_item: continue
|
if not web_item:
|
||||||
|
continue
|
||||||
|
|
||||||
row.item_code = web_item
|
row.item_code = web_item
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,6 @@ class Item(Document):
|
|||||||
(self.item_name, self.description, self.brand, self.name))
|
(self.item_name, self.description, self.brand, self.name))
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
super(Item, self).on_trash()
|
|
||||||
frappe.db.sql("""delete from tabBin where item_code=%s""", self.name)
|
frappe.db.sql("""delete from tabBin where item_code=%s""", self.name)
|
||||||
frappe.db.sql("delete from `tabItem Price` where item_code=%s", self.name)
|
frappe.db.sql("delete from `tabItem Price` where item_code=%s", self.name)
|
||||||
for variant_of in frappe.get_all("Item", filters={"variant_of": self.name}):
|
for variant_of in frappe.get_all("Item", filters={"variant_of": self.name}):
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ $(() => {
|
|||||||
{fieldname: "comment", fieldtype: "Small Text", label: "Your Review"}
|
{fieldname: "comment", fieldtype: "Small Text", label: "Your Review"}
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
let me = this;
|
|
||||||
let data = d.get_values();
|
let data = d.get_values();
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.e_commerce.doctype.item_review.item_review.add_item_review",
|
method: "erpnext.e_commerce.doctype.item_review.item_review.add_item_review",
|
||||||
@@ -39,7 +38,7 @@ $(() => {
|
|||||||
freeze: true,
|
freeze: true,
|
||||||
freeze_message: __("Submitting Review ..."),
|
freeze_message: __("Submitting Review ..."),
|
||||||
callback: (r) => {
|
callback: (r) => {
|
||||||
if(!r.exc) {
|
if (!r.exc) {
|
||||||
frappe.msgprint({
|
frappe.msgprint({
|
||||||
message: __("Thank you for submitting your review"),
|
message: __("Thank you for submitting your review"),
|
||||||
title: __("Review Submitted"),
|
title: __("Review Submitted"),
|
||||||
@@ -74,7 +73,7 @@ $(() => {
|
|||||||
end: me.page_length
|
end: me.page_length
|
||||||
},
|
},
|
||||||
callback: (result) => {
|
callback: (result) => {
|
||||||
if(result.message) {
|
if (result.message) {
|
||||||
let res = result.message;
|
let res = result.message;
|
||||||
me.get_user_review_html(res.reviews);
|
me.get_user_review_html(res.reviews);
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ $(() => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -121,7 +120,7 @@ $(() => {
|
|||||||
|
|
||||||
get_review_stars(rating) {
|
get_review_stars(rating) {
|
||||||
let stars = ``;
|
let stars = ``;
|
||||||
for(let i = 1; i < 6; i++) {
|
for (let i = 1; i < 6; i++) {
|
||||||
let fill_class = i <= rating ? 'star-click' : '';
|
let fill_class = i <= rating ? 'star-click' : '';
|
||||||
stars += `<svg class="icon icon-md ${fill_class}">
|
stars += `<svg class="icon icon-md ${fill_class}">
|
||||||
<use href="#icon-star"></use>
|
<use href="#icon-star"></use>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ def get_context(context):
|
|||||||
"warehouse": item.get("warehouse")
|
"warehouse": item.get("warehouse")
|
||||||
},
|
},
|
||||||
"actual_qty")
|
"actual_qty")
|
||||||
)
|
)
|
||||||
item.available = True if stock_qty else False
|
item.available = True if stock_qty else False
|
||||||
|
|
||||||
context.items = items
|
context.items = items
|
||||||
@@ -34,5 +34,5 @@ def get_wishlist_items():
|
|||||||
from
|
from
|
||||||
`tabWishlist Items`
|
`tabWishlist Items`
|
||||||
where
|
where
|
||||||
parent=%(user)s"""%{"user": frappe.db.escape(frappe.session.user)}, as_dict=1)
|
parent=%(user)s""" % {"user": frappe.db.escape(frappe.session.user)}, as_dict=1)
|
||||||
return
|
return
|
||||||
Reference in New Issue
Block a user