From 83193566305929539e37699c89a589eceefc6d01 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 11 Jun 2014 12:50:41 +0200 Subject: [PATCH] [IMP] website_sale: allow optional products in shop; In shop, it opens the modal jus after having clicked on the 'Add to cart'. The modal contains the optional products. --- addons/product/product.py | 8 +-- addons/website_sale/controllers/main.py | 36 ++++++++-- addons/website_sale/models/product.py | 1 + addons/website_sale/models/sale_order.py | 22 ++++++ .../static/src/js/website_sale.js | 20 ++++-- addons/website_sale/views/templates.xml | 71 +++++++++++++++++-- addons/website_sale/views/views.xml | 1 + 7 files changed, 135 insertions(+), 24 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index db86047c10a..34627f3d647 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -802,10 +802,8 @@ class product_product(osv.osv): uom.id, product.list_price, context['uom']) else: res[product.id] = product.list_price - price_extra = 0.0 - for variant_id in product.attribute_value_ids: - price_extra += variant_id.price_extra - res[product.id] = (res[product.id] or 0.0) + price_extra + res[product.id] = res[product.id] + product.price_extra + return res def _get_partner_code_name(self, cr, uid, ids, product, partner_id, context=None): @@ -864,6 +862,8 @@ class product_product(osv.osv): def _get_price_extra(self, cr, uid, ids, name, args, context=None): result = dict.fromkeys(ids, False) for product in self.browse(cr, uid, ids, context=context): + ctx = context.copy() + ctx.update(active_id=product.product_tmpl_id.id) price_extra = 0.0 for variant_id in product.attribute_value_ids: for price_id in variant_id.price_ids: diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 23225186dc8..4cb5e6f99a0 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -212,6 +212,17 @@ class website_sale(http.Controller): 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) + values = { 'search': search, 'category': category, @@ -223,6 +234,7 @@ class website_sale(http.Controller): 'main_object': product, 'product': product, 'variants': variants, + 'optional_products': optional_products } return request.website.render("website_sale.product", values) @@ -240,21 +252,31 @@ class website_sale(http.Controller): @http.route(['/shop/cart'], type='http', auth="public", website=True) def cart(self, **post): + cr, uid, context, pool = request.cr, request.uid, request.context, request.registry order = request.website.sale_get_order() + values = { 'order': order, - 'suggested_products': [], + 'suggested_products': [] } if order: - if not request.context.get('pricelist'): - request.context['pricelist'] = order.pricelist_id.id - values['suggested_products'] = order._cart_accessories(context=request.context) + if not context.get('pricelist'): + context['pricelist'] = order.pricelist_id.id + values['suggested_products'] = order._cart_accessories(context=context) + return request.website.render("website_sale.cart", values) @http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True) def cart_update(self, product_id, add_qty=1, set_qty=0, **kw): - cr, uid, context = request.cr, request.uid, request.context - request.website.sale_get_order(force_create=1)._cart_update(product_id=int(product_id), add_qty=add_qty, set_qty=set_qty) + 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) return request.redirect("/shop/cart") @http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True) @@ -445,7 +467,7 @@ class website_sale(http.Controller): @http.route(['/shop/checkout'], type='http', auth="public", website=True) def checkout(self, **post): - cr, uid, context, registry = request.cr, request.uid, request.context, request.registry + cr, uid, context, pool = request.cr, request.uid, request.context, request.registry order = request.website.sale_get_order(force_create=1, context=context) diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index 116822f2984..bedf0d1be0b 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -132,6 +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'), } def _defaults_website_sequence(self, cr, uid, *l, **kwargs): diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py index d9855034018..759884ab1fd 100644 --- a/addons/website_sale/models/sale_order.py +++ b/addons/website_sale/models/sale_order.py @@ -116,6 +116,28 @@ class sale_order(osv.Model): product_ids = random.sample(s, min(len(s),3)) return self.pool['product.product'].browse(cr, uid, product_ids, context=context) + def _cart_optional_products(self, cr, uid, ids, context=None): + for order in self.browse(cr, uid, ids, context=context): + products = {} + for l in order.website_order_line: + opt = {} + for o in l.product_id.optional_product_ids: + if not opt.get(o.product_tmpl_id.id): + opt[o.product_tmpl_id.id] = { + 'product_tmpl_id': o.product_tmpl_id, + 'product_ids': [] + } + if o not in opt[o.product_tmpl_id.id]: + opt[o.product_tmpl_id.id]['product_ids'].append(o) + + if opt: + products[l.id] = { + 'order_line_id': l, + 'optional_product_tmpl': opt + } + + return products + class website(orm.Model): _inherit = 'website' diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index 62c1f829bde..1325807713d 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -50,6 +50,13 @@ $(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) { @@ -70,12 +77,12 @@ $(document).ready(function () { var $form_var = $('form.js_add_cart_variants'); var variant_ids = $form_var.data("attribute_value_ids"); - $form_var.on('change', 'input, select', function (ev) { + $form_var.on('change', 'input.js_variant_change, select.js_variant_change', function (ev) { var values = []; $form_var.find("label").removeClass("text-muted css_not_available"); $form_var.find(".a-submit").removeProp("disabled"); - $form_var.find('input:checked, select').each(function () { + $form_var.find('input.js_variant_change:checked, select').each(function () { values.push(+$(this).val()); }); var available = false; @@ -89,10 +96,10 @@ $(document).ready(function () { } } - $form_var.find("input:radio, select").each(function () { + $form_var.find("input.js_variant_change:radio, select.js_variant_change").each(function () { var id = +$(this).val(); var values = [id]; - $form_var.find(">ul>li:not(:has(input[value='" + id + "'])) input:checked, select").each(function () { + $form_var.find(">ul>li: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) { @@ -112,10 +119,9 @@ $(document).ready(function () { $(".oe_price_h4").addClass("hidden"); $(".oe_not_available").removeClass("hidden"); $form_var.find('input[name="product_id"]').val(0); - $form_var.find(".a-submit").prop("disabled", "disabled"); + $form_var.find(".js_check_product").prop("disabled", "disabled"); } }); - $form_var.find("input:first").trigger('change'); - + $form_var.find("input.js_variant_change:first").trigger('change'); }); diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 470ca8383f4..9b51d819b86 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -387,7 +387,11 @@ - Add to Cart + Add to Cart + Add to Cart + + +
@@ -402,10 +406,60 @@
+
+ + @@ -685,7 +742,9 @@
- Process Checkout + + Process Checkout +
diff --git a/addons/website_sale/views/views.xml b/addons/website_sale/views/views.xml index 86e369f11e7..c6c30d0a162 100644 --- a/addons/website_sale/views/views.xml +++ b/addons/website_sale/views/views.xml @@ -26,6 +26,7 @@ +