feat: Card Actions and Wishlist
- Rough UI for card actions - Wishlist doctype - Indicators on card based on stock availability
This commit is contained in:
parent
d7130e31fe
commit
16b9c8c383
0
erpnext/e_commerce/doctype/wishlist/__init__.py
Normal file
0
erpnext/e_commerce/doctype/wishlist/__init__.py
Normal file
10
erpnext/e_commerce/doctype/wishlist/test_wishlist.py
Normal file
10
erpnext/e_commerce/doctype/wishlist/test_wishlist.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestWishlist(unittest.TestCase):
|
||||
pass
|
8
erpnext/e_commerce/doctype/wishlist/wishlist.js
Normal file
8
erpnext/e_commerce/doctype/wishlist/wishlist.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Wishlist', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
70
erpnext/e_commerce/doctype/wishlist/wishlist.json
Normal file
70
erpnext/e_commerce/doctype/wishlist/wishlist.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "field:user",
|
||||
"creation": "2021-03-10 18:52:28.769126",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"user",
|
||||
"section_break_2",
|
||||
"items"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Items",
|
||||
"options": "Wishlist Items"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-10 19:05:52.373601",
|
||||
"modified_by": "Administrator",
|
||||
"module": "E-commerce",
|
||||
"name": "Wishlist",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
10
erpnext/e_commerce/doctype/wishlist/wishlist.py
Normal file
10
erpnext/e_commerce/doctype/wishlist/wishlist.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Wishlist(Document):
|
||||
pass
|
104
erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json
Normal file
104
erpnext/e_commerce/doctype/wishlist_items/wishlist_items.json
Normal file
@ -0,0 +1,104 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-03-10 19:03:00.662714",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"item_code",
|
||||
"website_item",
|
||||
"column_break_3",
|
||||
"item_name",
|
||||
"item_details_section",
|
||||
"description",
|
||||
"column_break_7",
|
||||
"image",
|
||||
"image_view",
|
||||
"warehouse_section",
|
||||
"warehouse"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "website_item",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Website Item",
|
||||
"options": "Website Item"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.item_name",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "item_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item Details"
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.description",
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_7",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.image",
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach",
|
||||
"hidden": 1,
|
||||
"label": "Image"
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.image",
|
||||
"fieldname": "image_view",
|
||||
"fieldtype": "Image",
|
||||
"hidden": 1,
|
||||
"label": "Image View",
|
||||
"options": "image",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Warehouse",
|
||||
"options": "Warehouse"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-10 19:13:41.310816",
|
||||
"modified_by": "Administrator",
|
||||
"module": "E-commerce",
|
||||
"name": "Wishlist Items",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
10
erpnext/e_commerce/doctype/wishlist_items/wishlist_items.py
Normal file
10
erpnext/e_commerce/doctype/wishlist_items/wishlist_items.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class WishlistItems(Document):
|
||||
pass
|
@ -22,7 +22,7 @@ class ProductQuery:
|
||||
self.page_length = self.settings.products_per_page or 20
|
||||
self.fields = ['wi.name', 'wi.item_name', 'wi.item_code', 'wi.website_image', 'wi.variant_of',
|
||||
'wi.has_variants', 'wi.item_group', 'wi.image', 'wi.web_long_description', 'wi.description',
|
||||
'wi.route']
|
||||
'wi.route', 'wi.website_warehouse']
|
||||
self.conditions = ""
|
||||
self.or_conditions = ""
|
||||
self.substitutions = []
|
||||
@ -62,12 +62,22 @@ class ProductQuery:
|
||||
result = self.query_items(self.conditions, self.or_conditions,
|
||||
self.substitutions, start=start)
|
||||
|
||||
# add price info in results
|
||||
# add price and availability info in results
|
||||
for item in result:
|
||||
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')
|
||||
|
||||
if self.settings.show_stock_availability and 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"
|
||||
return result
|
||||
|
||||
def query_items(self, conditions, or_conditions, substitutions, start=0):
|
||||
|
@ -519,3 +519,54 @@ body.product-page {
|
||||
border: 1px solid var(--dark-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.card-indicator {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.like-action {
|
||||
text-align: center;
|
||||
margin-top: -2px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.wish-icon {
|
||||
cursor: pointer;
|
||||
stroke: #F47A7A !important;
|
||||
|
||||
&:hover {
|
||||
fill: #F47A7A;
|
||||
}
|
||||
}
|
||||
|
||||
.wished {
|
||||
.wish-icon {
|
||||
stroke: none;
|
||||
fill: #F47A7A !important;
|
||||
}
|
||||
}
|
||||
|
||||
.list-row-checkbox {
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:checked:before {
|
||||
display: block;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-add-to-cart-list {
|
||||
color: var(--blue-500);
|
||||
background-color: white;
|
||||
box-shadow: none;
|
||||
border: 1px solid var(--blue-500);
|
||||
margin: var(--margin-sm) 0;
|
||||
flex: none;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--blue-500);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
{%- macro item_card(title, image, url, description, rate, category, is_featured=False, is_full_width=False, align="Left") -%}
|
||||
{%- macro item_card(title, image, url, description, rate, category, in_stock=None, is_featured=False, is_full_width=False, align="Left") -%}
|
||||
{%- set align_items_class = resolve_class({
|
||||
'align-items-end': align == 'Right',
|
||||
'align-items-center': align == 'Center',
|
||||
@ -89,35 +89,61 @@
|
||||
<div class="col-sm-{{ col_size }} item-card">
|
||||
<div class="card {{ align_items_class }}">
|
||||
{% if image %}
|
||||
<div class="card-img-container">
|
||||
<img class="card-img" src="{{ image }}" alt="{{ title }}">
|
||||
</div>
|
||||
<div class="card-img-container">
|
||||
<a href="/{{ url or '#' }}" style="text-decoration: none;">
|
||||
<img class="card-img" src="{{ image }}" alt="{{ title }}">
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card-img-top no-image">
|
||||
{{ frappe.utils.get_abbr(title) }}
|
||||
</div>
|
||||
<a href="/{{ url or '#' }}" style="text-decoration: none;">
|
||||
<div class="card-img-top no-image">
|
||||
{{ frappe.utils.get_abbr(title) }}
|
||||
</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
{{ item_card_body(title, description, url, rate, category, is_featured, align) }}
|
||||
{{ item_card_body(title, description, url, rate, category, is_featured, align, in_stock) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro item_card_body(title, description, url, rate, category, is_featured, align) -%}
|
||||
{%- macro item_card_body(title, description, url, rate, category, is_featured, align, in_stock=None) -%}
|
||||
{%- set align_class = resolve_class({
|
||||
'text-right': align == 'Right',
|
||||
'text-center': align == 'Center' and not is_featured,
|
||||
'text-left': align == 'Left' or is_featured,
|
||||
}) -%}
|
||||
<div class="card-body {{ align_class }}">
|
||||
<div class="product-title">{{ title or '' }}</div>
|
||||
<div class="card-body {{ align_class }}" style="width:100%">
|
||||
|
||||
<div style="margin-top: 16px; display: flex;">
|
||||
<a href="/{{ url or '#' }}">
|
||||
<div class="product-title">{{ title or '' }}</div>
|
||||
</a>
|
||||
{% if in_stock %}
|
||||
<span class="indicator {{ in_stock }} card-indicator"></span>
|
||||
{% endif %}
|
||||
<input class="level-item list-row-checkbox hidden-xs"
|
||||
type="checkbox" data-name="{{ title }}" style="display: none !important;">
|
||||
<div class="like-action"
|
||||
data-name="{{ title }}" data-doctype="Item">
|
||||
<svg class="icon sm">
|
||||
<use class="wish-icon" href="#icon-heart"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
{% if is_featured %}
|
||||
<div class="product-price">{{ rate or '' }}</div>
|
||||
<div class="product-description ellipsis">{{ description or '' }}</div>
|
||||
{% else %}
|
||||
<div class="product-category">{{ category or '' }}</div>
|
||||
<div class="product-price">{{ rate or '' }}</div>
|
||||
<div style="display: flex;">
|
||||
{% if rate %}
|
||||
<div class="product-price" style="width: 60%;">{{ rate or '' }}</div>
|
||||
{% endif %}
|
||||
<div class="btn btn-sm btn-add-to-cart-list">
|
||||
{{ _('Add to Cart') }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a href="/{{ url or '#' }}" class="stretched-link"></a>
|
||||
{%- endmacro -%}
|
||||
|
@ -2,5 +2,5 @@
|
||||
|
||||
{{ item_card(
|
||||
item.item_name or item.name, item.website_image or item.image, item.route, item.website_description or item.description,
|
||||
item.formatted_price, item.item_group
|
||||
item.formatted_price, item.item_group, in_stock=item.in_stock
|
||||
) }}
|
||||
|
Loading…
x
Reference in New Issue
Block a user