diff --git a/erpnext/e_commerce/doctype/wishlist/wishlist.py b/erpnext/e_commerce/doctype/wishlist/wishlist.py index 94e2754f88b..7527c6f4157 100644 --- a/erpnext/e_commerce/doctype/wishlist/wishlist.py +++ b/erpnext/e_commerce/doctype/wishlist/wishlist.py @@ -3,8 +3,52 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe from frappe.model.document import Document class Wishlist(Document): pass + +@frappe.whitelist() +def add_to_wishlist(item_code, price): + """Insert Item into wishlist.""" + web_item_data = frappe.db.get_value("Website Item", {"item_code": item_code}, + ["image", "website_warehouse", "name", "item_name"], as_dict=1) + + wished_item_dict = { + "item_code": item_code, + "item_name": web_item_data.get("item_name"), + "website_item": web_item_data.get("name"), + "price": frappe.utils.flt(price), + "image": web_item_data.get("image"), + "website_warehouse": web_item_data.get("website_warehouse") + } + + if not frappe.db.exists("Wishlist", frappe.session.user): + # initialise wishlist + wishlist = frappe.get_doc({"doctype": "Wishlist"}) + wishlist.user = frappe.session.user + wishlist.append("items", wished_item_dict) + wishlist.save(ignore_permissions=True) + else: + wishlist = frappe.get_doc("Wishlist", frappe.session.user) + item = wishlist.append('items', wished_item_dict) + item.db_insert() + + if hasattr(frappe.local, "cookie_manager"): + frappe.local.cookie_manager.set_cookie("wish_count", str(len(wishlist.items))) + +@frappe.whitelist() +def remove_from_wishlist(item_code): + if frappe.db.exists("Wishlist Items", {"item_code": item_code}): + frappe.db.sql(""" + delete + from `tabWishlist Items` + where item_code=%(item_code)s + """%{"item_code": frappe.db.escape(item_code)}) + + frappe.db.commit() + + wishlist = frappe.get_doc("Wishlist", frappe.session.user) + if hasattr(frappe.local, "cookie_manager"): + frappe.local.cookie_manager.set_cookie("wish_count", str(len(wishlist.items))) \ No newline at end of file diff --git a/erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json b/erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json index 29f40660a45..18065a8861c 100644 --- a/erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json +++ b/erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json @@ -12,6 +12,8 @@ "item_details_section", "description", "column_break_7", + "section_break_8", + "price", "image", "image_view", "warehouse_section", @@ -52,6 +54,7 @@ }, { "fetch_from": "item_code.description", + "fetch_if_empty": 1, "fieldname": "description", "fieldtype": "Text Editor", "label": "Description" @@ -62,6 +65,7 @@ }, { "fetch_from": "item_code.image", + "fetch_if_empty": 1, "fieldname": "image", "fieldtype": "Attach", "hidden": 1, @@ -69,6 +73,7 @@ }, { "fetch_from": "item_code.image", + "fetch_if_empty": 1, "fieldname": "image_view", "fieldtype": "Image", "hidden": 1, @@ -87,12 +92,21 @@ "in_list_view": 1, "label": "Warehouse", "options": "Warehouse" + }, + { + "fieldname": "section_break_8", + "fieldtype": "Section Break" + }, + { + "fieldname": "price", + "fieldtype": "Float", + "label": "Price" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-03-10 19:13:41.310816", + "modified": "2021-03-12 18:23:03.487891", "modified_by": "Administrator", "module": "E-commerce", "name": "Wishlist Items", diff --git a/erpnext/e_commerce/product_query.py b/erpnext/e_commerce/product_query.py index 9743b768a54..28d33e6e81d 100644 --- a/erpnext/e_commerce/product_query.py +++ b/erpnext/e_commerce/product_query.py @@ -67,6 +67,7 @@ class ProductQuery: product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info') if product_info: item.formatted_price = (product_info.get('price') or {}).get('formatted_price') + item.price = product_info['price'].get('price_list_rate') if self.settings.show_stock_availability and item.get("website_warehouse"): stock_qty = frappe.utils.flt( @@ -78,6 +79,11 @@ class ProductQuery: "actual_qty") ) item.in_stock = "green" if stock_qty else "red" + + item.wished = False + if frappe.db.exists("Wishlist Items", {"item_code": item.item_code}): + item.wished = True + return result def query_items(self, conditions, or_conditions, substitutions, start=0): diff --git a/erpnext/e_commerce/shopping_cart/cart.py b/erpnext/e_commerce/shopping_cart/cart.py index c2c94a36644..011f29cdc6f 100644 --- a/erpnext/e_commerce/shopping_cart/cart.py +++ b/erpnext/e_commerce/shopping_cart/cart.py @@ -138,7 +138,7 @@ def update_cart(item_code, qty, additional_notes=None, with_items=False): "additional_notes": additional_notes }) else: - quotation_items[0].qty = qty + 1 + quotation_items[0].qty = qty quotation_items[0].additional_notes = additional_notes apply_cart_settings(quotation=quotation) diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 6b70dab8037..a8911216f72 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -11,7 +11,8 @@ ], "js/erpnext-web.min.js": [ "public/js/website_utils.js", - "public/js/shopping_cart.js" + "public/js/shopping_cart.js", + "public/js/wishlist.js" ], "css/erpnext-web.css": [ "public/scss/website.scss", diff --git a/erpnext/public/js/wishlist.js b/erpnext/public/js/wishlist.js new file mode 100644 index 00000000000..328bdb996df --- /dev/null +++ b/erpnext/public/js/wishlist.js @@ -0,0 +1,39 @@ +frappe.provide("erpnext.e_commerce"); +var wishlist = erpnext.e_commerce; + +frappe.ready(function() { + $(".wishlist").toggleClass('hidden', true); + wishlist.set_wishlist_count(); +}); + +$.extend(wishlist, { + set_wishlist_count: function() { + var wish_count = frappe.get_cookie("wish_count"); + if(frappe.session.user==="Guest") { + wish_count = 0; + } + + if(wish_count) { + $(".wishlist").toggleClass('hidden', false); + } + + var $wishlist = $('.wishlist-icon'); + var $badge = $wishlist.find("#wish-count"); + + if(parseInt(wish_count) === 0 || wish_count === undefined) { + $wishlist.css("display", "none"); + } + else { + $wishlist.css("display", "inline"); + } + if(wish_count) { + $badge.html(wish_count); + $wishlist.addClass('cart-animate'); + setTimeout(() => { + $wishlist.removeClass('cart-animate'); + }, 500); + } else { + $badge.remove(); + } + } +}); \ No newline at end of file diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss index 8380f6cf338..3d66f146c0c 100644 --- a/erpnext/public/scss/shopping_cart.scss +++ b/erpnext/public/scss/shopping_cart.scss @@ -349,20 +349,20 @@ body.product-page { } } -.cart-icon { - .cart-badge { - position: relative; - top: -10px; - left: -12px; - background: var(--red-600); - width: 16px; - align-items: center; - height: 16px; - font-size: 10px; - border-radius: 50%; - } + +.shopping-badge { + position: relative; + top: -10px; + left: -12px; + background: var(--red-600); + width: 16px; + align-items: center; + height: 16px; + font-size: 10px; + border-radius: 50%; } + .cart-animate { animation: wiggle 0.5s linear; } @@ -555,7 +555,28 @@ body.product-page { margin-left: 12px; } -.wish-icon { +.like-animate { + animation: expand cubic-bezier(0.04, 0.4, 0.5, 0.95) 1.6s forwards 1; +} + +@keyframes expand { + 30% { + transform: scale(1.6); + } + 50% { + transform: scale(0.8); + } + 70% { + transform: scale(1.3); + } + 100% { + transform: scale(1); + } + } + +@keyframes heart { 0%, 17.5% { font-size: 0; } } + +.not-wished { cursor: pointer; stroke: #F47A7A !important; @@ -565,10 +586,8 @@ body.product-page { } .wished { - .wish-icon { - stroke: none; - fill: #F47A7A !important; - } + stroke: none; + fill: #F47A7A !important; } .list-row-checkbox { diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html index 818316c0cf9..743daaf7e19 100644 --- a/erpnext/templates/includes/macros.html +++ b/erpnext/templates/includes/macros.html @@ -127,12 +127,11 @@ {% endif %} {% if not item.has_variants %} -