[enhancement] add variants in website

This commit is contained in:
Rushabh Mehta 2015-10-05 16:27:52 +05:30
parent 9cbf6b1b22
commit 80d2a55342
8 changed files with 763 additions and 675 deletions

View File

@ -20,7 +20,6 @@ $.extend(shopping_cart, {
if(!full_name || full_name==="Guest") { if(!full_name || full_name==="Guest") {
if(localStorage) { if(localStorage) {
localStorage.setItem("last_visited", window.location.pathname); localStorage.setItem("last_visited", window.location.pathname);
localStorage.setItem("pending_add_to_cart", opts.item_code);
} }
window.location.href = "/login"; window.location.href = "/login";
} else { } else {

View File

@ -19,6 +19,8 @@ class Quotation(SellingController):
self.validate_order_type() self.validate_order_type()
self.validate_uom_is_integer("stock_uom", "qty") self.validate_uom_is_integer("stock_uom", "qty")
self.validate_quotation_to() self.validate_quotation_to()
if self.items:
self.with_items = 1
def has_sales_order(self): def has_sales_order(self):
return frappe.db.get_value("Sales Order Item", {"prevdoc_docname": self.name, "docstatus": 1}) return frappe.db.get_value("Sales Order Item", {"prevdoc_docname": self.name, "docstatus": 1})

View File

@ -71,6 +71,7 @@ def get_product_list_for_group(product_group=None, start=0, limit=10):
concat(parent_website_route, "/", page_name) as route concat(parent_website_route, "/", page_name) as route
from `tabItem` from `tabItem`
where show_in_website = 1 where show_in_website = 1
and (variant_of = '' or variant_of is null)
and (item_group in (%s) and (item_group in (%s)
or name in (select parent from `tabWebsite Item Group` where item_group in (%s))) or name in (select parent from `tabWebsite Item Group` where item_group in (%s)))
""" % (child_groups, child_groups) """ % (child_groups, child_groups)

View File

@ -3,6 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
import json
from frappe import msgprint, _ from frappe import msgprint, _
from frappe.utils import cstr, flt, cint, getdate, now_datetime, formatdate from frappe.utils import cstr, flt, cint, getdate, now_datetime, formatdate
from frappe.website.website_generator import WebsiteGenerator from frappe.website.website_generator import WebsiteGenerator
@ -79,12 +80,43 @@ class Item(WebsiteGenerator):
self.update_variants() self.update_variants()
def get_context(self, context): def get_context(self, context):
context["parent_groups"] = get_parent_item_groups(self.item_group) + \ context.parent_groups = get_parent_item_groups(self.item_group) + \
[{"name": self.name}] [{"name": self.name}]
if self.slideshow: if self.slideshow:
context.update(get_slideshow(self)) context.update(get_slideshow(self))
context["parents"] = self.get_parents(context) if self.has_variants:
attribute_values_available = {}
context.attribute_values = {}
# load variants
context.variants = frappe.get_all("Item",
filters={"variant_of": self.name, "show_in_website": 1})
# load attributes
for v in context.variants:
v.attributes = frappe.get_all("Item Variant Attribute",
fields=["attribute", "attribute_value"], filters={"parent": v.name})
for attr in v.attributes:
values = attribute_values_available.setdefault(attr.attribute, [])
if attr.attribute_value not in values:
values.append(attr.attribute_value)
# filter attributes, order based on attribute table
for attr in self.attributes:
values = context.attribute_values.setdefault(attr.attribute, [])
# get list of values defined (for sequence)
for attr_value in frappe.db.get_all("Item Attribute Value",
fields=["attribute_value"], filters={"parent": attr.attribute}, order_by="idx asc"):
if attr_value.attribute_value in attribute_values_available.get(attr.attribute, []):
values.append(attr_value.attribute_value)
context.variant_info = json.dumps(context.variants)
context.parents = self.get_parents(context)
return context return context

View File

@ -30,6 +30,22 @@
<h4 class="item-price" itemprop="price"></h4> <h4 class="item-price" itemprop="price"></h4>
<div class="item-stock" itemprop="availablity"></div> <div class="item-stock" itemprop="availablity"></div>
<div class="item-cart hide"> <div class="item-cart hide">
{% if has_variants %}
{% for d in attributes %}
<div class="item-view-attribute"
style="margin-bottom: 10px;">
<h6 class="text-muted">{{ _(d.attribute) }}</h6>
<select class="form-control"
style="max-width: 140px"
data-attribute="{{ d.attribute }}">
{% for value in attribute_values[d.attribute] %}
<option value="{{ value }}">{{ _(value) }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
{% endif %}
</select>
<div id="item-add-to-cart"> <div id="item-add-to-cart">
<button class="btn btn-primary btn-sm"> <button class="btn btn-primary btn-sm">
{{ _("Add to Cart") }}</button> {{ _("Add to Cart") }}</button>
@ -76,13 +92,8 @@
<script> <script>
{% include "templates/includes/product_page.js" %} {% include "templates/includes/product_page.js" %}
$(function() { {% if variant_info %}
if(window.logged_in && getCookie("system_user")==="yes") { window.variant_info = {{ variant_info }};
frappe.has_permission("Item", "{{ name }}", "write", function(r) { {% endif %}
frappe.require("/assets/frappe/js/frappe/website/editable.js");
frappe.make_editable($('[itemprop="description"]'), "Item", "{{ name }}", "web_long_description");
});
}
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -2,7 +2,7 @@
// License: GNU General Public License v3. See license.txt // License: GNU General Public License v3. See license.txt
frappe.ready(function() { frappe.ready(function() {
var item_code = $('[itemscope] [itemprop="productID"]').text().trim(); window.item_code = $('[itemscope] [itemprop="productID"]').text().trim();
var qty = 0; var qty = 0;
frappe.call({ frappe.call({
@ -12,7 +12,6 @@ frappe.ready(function() {
item_code: "{{ name }}" item_code: "{{ name }}"
}, },
callback: function(r) { callback: function(r) {
console.log(r.message);
$(".item-cart").toggleClass("hide", !!!r.message.price); $(".item-cart").toggleClass("hide", !!!r.message.price);
if(r.message && r.message.price) { if(r.message && r.message.price) {
$(".item-price") $(".item-price")
@ -38,7 +37,7 @@ frappe.ready(function() {
$("#item-add-to-cart button").on("click", function() { $("#item-add-to-cart button").on("click", function() {
shopping_cart.update_cart({ shopping_cart.update_cart({
item_code: item_code, item_code: get_item_code(),
qty: 1, qty: 1,
callback: function(r) { callback: function(r) {
if(!r.exc) { if(!r.exc) {
@ -52,7 +51,7 @@ frappe.ready(function() {
$("#item-update-cart button").on("click", function() { $("#item-update-cart button").on("click", function() {
shopping_cart.update_cart({ shopping_cart.update_cart({
item_code: item_code, item_code: get_item_code(),
qty: $("#item-update-cart input").val(), qty: $("#item-update-cart input").val(),
btn: this, btn: this,
callback: function(r) { callback: function(r) {
@ -64,11 +63,6 @@ frappe.ready(function() {
}, },
}); });
}); });
if(localStorage && localStorage.getItem("pending_add_to_cart") && full_name) {
localStorage.removeItem("pending_add_to_cart");
$("#item-add-to-cart button").trigger("click");
}
}); });
var toggle_update_cart = function(qty) { var toggle_update_cart = function(qty) {
@ -77,3 +71,29 @@ var toggle_update_cart = function(qty) {
.toggle(qty ? true : false) .toggle(qty ? true : false)
.find("input").val(qty); .find("input").val(qty);
} }
function get_item_code() {
if(window.variant_info) {
attributes = {};
$('[itemscope]').find(".item-view-attribute select").each(function() {
attributes[$(this).attr('data-attribute')] = $(this).val();
});
for(var i in variant_info) {
var variant = variant_info[i];
var match = true;
for(var j in variant.attributes) {
if(attributes[variant.attributes[j].attribute]
!= variant.attributes[j].attribute_value) {
match = false;
break;
}
}
if(match) {
return variant.name;
}
}
throw "Unable to match variant";
} else {
return item_code;
}
}

View File

@ -14,7 +14,7 @@ def get_product_list(search=None, start=0, limit=10):
# base query # base query
query = """select name, item_name, page_name, website_image, item_group, query = """select name, item_name, page_name, website_image, item_group,
web_long_description as website_description, parent_website_route web_long_description as website_description, parent_website_route
from `tabItem` where show_in_website = 1""" from `tabItem` where show_in_website = 1 and (variant_of is null or variant_of = '')"""
# search term condition # search term condition
if search: if search:

View File

@ -76,6 +76,29 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "User Id",
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -471,7 +494,7 @@
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"modified": "2015-10-02 07:38:42.365280", "modified": "2015-10-07 00:26:20.667566",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Utilities", "module": "Utilities",
"name": "Contact", "name": "Contact",