[FIX] website_sale(_options): text in field qty throws error and/or create infinite quotations

Before this commit:
1. If user wrote text in the quantity field to add to his cart, it would crash
and show a server error.

Now, if the user insert a non-valid quantity in the field, we set it to 1

Step to reproduce:
With website_sale only
  - Go to a product page on the shop
  - Insert 'abc' in the quantity field and click 'Add to Cart'
  - Server will throw an error 'Can't parse float..'
With website_sale_options
  - Go to a product page on the shop
  - Insert 'abc' in the quantity field and click 'Add to Cart'
  - Popup confirmation with optional product will show with 'NaN' in the qty
  - Click 'Proceed to checkout'
  - Server will throw an error 'Can't parse int..'

2. On the checkout, if user typed text in qty field it would create infinite
quotations.
Some modules (eg: website_event_sale) would hide this behavior because they
override the RPC call to '/shop/cart/update_json' and throw an error on the
RPC.

Now, if user type incorrect integer quantity, we set the quantity to 1.

Step to reproduce:
1. On base (website_sale only)
  - Add an item to your cart
  - On checkout page, set qty to 'abcd' or whatever text
  - Check your browser console, every 500ms their will be a RPC call
  - Check your quotations in backend, their will be a new one every 500ms
2. On db-all
  - Add an item to your cart
  - Set qty to 'abcd' or whatever text
  - Check your browser console, it will throw an error on the second call

This closes #20482, closes #20904
This commit is contained in:
Romain Derie
2017-11-29 13:31:59 +01:00
parent 832d73deb4
commit 82bde85030
4 changed files with 20 additions and 4 deletions
+1 -2
View File
@@ -368,7 +368,7 @@ class website_sale(http.Controller):
@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):
request.website.sale_get_order(force_create=1)._cart_update(product_id=int(product_id), add_qty=float(add_qty), set_qty=float(set_qty))
request.website.sale_get_order(force_create=1)._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)
@@ -377,7 +377,6 @@ class website_sale(http.Controller):
if order.state != 'draft':
request.website.sale_reset()
return {}
value = order._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty)
if not order.cart_quantity:
request.website.sale_reset()
+10
View File
@@ -79,6 +79,16 @@ class sale_order(osv.Model):
""" Add or set product quantity, add_qty can be negative """
sol = self.pool.get('sale.order.line')
try:
if add_qty:
add_qty = float(add_qty)
except ValueError:
add_qty = 1
try:
if set_qty:
set_qty = float(set_qty)
except ValueError:
set_qty = 0
quantity = 0
for so in self.browse(cr, uid, ids, context=context):
if so.state != 'draft':
@@ -153,6 +153,9 @@ $('.oe_website_sale').each(function () {
return;
}
var value = parseInt($input.val() || 0, 10);
if (isNaN(value)) {
value = 1;
}
var $dom = $(this).closest('tr');
var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
@@ -173,7 +176,11 @@ $('.oe_website_sale').each(function () {
'set_qty': value})
.then(function (data) {
$input.data('update_change', false);
if (value !== parseInt($input.val() || 0, 10)) {
var check_value = parseInt($input.val() || 0, 10);
if (isNaN(check_value)) {
check_value = 1;
}
if (value !== check_value) {
$input.trigger('change');
return;
}
@@ -42,7 +42,7 @@ class website_sale_options(website_sale):
value = {}
if add_qty or set_qty:
value = order._cart_update(product_id=int(product_id),
add_qty=int(add_qty), set_qty=int(set_qty),
add_qty=add_qty, set_qty=set_qty,
optional_product_ids=optional_product_ids)
# options have all time the same quantity