test: Recommendations, Reviews and Wishlist
- Tests for verified and unverified item reviewers - Test for recommended items and their prices - Test for adding removing items from Wishlist - Bug: Wishlist deletes all entries of an item code irrespective of user - Get Item reviews only if enabled - Removed price fields from Wishlist Item and made fields read only - Removed unused price stored as data on Wishlist buttons - Customer Reviews page checks if reviews are enabled else shows No Reviews - Moved price stock fetching in Wishlist in separate function - Made fields read only in Item Review
This commit is contained in:
parent
4d254a7ad3
commit
b4529b8511
@ -22,14 +22,16 @@
|
||||
"fieldname": "website_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Website Item",
|
||||
"options": "Website Item"
|
||||
"options": "Website Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "User",
|
||||
"options": "User"
|
||||
"options": "User",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
@ -53,33 +55,38 @@
|
||||
"fieldname": "rating",
|
||||
"fieldtype": "Rating",
|
||||
"in_list_view": 1,
|
||||
"label": "Rating"
|
||||
"label": "Rating",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "comment",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Comment"
|
||||
"label": "Comment",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "review_title",
|
||||
"fieldtype": "Data",
|
||||
"label": "Review Title"
|
||||
"label": "Review Title",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer",
|
||||
"options": "Customer"
|
||||
"options": "Customer",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "published_on",
|
||||
"fieldtype": "Data",
|
||||
"label": "Published on"
|
||||
"label": "Published on",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-04-02 15:56:00.447950",
|
||||
"modified": "2021-08-09 08:06:02.476254",
|
||||
"modified_by": "Administrator",
|
||||
"module": "E-commerce",
|
||||
"name": "Item Review",
|
||||
|
@ -11,6 +11,9 @@ from frappe.contacts.doctype.contact.contact import get_contact_name
|
||||
from frappe.utils import flt, cint
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import get_shopping_cart_settings
|
||||
|
||||
class UnverifiedReviewer(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
class ItemReview(Document):
|
||||
pass
|
||||
|
||||
@ -47,6 +50,10 @@ def get_item_reviews(web_item, start, end, data=None):
|
||||
@frappe.whitelist()
|
||||
def add_item_review(web_item, title, rating, comment=None):
|
||||
""" Add an Item Review by a user if non-existent. """
|
||||
if frappe.session.user == "Guest":
|
||||
frappe.throw(_("You are not verified to write a review yet. Please contact us for verification."),
|
||||
exc=UnverifiedReviewer)
|
||||
|
||||
if not frappe.db.exists("Item Review", {"user": frappe.session.user, "website_item": web_item}):
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Item Review",
|
||||
@ -62,6 +69,9 @@ def add_item_review(web_item, title, rating, comment=None):
|
||||
doc.insert()
|
||||
|
||||
def get_customer(silent=False):
|
||||
"""
|
||||
silent: Return customer if exists else return nothing. Dont throw error.
|
||||
"""
|
||||
user = frappe.session.user
|
||||
contact_name = get_contact_name(user)
|
||||
customer = None
|
||||
@ -78,4 +88,5 @@ def get_customer(silent=False):
|
||||
elif silent:
|
||||
return None
|
||||
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."),
|
||||
exc=UnverifiedReviewer)
|
@ -1,10 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||
from erpnext.e_commerce.doctype.item_review.item_review import get_item_reviews, \
|
||||
add_item_review, UnverifiedReviewer
|
||||
from erpnext.e_commerce.shopping_cart.cart import get_party
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import setup_e_commerce_settings
|
||||
|
||||
class TestItemReview(unittest.TestCase):
|
||||
pass
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
item = make_item("Test Mobile Phone")
|
||||
if not frappe.db.exists("Website Item", {"item_code": "Test Mobile Phone"}):
|
||||
make_website_item(item, save=True)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
frappe.get_cached_doc("Website Item", {"item_code": "Test Mobile Phone"}).delete()
|
||||
|
||||
def test_add_and_get_item_reviews_from_customer(self):
|
||||
"Add / Get Reviews from a User that is a valid customer (has added to cart or purchased in the past)"
|
||||
# create user
|
||||
web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
|
||||
test_user = create_user("test_reviewer@example.com", "Customer")
|
||||
frappe.set_user(test_user.name)
|
||||
|
||||
# create customer and contact against user
|
||||
customer = get_party()
|
||||
|
||||
# post review on "Test Mobile Phone"
|
||||
try:
|
||||
add_item_review(web_item, "Great Product", 3, "Would recommend this product")
|
||||
review_name = frappe.db.get_value("Item Review", {"website_item": web_item})
|
||||
except Exception:
|
||||
self.fail(f"Error while publishing review for {web_item}")
|
||||
|
||||
review_data = get_item_reviews(web_item, 0, 10)
|
||||
|
||||
self.assertEqual(len(review_data.reviews), 1)
|
||||
self.assertEqual(review_data.average_rating, 3)
|
||||
self.assertEqual(review_data.reviews_per_rating[2], 100)
|
||||
|
||||
# tear down
|
||||
frappe.set_user("Administrator")
|
||||
frappe.delete_doc("Item Review", review_name)
|
||||
customer.delete()
|
||||
|
||||
def test_add_item_review_from_non_customer(self):
|
||||
"Check if logged in user (who is not a customer yet) is blocked from posting reviews."
|
||||
web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
|
||||
test_user = create_user("test_reviewer@example.com", "Customer")
|
||||
frappe.set_user(test_user.name)
|
||||
|
||||
with self.assertRaises(UnverifiedReviewer):
|
||||
add_item_review(web_item, "Great Product", 3, "Would recommend this product")
|
||||
|
||||
# tear down
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
def test_add_item_reviews_from_guest_user(self):
|
||||
"Check if Guest user is blocked from posting reviews."
|
||||
web_item = frappe.db.get_value("Website Item", {"item_code": "Test Mobile Phone"})
|
||||
frappe.set_user("Guest")
|
||||
|
||||
with self.assertRaises(UnverifiedReviewer):
|
||||
add_item_review(web_item, "Great Product", 3, "Would recommend this product")
|
||||
|
||||
# tear down
|
||||
frappe.set_user("Administrator")
|
||||
|
@ -10,6 +10,7 @@ from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||
from erpnext.controllers.item_variant import create_variant
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import setup_e_commerce_settings
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import get_shopping_cart_settings
|
||||
from erpnext.e_commerce.shopping_cart.product_info import get_product_info_for_website
|
||||
|
||||
WEBITEM_DESK_TESTS = ("test_website_item_desk_item_sync", "test_publish_variant_and_template")
|
||||
@ -106,7 +107,7 @@ class TestWebsiteItem(unittest.TestCase):
|
||||
|
||||
def test_publish_variant_and_template(self):
|
||||
"Check if template is published on publishing variant."
|
||||
template = frappe.get_doc("Item", "Test Web Item")
|
||||
# template "Test Web Item" created on setUp
|
||||
variant = create_variant("Test Web Item", {"Test Size": "Large"})
|
||||
variant.save()
|
||||
|
||||
@ -119,7 +120,7 @@ class TestWebsiteItem(unittest.TestCase):
|
||||
# check if template is published
|
||||
try:
|
||||
template_web_item = frappe.get_doc("Website Item", {"item_code": variant.variant_of})
|
||||
except DoesNotExistError:
|
||||
except frappe.DoesNotExistError:
|
||||
self.fail(f"Template of {variant.item_code}, {variant.variant_of} not published")
|
||||
|
||||
# teardown
|
||||
@ -334,15 +335,114 @@ class TestWebsiteItem(unittest.TestCase):
|
||||
stock_entry.cancel()
|
||||
frappe.get_cached_doc("Website Item", {"item_code": "Test Mobile Phone"}).delete()
|
||||
|
||||
|
||||
def create_regular_web_item(self):
|
||||
"Create Regular Item and Website Item."
|
||||
def test_recommended_item(self):
|
||||
"Check if added recommended items are fetched correctly."
|
||||
item_code = "Test Mobile Phone"
|
||||
web_item = self.create_regular_web_item(item_code)
|
||||
|
||||
setup_e_commerce_settings({
|
||||
"enable_recommendations": 1,
|
||||
"show_price": 1
|
||||
})
|
||||
|
||||
# create recommended web item and price for it
|
||||
recommended_web_item = self.create_regular_web_item("Test Mobile Phone 1")
|
||||
make_web_item_price(item_code="Test Mobile Phone 1")
|
||||
|
||||
# add recommended item to first web item
|
||||
web_item.append("recommended_items", {"website_item": recommended_web_item.name})
|
||||
web_item.save()
|
||||
|
||||
frappe.local.shopping_cart_settings = None
|
||||
e_commerce_settings = get_shopping_cart_settings()
|
||||
recommended_items = web_item.get_recommended_items(e_commerce_settings)
|
||||
|
||||
# test results if show price is enabled
|
||||
self.assertEqual(len(recommended_items), 1)
|
||||
recomm_item = recommended_items[0]
|
||||
self.assertEqual(recomm_item.get("website_item_name"), "Test Mobile Phone 1")
|
||||
self.assertTrue(bool(recomm_item.get("price_info"))) # price fetched
|
||||
|
||||
price_info = recomm_item.get("price_info")
|
||||
self.assertEqual(price_info.get("price_list_rate"), 1000)
|
||||
self.assertEqual(price_info.get("formatted_price"), "₹ 1,000.00")
|
||||
|
||||
# test results if show price is disabled
|
||||
setup_e_commerce_settings({"show_price": 0})
|
||||
|
||||
frappe.local.shopping_cart_settings = None
|
||||
e_commerce_settings = get_shopping_cart_settings()
|
||||
recommended_items = web_item.get_recommended_items(e_commerce_settings)
|
||||
|
||||
self.assertEqual(len(recommended_items), 1)
|
||||
self.assertFalse(bool(recommended_items[0].get("price_info"))) # price not fetched
|
||||
|
||||
# tear down
|
||||
frappe.get_cached_doc("Item Price", {"item_code": "Test Mobile Phone 1"}).delete()
|
||||
web_item.delete()
|
||||
recommended_web_item.delete()
|
||||
|
||||
def test_recommended_item_for_guest_user(self):
|
||||
"Check if added recommended items are fetched correctly for guest user."
|
||||
item_code = "Test Mobile Phone"
|
||||
web_item = self.create_regular_web_item(item_code)
|
||||
|
||||
# price visible to guests
|
||||
setup_e_commerce_settings({
|
||||
"enable_recommendations": 1,
|
||||
"show_price": 1,
|
||||
"hide_price_for_guest": 0
|
||||
})
|
||||
|
||||
# create recommended web item and price for it
|
||||
recommended_web_item = self.create_regular_web_item("Test Mobile Phone 1")
|
||||
make_web_item_price(item_code="Test Mobile Phone 1")
|
||||
|
||||
# add recommended item to first web item
|
||||
web_item.append("recommended_items", {"website_item": recommended_web_item.name})
|
||||
web_item.save()
|
||||
|
||||
frappe.set_user("Guest")
|
||||
|
||||
frappe.local.shopping_cart_settings = None
|
||||
e_commerce_settings = get_shopping_cart_settings()
|
||||
recommended_items = web_item.get_recommended_items(e_commerce_settings)
|
||||
|
||||
# test results if show price is enabled
|
||||
self.assertEqual(len(recommended_items), 1)
|
||||
self.assertTrue(bool(recommended_items[0].get("price_info"))) # price fetched
|
||||
|
||||
# price hidden from guests
|
||||
frappe.set_user("Administrator")
|
||||
setup_e_commerce_settings({"hide_price_for_guest": 1})
|
||||
frappe.set_user("Guest")
|
||||
|
||||
frappe.local.shopping_cart_settings = None
|
||||
e_commerce_settings = get_shopping_cart_settings()
|
||||
recommended_items = web_item.get_recommended_items(e_commerce_settings)
|
||||
|
||||
# test results if show price is enabled
|
||||
self.assertEqual(len(recommended_items), 1)
|
||||
self.assertFalse(bool(recommended_items[0].get("price_info"))) # price fetched
|
||||
|
||||
# tear down
|
||||
frappe.set_user("Administrator")
|
||||
frappe.get_cached_doc("Item Price", {"item_code": "Test Mobile Phone 1"}).delete()
|
||||
web_item.delete()
|
||||
recommended_web_item.delete()
|
||||
|
||||
def create_regular_web_item(self, item_code=None):
|
||||
"Create Regular Item and Website Item."
|
||||
item_code = item_code or "Test Mobile Phone"
|
||||
item = make_item(item_code)
|
||||
|
||||
if not frappe.db.exists("Website Item", {"item_code": item_code}):
|
||||
web_item = make_website_item(item, save=False)
|
||||
web_item.save()
|
||||
else:
|
||||
web_item = frappe.get_cached_doc("Website Item", {"item_code": item_code})
|
||||
|
||||
return web_item
|
||||
|
||||
def make_web_item_price(**kwargs):
|
||||
item_code = kwargs.get("item_code")
|
||||
|
@ -198,8 +198,13 @@ class WebsiteItem(WebsiteGenerator):
|
||||
self.set_disabled_attributes(context)
|
||||
self.set_metatags(context)
|
||||
self.set_shopping_cart_data(context)
|
||||
|
||||
settings = context.shopping_cart.cart_settings
|
||||
|
||||
self.get_product_details_section(context)
|
||||
get_item_reviews(self.name, 0, 4, context)
|
||||
|
||||
if settings.enable_reviews:
|
||||
get_item_reviews(self.name, 0, 4, context)
|
||||
|
||||
context.wished = False
|
||||
if frappe.db.exists("Wishlist Item", {"item_code": self.item_code, "parent": frappe.session.user}):
|
||||
@ -208,7 +213,6 @@ class WebsiteItem(WebsiteGenerator):
|
||||
context.user_is_customer = check_if_user_is_customer()
|
||||
|
||||
context.recommended_items = None
|
||||
settings = context.shopping_cart.cart_settings
|
||||
if settings and settings.enable_recommendations:
|
||||
context.recommended_items = self.get_recommended_items(settings)
|
||||
|
||||
|
@ -1,10 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||
from erpnext.e_commerce.doctype.wishlist.wishlist import add_to_wishlist, remove_from_wishlist
|
||||
|
||||
class TestWishlist(unittest.TestCase):
|
||||
pass
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
item = make_item("Test Phone Series X")
|
||||
if not frappe.db.exists("Website Item", {"item_code": "Test Phone Series X"}):
|
||||
make_website_item(item, save=True)
|
||||
|
||||
item = make_item("Test Phone Series Y")
|
||||
if not frappe.db.exists("Website Item", {"item_code": "Test Phone Series Y"}):
|
||||
make_website_item(item, save=True)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
frappe.get_cached_doc("Website Item", {"item_code": "Test Phone Series X"}).delete()
|
||||
frappe.get_cached_doc("Website Item", {"item_code": "Test Phone Series Y"}).delete()
|
||||
frappe.get_cached_doc("Item", "Test Phone Series X").delete()
|
||||
frappe.get_cached_doc("Item", "Test Phone Series Y").delete()
|
||||
|
||||
def test_add_remove_items_in_wishlist(self):
|
||||
"Check if items are added and removed from user's wishlist."
|
||||
# add first item
|
||||
add_to_wishlist("Test Phone Series X")
|
||||
|
||||
# check if wishlist was created and item was added
|
||||
self.assertTrue(frappe.db.exists("Wishlist", {"user": frappe.session.user}))
|
||||
self.assertTrue(frappe.db.exists("Wishlist Item", {"item_code": "Test Phone Series X", "parent": frappe.session.user}))
|
||||
|
||||
# add second item to wishlist
|
||||
add_to_wishlist("Test Phone Series Y")
|
||||
wishlist_length = frappe.db.get_value(
|
||||
"Wishlist Item",
|
||||
{"parent": frappe.session.user},
|
||||
"count(*)"
|
||||
)
|
||||
self.assertEqual(wishlist_length, 2)
|
||||
|
||||
remove_from_wishlist("Test Phone Series X")
|
||||
remove_from_wishlist("Test Phone Series Y")
|
||||
|
||||
wishlist_length = frappe.db.get_value(
|
||||
"Wishlist Item",
|
||||
{"parent": frappe.session.user},
|
||||
"count(*)"
|
||||
)
|
||||
self.assertIsNone(frappe.db.exists("Wishlist Item", {"parent": frappe.session.user}))
|
||||
self.assertEqual(wishlist_length, 0)
|
||||
|
||||
# tear down
|
||||
frappe.get_doc("Wishlist", {"user": frappe.session.user}).delete()
|
||||
|
||||
def test_add_remove_in_wishlist_multiple_users(self):
|
||||
"Check if items are added and removed from the correct user's wishlist."
|
||||
test_user = create_user("test_reviewer@example.com", "Customer")
|
||||
test_user_1 = create_user("test_reviewer_1@example.com", "Customer")
|
||||
|
||||
# add to wishlist for first user
|
||||
frappe.set_user(test_user.name)
|
||||
add_to_wishlist("Test Phone Series X")
|
||||
|
||||
# add to wishlist for second user
|
||||
frappe.set_user(test_user_1.name)
|
||||
add_to_wishlist("Test Phone Series X")
|
||||
|
||||
# check wishlist and its content for users
|
||||
self.assertTrue(frappe.db.exists("Wishlist", {"user": test_user.name}))
|
||||
self.assertTrue(frappe.db.exists("Wishlist Item",
|
||||
{"item_code": "Test Phone Series X", "parent": test_user.name}))
|
||||
|
||||
self.assertTrue(frappe.db.exists("Wishlist", {"user": test_user_1.name}))
|
||||
self.assertTrue(frappe.db.exists("Wishlist Item",
|
||||
{"item_code": "Test Phone Series X", "parent": test_user_1.name}))
|
||||
|
||||
# remove item for second user
|
||||
remove_from_wishlist("Test Phone Series X")
|
||||
|
||||
# make sure item was removed for second user and not first
|
||||
self.assertFalse(frappe.db.exists("Wishlist Item",
|
||||
{"item_code": "Test Phone Series X", "parent": test_user_1.name}))
|
||||
self.assertTrue(frappe.db.exists("Wishlist Item",
|
||||
{"item_code": "Test Phone Series X", "parent": test_user.name}))
|
||||
|
||||
# remove item for first user
|
||||
frappe.set_user(test_user.name)
|
||||
remove_from_wishlist("Test Phone Series X")
|
||||
self.assertFalse(frappe.db.exists("Wishlist Item",
|
||||
{"item_code": "Test Phone Series X", "parent": test_user.name}))
|
||||
|
||||
# tear down
|
||||
frappe.set_user("Administrator")
|
||||
frappe.get_doc("Wishlist", {"user": test_user.name}).delete()
|
||||
frappe.get_doc("Wishlist", {"user": test_user_1.name}).delete()
|
@ -10,15 +10,17 @@ class Wishlist(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def add_to_wishlist(item_code, price, formatted_price=None):
|
||||
def add_to_wishlist(item_code):
|
||||
"""Insert Item into wishlist."""
|
||||
|
||||
if frappe.db.exists("Wishlist Item", {"item_code": item_code, "parent": frappe.session.user}):
|
||||
return
|
||||
|
||||
web_item_data = frappe.db.get_value("Website Item", {"item_code": item_code},
|
||||
["image", "website_warehouse", "name", "web_item_name", "item_name", "item_group", "route"]
|
||||
, as_dict=1)
|
||||
web_item_data = frappe.db.get_value(
|
||||
"Website Item",
|
||||
{"item_code": item_code},
|
||||
["image", "website_warehouse", "name", "web_item_name", "item_name", "item_group", "route"],
|
||||
as_dict=1)
|
||||
|
||||
wished_item_dict = {
|
||||
"item_code": item_code,
|
||||
@ -26,8 +28,6 @@ def add_to_wishlist(item_code, price, formatted_price=None):
|
||||
"item_group": web_item_data.get("item_group"),
|
||||
"website_item": web_item_data.get("name"),
|
||||
"web_item_name": web_item_data.get("web_item_name"),
|
||||
"price": frappe.utils.flt(price),
|
||||
"formatted_price": formatted_price,
|
||||
"image": web_item_data.get("image"),
|
||||
"warehouse": web_item_data.get("website_warehouse"),
|
||||
"route": web_item_data.get("route")
|
||||
@ -51,10 +51,12 @@ def add_to_wishlist(item_code, price, formatted_price=None):
|
||||
def remove_from_wishlist(item_code):
|
||||
if frappe.db.exists("Wishlist Item", {"item_code": item_code, "parent": frappe.session.user}):
|
||||
frappe.db.sql("""
|
||||
delete
|
||||
from `tabWishlist Item`
|
||||
where item_code=%(item_code)s
|
||||
""" % {"item_code": frappe.db.escape(item_code)})
|
||||
DELETE
|
||||
FROM `tabWishlist Item`
|
||||
WHERE
|
||||
item_code=%(item_code)s
|
||||
and parent='%(user)s'
|
||||
""" % {"item_code": frappe.db.escape(item_code), "user": frappe.session.user})
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
|
@ -18,8 +18,6 @@
|
||||
"image",
|
||||
"image_view",
|
||||
"section_break_8",
|
||||
"price",
|
||||
"formatted_price",
|
||||
"warehouse_section",
|
||||
"warehouse"
|
||||
],
|
||||
@ -39,7 +37,8 @@
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Website Item",
|
||||
"options": "Website Item"
|
||||
"options": "Website Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
@ -50,20 +49,23 @@
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name"
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "item_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item Details"
|
||||
"label": "Item Details",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.description",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Description"
|
||||
"label": "Description",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_7",
|
||||
@ -97,50 +99,43 @@
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Warehouse",
|
||||
"options": "Warehouse"
|
||||
"options": "Warehouse",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "price",
|
||||
"fieldtype": "Float",
|
||||
"label": "Price"
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.item_group",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item Group",
|
||||
"options": "Item Group"
|
||||
"options": "Item Group",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "website_item.route",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "route",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Route"
|
||||
},
|
||||
{
|
||||
"fieldname": "formatted_price",
|
||||
"fieldtype": "Data",
|
||||
"label": "Formatted Price"
|
||||
"label": "Route",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "website_item.web_item_name",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "web_item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Webiste Item Name",
|
||||
"label": "Website Item Name",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-08 13:14:14.919749",
|
||||
"modified": "2021-08-09 10:30:41.964802",
|
||||
"modified_by": "Administrator",
|
||||
"module": "E-commerce",
|
||||
"name": "Wishlist Item",
|
||||
|
@ -105,9 +105,7 @@ erpnext.ProductGrid = class {
|
||||
let icon_class = item.wished ? "wished" : "not-wished";
|
||||
return `
|
||||
<div class="like-action ${ item.wished ? "like-action-wished" : ''}"
|
||||
data-item-code="${ item.item_code }"
|
||||
data-price="${ item.price || '' }"
|
||||
data-formatted-price="${ item.formatted_price || '' }">
|
||||
data-item-code="${ item.item_code }">
|
||||
<svg class="icon sm">
|
||||
<use class="${ icon_class } wish-icon" href="#icon-heart"></use>
|
||||
</svg>
|
||||
|
@ -139,9 +139,7 @@ erpnext.ProductList = class {
|
||||
|
||||
return `
|
||||
<div class="like-action-list ${ item.wished ? "like-action-wished" : ''}"
|
||||
data-item-code="${ item.item_code }"
|
||||
data-price="${ item.price || '' }"
|
||||
data-formatted-price="${ item.formatted_price || '' }">
|
||||
data-item-code="${ item.item_code }">
|
||||
<svg class="icon sm">
|
||||
<use class="${ icon_class } wish-icon" href="#icon-heart"></use>
|
||||
</svg>
|
||||
|
@ -118,11 +118,7 @@ $.extend(wishlist, {
|
||||
btn.addClass("like-action-wished");
|
||||
this.toggle_button_class($wish_icon, 'not-wished', 'wished');
|
||||
|
||||
let args = {
|
||||
item_code: btn.data('item-code'),
|
||||
price: btn.data('price'),
|
||||
formatted_price: btn.data('formatted-price')
|
||||
};
|
||||
let args = {item_code: btn.data('item-code')};
|
||||
let failure_action = function() {
|
||||
me.toggle_button_class($wish_icon, 'wished', 'not-wished');
|
||||
};
|
||||
|
@ -1147,6 +1147,10 @@ body.product-page {
|
||||
}
|
||||
}
|
||||
|
||||
.btn-view-more {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.rating-summary-section {
|
||||
display: flex;
|
||||
}
|
||||
|
@ -13,9 +13,7 @@
|
||||
<!-- Wishlist -->
|
||||
{% if cart_settings.enable_wishlist %}
|
||||
<div class="like-action-item-fp like-action {{ 'like-action-wished' if wished else ''}} ml-2"
|
||||
data-item-code="{{ doc.item_code }}"
|
||||
data-price="{{ price_info.get('price_list_rate') if price_info else 0 }}"
|
||||
data-formatted-price="{{ price_info.get('formatted_price') if price_info else 0 }}">
|
||||
data-item-code="{{ doc.item_code }}">
|
||||
<svg class="icon sm">
|
||||
<use class="{{ 'wished' if wished else 'not-wished' }} wish-icon" href="#icon-heart"></use>
|
||||
</svg>
|
||||
|
@ -231,7 +231,7 @@
|
||||
{{ average_rating or 0 }}
|
||||
</h2>
|
||||
<div class="mb-2" style="margin-top: -.5rem;">
|
||||
{{ frappe.utils.cstr(total_reviews) + " " + _("ratings") }}
|
||||
{{ frappe.utils.cstr(total_reviews or 0) + " " + _("ratings") }}
|
||||
</div>
|
||||
|
||||
<!-- Ratings Summary -->
|
||||
|
@ -5,45 +5,54 @@
|
||||
|
||||
{% block page_content %}
|
||||
<div class="product-container reviews-full-page col-md-12">
|
||||
<!-- Title and Action -->
|
||||
<div class="w-100 mb-6 d-flex">
|
||||
<div class="reviews-header col-9">
|
||||
{{ _("Customer Reviews") }}
|
||||
{% if enable_reviews %}
|
||||
<!-- Title and Action -->
|
||||
<div class="w-100 mb-6 d-flex">
|
||||
<div class="reviews-header col-9">
|
||||
{{ _("Customer Reviews") }}
|
||||
</div>
|
||||
|
||||
<div class="write-a-review-btn col-3">
|
||||
<!-- Write a Review for legitimate users -->
|
||||
{% if frappe.session.user != "Guest" and user_is_customer %}
|
||||
<button class="btn btn-write-review"
|
||||
data-web-item="{{ web_item }}">
|
||||
{{ _("Write a Review") }}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="write-a-review-btn col-3">
|
||||
<!-- Write a Review for legitimate users -->
|
||||
{% if frappe.session.user != "Guest" and user_is_customer %}
|
||||
<button class="btn btn-write-review"
|
||||
data-web-item="{{ web_item }}">
|
||||
{{ _("Write a Review") }}
|
||||
</button>
|
||||
<!-- Summary -->
|
||||
{{ ratings_summary(reviews, reviews_per_rating, average_rating, average_whole_rating, for_summary=True, total_reviews=total_reviews) }}
|
||||
|
||||
|
||||
<!-- Reviews and Comments -->
|
||||
<div class="mt-8">
|
||||
{% if reviews %}
|
||||
{{ user_review(reviews) }}
|
||||
|
||||
{% if not reviews | len >= total_reviews %}
|
||||
<button class="btn btn-light btn-view-more mr-2 mt-4 mb-4 w-30"
|
||||
data-web-item="{{ web_item }}">
|
||||
{{ _("View More") }}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<h6 class="text-muted mt-6">
|
||||
{{ _("No Reviews") }}
|
||||
</h6>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary -->
|
||||
{{ ratings_summary(reviews, reviews_per_rating, average_rating, average_whole_rating, for_summary=True, total_reviews=total_reviews) }}
|
||||
|
||||
|
||||
<!-- Reviews and Comments -->
|
||||
<div class="mt-8">
|
||||
{% if reviews %}
|
||||
{{ user_review(reviews) }}
|
||||
|
||||
{% if not reviews | len >= total_reviews %}
|
||||
<button class="btn btn-light btn-view-more mr-2 mt-4 mb-4 w-30"
|
||||
data-web-item="{{ web_item }}">
|
||||
{{ _("View More") }}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<h6 class="text-muted mt-6">
|
||||
{% else %}
|
||||
<!-- If reviews are disabled -->
|
||||
<div class="text-center">
|
||||
<h3 class="text-muted mt-8">
|
||||
{{ _("No Reviews") }}
|
||||
</h6>
|
||||
{% endif %}
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -3,6 +3,7 @@
|
||||
import frappe
|
||||
from erpnext.e_commerce.doctype.item_review.item_review import get_item_reviews
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import check_if_user_is_customer
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import get_shopping_cart_settings
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
@ -13,4 +14,6 @@ def get_context(context):
|
||||
context.item_code = frappe.form_dict.get("item_code")
|
||||
context.web_item = frappe.db.get_value("Website Item", {"item_code": context.item_code}, "name")
|
||||
context.user_is_customer = check_if_user_is_customer()
|
||||
get_item_reviews(context.web_item, 0, 10, context)
|
||||
context.enable_reviews = get_shopping_cart_settings().enable_reviews
|
||||
if context.enable_reviews:
|
||||
get_item_reviews(context.web_item, 0, 10, context)
|
||||
|
@ -3,29 +3,16 @@
|
||||
import frappe
|
||||
from erpnext.utilities.product import get_price
|
||||
from erpnext.e_commerce.shopping_cart.cart import _set_price_list
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import get_shopping_cart_settings
|
||||
|
||||
def get_context(context):
|
||||
settings = frappe.get_doc("E Commerce Settings")
|
||||
items = get_wishlist_items()
|
||||
selling_price_list = _set_price_list(settings)
|
||||
is_guest = frappe.session.user == "Guest"
|
||||
|
||||
for item in items:
|
||||
if settings.show_stock_availability:
|
||||
item.available = get_stock_availability(item.item_code, item.get("warehouse"))
|
||||
settings = get_shopping_cart_settings()
|
||||
items = get_wishlist_items() if not is_guest else []
|
||||
selling_price_list = _set_price_list(settings) if not is_guest else None
|
||||
|
||||
price_details = get_price(
|
||||
item.item_code,
|
||||
selling_price_list,
|
||||
settings.default_customer_group,
|
||||
settings.company
|
||||
)
|
||||
|
||||
if price_details:
|
||||
item.formatted_price = price_details.get('formatted_price')
|
||||
item.formatted_mrp = price_details.get('formatted_mrp')
|
||||
if item.formatted_mrp:
|
||||
item.discount = price_details.get('formatted_discount_percent') or \
|
||||
price_details.get('formatted_discount_rate')
|
||||
items = set_stock_price_details(items, settings, selling_price_list)
|
||||
|
||||
context.items = items
|
||||
context.settings = settings
|
||||
@ -53,6 +40,27 @@ def get_wishlist_items():
|
||||
},
|
||||
fields=[
|
||||
"web_item_name", "item_code", "item_name",
|
||||
"website_item", "price", "warehouse",
|
||||
"website_item", "warehouse",
|
||||
"image", "item_group", "route"
|
||||
])
|
||||
|
||||
def set_stock_price_details(items, settings, selling_price_list):
|
||||
for item in items:
|
||||
if settings.show_stock_availability:
|
||||
item.available = get_stock_availability(item.item_code, item.get("warehouse"))
|
||||
|
||||
price_details = get_price(
|
||||
item.item_code,
|
||||
selling_price_list,
|
||||
settings.default_customer_group,
|
||||
settings.company
|
||||
)
|
||||
|
||||
if price_details:
|
||||
item.formatted_price = price_details.get('formatted_price')
|
||||
item.formatted_mrp = price_details.get('formatted_mrp')
|
||||
if item.formatted_mrp:
|
||||
item.discount = price_details.get('formatted_discount_percent') or \
|
||||
price_details.get('formatted_discount_rate')
|
||||
|
||||
return items
|
Loading…
x
Reference in New Issue
Block a user