summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@odoo.com>2014-06-24 17:37:13 +0200
committerChristophe Matthieu <chm@odoo.com>2014-06-24 17:37:13 +0200
commit7505cce2e96771942e804596383dce255528dfd2 (patch)
tree97011141c62070fc08199ba1d34a0dae526b010a /addons
parent204a62499a4337cecc8050801806e6b8ebda1665 (diff)
[WIP]
Diffstat (limited to 'addons')
-rw-r--r--addons/website_sale/controllers/main.py5
-rw-r--r--addons/website_sale/models/product.py1
-rw-r--r--addons/website_sale/models/sale_order.py23
-rw-r--r--addons/website_sale/static/src/js/website.tour.sale.js75
-rw-r--r--addons/website_sale/static/src/js/website_sale.js32
-rw-r--r--addons/website_sale/tests/test_sale_process.py1
-rw-r--r--addons/website_sale/views/templates.xml76
-rw-r--r--addons/website_sale_options/controllers/main.py21
-rw-r--r--addons/website_sale_options/models/__init__.py1
-rw-r--r--addons/website_sale_options/models/product.py10
-rw-r--r--addons/website_sale_options/models/sale_order.py66
-rw-r--r--addons/website_sale_options/static/src/js/website_sale.js37
-rw-r--r--addons/website_sale_options/static/src/js/website_sale.test.js80
-rw-r--r--addons/website_sale_options/tests/__init__.py1
-rw-r--r--addons/website_sale_options/tests/customize_test.py14
-rw-r--r--addons/website_sale_options/views/templates.xml175
16 files changed, 327 insertions, 291 deletions
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 52d4c15df38..486914dfd6a 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -216,7 +216,7 @@ class website_sale(http.Controller):
product = template_obj.browse(cr, uid, int(product), context=context)
attribute_value_ids = []
- if request.website.company_pricelist_id.id != context['pricelist']:
+ if request.website.pricelist_id.id != context['pricelist']:
company_currency_id = request.website.company_currency_id.id
currency_id = self.get_pricelist().currency_id.id
for p in product.product_variant_ids:
@@ -289,12 +289,11 @@ class website_sale(http.Controller):
@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, display=True):
order = request.website.sale_get_order(force_create=1)
- line_id, quantity, option_ids = order._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty)
+ line_id, 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,
- 'option_ids': option_ids,
'cart_quantity': order.cart_quantity,
'website_sale.total': request.website._render("website_sale.total", {
'website_sale_order': request.website.sale_get_order()
diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py
index 06b61dc6465..ce206372047 100644
--- a/addons/website_sale/models/product.py
+++ b/addons/website_sale/models/product.py
@@ -132,7 +132,6 @@ 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.template','product_optional_rel','src_id','dest_id',string='Optional Products', help="Products to propose when add to cart."),
}
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 695d60a4f6a..49f69c9ff57 100644
--- a/addons/website_sale/models/sale_order.py
+++ b/addons/website_sale/models/sale_order.py
@@ -51,18 +51,12 @@ class sale_order(osv.Model):
'order': order
}
- def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None):
+ def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None, *args):
for so in self.browse(cr, uid, ids, context=context):
- order_line_id = None
-
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
if line_id:
domain += [('id', '=', line_id)]
-
- order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
- if order_line_ids:
- order_line_id = order_line_ids[0]
- return order_line_id
+ return self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
def _website_product_id_change(self, cr, uid, ids, order_id, product_id, line_id=None, context=None):
so = self.pool.get('sale.order').browse(cr, uid, order_id, context=context)
@@ -87,13 +81,16 @@ class sale_order(osv.Model):
values['tax_id'] = [(6, 0, values['tax_id'])]
return values
- def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, linked_line_id=None, optional_product_ids=None, context=None):
+ def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, context=None, *args):
""" Add or set product quantity, add_qty can be negative """
sol = self.pool.get('sale.order.line')
quantity = 0
for so in self.browse(cr, uid, ids, context=context):
- line_id = so._cart_find_product_line(product_id, line_id, context=context)
+ if line_id != False:
+ line_ids = so._cart_find_product_line(product_id, line_id, context=context, *args)
+ if line_ids:
+ line_id = line_ids[0]
# Create line if no line with product_id can be located
if not line_id:
@@ -132,9 +129,7 @@ class website(orm.Model):
_columns = {
'pricelist_id': fields.related('user_id','partner_id','property_product_pricelist',
type='many2one', relation='product.pricelist', string='Default pricelist'),
- 'company_pricelist_id': fields.related('company_id','partner_id','property_product_pricelist',
- type='many2one', relation='product.pricelist', string='Default pricelist'),
- 'company_currency_id': fields.related('company_pricelist_id','currency_id',
+ 'currency_id': fields.related('pricelist_id','currency_id',
type='many2one', relation='res.currency', string='Default pricelist'),
}
@@ -230,7 +225,7 @@ class website(orm.Model):
})
def compute_curency(self, cr, uid, ids, from_amount, from_currency_id=None, context=None):
- from_currency_id = from_currency_id or self.browse(cr, SUPERUSER_ID, ids[0]).company_currency_id.id
+ from_currency_id = from_currency_id or self.browse(cr, SUPERUSER_ID, ids[0]).currency_id.id
to_currency_id = self.pool.get("res.users").browse(cr, uid, uid).partner_id.property_product_pricelist.currency_id.id
return self.pool['res.currency'].compute(cr, uid, from_currency_id, to_currency_id, from_amount, context=context)
diff --git a/addons/website_sale/static/src/js/website.tour.sale.js b/addons/website_sale/static/src/js/website.tour.sale.js
index 65ed620e3a4..09fe9f26171 100644
--- a/addons/website_sale/static/src/js/website.tour.sale.js
+++ b/addons/website_sale/static/src/js/website.tour.sale.js
@@ -1,80 +1,5 @@
(function () {
'use strict';
- openerp.Tour.register({
- id: 'shop_customize',
- name: "Customize the page and search a product",
- path: '/shop',
- mode: 'test',
- steps: [
- {
- title: "open customize menu",
- element: '#customize-menu-button',
- },
- {
- title: "click on 'Product Attribute's Filters'",
- element: "#customize-menu a:contains(Product Attribute's Filters)",
- },
- {
- title: "select product attribute memory 16 Go",
- waitNot: '#customize-menu:visible',
- element: 'form.js_attributes label:contains(16 Go) input:not(:checked)',
- },
- {
- title: "check the selection",
- waitFor: 'form.js_attributes label:contains(16 Go) input:checked',
- },
- {
- title: "select iPod",
- waitNot: '.oe_website_sale .oe_product_cart:eq(2)',
- element: '.oe_product_cart a:contains("iPod")',
- },
- {
- title: "open customize menu 2",
- waitFor: 'form[action^="/shop/cart/update"] label:contains(32 Go) input',
- element: '#customize-menu-button',
- },
- {
- title: "click on 'Confirm: Add To Cart'",
- element: "#customize-menu a:contains(Confirm: Add To Cart)",
- },
- {
- title: "click on 'Add to Cart' button",
- waitNot: '#customize-menu:visible',
- element: "a[data-toggle='modal']:contains(Add to Cart)",
- },
- {
- title: "click in modal on 'Proceed to checkout' button",
- element: '.modal a:contains("Proceed to checkout")',
- },
- {
- title: "return to the iPod product",
- waitFor: '#cart_products',
- element: "a:contains(iPod)",
- },
- {
- title: "open customize menu 3",
- waitFor: 'form[action^="/shop/cart/update"] label:contains(32 Go) input',
- element: '#customize-menu-button',
- },
- {
- title: "click on 'Confirm: Add To Cart'",
- element: "#customize-menu a:contains(Confirm: Add To Cart)",
- },
- {
- title: "click on 'My Cart'",
- waitFor: "a.a-submit:contains(Add to Cart)",
- element: "a[href='/shop/cart']",
- },
- {
- title: "remove iPod from cart",
- element: '#cart_products a.js_add_cart_json:first',
- },
- {
- title: "finish",
- waitFor: '.my_cart_quantity:contains(1)',
- },
- ]
- });
openerp.Tour.register({
id: 'shop_buy_product',
diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js
index f9ac456ff4e..c9a8c8eea3a 100644
--- a/addons/website_sale/static/src/js/website_sale.js
+++ b/addons/website_sale/static/src/js/website_sale.js
@@ -85,7 +85,7 @@ $(document).ready(function () {
$('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 $product_id = $parent.find('input.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 variant_ids = $ul.data("attribute_value_ids");
@@ -127,11 +127,11 @@ $(document).ready(function () {
if (product_id) {
$parent.removeClass("css_not_available");
- $porduct_id.val(product_id);
+ $product_id.val(product_id);
$parent.find(".js_check_product").removeAttr("disabled");
} else {
$parent.addClass("css_not_available");
- $porduct_id.val(0);
+ $product_id.val(0);
$parent.find(".js_check_product").attr("disabled", "disabled");
}
});
@@ -139,32 +139,6 @@ $(document).ready(function () {
$('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
});
- $('#modal_optional_products').on('show.bs.modal', function () {
- var $confirm = $('#product_confirmation .js_attributes');
- if (!$confirm.size()) return;
- $confirm.empty();
- $('.js_add_cart_variants:first ul:first > li').each(function () {
- var $li = $(this);
- var $span = $("<div><span></span>: <span></span></div>");
- var attr = $li.children().first().text();
- var value = $li.find("label:has(input:checked) span:first").text();
- if (!/\S/.test(value)) {
- value = $li.find("label:has(input:checked) input").attr("title");
- }
- $span.children().first().text( attr );
- $span.children().last().text( value );
- $confirm.append($span);
- });
- });
-
- $("a.js_add, a.js_remove").click(function (event) {
- event.preventDefault();
- var $parent = $(this).parents('.js_product:first');
- $parent.find("a.js_add, span.js_remove").toggleClass("hidden");
- $parent.find("input.js_optional_same_quantity").val( $(this).hasClass("js_add") ? 1 : 0 );
- var $remove = $parent.find(".js_remove");
- });
-
$("input.js_quantity").change(function (event) {
var qty = parseFloat($(this).val());
if (qty === 1) {
diff --git a/addons/website_sale/tests/test_sale_process.py b/addons/website_sale/tests/test_sale_process.py
index 788b6201734..ec7d5ddb46d 100644
--- a/addons/website_sale/tests/test_sale_process.py
+++ b/addons/website_sale/tests/test_sale_process.py
@@ -12,7 +12,6 @@ inject = [
class TestUi(openerp.tests.HttpCase):
def test_01_admin_shop_tour(self):
self.phantom_js("/", "openerp.Tour.run('shop', 'test')", "openerp.Tour.tours.shop", login="admin")
- self.phantom_js("/", "openerp.Tour.run('shop_customize', 'test')", "openerp.Tour.tours.shop_customize", login="admin", inject=inject)
def test_02_admin_checkout(self):
self.phantom_js("/", "openerp.Tour.run('shop_buy_product', 'test')", "openerp.Tour.tours.shop_buy_product", login="admin", inject=inject)
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 25f617f552b..3372fc26748 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -393,79 +393,7 @@
<t t-call="website_sale.product_price"/>
<p t-if="len(product.product_variant_ids) > 1" class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
- <a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
- </div>
-
- <div id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
- <div class="modal-dialog modal-lg">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h4 class="modal-title" id="myModalLabel">Product to add in your shopping cart</h4>
- </div>
- <div class="modal-body">
- <table class="table table-striped table-condensed">
- <thead>
- <tr>
- <th colspan="2">Product</th>
- <th style="min-width: 140px;"> </th>
- <th width="100">Price</th>
- <th width="120">Quantity</th>
- </tr>
- </thead>
- <tbody>
- <tr id="product_confirmation">
- <td width="100">
- <span t-field="product.image_medium" t-field-options='{"widget": "image" }'/>
- </td>
- <td colspan="2">
- <strong t-field="product.name"/>
- <div class="text-muted">
- <div t-field="product.description_sale"/>
- <div class="js_attributes"/>
- </div>
- </td>
- <td>
- <span t-attf-class="text-danger oe_default_price" t-att-style="'' if (website.compute_curency(product.lst_price) - product.price) &gt; 0.1 else 'display: none;'" style="text-decoration: line-through; white-space: nowrap;"
- t-field="product.lst_price"
- t-field-options='{
- "widget": "monetary",
- "from_currency": "website.company_currency_id",
- "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
- }'/><br/>
- <span class="oe_price" style="white-space: nowrap;"
- t-field="product.price"
- t-field-options='{
- "widget": "monetary",
- "from_currency": "website.company_currency_id",
- "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
- }'/>
- </td>
- <td>
- <div class="input-group">
- <span class="input-group-addon">
- <a t-attf-href="#" class="mb8 js_add_cart_json">
- <i class="fa fa-minus"></i>
- </a>
- </span>
- <input type="text" class="js_quantity form-control" data-min="1" name="add_qty" value="1"/>
- <span class="input-group-addon">
- <a t-attf-href="#" class="mb8 float_left js_add_cart_json">
- <i class="fa fa-plus"></i>
- </a>
- </span>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <div class="modal-footer">
- <a class="btn btn-default a-submit js_goto_shop"><i class="fa fa-chevron-left"></i> Continue shopping</a>
- <a class="btn btn-primary pull-right a-submit"><i class="fa fa-shopping-cart fa-fw"></i> Proceed to checkout</a>
- </div>
- </div>
- </div>
+ <a id="add_to_cart" class="btn btn-primary btn-lg mt8 js_check_product a-submit" href="#">Add to Cart</a>
</div>
</form>
@@ -488,7 +416,7 @@
</template>
<template id="product_quantity" inherit_id="website_sale.product" optional="enabled" name="Select Quantity">
- <xpath expr="//a[@data-target='#modal_optional_products']" position="before">
+ <xpath expr="//form" position="inside">
<div class="css_quantity input-group" style="width: 108px;">
<span class="input-group-addon">
<a t-attf-href="#" class="mb8 js_add_cart_json">
diff --git a/addons/website_sale_options/controllers/main.py b/addons/website_sale_options/controllers/main.py
index e157b8da5c4..fa014fbf9f7 100644
--- a/addons/website_sale_options/controllers/main.py
+++ b/addons/website_sale_options/controllers/main.py
@@ -4,7 +4,6 @@ from openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website.models.website import slug
-from openerp.addons.website_sale.controllers.main import QueryURL
from openerp.addons.website_sale.controllers.main import website_sale
class website_sale_options(website_sale):
@@ -23,11 +22,12 @@ class website_sale_options(website_sale):
r.qcontext['optional_product_ids'] = optional_product_ids
return r
- def cart_update(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
+ @http.route(['/shop/cart/update_option_json'], type='json', auth="public", methods=['POST'], website=True)
+ def cart_options_update_json(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
order = request.website.sale_get_order(force_create=1)
- prod_obj = pool['product.product']
+ line_id = None
optional_product_ids = []
for k, v in kw.items():
if "optional-product-" in k and int(kw.get(k.replace("product", "quantity"))):
@@ -36,11 +36,16 @@ class website_sale_options(website_sale):
line_id, quantity = order._cart_update(product_id=int(product_id),
add_qty=int(add_qty), set_qty=int(set_qty),
optional_product_ids=optional_product_ids)
+
# options have all time the same quantity
for option_id in optional_product_ids:
- order._cart_update(product_id=option_id, set_qty=value.get('quantity'), linked_line_id=value.get('line_id'))
+ order._cart_update(product_id=option_id, set_qty=quantity, linked_line_id=line_id)
+
+ return {
+ 'quantity': quantity,
+ 'cart_quantity': order.cart_quantity,
+ 'website_sale.total': request.website._render("website_sale.total", {
+ 'website_sale_order': request.website.sale_get_order()
+ })
+ }
- if goto_shop:
- return request.redirect("/shop/product/%s" % slug(prod_obj.browse(cr, uid, product_id).product_tmpl_id))
- else:
- return request.redirect("/shop/cart")
diff --git a/addons/website_sale_options/models/__init__.py b/addons/website_sale_options/models/__init__.py
index 98ba3c432f5..806ebb7b64f 100644
--- a/addons/website_sale_options/models/__init__.py
+++ b/addons/website_sale_options/models/__init__.py
@@ -1 +1,2 @@
+import product
import sale_order \ No newline at end of file
diff --git a/addons/website_sale_options/models/product.py b/addons/website_sale_options/models/product.py
new file mode 100644
index 00000000000..cd84e42a7da
--- /dev/null
+++ b/addons/website_sale_options/models/product.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from openerp import tools
+from openerp.osv import osv, fields
+
+class product_template(osv.Model):
+ _inherit = "product.template"
+
+ _columns = {
+ 'optional_product_ids': fields.many2many('product.template','product_optional_rel','src_id','dest_id',string='Optional Products', help="Products to propose when add to cart."),
+ } \ No newline at end of file
diff --git a/addons/website_sale_options/models/sale_order.py b/addons/website_sale_options/models/sale_order.py
index a3adf5ed2ca..30f29a8ff04 100644
--- a/addons/website_sale_options/models/sale_order.py
+++ b/addons/website_sale_options/models/sale_order.py
@@ -2,17 +2,19 @@
from openerp import SUPERUSER_ID
from openerp.osv import osv, orm, fields
-from openerp.addons.web.http import request
from openerp.tools.translate import _
class sale_order(osv.Model):
_inherit = "sale.order"
- def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, linked_line_id=None, optional_product_ids=None, context=None):
- for so in self.browse(cr, uid, ids, context=context):
+ def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None, *args):
+ line_ids = super(sale_order, self)._cart_find_product_line(cr, uid, ids, product_id, line_id, context=context)
+ linked_line_id = args.get('linked_line_id')
+ optional_product_ids = args.get('optional_product_ids')
- domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
+ for so in self.browse(cr, uid, ids, context=context):
+ domain = [('order_id', '=', so.id), ('product_id', '=', product_id), ('id', 'in', line_ids)]
if line_id:
domain += [('id', '=', line_id)]
domain += linked_line_id and [('linked_line_id', '=', linked_line_id)] or [('linked_line_id', '=', False)]
@@ -22,51 +24,35 @@ class sale_order(osv.Model):
else:
domain += [('option_line_ids', '=', False)]
- order_line_id = None
- order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
- if order_line_ids:
- order_line_id = order_line_ids[0]
- return order_line_id
+ return self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
- def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, linked_line_id=None, optional_product_ids=None, context=None):
+ def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, context=None, *args):
""" Add or set product quantity, add_qty can be negative """
+ line_id, quantity = super(sale_order, self)._cart_update(cr, uid, ids, product_id, line_id, add_qty, set_qty, context=context, *args)
+ linked_line_id = args.get('linked_line_id')
sol = self.pool.get('sale.order.line')
- quantity = 0
for so in self.browse(cr, uid, ids, context=context):
- line_id = so._cart_find_product_line(product_id, line_id, linked_line_id, optional_product_ids, context=context)
-
- # Create line if no line with product_id can be located
- if not line_id:
- values = self._website_product_id_change(cr, uid, ids, so.id, product_id, context=context)
- if linked_line_id and linked_line_id in map(int,so.order_line):
- values["linked_line_id"] = linked_line_id
- linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
- values["name"] = _("%s\nLinked to: %s") % (values["name"], linked.product_id.name_get()[0][1])
- line_id = sol.create(cr, SUPERUSER_ID, values, context=context)
- if add_qty:
- add_qty -= 1
+ values = {}
- # compute new quantity
- if set_qty:
- quantity = set_qty
- elif add_qty != None:
- quantity = sol.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)
+ if linked_line_id and linked_line_id in map(int,so.order_line):
+ linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
+ sol.write(cr, SUPERUSER_ID, [line_id], {
+ "name": _("%s\nOption for: %s") % (values["name"], linked.product_id.name_get()[0][1]),
+ "linked_line_id": linked_line_id
+ }, context=context)
# select linked product
option_ids = [line.id for line in so.order_line if line.linked_line_id.id == line_id]
- # Remove zero of negative lines
- if quantity <= 0:
- sol.unlink(cr, SUPERUSER_ID, [line_id] + option_ids, context=context)
- else:
- # update line
- values = self._website_product_id_change(cr, uid, ids, so.id, product_id, line_id, context=context)
- values['product_uom_qty'] = quantity
- sol.write(cr, SUPERUSER_ID, [line_id], values, context=context)
-
- # change quantity of linked product
- if option_ids:
- sol.write(cr, SUPERUSER_ID, option_ids, {'product_uom_qty': quantity}, context=context)
+ if option_ids:
+ # Remove zero of negative lines
+ if quantity <= 0:
+ sol.unlink(cr, SUPERUSER_ID, option_ids, context=context)
+ else:
+ # update line
+ sol.write(cr, SUPERUSER_ID, option_ids, {
+ 'product_uom_qty': quantity
+ }, context=context)
return (line_id, quantity)
diff --git a/addons/website_sale_options/static/src/js/website_sale.js b/addons/website_sale_options/static/src/js/website_sale.js
index 8b137891791..30e2d8272bd 100644
--- a/addons/website_sale_options/static/src/js/website_sale.js
+++ b/addons/website_sale_options/static/src/js/website_sale.js
@@ -1 +1,38 @@
+$(document).ready(function () {
+ $('#add_to_cart').click(function (event) {
+ event.preventDefault();
+ openerp.jsonRpc("/shop/cart/update_json", 'call', {
+ 'line_id': parseInt($input.data('line-id'),10),
+ 'product_id': parseInt($input.data('product-id'),10),
+ 'set_qty': value})
+ .then(function (data) {
+ if (!data.quantity) {
+ location.reload();
+ return;
+ }
+ if (data.option_ids.length) {
+ _.each(data.option_ids, function (line_id) {
+ $(".js_quantity[data-line-id="+line_id+"]").text(data.quantity);
+ });
+ }
+ var $q = $(".my_cart_quantity");
+ $q.parent().parent().removeClass("hidden", !data.quantity);
+ $q.html(data.cart_quantity).hide().fadeIn(600);
+ $input.val(data.quantity);
+ $("#cart_total").replaceWith(data['website_sale.total']);
+ });
+ return false;
+ });
+
+ $('form:has(#add_to_cart)').submit(function (event) {
+ event.preventDefault();
+ $(this).ajaxSubmit({
+ beforeSubmit: function () { console.log("beforeSubmit"); },
+ success: function () { console.log("success"); },
+ url: '/stqdfdsfdf'
+ });
+ return false;
+ });
+
+});
diff --git a/addons/website_sale_options/static/src/js/website_sale.test.js b/addons/website_sale_options/static/src/js/website_sale.test.js
new file mode 100644
index 00000000000..53917722835
--- /dev/null
+++ b/addons/website_sale_options/static/src/js/website_sale.test.js
@@ -0,0 +1,80 @@
+(function () {
+ 'use strict';
+
+ openerp.Tour.register({
+ id: 'shop_customize',
+ name: "Customize the page and search a product",
+ path: '/shop',
+ mode: 'test',
+ steps: [
+ {
+ title: "open customize menu",
+ element: '#customize-menu-button',
+ },
+ {
+ title: "click on 'Product Attribute's Filters'",
+ element: "#customize-menu a:contains(Product Attribute's Filters)",
+ },
+ {
+ title: "select product attribute memory 16 Go",
+ waitNot: '#customize-menu:visible',
+ element: 'form.js_attributes label:contains(16 Go) input:not(:checked)',
+ },
+ {
+ title: "check the selection",
+ waitFor: 'form.js_attributes label:contains(16 Go) input:checked',
+ },
+ {
+ title: "select iPod",
+ waitNot: '.oe_website_sale .oe_product_cart:eq(2)',
+ element: '.oe_product_cart a:contains("iPod")',
+ },
+ {
+ title: "open customize menu 2",
+ waitFor: 'form[action^="/shop/cart/update"] label:contains(32 Go) input',
+ element: '#customize-menu-button',
+ },
+ {
+ title: "click on 'Confirm: Add To Cart'",
+ element: "#customize-menu a:contains(Confirm: Add To Cart)",
+ },
+ {
+ title: "click on 'Add to Cart' button",
+ waitNot: '#customize-menu:visible',
+ element: "a[data-toggle='modal']:contains(Add to Cart)",
+ },
+ {
+ title: "click in modal on 'Proceed to checkout' button",
+ element: '.modal a:contains("Proceed to checkout")',
+ },
+ {
+ title: "return to the iPod product",
+ waitFor: '#cart_products',
+ element: "a:contains(iPod)",
+ },
+ {
+ title: "open customize menu 3",
+ waitFor: 'form[action^="/shop/cart/update"] label:contains(32 Go) input',
+ element: '#customize-menu-button',
+ },
+ {
+ title: "click on 'Confirm: Add To Cart'",
+ element: "#customize-menu a:contains(Confirm: Add To Cart)",
+ },
+ {
+ title: "click on 'My Cart'",
+ waitFor: "a.a-submit:contains(Add to Cart)",
+ element: "a[href='/shop/cart']",
+ },
+ {
+ title: "remove iPod from cart",
+ element: '#cart_products a.js_add_cart_json:first',
+ },
+ {
+ title: "finish",
+ waitFor: '.my_cart_quantity:contains(1)',
+ },
+ ]
+ });
+
+}());
diff --git a/addons/website_sale_options/tests/__init__.py b/addons/website_sale_options/tests/__init__.py
new file mode 100644
index 00000000000..1f7db92d733
--- /dev/null
+++ b/addons/website_sale_options/tests/__init__.py
@@ -0,0 +1 @@
+import customize_test \ No newline at end of file
diff --git a/addons/website_sale_options/tests/customize_test.py b/addons/website_sale_options/tests/customize_test.py
new file mode 100644
index 00000000000..478c06ff221
--- /dev/null
+++ b/addons/website_sale_options/tests/customize_test.py
@@ -0,0 +1,14 @@
+import os
+
+import openerp.tests
+
+inject = [
+ ("openerp.Tour", os.path.join(os.path.dirname(__file__), '../../web/static/src/js/tour.js')),
+ ("openerp.Tour.ShopTest", os.path.join(os.path.dirname(__file__), "../static/src/js/website.tour.sale.js")),
+]
+
+@openerp.tests.common.at_install(False)
+@openerp.tests.common.post_install(True)
+class TestUi(openerp.tests.HttpCase):
+ def test_01_admin_shop_tour(self):
+ self.phantom_js("/", "openerp.Tour.run('shop_customize', 'test')", "openerp.Tour.tours.shop_customize", login="admin", inject=inject)
diff --git a/addons/website_sale_options/views/templates.xml b/addons/website_sale_options/views/templates.xml
index cc181631633..e4760b893ea 100644
--- a/addons/website_sale_options/views/templates.xml
+++ b/addons/website_sale_options/views/templates.xml
@@ -2,54 +2,137 @@
<openerp>
<data>
-<template id="optional_products" inherit_id="website_sale.product" name="Optional Products">
- <xpath expr="//tr[@id='product_confirmation']" position="after">
- <tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
- <t t-set="option_inc" t-value="0"/>
- <tr class="js_product" t-foreach="optional_product_ids" t-as="product">
- <td width="100">
- <input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
- <span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
- </td>
- <td>
- <div class="pull-left">
- <strong class="media-heading" t-field="product.name"/>
- <div class="text-muted" t-field="product.description_sale"/>
+<template id="debugger" inherit_id="website.debugger" name="Event Debugger">
+ <xpath expr='//t[@t-set="debugger_hook"]' position="after">
+ <script type="text/javascript" src="/website_sale_options/static/src/js/website_sale.test.js"></script>
+ </xpath>
+</template>
+
+<template id="product_options_script" inherit_id="website_sale.product" name="Script for Options">
+ <xpath expr="//t[@t-set='head']" position="inside">
+ <script type="text/javascript" src="/website_sale_options/static/src/js/website_sale.js"></script>
+ </xpath>
+</template>
+
+<template id="optional_products" name="Optional Products">
+<div id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
+ <div class="modal-dialog modal-lg">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h4 class="modal-title" id="myModalLabel">Product to add in your shopping cart</h4>
+ </div>
+ <div class="modal-body">
+ <table class="table table-striped table-condensed">
+ <thead>
+ <tr>
+ <th colspan="2">Product</th>
+ <th style="min-width: 140px;"> </th>
+ <th width="100">Price</th>
+ <th width="120">Quantity</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id="product_confirmation">
+ <td width="100">
+ <span t-field="product.image_medium" t-field-options='{"widget": "image" }'/>
+ </td>
+ <td colspan="2">
+ <strong t-field="product.name"/>
+ <div class="text-muted">
+ <div t-field="product.description_sale"/>
+ <div class="js_attributes"/>
+ </div>
+ </td>
+ <td>
+ <span t-attf-class="text-danger oe_default_price" t-att-style="'' if (website.compute_curency(product.lst_price) - product.price) &gt; 0.1 else 'display: none;'" style="text-decoration: line-through; white-space: nowrap;"
+ t-field="product.lst_price"
+ t-field-options='{
+ "widget": "monetary",
+ "from_currency": "website.currency_id",
+ "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
+ }'/><br/>
+ <span class="oe_price" style="white-space: nowrap;"
+ t-field="product.price"
+ t-field-options='{
+ "widget": "monetary",
+ "from_currency": "website.currency_id",
+ "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
+ }'/>
+ </td>
+ <td>
+ <div class="input-group">
+ <span class="input-group-addon">
+ <a t-attf-href="#" class="mb8 js_add_cart_json">
+ <i class="fa fa-minus"></i>
+ </a>
+ </span>
+ <input type="text" class="js_quantity form-control" data-min="1" name="add_qty" value="1"/>
+ <span class="input-group-addon">
+ <a t-attf-href="#" class="mb8 float_left js_add_cart_json">
+ <i class="fa fa-plus"></i>
+ </a>
+ </span>
+ </div>
+ </td>
+ </tr>
+
+ <tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
+ <t t-set="option_inc" t-value="0"/>
+ <tr class="js_product" t-foreach="optional_product_ids" t-as="product">
+ <td width="100">
+ <input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
+ <span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
+ </td>
+ <td>
+ <div class="pull-left">
+ <strong class="media-heading" t-field="product.name"/>
+ <div class="text-muted" t-field="product.description_sale"/>
+ </div>
+ </td>
+ <td>
+ <div class="pull-right">
+ <t t-call="website_sale.variants"/>
+ </div>
+ </td>
+ <td>
+ <t t-if="(website.compute_curency(product.lst_price) - product.price) &gt; 0.1">
+ <span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
+ t-field="product.lst_price"
+ t-field-options='{
+ "widget": "monetary",
+ "from_currency": "website.currency_id",
+ "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
+ }'/><br/>
+ </t>
+ <span class="oe_price" style="white-space: nowrap;"
+ t-field="product.price"
+ t-field-options='{
+ "widget": "monetary",
+ "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
+ }'/>
+ <p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
+ </td>
+ <td>
+ <input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
+ <a href="#" class="js_add"><strong>Add to Cart</strong></a>
+ <span class="js_remove hidden">
+ <span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
+ <a href="#" class="js_remove"><small>Remove from cart</small></a>
+ </span>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
</div>
- </td>
- <td>
- <div class="pull-right">
- <t t-call="website_sale.variants"/>
+ <div class="modal-footer">
+ <a class="btn btn-default a-submit js_goto_shop"><i class="fa fa-chevron-left"></i> Continue shopping</a>
+ <a class="btn btn-primary pull-right a-submit"><i class="fa fa-shopping-cart fa-fw"></i> Proceed to checkout</a>
</div>
- </td>
- <td>
- <t t-if="(website.compute_curency(product.lst_price) - product.price) &gt; 0.1">
- <span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
- t-field="product.lst_price"
- t-field-options='{
- "widget": "monetary",
- "from_currency": "website.company_currency_id",
- "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
- }'/><br/>
- </t>
- <span class="oe_price" style="white-space: nowrap;"
- t-field="product.price"
- t-field-options='{
- "widget": "monetary",
- "display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
- }'/>
- <p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
- </td>
- <td>
- <input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
- <a href="#" class="js_add"><strong>Add to Cart</strong></a>
- <span class="js_remove hidden">
- <span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
- <a href="#" class="js_remove"><small>Remove from cart</small></a>
- </span>
- </td>
- </tr>
- </xpath>
+ </div>
+ </div>
+ </div>
</template>
</data>