[FIX] website_sale_stock: use correct qty to show warning/error
Without this commit, if you had:
- 3 Qty for product P in WH1
- 10 Qty for product P in WH2
- no warehouse set on website
- set show stock and prevent sales if not enough stock enabled
And then:
- Add 3 P in your cart
- In cart, add more P, it would let you do it, while it shouldn't
You would then be stuck on payment step as it would tell you only 3 are
available.
This commit improves 6b05fb2b21a3 by ensuring the warehouse_id used is the
correct one (the one that will be used on the SO (required field)).
That commit was fixing a case that was not supposed to happen[1], it is that
case that should have been fixed (which is fixed by previous commit of this PR)
[1]: it would fix the 'issue' when you add a product which has no stock
available for the warehouse that will be used when creating the SO, by
letting you through the warning, but you would then be stuck on the
payment step as the qty check would be correctly done.
The fix should have been to display the correct qty and prevent the add to
cart in that case.
closes odoo/odoo#78045
X-original-commit: 5f74b84f67222147b2eb7caadb2d831a059aae4e
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Signed-off-by: Adrien Widart <adwid@users.noreply.github.com>
Co-authored-by: Romain Derie <rde@odoo.com>
Co-authored-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
committed by
Adrien Widart
co-authored by
Adrien Widart
parent
4680f66586
commit
e5a77f2cc1
@@ -17,12 +17,8 @@ class SaleOrder(models.Model):
|
||||
for line in self.order_line:
|
||||
if line.product_id.type == 'product' and not line.product_id.allow_out_of_stock_order:
|
||||
cart_qty = sum(self.order_line.filtered(lambda p: p.product_id.id == line.product_id.id).mapped('product_uom_qty'))
|
||||
# The quantity should be computed based on the warehouse of the website, not the
|
||||
# warehouse of the SO.
|
||||
website = self.env['website'].get_current_website()
|
||||
avl_qty = line.product_id.with_context(warehouse=website.warehouse_id.id).free_qty
|
||||
if cart_qty > avl_qty and (line_id == line.id):
|
||||
qty = avl_qty - cart_qty
|
||||
if cart_qty > line.product_id.with_context(warehouse=self.warehouse_id.id).free_qty and (line_id == line.id):
|
||||
qty = line.product_id.with_context(warehouse=self.warehouse_id.id).free_qty - cart_qty
|
||||
new_val = super(SaleOrder, self)._cart_update(line.product_id.id, line.id, qty, 0, **kwargs)
|
||||
values.update(new_val)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.website.tools import MockRequest
|
||||
from odoo.addons.sale.tests.test_sale_product_attribute_value_config import TestSaleProductAttributeValueCommon
|
||||
from odoo.tests import tagged
|
||||
|
||||
@@ -9,31 +10,31 @@ from odoo.tests import tagged
|
||||
class TestWebsiteSaleStockProductWarehouse(TestSaleProductAttributeValueCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
# Run the tests in another company, so the tests do not rely on the
|
||||
# database state (eg the default company's warehouse)
|
||||
self.company = self.env['res.company'].create({'name': 'Company C'})
|
||||
self.env.user.company_id = self.company
|
||||
self.website = self.env['website'].create({'name': 'Website Company C'})
|
||||
self.website.company_id = self.company
|
||||
cls.company = cls.env['res.company'].create({'name': 'Company C'})
|
||||
cls.env.user.company_id = cls.company
|
||||
cls.website = cls.env['website'].create({'name': 'Website Company C'})
|
||||
cls.website.company_id = cls.company
|
||||
|
||||
# Set two warehouses (one was created on company creation)
|
||||
self.warehouse_1 = self.env['stock.warehouse'].search([('company_id', '=', self.company.id)])
|
||||
self.warehouse_2 = self.env['stock.warehouse'].create({
|
||||
cls.warehouse_1 = cls.env['stock.warehouse'].search([('company_id', '=', cls.company.id)])
|
||||
cls.warehouse_2 = cls.env['stock.warehouse'].create({
|
||||
'name': 'Warehouse 2',
|
||||
'code': 'WH2'
|
||||
})
|
||||
|
||||
# Create two stockable products
|
||||
self.product_A = self.env['product.product'].create({
|
||||
cls.product_A = cls.env['product.product'].create({
|
||||
'name': 'Product A',
|
||||
'allow_out_of_stock_order': False,
|
||||
'type': 'product',
|
||||
'default_code': 'E-COM1',
|
||||
})
|
||||
|
||||
self.product_B = self.env['product.product'].create({
|
||||
cls.product_B = cls.env['product.product'].create({
|
||||
'name': 'Product B',
|
||||
'allow_out_of_stock_order': False,
|
||||
'type': 'product',
|
||||
@@ -41,17 +42,17 @@ class TestWebsiteSaleStockProductWarehouse(TestSaleProductAttributeValueCommon):
|
||||
})
|
||||
|
||||
# Add 10 Product A in WH1 and 15 Product 1 in WH2
|
||||
quants = self.env['stock.quant'].with_context(inventory_mode=True).create([{
|
||||
'product_id': self.product_A.id,
|
||||
quants = cls.env['stock.quant'].with_context(inventory_mode=True).create([{
|
||||
'product_id': cls.product_A.id,
|
||||
'inventory_quantity': qty,
|
||||
'location_id': wh.lot_stock_id.id,
|
||||
} for wh, qty in [(self.warehouse_1, 10.0), (self.warehouse_2, 15.0)]])
|
||||
} for wh, qty in [(cls.warehouse_1, 10.0), (cls.warehouse_2, 15.0)]])
|
||||
|
||||
# Add 10 Product 2 in WH2
|
||||
quants |= self.env['stock.quant'].with_context(inventory_mode=True).create({
|
||||
'product_id': self.product_B.id,
|
||||
quants |= cls.env['stock.quant'].with_context(inventory_mode=True).create({
|
||||
'product_id': cls.product_B.id,
|
||||
'inventory_quantity': 10.0,
|
||||
'location_id': self.warehouse_2.lot_stock_id.id,
|
||||
'location_id': cls.warehouse_2.lot_stock_id.id,
|
||||
})
|
||||
quants.action_apply_inventory()
|
||||
|
||||
@@ -79,3 +80,24 @@ class TestWebsiteSaleStockProductWarehouse(TestSaleProductAttributeValueCommon):
|
||||
|
||||
# Check available quantity of product is according to warehouse
|
||||
self.assertEqual(combination_info['free_qty'], qty_b, "%s units of Product B should be available in warehouse %s" % (qty_b, wh))
|
||||
|
||||
def test_02_update_cart_with_multi_warehouses(self):
|
||||
""" When the user updates his cart and increases a product quantity, if
|
||||
this quantity is not available in the SO's warehouse, a warning should
|
||||
be returned and the quantity updated to its maximum. """
|
||||
|
||||
so = self.env['sale.order'].create({
|
||||
'partner_id': self.env.user.partner_id.id,
|
||||
'order_line': [(0, 0, {
|
||||
'name': self.product_A.name,
|
||||
'product_id': self.product_A.id,
|
||||
'product_uom_qty': 5,
|
||||
'product_uom': self.product_A.uom_id.id,
|
||||
'price_unit': self.product_A.list_price,
|
||||
})]
|
||||
})
|
||||
|
||||
with MockRequest(self.env, website=self.website, sale_order_id=so.id):
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user