diff --git a/stock_request/models/stock_request.py b/stock_request/models/stock_request.py index d37da9d15..87afe8ca2 100644 --- a/stock_request/models/stock_request.py +++ b/stock_request/models/stock_request.py @@ -231,19 +231,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( @@ -264,7 +261,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): diff --git a/stock_request/models/stock_request_order.py b/stock_request/models/stock_request_order.py index fa7738f68..f7a15c995 100644 --- a/stock_request/models/stock_request_order.py +++ b/stock_request/models/stock_request_order.py @@ -50,6 +50,8 @@ class StockRequestOrder(models.Model): index=True, readonly=True, tracking=True, + compute="_compute_state", + store=True, ) requested_by = fields.Many2one( "res.users", @@ -141,6 +143,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: @@ -223,37 +238,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" diff --git a/stock_request/tests/test_stock_request.py b/stock_request/tests/test_stock_request.py index 3ba36f534..ec91f2a5f 100644 --- a/stock_request/tests/test_stock_request.py +++ b/stock_request/tests/test_stock_request.py @@ -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( @@ -1115,3 +1117,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")