mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_inventory: be able to do adjustments in same location but for different products
This commit is contained in:
committed by
Lois Rilo
parent
3c2d9bf757
commit
609a487ecd
@@ -255,22 +255,37 @@ class InventoryAdjustmentsGroup(models.Model):
|
||||
for rec in self:
|
||||
rec.stock_quant_ids = rec._get_quants(rec.location_ids)
|
||||
|
||||
def _get_quant_joined_names(self, quants, field):
|
||||
return ", ".join(quants.mapped(f"{field}.display_name"))
|
||||
|
||||
def action_state_to_in_progress(self):
|
||||
self.ensure_one()
|
||||
active_rec = self.env["stock.inventory"].search(
|
||||
[
|
||||
("state", "=", "in_progress"),
|
||||
("location_ids", "child_of", self.location_ids.ids),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
if active_rec:
|
||||
raise UserError(
|
||||
_(
|
||||
"There's already an Adjustment in Process using one requested Location: %s"
|
||||
)
|
||||
% active_rec.name
|
||||
search_filter = [
|
||||
(
|
||||
"location_id",
|
||||
"child_of" if not self.exclude_sublocation else "in",
|
||||
self.location_ids.ids,
|
||||
),
|
||||
("to_do", "=", True),
|
||||
]
|
||||
|
||||
if self.product_ids:
|
||||
search_filter.append(("product_id", "in", self.product_ids.ids))
|
||||
error_field = "product_id"
|
||||
error_message = _(
|
||||
"There are active adjustments for the requested products: %s"
|
||||
)
|
||||
else:
|
||||
error_field = "location_id"
|
||||
error_message = _(
|
||||
"There's already an Adjustment in Process using one requested Location: %s"
|
||||
)
|
||||
|
||||
quants = self.env["stock.quant"].search(search_filter)
|
||||
if quants:
|
||||
names = self._get_quant_joined_names(quants, error_field)
|
||||
raise ValidationError(error_message % names)
|
||||
|
||||
quants = self._get_quants(self.location_ids)
|
||||
self.write(
|
||||
{
|
||||
@@ -292,7 +307,7 @@ class InventoryAdjustmentsGroup(models.Model):
|
||||
self.state = "done"
|
||||
self.stock_quant_ids.update(
|
||||
{
|
||||
"to_do": True,
|
||||
"to_do": False,
|
||||
"user_id": False,
|
||||
"inventory_date": False,
|
||||
}
|
||||
@@ -310,7 +325,7 @@ class InventoryAdjustmentsGroup(models.Model):
|
||||
self.state = "draft"
|
||||
self.stock_quant_ids.update(
|
||||
{
|
||||
"to_do": True,
|
||||
"to_do": False,
|
||||
"user_id": False,
|
||||
"inventory_date": False,
|
||||
}
|
||||
@@ -366,30 +381,38 @@ class InventoryAdjustmentsGroup(models.Model):
|
||||
result["context"] = {}
|
||||
return result
|
||||
|
||||
@api.constrains("state", "location_ids")
|
||||
def _check_inventory_in_progress_not_override(self):
|
||||
inventories = self.search([("state", "=", "in_progress")])
|
||||
for rec in inventories:
|
||||
inventory = inventories.filtered(
|
||||
lambda x: x.id != rec.id
|
||||
and (
|
||||
any(i in x.location_ids for i in rec.location_ids)
|
||||
or (
|
||||
any(
|
||||
i in x.location_ids.child_internal_location_ids
|
||||
for i in rec.location_ids
|
||||
for rec in self:
|
||||
if rec.state == "in_progress":
|
||||
location_condition = [
|
||||
(
|
||||
"location_ids",
|
||||
"child_of" if not rec.exclude_sublocation else "in",
|
||||
rec.location_ids.ids,
|
||||
)
|
||||
]
|
||||
if rec.product_ids:
|
||||
product_condition = [
|
||||
("state", "=", "in_progress"),
|
||||
("id", "!=", rec.id),
|
||||
("product_ids", "in", rec.product_ids.ids),
|
||||
] + location_condition
|
||||
inventories = self.search(product_condition)
|
||||
else:
|
||||
inventories = self.search(
|
||||
[("state", "=", "in_progress"), ("id", "!=", rec.id)]
|
||||
+ location_condition
|
||||
)
|
||||
for inventory in inventories:
|
||||
if any(
|
||||
i in inventory.location_ids.ids for i in rec.location_ids.ids
|
||||
):
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Cannot have more than one in-progress inventory adjustment "
|
||||
"affecting the same location or product at the same time."
|
||||
)
|
||||
)
|
||||
and not x.exclude_sublocation
|
||||
)
|
||||
)
|
||||
)
|
||||
if len(inventory) > 0:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Cannot be more than one in progress inventory adjustment "
|
||||
"affecting the same location at the same time."
|
||||
)
|
||||
)
|
||||
|
||||
@api.constrains("product_selection", "product_ids")
|
||||
def _check_one_product_in_product_selection(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ from odoo import _, api, fields, models
|
||||
class StockQuant(models.Model):
|
||||
_inherit = "stock.quant"
|
||||
|
||||
to_do = fields.Boolean(default=True)
|
||||
to_do = fields.Boolean(default=False)
|
||||
|
||||
def _apply_inventory(self):
|
||||
res = super()._apply_inventory()
|
||||
|
||||
@@ -408,3 +408,116 @@ class TestStockInventory(TransactionCase):
|
||||
self.assertEqual(inventory1.count_stock_moves, 2)
|
||||
self.assertEqual(inventory1.count_stock_quants, 2)
|
||||
self.assertEqual(inventory1.state, "done")
|
||||
|
||||
def test_08_multiple_inventories_same_location(self):
|
||||
quant1 = self.quant_model.search(
|
||||
[
|
||||
("product_id", "=", self.product.id),
|
||||
("location_id", "=", self.location1.id),
|
||||
]
|
||||
)
|
||||
self.assertTrue(quant1)
|
||||
self.quant_model.sudo().create(
|
||||
{
|
||||
"product_id": self.product2.id,
|
||||
"quantity": 100.0,
|
||||
"location_id": self.location1.id,
|
||||
}
|
||||
)
|
||||
quant2 = self.quant_model.search(
|
||||
[
|
||||
("product_id", "=", self.product2.id),
|
||||
("location_id", "=", self.location1.id),
|
||||
]
|
||||
)
|
||||
self.assertTrue(quant2)
|
||||
inventory1 = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Test_8_1",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [self.location1.id],
|
||||
"product_ids": [self.product.id],
|
||||
}
|
||||
)
|
||||
inventory1.action_state_to_in_progress()
|
||||
self.assertEqual(inventory1.state, "in_progress")
|
||||
inventory2 = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Test_8_2",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [self.location1.id],
|
||||
"product_ids": [self.product2.id],
|
||||
}
|
||||
)
|
||||
inventory2.action_state_to_in_progress()
|
||||
self.assertEqual(inventory2.state, "in_progress")
|
||||
self.assertEqual(inventory1.state, "in_progress")
|
||||
|
||||
def test_09_product_inventory_global_and_sublocations_review(self):
|
||||
self.location4 = self.location_model.create(
|
||||
{
|
||||
"name": "Location 4",
|
||||
"usage": "internal",
|
||||
"location_id": self.location1.id,
|
||||
}
|
||||
)
|
||||
location_global = self.location_model.create(
|
||||
{
|
||||
"name": "Global Location",
|
||||
"usage": "internal",
|
||||
}
|
||||
)
|
||||
self.location1.location_id = location_global.id
|
||||
self.location2.location_id = location_global.id
|
||||
self.location3.location_id = location_global.id
|
||||
self.location4.location_id = location_global.id
|
||||
inventory_global = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Global",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [location_global.id],
|
||||
"product_ids": [self.product.id],
|
||||
}
|
||||
)
|
||||
inventory_global.action_state_to_in_progress()
|
||||
self.assertEqual(inventory_global.state, "in_progress")
|
||||
inventory_sub_no_product = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Sub_No_Product",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [self.location4.id],
|
||||
}
|
||||
)
|
||||
inventory_sub_no_product.action_state_to_in_progress()
|
||||
self.assertEqual(inventory_sub_no_product.state, "in_progress")
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
inventory_sub_with_product = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Sub_With_Product",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [self.location1.id],
|
||||
}
|
||||
)
|
||||
inventory_sub_with_product.action_state_to_in_progress()
|
||||
|
||||
def test_10_inventory_quant_to_do_states(self):
|
||||
inventory = self.inventory_model.create(
|
||||
{
|
||||
"name": "Inventory_Test_10",
|
||||
"product_selection": "manual",
|
||||
"location_ids": [self.location1.id],
|
||||
"product_ids": [self.product.id],
|
||||
}
|
||||
)
|
||||
inventory.action_state_to_in_progress()
|
||||
quants = inventory.stock_quant_ids
|
||||
self.assertTrue(all(quant.to_do for quant in quants))
|
||||
inventory.action_state_to_draft()
|
||||
self.assertFalse(inventory.stock_quant_ids)
|
||||
self.assertTrue(all(not quant.to_do for quant in quants))
|
||||
inventory.action_state_to_in_progress()
|
||||
quants = inventory.stock_quant_ids
|
||||
self.assertTrue(all(quant.to_do for quant in quants))
|
||||
self.assertTrue(inventory.stock_quant_ids)
|
||||
inventory.action_state_to_done()
|
||||
self.assertTrue(all(not quant.to_do for quant in quants))
|
||||
|
||||
Reference in New Issue
Block a user