[FIX] website_sale_stock: include WH in SO's context

In a multi-warehouses environment, editing the quantities of the cart
products can lead to incorrect behaviors.

To reproduce the issue:
(Let WH01 be the default company's warehouse)
1. Create a second warehouse WH02
2. In Settings > Website > Products:
    - Inventory > Warehouse: WH01
3. Create a product P:
    - Type: Storable
    - Availability: Show inventory on website and prevent sales if not
enough stock
    - Available on eShop
4. Update P's quantity:
    - Location: WH01/Stock, Qty: 10
5. Create a sale order SO:
    - Lines:
        - 100 x P
    - Warehouse: WH02
6. Confirm SO
7. Go on eShop
8. Add P to the cart
9. On cart page, increase the quantity of P

Error: The quantity becomes -90 (then the product is automatically
removed from the cart)

The quantity maximum that the user can select is defined thanks to:
https://github.com/odoo/odoo/blob/8d2fd05382705d4b3987ebac4c842d8507ede9cf/addons/website_sale_stock/views/website_sale_stock_templates.xml#L12

When computing all the quantities (in `_compute_quantities_dict`), if
there isn't any warehouse in the context, the quantities will be
calculated on the basis of all warehouses:
https://github.com/odoo/odoo/blob/48698838dd47442145395d3d4396b64b6901dba1/addons/stock/models/product.py#L238-L248
As a result, in the above case, `virtual_available` will be equal to
`10 - 100 = -90`. However, a SO is linked to a specific warehouse, so
the computations should be based on this warehouse. That way,
`virtual_available` will be 10 and, when editing the quantities in the
cart, the maximum value will be correctly computed.

OPW-2667470

closes odoo/odoo#79370

X-original-commit: 2beb6b1b35ef4c02b6ca1494d1b10fb2cd3b752d
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit is contained in:
Adrien Widart
2021-11-04 14:29:39 +00:00
parent fdc2ed1ee6
commit 5ec823e9ff
2 changed files with 7 additions and 0 deletions
@@ -23,3 +23,7 @@ class Website(models.Model):
self.env['ir.default'].get('sale.order', 'warehouse_id') or
self.env['stock.warehouse'].sudo().search([('company_id', '=', self.company_id.id)], limit=1).id
)
def sale_get_order(self, force_create=False, code=None, update_pricelist=False, force_pricelist=False):
so = super().sale_get_order(force_create=force_create, code=code, update_pricelist=update_pricelist, force_pricelist=force_pricelist)
return so.with_context(warehouse=so.warehouse_id.id) if so else so
@@ -98,6 +98,9 @@ class TestWebsiteSaleStockProductWarehouse(TestSaleProductAttributeValueCommon):
})
with MockRequest(self.env, website=self.website, sale_order_id=so.id):
website_so = self.website.sale_get_order()
self.assertEqual(website_so.order_line.product_id.virtual_available, 10, "This quantity should be based on SO's warehouse")
values = so._cart_update(product_id=self.product_A.id, line_id=so.order_line.id, set_qty=20)
self.assertTrue(values.get('warning', False))
self.assertEqual(values.get('quantity'), 10)