From 1d75625941e183d2c594d0bdf3aef8debcba3feb Mon Sep 17 00:00:00 2001 From: "Laurent Mignonn (ACSONE)" Date: Wed, 11 Dec 2024 14:28:29 +0100 Subject: [PATCH] [FIXUP] check line overlap only at confirmation --- sale_order_blanket_order/models/sale_order.py | 26 +++++++--------- .../models/sale_order_line.py | 5 +++- .../tests/test_sale_blanket_order.py | 30 ++++++++++--------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/sale_order_blanket_order/models/sale_order.py b/sale_order_blanket_order/models/sale_order.py index f053e781343..1deb5a38958 100644 --- a/sale_order_blanket_order/models/sale_order.py +++ b/sale_order_blanket_order/models/sale_order.py @@ -118,10 +118,7 @@ def init(self): @api.constrains("order_type", "blanket_order_id", "state") def _check_order_type(self): for order in self: - if order.state not in ("sale", "done") and order._origin.state not in ( - "sale", - "done", - ): + if order.state != "sale": continue if order.order_type == "blanket" and order.blanket_order_id: raise ValidationError(_("A blanket order cannot have a blanket order.")) @@ -141,10 +138,7 @@ def _check_order_type(self): ) def _check_validity_dates(self): for order in self: - if order.state not in ("sale", "done") and order._origin.state not in ( - "sale", - "done", - ): + if order.state != "sale": continue if order.order_type == "blanket": if not order.blanket_validity_start_date: @@ -168,10 +162,7 @@ def _check_validity_dates(self): ) def _check_call_of_link_to_valid_blanket(self): for rec in self: - if rec.state not in ("sale", "done") and rec._origin.state not in ( - "sale", - "done", - ): + if rec.state != "sale": continue if ( rec.order_type != "call_off" @@ -199,10 +190,7 @@ def _check_call_of_link_to_valid_blanket(self): @api.constrains("order_type", "blanket_order_id", "state") def _check_blanket_order_state(self): for order in self: - if order.state not in ("sale", "done") and order._origin.state not in ( - "sale", - "done", - ): + if order.state != "sale": continue if ( order.order_type != "call_off" @@ -317,6 +305,12 @@ def _on_blanket_order_confirm(self): raise ValidationError( _("Only blanket orders can be confirmed as blanket orders.") ) + # trigger validation on sale order lines for constrains + # _validate_fields We force the validation to be done here + # even if it will be done later at flush time. This is to + # ensure that the data are correct before performing any others + # operations that could use the data. + self.order_line._check_blanket_product_not_overlapping() for order in self: order.commitment_date = order.blanket_validity_start_date self.blanket_need_to_be_finalized = True diff --git a/sale_order_blanket_order/models/sale_order_line.py b/sale_order_blanket_order/models/sale_order_line.py index e7aab8d95a0..43d49a15d66 100644 --- a/sale_order_blanket_order/models/sale_order_line.py +++ b/sale_order_blanket_order/models/sale_order_line.py @@ -104,6 +104,7 @@ def _check_call_off_order_line_price(self): "product_id", "product_packaging_id", "order_partner_id", + "state", ) def _check_blanket_product_not_overlapping(self): """We check that a product is not part of multiple blanket orders @@ -128,6 +129,7 @@ def _check_blanket_product_not_overlapping(self): "product_id", "product_packaging_id", "order_partner_id", + "state", ] ) for rec in self: @@ -136,6 +138,7 @@ def _check_blanket_product_not_overlapping(self): order.order_type != "blanket" or not rec.blanket_validity_start_date or not rec.blanket_validity_end_date + or rec.state != "sale" ): continue # here we use a plain SQL query to benefit of the daterange @@ -162,7 +165,7 @@ def _check_blanket_product_not_overlapping(self): domain = [ ("call_off_remaining_qty", ">", 0), ("order_id", "!=", order.id), - ("state", "not in", ["done", "cancel"]), + ("state", "not in", ["draft", "cancel"]), ("order_type", "=", "blanket"), ] for ( diff --git a/sale_order_blanket_order/tests/test_sale_blanket_order.py b/sale_order_blanket_order/tests/test_sale_blanket_order.py index 1d497df289c..118106960b1 100644 --- a/sale_order_blanket_order/tests/test_sale_blanket_order.py +++ b/sale_order_blanket_order/tests/test_sale_blanket_order.py @@ -66,7 +66,21 @@ def test_confirm_no_blanket_order(self): order.action_confirm() def test_no_product_overlap(self): - # Create a blanket order with a product that is already in the blanket order + self.blanket_so.action_confirm() + order = self.env["sale.order"].create( + { + "order_type": "blanket", + "partner_id": self.partner.id, + "blanket_validity_start_date": "2024-02-01", + "blanket_validity_end_date": "2025-01-31", + "order_line": [ + Command.create( + {"product_id": self.product_1.id, "product_uom_qty": 10.0} + ), + ], + } + ) + # Validate a blanket order with a product that is already in the blanket order with self.assertRaisesRegex( ValidationError, ( @@ -74,19 +88,7 @@ def test_no_product_overlap(self): f"{self.blanket_so.name}." ), ): - self.env["sale.order"].create( - { - "order_type": "blanket", - "partner_id": self.partner.id, - "blanket_validity_start_date": "2024-02-01", - "blanket_validity_end_date": "2025-01-31", - "order_line": [ - Command.create( - {"product_id": self.product_1.id, "product_uom_qty": 10.0} - ), - ], - } - ) + order.action_confirm() def test_reservation(self): # Confirm the blanket order with reservation at call off