[IMP] stock_request: Convert the state field of stock.request.order as compute store to complete all use cases.

This change prevents stock.request.order from remaining in the open state when they have already finished.

TT44811
This commit is contained in:
Víctor Martínez
2023-08-25 12:27:46 +02:00
parent 88bd31ac0e
commit c1cacf84ae
3 changed files with 121 additions and 31 deletions

View File

@@ -272,19 +272,16 @@ class StockRequest(models.Model):
def action_cancel(self):
self.sudo().mapped("move_ids")._action_cancel()
self.write({"state": "cancel"})
self.mapped("order_id").check_cancel()
return True
def action_done(self):
self.write({"state": "done"})
self.mapped("order_id").check_done()
return True
def check_cancel(self):
for request in self:
if request._check_cancel_allocation():
request.write({"state": "cancel"})
request.mapped("order_id").check_cancel()
def check_done(self):
precision = self.env["decimal.precision"].precision_get(
@@ -305,7 +302,6 @@ class StockRequest(models.Model):
elif request._check_cancel_allocation():
# If qty_done=0 and qty_cancelled>0 it's cancelled
request.write({"state": "cancel"})
request.mapped("order_id").check_cancel()
return True
def _check_cancel_allocation(self):

View File

@@ -51,6 +51,8 @@ class StockRequestOrder(models.Model):
index=True,
readonly=True,
tracking=True,
compute="_compute_state",
store=True,
)
requested_by = fields.Many2one(
"res.users",
@@ -144,6 +146,19 @@ class StockRequestOrder(models.Model):
("name_uniq", "unique(name, company_id)", "Stock Request name must be unique")
]
@api.depends("stock_request_ids.state")
def _compute_state(self):
for item in self:
states = item.stock_request_ids.mapped("state")
if not item.stock_request_ids or all(x == "draft" for x in states):
item.state = "draft"
elif all(x == "cancel" for x in states):
item.state = "cancel"
elif all(x in ("done", "cancel") for x in states):
item.state = "done"
else:
item.state = "open"
@api.depends("stock_request_ids.allocation_ids")
def _compute_picking_ids(self):
for record in self:
@@ -226,37 +241,19 @@ class StockRequestOrder(models.Model):
_("There should be at least one request item for confirming the order.")
)
self.mapped("stock_request_ids").action_confirm()
self.write({"state": "open"})
return True
def action_draft(self):
self.mapped("stock_request_ids").action_draft()
self.write({"state": "draft"})
return True
def action_cancel(self):
self.mapped("stock_request_ids").action_cancel()
self.write({"state": "cancel"})
return True
def action_done(self):
self.write({"state": "done"})
return True
def check_done(self):
for rec in self:
if not rec.stock_request_ids.filtered(
lambda r: r.state not in ["done", "cancel"]
):
rec.action_done()
return
def check_cancel(self):
for rec in self:
if not rec.stock_request_ids.filtered(lambda r: r.state != "cancel"):
rec.write({"state": "cancel"})
return
def action_view_transfer(self):
action = self.env["ir.actions.act_window"]._for_xml_id(
"stock.action_picking_tree_all"

View File

@@ -1,5 +1,5 @@
# Copyright 2017 ForgeFlow S.L.
# Copyright 2022 Tecnativa - Víctor Martínez
# Copyright 2022-2023 Tecnativa - Víctor Martínez
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0).
from collections import Counter
@@ -12,6 +12,16 @@ from odoo.tests import common, new_test_user
class TestStockRequest(common.TransactionCase):
def setUp(self):
super().setUp()
self.env = self.env(
context=dict(
self.env.context,
mail_create_nolog=True,
mail_create_nosubscribe=True,
mail_notrack=True,
no_reset_password=True,
tracking_disable=True,
)
)
# common models
self.stock_request = self.env["stock.request"]
self.request_order = self.env["stock.request.order"]
@@ -35,25 +45,17 @@ class TestStockRequest(common.TransactionCase):
self.wh2 = self.env["stock.warehouse"].search(
[("company_id", "=", self.company_2.id)], limit=1
)
ctx = {
"mail_create_nolog": True,
"mail_create_nosubscribe": True,
"mail_notrack": True,
"no_reset_password": True,
}
self.stock_request_user = new_test_user(
self.env,
login="stock_request_user",
groups="stock_request.group_stock_request_user",
company_ids=[(6, 0, [self.main_company.id, self.company_2.id])],
context=ctx,
)
self.stock_request_manager = new_test_user(
self.env,
login="stock_request_manager",
groups="stock_request.group_stock_request_manager",
company_ids=[(6, 0, [self.main_company.id, self.company_2.id])],
context=ctx,
)
self.product = self._create_product("SH", "Shoes", False)
self.product_company_2 = self._create_product(
@@ -1074,3 +1076,98 @@ class TestStockRequestBase(TestStockRequest):
self.assertEqual(sr3.qty_cancelled, 5)
# Set the request order to done if there are any delivered lines
self.assertEqual(order.state, "done")
class TestStockRequestOrderState(TestStockRequest):
def setUp(self):
super().setUp()
self.product_a = self._create_product(
"CODEA",
"Product A",
self.main_company.id,
)
self.product_a.route_ids = [(6, 0, self.route.ids)]
self.product_b = self._create_product(
"CODEB",
"Product B",
self.main_company.id,
)
self.product_b.route_ids = [(6, 0, self.route.ids)]
expected_date = fields.Datetime.now()
vals = {
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
"stock_request_ids": [
(
0,
0,
{
"product_id": self.product_a.id,
"product_uom_id": self.product_a.uom_id.id,
"product_uom_qty": 1.0,
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
},
),
(
0,
0,
{
"product_id": self.product_b.id,
"product_uom_id": self.product_b.uom_id.id,
"product_uom_qty": 1.0,
"company_id": self.main_company.id,
"warehouse_id": self.warehouse.id,
"location_id": self.warehouse.lot_stock_id.id,
"expected_date": expected_date,
},
),
],
}
self.order = self.request_order.new(vals)
self.request_a = self.order.stock_request_ids.filtered(
lambda x: x.product_id == self.product_a
)
self.request_b = self.order.stock_request_ids.filtered(
lambda x: x.product_id == self.product_b
)
def test_stock_request_order_state_01(self):
"""Request A: Done + Request B: Done = Done."""
self.order.action_confirm()
self.request_a.action_done()
self.request_b.action_done()
self.assertEqual(self.request_a.state, "done")
self.assertEqual(self.request_b.state, "done")
self.assertEqual(self.order.state, "done")
def test_stock_request_order_state_02(self):
"""Request A: Cancel + Request B: Cancel = Cancel."""
self.order.action_confirm()
self.request_a.action_cancel()
self.request_b.action_cancel()
self.assertEqual(self.request_a.state, "cancel")
self.assertEqual(self.request_b.state, "cancel")
self.assertEqual(self.order.state, "cancel")
def test_stock_request_order_state_03(self):
"""Request A: Done + Request B: Cancel = Done."""
self.order.action_confirm()
self.request_a.action_done()
self.request_b.action_cancel()
self.assertEqual(self.request_a.state, "done")
self.assertEqual(self.request_b.state, "cancel")
self.assertEqual(self.order.state, "done")
def test_stock_request_order_state_04(self):
"""Request A: Cancel + Request B: Done = DOne."""
self.order.action_confirm()
self.request_a.action_cancel()
self.request_b.action_done()
self.assertEqual(self.request_a.state, "cancel")
self.assertEqual(self.request_b.state, "done")
self.assertEqual(self.order.state, "done")