[IMP] website_sale: confirm/options dialog box have same layout of my cart

This commit is contained in:
Christophe Matthieu 2014-06-13 12:31:41 +02:00
parent 8a24171996
commit 57c59ddfac
5 changed files with 241 additions and 173 deletions

View File

@ -90,6 +90,7 @@ class QueryURL(object):
for k,v in kw.items():
if v:
if isinstance(v, list) or isinstance(v, set):
print k, v
l.append(werkzeug.url_encode([(k,i) for i in v]))
else:
l.append(werkzeug.url_encode([(k,v)]))
@ -126,6 +127,8 @@ class website_sale(http.Controller):
domain += [('product_variant_ids.public_categ_ids', 'child_of', int(category))]
attrib_values = [map(int,v.split(",")) for v in request.httprequest.args.getlist('attrib') if v]
attrib_set = set([v[1] for v in attrib_values])
if attrib_values:
attrib = None
ids = []
@ -142,8 +145,8 @@ class website_sale(http.Controller):
if attrib:
domain += [('attribute_line_ids.value_ids', 'in', ids)]
attrib_set = set([v[1] for v in attrib_values])
keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_set)
attrib_query = set(["%s,%s" % (v[0],v[1]) for v in attrib_values])
keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_query)
if not context.get('pricelist'):
context['pricelist'] = int(self.get_pricelist())
@ -201,7 +204,8 @@ class website_sale(http.Controller):
attrib_values = [map(int,v.split(",")) for v in request.httprequest.args.getlist('attrib') if v]
attrib_set = set([v[1] for v in attrib_values])
keep = QueryURL('/shop', category=category and category.id, search=search, attrib=attrib_set)
attrib_query = set(["%s,%s" % (v[0],v[1]) for v in attrib_values])
keep = QueryURL('/shop', category=category and category.id, search=search, attrib=attrib_query)
category_ids = category_obj.search(cr, uid, [], context=context)
category_list = category_obj.name_get(cr, uid, category_ids, context=context)
@ -260,12 +264,25 @@ class website_sale(http.Controller):
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):
def cart_update(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)
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")
if goto_shop:
path = "/shop"
l = list()
for k,v in kw.items():
if v and k in ["category", "search", "attrib"]:
if isinstance(v, list) or isinstance(v, set):
l.append(werkzeug.url_encode([(k,i) for i in v]))
else:
l.append(werkzeug.url_encode([(k,v)]))
if l:
path += '?' + '&'.join(l)
return request.redirect(path)
else:
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, display=True):

View File

@ -302,16 +302,13 @@
display: none;
}
.css_not_available .row > div:nth-child(3), .css_not_available .row > div:nth-child(4) {
.css_not_available.js_product > *:nth-child(3) > *, .css_not_available.js_product *:nth-child(4) > * {
display: none;
}
.css_not_available .row > div:last-child {
display: block;
}
.css_not_available .product_price {
.css_not_available.js_product .product_price {
display: none;
}
.css_not_available .css_not_available_msg {
.css_not_available.js_product .css_not_available_msg {
display: block;
}

View File

@ -259,12 +259,9 @@
.css_not_available_msg
display: none
.css_not_available
.row
> div:nth-child(3), > div:nth-child(4)
display: none
> div:last-child
display: block
.css_not_available.js_product
> *:nth-child(3) > *, *:nth-child(4) > *
display: none
.product_price
display: none
.css_not_available_msg

View File

@ -123,24 +123,39 @@ $(document).ready(function () {
$('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
});
$("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 );
});
$('#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 quantity = parseInt($('input[name="add_qty"]').val() || 1, 10);
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) {
var qty = parseInt($('input.js_quantity', this).val(),10);
if($('input.js_optional_same_quantity', this).val() !== '0') {
qty = quantity;
}
if (product_id && qty) {
defs.push(openerp.jsonRpc("/shop/cart/update_json", 'call', {
'line_id': null,
'product_id': product_id,
'add_qty': quantity,
'add_qty': qty,
'display': false}));
}
});
$.when.apply($.when, defs).then(function () {
if ($link.hasClass("js_goto_shop")) {
$form.prepend('<input type="hidden" name="goto_shop" value="1"/>');
}
$form.submit();
});
return false;

View File

@ -373,28 +373,147 @@
</div><div class="col-sm-5 col-md-5 col-lg-4 col-lg-offset-1">
<h1 itemprop="name" t-field="product.name">Product Name</h1>
<span itemprop="url" style="display:none;" t-esc="'/shop/product/%s' % slug(product)"/>
<form action="/shop/cart/update" class="js_add_cart_json" method="POST">
<input type="hidden" t-if="len(product.product_variant_ids) == 1" name="product_id" t-att-value="product.product_variant_ids[0].id"/>
<t t-if="len(product.product_variant_ids) &gt; 1">
<label label-default="label-default" class="radio" t-foreach="product.product_variant_ids" t-as="variant_id">
<input type="radio" name="product_id" t-att-value="variant_id.id"/>
<span t-esc="variant_id.name_get()[0][1]"/>
<span class="badge" t-if="variant_id.price_extra">
<t t-esc="variant_id.price_extra > 0 and '+' or ''"/><span t-field="variant_id.price_extra" t-field-options='{ "widget": "monetary", "display_currency": "pricelist.currency_id" }'/>
</span>
</label>
<form t-att-action="keep('/shop/cart/update')" class="js_add_cart_variants" method="POST">
<div class="js_product">
<t t-placeholder="select">
<input type="hidden" class="product_id" name="product_id" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
<t t-call="website_sale.variants">
<t t-set="ul_class" t-value="'nav-stacked'"/>
</t>
</t>
<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>
<t t-name="button">
<t t-placeholder="button">
<a t-if="not optional_product_ids" class="btn btn-primary btn-lg mt8 a-submit js_check_product">Add to Cart</a>
<a t-if="optional_product_ids" class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
<t t-if="optional_products">
<t t-call="website_sale.product_modal_optional_products"/>
</t>
</t>
</div>
<div t-if="optional_product_ids" 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" width="100">Product</th>
<th width="100">Price</th>
<th width="120">Quantity</th>
</tr>
</thead>
<tbody>
<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>
<div class="pull-right">
<t t-call="website_sale.variants"/>
</div>
</td>
<td>
<t t-if="product.lst_price != product.price">
<span class="text-danger" style="text-decoration: line-through;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/><br/>
</t>
<span class="oe_price"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.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" value="0"/>
<input type="hidden" class="js_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">
Will be add to your cart<br/>
<a href="#" class="js_remove"><small>Cancel</small></a>
</span>
</td>
</tr>
</tbody>
</table>
<!--
<div class="js_product" t-foreach="optional_product_ids" t-as="product">
<strong class="media-heading" t-field="product.name"/>
<div class="row">
<div class="col-xs-2">
<span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
</div>
<div class="col-xs-6">
<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'"/>
<t t-call="website_sale.variants"/>
</div>
<div class="col-xs-2">
<strong>Price</strong><br/>
<t t-if="product.lst_price != product.price">
<span class="text-danger" style="text-decoration: line-through;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/><br/>
</t>
<span class="oe_price"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/>
</div>
<div class="col-xs-2">
<strong>Number</strong><br/>
<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" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
<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>
</div>
<div class="col-xs-4">
<p class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
</div>
</div>
</div> -->
</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>
</div>
</form>
<hr t-if="product.description_sale"/>
@ -414,124 +533,55 @@
</t>
</template>
<template id="product_preview" inherit_id="website_sale.product" optional="enabled" name="Product Preview">
<xpath expr="//t[@t-name='button']" position="replace">
<a t-if="optional_products" class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
<t t-call="website_sale.product_modal_optional_products"/>
<template id="product_confirmation" inherit_id="website_sale.product" optional="enabled" name="Confirm: Add To Cart">
<xpath expr="//div[@id='modal_optional_products']" position="attributes">
<attribute name="t-if">True</attribute>
</xpath>
</template>
<template id="product_modal_optional_products">
<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 to your shopping cart</h4>
<xpath expr="//t[@t-placeholder='button']" position="replace">
<a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
</xpath>
<xpath expr="//t[@t-set='option_inc'][@t-value='0']" position="before">
<tr>
<td width="100">
<span t-field="product.image_medium" t-field-options='{"widget": "image" }'/>
</td>
<td>
<strong t-field="product.name"/>
<div class="text-muted" t-field="product.description_sale"/>
</td>
<td>
<t t-if="product.lst_price != product.price">
<span class="text-danger" style="text-decoration: line-through;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/><br/>
</t>
<span class="oe_price"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.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" 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>
<div class="modal-body">
<div class="row">
<div class="col-xs-2">
<strong t-field="product.name"/>
<span t-field="product.image_medium" t-field-options='{"widget": "image", "class": "img-rounded shadow" }'/>
</div>
<div class="col-xs-6">
</div>
<div class="col-xs-2">
<strong>Price</strong><br/>
<t t-if="product.lst_price != product.price">
<span class="text-danger" style="text-decoration: line-through;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/><br/>
</t>
<span class="oe_price"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/>
</div>
<div class="col-xs-2">
<strong>Number</strong><br/>
<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" 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>
</div>
</div>
<hr/>
<t t-set="option_inc" t-value="0"/>
<div class="js_product" t-foreach="optional_product_ids" t-as="product">
<strong class="media-heading" t-field="product.name"/>
<div class="row">
<div class="col-xs-2">
<span t-field="product.image_small" t-field-options='{"widget": "image", "class": "img-rounded shadow" }'/>
</div>
<div class="col-xs-6">
<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'"/>
<t t-call="website_sale.variants"/>
</div>
<div class="col-xs-2">
<strong>Price</strong><br/>
<t t-if="product.lst_price != product.price">
<span class="text-danger" style="text-decoration: line-through;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/><br/>
</t>
<span class="oe_price"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/>
</div>
<div class="col-xs-2">
<strong>Number</strong><br/>
<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" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
<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>
</div>
<div class="col-xs-4">
<p class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-primary a-submit">Continue</a>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</td>
</tr>
</xpath>
</template>
<template id="product_price">
@ -557,31 +607,23 @@
</div>
</template>
<template id="product_variants" inherit_id="website_sale.product" optional="enabled" name="Product Variants">
<xpath expr="//form[@action='/shop/cart/update']" position="replace">
<form action="/shop/cart/update" class="js_add_cart_variants" method="POST">
<t t-call="website_sale.product_modal_optional_products"/>
<div class="js_product">
<input type="hidden" class="product_id" name="product_id" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
<t t-call="website_sale.variants">
<t t-set="ul_class" t-value="'nav-stacked'"/>
</t>
<t t-call="website_sale.product_price"/>
<p class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
<a t-if="not optional_product_ids" class="btn btn-primary btn-lg mt8 a-submit js_check_product">Add to Cart</a>
<a t-if="optional_product_ids" class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
</div>
</form>
<template id="product_variants" inherit_id="website_sale.product" optional="disabled" name="List View of Variants">
<xpath expr="//t[@t-placeholder='select']" position="replace">
<input type="hidden" t-if="len(product.product_variant_ids) == 1" name="product_id" t-att-value="product.product_variant_ids[0].id"/>
<t t-if="len(product.product_variant_ids) &gt; 1">
<label label-default="label-default" class="radio" t-foreach="product.product_variant_ids" t-as="variant_id">
<input type="radio" name="product_id" t-att-value="variant_id.id"/>
<span t-esc="variant_id.name_get()[0][1]"/>
<span class="badge" t-if="variant_id.price_extra">
<t t-esc="variant_id.price_extra > 0 and '+' or ''"/><span t-field="variant_id.price_extra" t-field-options='{ "widget": "monetary", "display_currency": "pricelist.currency_id" }'/>
</span>
</label>
</t>
</xpath>
</template>
<template id="variants">
<ul t-attf-class="nav nav-pills js_add_cart_variants #{ul_class}" t-att-data-attribute_value_ids="[[p.id, map(int, p.attribute_value_ids), p.price] for p in product.product_variant_ids]">
<ul t-attf-class="list-unstyled js_add_cart_variants #{ul_class}" t-att-data-attribute_value_ids="[[p.id, map(int, p.attribute_value_ids), p.price] for p in product.product_variant_ids]">
<t t-foreach="product.attribute_line_ids" t-as="variant_id">
<li t-if="len(variant_id.value_ids) > 1">
@ -862,7 +904,7 @@
</colgroup>
<thead>
<tr>
<th colspan="2">Suggested products</th>
<th colspan="4">Suggested products</th>
</tr>
</thead>
<tbody>