From c400789d6e303ac3835dab6863363d0984e01e95 Mon Sep 17 00:00:00 2001
From: rde <rde@odoo.com>
Date: Mon, 9 Oct 2017 13:01:23 +0200
Subject: [PATCH] [FIX] website_sale_stock(_option): prevent negative stock &
 traceback

Before this commit, multiple tabs/session adding items to cart  could lead to
negative stock displayed in the quantity field.
In some case, it could throw a traceback because the wanted product had
became unavailable in the meantime, causing the cart to be updated and the
line to be deleted from the cart. But then, this line was being accessed again.

Now, negative values are prevented at the screen. And there is a check on the
line record to be sure it exists before accessing it.
---
 addons/website_sale_stock/models/sale_order.py                | 3 ++-
 addons/website_sale_stock/static/src/js/website_sale_stock.js | 4 ++++
 .../website_sale_stock/views/website_sale_stock_templates.xml | 2 +-
 .../views/website_sale_stock_templates.xml                    | 2 +-
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/addons/website_sale_stock/models/sale_order.py b/addons/website_sale_stock/models/sale_order.py
index e73bee0b6d7e..ecc653f98d17 100644
--- a/addons/website_sale_stock/models/sale_order.py
+++ b/addons/website_sale_stock/models/sale_order.py
@@ -22,7 +22,8 @@ class SaleOrder(models.Model):
                     new_val = super(SaleOrder, self)._cart_update(line.product_id.id, line.id, qty, 0, **kwargs)
                     values.update(new_val)
 
-                    if new_val['quantity']:
+                    # Make sure line still exists, it may have been deleted in super()_cartupdate because qty can be <= 0
+                    if line.exists() and new_val['quantity']:
                         line.warning_stock = _('You ask for %s products but only %s is available') % (cart_qty, new_val['quantity'])
                     else:
                         self.warning_stock = _("Some products became unavailable and your cart has been updated. We're sorry for the inconvenience.")
diff --git a/addons/website_sale_stock/static/src/js/website_sale_stock.js b/addons/website_sale_stock/static/src/js/website_sale_stock.js
index 90f8c9ce8239..2a3a7f8cc6fe 100644
--- a/addons/website_sale_stock/static/src/js/website_sale_stock.js
+++ b/addons/website_sale_stock/static/src/js/website_sale_stock.js
@@ -32,6 +32,7 @@ $('.oe_website_sale').each(function() {
         }
     });
 
+
     /* Renders a specific message concerning the stock of the product
         and its variants on the product website page.
     */
@@ -49,6 +50,9 @@ $('.oe_website_sale').each(function() {
                 var info = variant_ids[k][4];
                 if(_.contains(['always', 'threshold'], info['inventory_availability'])) {
                     info['virtual_available'] -= parseInt(info['cart_qty']);
+                    if (info['virtual_available'] < 0) {
+                        info['virtual_available'] = 0;
+                    }
                     // Handle case when manually write in input
                     if(qty > info['virtual_available']) {
                         $parent.find('input[name="add_qty"]').val(info['virtual_available'] || 1);
diff --git a/addons/website_sale_stock/views/website_sale_stock_templates.xml b/addons/website_sale_stock/views/website_sale_stock_templates.xml
index 9564d86f6a26..4892b0d853d7 100644
--- a/addons/website_sale_stock/views/website_sale_stock_templates.xml
+++ b/addons/website_sale_stock/views/website_sale_stock_templates.xml
@@ -57,7 +57,7 @@
             <div class='availability_messages'/>
         </xpath>
         <xpath expr="//div[hasclass('js_cart_lines')]" position="after">
-          <t t-if='website_sale_order and not website_sale_order.website_order_line'>
+          <t t-if='website_sale_order'>
             <div t-if='website_sale_order._get_stock_warning(clear=False)' class="alert alert-warning">
               <strong>Warning!</strong> <t t-esc='website_sale_order._get_stock_warning()'/>
             </div>
diff --git a/addons/website_sale_stock_options/views/website_sale_stock_templates.xml b/addons/website_sale_stock_options/views/website_sale_stock_templates.xml
index e144b33afa11..8f34365277f5 100644
--- a/addons/website_sale_stock_options/views/website_sale_stock_templates.xml
+++ b/addons/website_sale_stock_options/views/website_sale_stock_templates.xml
@@ -3,7 +3,7 @@
     <!-- Shopping Cart Lines -->
     <template id="website_sale_stock_modal" inherit_id="website_sale_options.modal" name="Stocks Modal">
         <xpath expr="//input[@type='text'][hasclass('quantity')]" position="attributes">
-          <attribute name='t-att-data-max'>product.sudo().virtual_available - product.cart_qty</attribute>
+          <attribute name='t-att-data-max'>max(product.sudo().virtual_available - product.cart_qty, 1)</attribute>
         </xpath>
         <xpath expr="//div[hasclass('css_quantity')]" position="after">
           <div class='availability_messages'/>
-- 
GitLab