From a86200597ff3e0a8fbbf3b9272f7a3b80b1f5bfe Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Wed, 28 Feb 2018 16:11:42 +0100 Subject: [PATCH] [FIX] website_sale: update when changing quantity There is several issue happening when changing quantity: 1) if website_sale_stock is installed, the displayed price is not updated when changing quantities. 2) if the "Add to Cart" price is not updated, it erroneously displays the price multiplied by the quantity. 3) when prices are updated, it only update attribute_value_ids. 4) when variant are displayed as list view, visually the last list item is selected instead of the first, also changing quantity doesn't update price as it should be given pricelist. The first issue is caused by invalid JSON in data-attribute_value_ids attribute. The code modify the `.data('attribute_value_ids')` thinking it will be permanent. But if the value was invalid JSON we always parse it on the fly inside a temporary object so the object is never changed. The second issue is because originally, the "data-attribute_value_ids" inside "Add to Cart" was set wrongly (when rendering the view) because get_attribute_value_ids got the website_price multiplied by quantity. The third issue was even with website_sale_stock is not installed `.data('attribute_value_ids')` was only updated for one of the possible multiple ones in the page. With this change, we had json.dumps to ensure data-attribute_value_ids is good JSON, and we correct errors so it is fixed for instance only updating sources without updating website_sale and website_sale_options modules. note: when views are updated, this also solves a bigger issue when python2 is used (because attribute_value_ids contained u'text' strings. master equivalent of #23392 without js crutches for xml not updated opw-1816479 closes #23467 --- addons/website_sale/controllers/main.py | 2 +- addons/website_sale/data/demo.xml | 1 + .../static/src/js/website_sale.js | 40 +++----- addons/website_sale/views/templates.xml | 11 ++- .../static/src/js/website_sale.test.js | 93 +++++++++++++++++++ .../views/website_sale_options_templates.xml | 2 +- .../static/src/js/website_sale_stock.js | 9 +- 7 files changed, 119 insertions(+), 39 deletions(-) diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index d3a44363fab..3cf961ada09 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -151,7 +151,7 @@ class WebsiteSale(http.Controller): else: price = variant.website_public_price / quantity visible_attribute_ids = [v.id for v in variant.attribute_value_ids if v.attribute_id.id in visible_attrs_ids] - attribute_value_ids.append([variant.id, visible_attribute_ids, variant.website_price, price]) + attribute_value_ids.append([variant.id, visible_attribute_ids, variant.website_price / quantity, price]) return attribute_value_ids def _get_search_order(self, post): diff --git a/addons/website_sale/data/demo.xml b/addons/website_sale/data/demo.xml index 80401d1095c..d195702f5ad 100644 --- a/addons/website_sale/data/demo.xml +++ b/addons/website_sale/data/demo.xml @@ -545,6 +545,7 @@ Weight: 31 grams 20 + 2 formula diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index 874b9f698b5..1544f199088 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -88,18 +88,12 @@ odoo.define('website_sale.website_sale', function (require) { $(oe_website_sale).on("change", 'input[name="add_qty"]', function (event) { var product_ids = []; - var product_dom = $(".js_product .js_add_cart_variants[data-attribute_value_ids]"); + var product_dom = $(event.target).closest(".js_product").find(".js_add_cart_variants"); var qty = $(event.target).closest('form').find('input[name="add_qty"]').val(); - if (!product_dom.length) { - return; - } var attribute_value_ids = product_dom.data("attribute_value_ids"); - if(_.isString(attribute_value_ids)) { - attribute_value_ids = JSON.parse(attribute_value_ids.replace(/'/g, '"')); - } _.each(attribute_value_ids, function(entry) { - product_ids.push(entry[0]);}); - var qty = $(event.target).closest('form').find('input[name="add_qty"]').val(); + product_ids.push(entry[0]); + }); if ($("#product_detail").length) { // display the reduction from the pricelist in function of the quantity @@ -109,7 +103,7 @@ odoo.define('website_sale.website_sale', function (require) { for(var j=0; j < current.length; j++){ current[j][2] = data[current[j][0]]; } - product_dom.attr("data-attribute_value_ids", JSON.stringify(current)).trigger("change"); + product_dom.trigger("change"); }); } }); @@ -210,8 +204,7 @@ odoo.define('website_sale.website_sale', function (require) { $('input[name="'+$input.attr("name")+'"]').add($input).filter(function () { var $prod = $(this).closest('*:has(input[name="product_id"])'); return !$prod.length || +$prod.find('input[name="product_id"]').val() === product_id; - }).val(new_qty); - $input.change(); + }).val(new_qty).change(); return false; }); @@ -298,27 +291,14 @@ odoo.define('website_sale.website_sale', function (require) { } } - $(oe_website_sale).on('change', 'input.js_product_change', function () { - var self = this; - var $parent = $(this).closest('.js_product'); - $.when(base.ready()).then(function() { - $parent.find(".oe_default_price:first .oe_currency_value").html( price_to_str(+$(self).data('lst_price')) ); - $parent.find(".oe_price:first .oe_currency_value").html(price_to_str(+$(self).data('price')) ); - }); - update_product_image(this, +$(this).val()); - }); - - $(oe_website_sale).on('change', 'input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]', function (ev) { - var $ul = $(ev.target).closest('.js_add_cart_variants'); - var $parent = $ul.closest('.js_product'); + $(oe_website_sale).on('change', 'input.js_variant_change, select.js_variant_change, input.js_product_change, [data-attribute_value_ids]', function (ev) { + var $parent = $(ev.target).closest('.js_product'); + var $ul = $parent.find('.js_add_cart_variants'); var $product_id = $parent.find('.product_id').first(); var $price = $parent.find(".oe_price:first .oe_currency_value"); var $default_price = $parent.find(".oe_default_price:first .oe_currency_value"); var $optional_price = $parent.find(".oe_optional:first .oe_currency_value"); var variant_ids = $ul.data("attribute_value_ids"); - if(_.isString(variant_ids)) { - variant_ids = JSON.parse(variant_ids.replace(/'/g, '"')); - } var values = []; var unchanged_values = $parent.find('div.oe_unchanged_value_ids').data('unchanged_value_ids') || []; @@ -326,12 +306,14 @@ odoo.define('website_sale.website_sale', function (require) { values.push(+$(this).val()); }); values = values.concat(unchanged_values); + var list_variant_id = parseInt($parent.find('input.js_product_change:checked').val()); $parent.find("label").removeClass("text-muted css_not_available"); var product_id = false; for (var k in variant_ids) { - if (_.isEmpty(_.difference(variant_ids[k][1], values))) { + if (_.isEmpty(_.difference(variant_ids[k][1], values)) || + variant_ids[k][0] === list_variant_id) { $.when(base.ready()).then(function() { $price.html(price_to_str(variant_ids[k][2])); $default_price.html(price_to_str(variant_ids[k][3])); diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index cae42a8416d..4325d669fda 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -458,8 +458,7 @@

Product Name