[IMP] stock_location_product_restriction: Don't check zero quants on locations

For location restriction violation, don't check zero quants
This commit is contained in:
Denis Roussel
2024-12-04 15:49:38 +01:00
parent 0c9c2035bb
commit e28db5cc46
2 changed files with 82 additions and 6 deletions

View File

@@ -70,7 +70,25 @@ class StockLocation(models.Model):
@api.depends("product_restriction")
def _compute_restriction_violation(self):
records = self
self.env["stock.quant"].flush_model(
[
"product_id",
"location_id",
"quantity",
"reserved_quantity",
"available_quantity",
"inventory_quantity",
]
)
self.flush_model(
[
"product_restriction",
]
)
ProductProduct = self.env["product.product"]
precision_digits = max(
6, self.sudo().env.ref("product.decimal_product_uom").digits * 2
)
SQL = """
SELECT
stock_quant.location_id,
@@ -82,6 +100,11 @@ class StockLocation(models.Model):
stock_quant.location_id in %s
and stock_location.id = stock_quant.location_id
and stock_location.product_restriction = 'same'
/* Mimic the _unlink_zero_quant() query in Odoo */
AND (NOT (round(quantity::numeric, %s) = 0 OR quantity IS NULL)
OR NOT round(reserved_quantity::numeric, %s) = 0
OR NOT (round(inventory_quantity::numeric, %s) = 0
OR inventory_quantity IS NULL))
GROUP BY
stock_quant.location_id
HAVING count(distinct(product_id)) > 1
@@ -93,7 +116,9 @@ class StockLocation(models.Model):
if not ids:
product_ids_by_location_id = dict()
else:
self.env.cr.execute(SQL, (ids,))
self.env.cr.execute(
SQL, (ids, precision_digits, precision_digits, precision_digits)
)
product_ids_by_location_id = dict(self.env.cr.fetchall())
for record in self:
record_id = record.id
@@ -112,12 +137,30 @@ class StockLocation(models.Model):
record.restriction_violation_message = restriction_violation_message
def _search_has_restriction_violation(self, operator, value):
precision_digits = max(
6, self.sudo().env.ref("product.decimal_product_uom").digits * 2
)
search_has_violation = (
# has_restriction_violation != False
(operator in NEGATIVE_TERM_OPERATORS and not value)
# has_restriction_violation = True
or (operator not in NEGATIVE_TERM_OPERATORS and value)
)
self.env["stock.quant"].flush_model(
[
"product_id",
"location_id",
"quantity",
"reserved_quantity",
"available_quantity",
"inventory_quantity",
]
)
self.flush_model(
[
"product_restriction",
]
)
SQL = """
SELECT
stock_quant.location_id
@@ -127,11 +170,23 @@ class StockLocation(models.Model):
WHERE
stock_location.id = stock_quant.location_id
and stock_location.product_restriction = 'same'
/* Mimic the _unlink_zero_quant() query in Odoo */
AND (NOT (round(quantity::numeric, %s) = 0 OR quantity IS NULL)
OR NOT round(reserved_quantity::numeric, %s) = 0
OR NOT (round(inventory_quantity::numeric, %s) = 0
OR inventory_quantity IS NULL))
GROUP BY
stock_quant.location_id
HAVING count(distinct(product_id)) > 1
"""
self.env.cr.execute(SQL)
self.env.cr.execute(
SQL,
(
precision_digits,
precision_digits,
precision_digits,
),
)
violation_ids = [r[0] for r in self.env.cr.fetchall()]
if search_has_violation:
op = "in"

View File

@@ -38,7 +38,7 @@ class TestStockLocation(TransactionCase):
# quants
StockQuant = cls.env["stock.quant"]
StockQuant.create(
cls.quant_1_lvl_1_1_1 = StockQuant.create(
{
"product_id": cls.product_1.id,
"location_id": cls.loc_lvl_1_1_1.id,
@@ -46,7 +46,7 @@ class TestStockLocation(TransactionCase):
"owner_id": cls.env.user.id,
}
)
StockQuant.create(
cls.quant_2_lvl_1_1_1 = StockQuant.create(
{
"product_id": cls.product_2.id,
"location_id": cls.loc_lvl_1_1_1.id,
@@ -54,7 +54,7 @@ class TestStockLocation(TransactionCase):
"owner_id": cls.env.user.id,
}
)
StockQuant.create(
cls.quant_1_lvl_1_1_2 = StockQuant.create(
{
"product_id": cls.product_1.id,
"location_id": cls.loc_lvl_1_1_2.id,
@@ -62,7 +62,7 @@ class TestStockLocation(TransactionCase):
"owner_id": cls.env.user.id,
}
)
StockQuant.create(
cls.quant_2_lvl_1_1_2 = StockQuant.create(
{
"product_id": cls.product_2.id,
"location_id": cls.loc_lvl_1_1_2.id,
@@ -262,3 +262,24 @@ class TestStockLocation(TransactionCase):
# Check location creation
with Form(self.StockLocation) as location_form:
location_form.name = "Test"
def test_zero_quant(self):
"""
Data:
* Location level_1_1_1 with 2 different products no restriction
Test Case:
1. Check restriction message
2. Change product 1 quant to 0.0
3. Set restriction 'same' on location level_1_1_1
4. Check restriction message
Expected result:
1. No restriction message
"""
self.loc_lvl_1_1_1.product_restriction = "any"
self.assertFalse(self.loc_lvl_1_1_1.has_restriction_violation)
self.assertFalse(self.loc_lvl_1_1_1.restriction_violation_message)
self.quant_1_lvl_1_1_1.inventory_quantity = 0.0
self.quant_1_lvl_1_1_1._apply_inventory()
self.loc_lvl_1_1_1.product_restriction = "same"
self.assertFalse(self.loc_lvl_1_1_1.has_restriction_violation)
self.assertFalse(self.loc_lvl_1_1_1.restriction_violation_message)