diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 4cb5e6f99a0..9f0005908ad 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -191,6 +191,7 @@ class website_sale(http.Controller):
def product(self, product, category='', search='', **kwargs):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
category_obj = pool['product.public.category']
+ template_obj = pool['product.template']
context.update(active_id=product.id)
@@ -208,20 +209,13 @@ class website_sale(http.Controller):
if not context.get('pricelist'):
context['pricelist'] = int(self.get_pricelist())
- product = request.registry.get('product.template').browse(request.cr, request.uid, int(product), context=context)
+ product = template_obj.browse(request.cr, request.uid, int(product), context=context)
- variants = [[p.id, map(int, p.attribute_value_ids), p.price] for p in product.product_variant_ids]
-
-
- optional_products = {}
- for o in product.optional_product_ids:
- if not optional_products.get(o.product_tmpl_id.id):
- optional_products[o.product_tmpl_id.id] = {
- 'product_tmpl_id': o.product_tmpl_id,
- 'product_ids': []
- }
- if o not in optional_products[o.product_tmpl_id.id]:
- optional_products[o.product_tmpl_id.id]['product_ids'].append(o)
+ optional_product_ids = []
+ for p in product.optional_product_ids:
+ ctx = context.copy()
+ ctx.update(active_id=p.id)
+ optional_product_ids.append(template_obj.browse(cr, uid, p.id, context=ctx))
values = {
'search': search,
@@ -233,8 +227,7 @@ class website_sale(http.Controller):
'category_list': category_list,
'main_object': product,
'product': product,
- 'variants': variants,
- 'optional_products': optional_products
+ 'optional_product_ids': optional_product_ids
}
return request.website.render("website_sale.product", values)
@@ -270,19 +263,16 @@ class website_sale(http.Controller):
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
order = request.website.sale_get_order(force_create=1)
-
- print kw
- for key,val in kw.items():
- if 'option-' in key:
- order._cart_update(product_id=int(key.split("-")[1]), add_qty=1)
-
- order._cart_update(product_id=int(product_id), add_qty=add_qty, set_qty=set_qty)
+ if add_qty or set_qty:
+ order._cart_update(product_id=int(product_id), add_qty=int(add_qty), set_qty=int(set_qty))
return request.redirect("/shop/cart")
@http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True)
- def cart_update_json(self, product_id, line_id, add_qty=None, set_qty=None):
+ def cart_update_json(self, product_id, line_id, add_qty=None, set_qty=None, display=True):
order = request.website.sale_get_order(force_create=1)
quantity = order._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty)
+ if not display:
+ return None
return {
'quantity': quantity,
'cart_quantity': order.cart_quantity,
diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py
index bedf0d1be0b..51359c4851a 100644
--- a/addons/website_sale/models/product.py
+++ b/addons/website_sale/models/product.py
@@ -132,7 +132,7 @@ class product_template(osv.Model):
'website_sequence': fields.integer('Sequence', help="Determine the display order in the Website E-commerce"),
'website_url': fields.function(_website_url, string="Website url", type="char"),
'public_categ_ids': fields.many2many('product.public.category', string='Public Category', help="Those categories are used to group similar products for e-commerce."),
- 'optional_product_ids': fields.many2many('product.product', string='Optional Products'),
+ 'optional_product_ids': fields.many2many('product.template','product_optional_rel','src_id','dest_id',string='Optional Products'),
}
def _defaults_website_sequence(self, cr, uid, *l, **kwargs):
diff --git a/addons/website_sale/static/src/css/website_sale.css b/addons/website_sale/static/src/css/website_sale.css
index 73d374357ab..41db67c0ffe 100644
--- a/addons/website_sale/static/src/css/website_sale.css
+++ b/addons/website_sale/static/src/css/website_sale.css
@@ -302,10 +302,12 @@
color: #cccccc;
}
.js_add_cart_variants label.css_not_available {
- opacity: 0.3;
+ opacity: 0.6;
}
-.js_add_cart_variants label.css_not_available input {
- opacity: 0;
+.js_add_cart_variants label.css_attribute_color.css_not_available {
+ opacity: 1;
+ background-image: url("/website_sale/static/src/img/redcross.png");
+ background-size: cover;
}
.product_detail_img {
diff --git a/addons/website_sale/static/src/css/website_sale.sass b/addons/website_sale/static/src/css/website_sale.sass
index 40308925552..05bcff522da 100644
--- a/addons/website_sale/static/src/css/website_sale.sass
+++ b/addons/website_sale/static/src/css/website_sale.sass
@@ -261,9 +261,11 @@
option.css_not_available
color: #ccc
label.css_not_available
- opacity: 0.3
- input
- opacity: 0
+ opacity: 0.6
+ label.css_attribute_color.css_not_available
+ opacity: 1
+ background-image: url('/website_sale/static/src/img/redcross.png')
+ background-size: cover
.product_detail_img
margin-left: auto
diff --git a/addons/website_sale/static/src/img/redcross.png b/addons/website_sale/static/src/img/redcross.png
new file mode 100644
index 00000000000..92a87401e89
Binary files /dev/null and b/addons/website_sale/static/src/img/redcross.png differ
diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js
index 1325807713d..fce5f72b861 100644
--- a/addons/website_sale/static/src/js/website_sale.js
+++ b/addons/website_sale/static/src/js/website_sale.js
@@ -38,7 +38,8 @@ $(document).ready(function () {
ev.preventDefault();
var $link = $(ev.currentTarget);
var $input = $link.parent().parent().find("input");
- $input.val(($link.has(".fa-minus").length ? -1 : 1) + parseFloat($input.val(),10));
+ var quantity = ($link.has(".fa-minus").length ? -1 : 1) + parseFloat($input.val(),10);
+ $input.val(quantity > 0 ? quantity : 0);
$input.change();
return false;
});
@@ -50,18 +51,10 @@ $(document).ready(function () {
$(this).closest("form").submit();
});
- // modal to select optional product in my cart
- $("#modal_optional_products label").mousedown(function(event) {
- $(event.currentTarget).parents('li.optional_product_tmpl:first').find("input[type=checkbox]").each(function () {
- if($(this).parent()[0] != event.currentTarget) $(this).removeAttr('checked');
- });
- });
-
// change price when they are variants
- var $price = $(".oe_price .oe_currency_value");
$('form.js_add_cart_json label').on('mouseup', function (ev) {
- ev.preventDefault();
- var $label = $(ev.currentTarget);
+ var $label = $(this);
+ var $price = $label.parents("form:first").find(".oe_price .oe_currency_value");
if (!$price.data("price")) {
$price.data("price", parseFloat($price.text()));
}
@@ -75,53 +68,82 @@ $(document).ready(function () {
$('.css_attribute_color:has(input:checked)').addClass("active");
});
- var $form_var = $('form.js_add_cart_variants');
- var variant_ids = $form_var.data("attribute_value_ids");
- $form_var.on('change', 'input.js_variant_change, select.js_variant_change', function (ev) {
+ $('input.js_variant_change, select.js_variant_change').change(function (ev) {
+ var $ul = $(this).parents('ul.js_add_cart_variants:first');
+ var $parent = $ul.parents('.js_product:first');
+ var $porduct_id = $parent.find('input.product_id, input.optional_product_id').first();
+ var $price = $parent.find(".oe_price .oe_currency_value:first");
+ var variant_ids = $ul.data("attribute_value_ids");
var values = [];
- $form_var.find("label").removeClass("text-muted css_not_available");
- $form_var.find(".a-submit").removeProp("disabled");
-
- $form_var.find('input.js_variant_change:checked, select').each(function () {
+ $parent.find('input.js_variant_change:checked, select.js_variant_change').each(function () {
values.push(+$(this).val());
});
- var available = false;
+
+ $parent.find("label").removeClass("text-muted css_not_available");
+
+ var product_id = false;
for (var k in variant_ids) {
if (_.isEqual(variant_ids[k][1], values)) {
- var dec = variant_ids[k][2] % 1;
- $('input[name="product_id"]').val(variant_ids[k][0]);
- $price.html(variant_ids[k][2] + (dec < 0.01 ? ".00" : (dec < 1 ? "0" : "") ));
- available = true;
+ var dec = ((variant_ids[k][2] % 1) * 100) | 0;
+ $price.html(variant_ids[k][2] + (dec ? '' : '.0') + (dec%10 ? '' : '0'));
+ product_id = variant_ids[k][0];
break;
}
}
- $form_var.find("input.js_variant_change:radio, select.js_variant_change").each(function () {
- var id = +$(this).val();
+ $parent.find("input.js_variant_change:radio, select.js_variant_change").each(function () {
+ var $input = $(this);
+ var id = +$input.val();
var values = [id];
- $form_var.find(">ul>li:not(:has(input.js_variant_change[value='" + id + "'])) input.js_variant_change:checked, select").each(function () {
+
+ $parent.find("ul:not(:has(input.js_variant_change[value='" + id + "'])) input.js_variant_change:checked, select").each(function () {
values.push(+$(this).val());
});
+
for (var k in variant_ids) {
if (!_.difference(values, variant_ids[k][1]).length) {
return;
}
}
- $(this).parents("label:not(.css_attribute_color):first").addClass("text-muted");
- $(this).parents("label.css_attribute_color:first").addClass("css_not_available");
- $(this).find("option[value='" + id + "']").addClass("css_not_available");
+ $input.parents("label:first").addClass("css_not_available");
+ $input.find("option[value='" + id + "']").addClass("css_not_available");
});
- if (available) {
- $(".oe_price_h4").removeClass("hidden");
- $(".oe_not_available").addClass("hidden");
+ if (product_id) {
+ $parent.removeClass("oe_not_available");
+ $porduct_id.val(product_id);
+ $parent.find(".js_check_product").removeAttr("disabled");
} else {
- $(".oe_price_h4").addClass("hidden");
- $(".oe_not_available").removeClass("hidden");
- $form_var.find('input[name="product_id"]').val(0);
- $form_var.find(".js_check_product").prop("disabled", "disabled");
+ $parent.addClass("oe_not_available");
+ $porduct_id.val(0);
+ $parent.find(".js_check_product").attr("disabled", "disabled");
}
});
- $form_var.find("input.js_variant_change:first").trigger('change');
+ $('ul.js_add_cart_variants').each(function () {
+ $('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
+ });
+
+ $('#product_detail form[action^="/shop/cart/update"] .a-submit').off("click").click(function (event) {
+ event.preventDefault();
+ var $link = $(this);
+ var $form = $link.parents("form:first");
+ var defs = [];
+ $link.attr('disabled', 'disabled');
+ $('.js_product', $form).each(function () {
+ var product_id = parseInt($('input.optional_product_id', this).val(),10);
+ var quantity = parseInt($('input.js_quantity', this).val(),10);
+ if (product_id && quantity) {
+ defs.push(openerp.jsonRpc("/shop/cart/update_json", 'call', {
+ 'line_id': null,
+ 'product_id': product_id,
+ 'add_qty': quantity,
+ 'display': false}));
+ }
+ });
+ $.when.apply($.when, defs).then(function () {
+ $form.submit();
+ });
+ return false;
+ });
});
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 9b51d819b86..6e32fc934f2 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -387,11 +387,14 @@