[IMP] stock_cycle_count: Implement constrains in inventory adjustment.

The previous method was too restrictive, and would cause conflicts
in cases where another module would introduce changes to the inventory
adjustment that were not really affecting to the cycle count.

We implement the minimum necessary constrains to ensure consistency between
the cycle count and the related inventory adjusment.
This commit is contained in:
Jordi Ballester Alomar
2022-11-04 17:12:43 +01:00
parent 966af99dfd
commit 68d561eb05
2 changed files with 64 additions and 16 deletions

View File

@@ -1,9 +1,9 @@
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017-2022 ForgeFlow S.L.
# (http://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError
PERCENT = 100.0
@@ -88,18 +88,45 @@ class StockInventory(models.Model):
res._link_to_planned_cycle_count()
return res
def write(self, vals):
for inventory in self:
if inventory._allow_write(vals):
raise UserError(
_(
"You cannot modify the configuration of an Inventory "
"Adjustment related to a Cycle Count."
)
)
return super(StockInventory, self).write(vals)
def _is_consistent_with_cycle_count(self):
self.ensure_one()
if (
not self.location_ids
or len(self.location_ids) > 1
or self.location_ids != self.cycle_count_id.location_id
):
return False, _(
"The location in the inventory does not match with the cycle count."
)
if self.product_ids:
return False, _(
"The adjustment should be done for all products in the location."
)
if self.company_id != self.cycle_count_id.company_id:
return False, _(
"The company of the adjustment does not match with the "
"company in the cycle count."
)
if not self.exclude_sublocation:
return False, _(
"An adjustment linked to a cycle count should exclude the sublocations."
)
return True, ""
def _allow_write(self, vals):
return (
self.cycle_count_id and "state" not in vals.keys() and self.state == "draft"
)
@api.constrains(
"cycle_count_id",
"location_ids",
"product_ids",
"company_id",
"exclude_sublocation",
)
def _check_cycle_count_consistency(self):
for rec in self.filtered(lambda r: r.cycle_count_id):
is_consistent, msg = rec._is_consistent_with_cycle_count()
if not is_consistent:
raise ValidationError(
_(
"The Inventory Adjustment is inconsistent with the Cycle Count:\n%s"
)
% msg
)

View File

@@ -316,3 +316,24 @@ class TestStockCycleCount(common.TransactionCase):
)
self.assertEqual(inventory.cycle_count_id, self.cycle_count_1)
self.assertEqual(self.cycle_count_1.state, "open")
def test_cycle_count_contrains(self):
"""Test the various constrains defined in the inventory adjustment."""
self.cycle_count_1.action_create_inventory_adjustment()
inventory = self.inventory_model.search(
[("cycle_count_id", "=", self.cycle_count_1.id)]
)
with self.assertRaises(ValidationError):
inventory.product_ids = self.product1
with self.assertRaises(ValidationError):
inventory.location_ids = False
loc = self.stock_location_model.create(
{"name": "Second Location", "usage": "internal"}
)
with self.assertRaises(ValidationError):
inventory.location_ids += loc
with self.assertRaises(ValidationError):
inventory.exclude_sublocation = False
company = self.env["res.company"].create({"name": "Test"})
with self.assertRaises(ValidationError):
inventory.company_id = company