From c2196c5441ff2a28ef3c0a91d0eaecad9001cc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Fri, 29 Nov 2024 12:13:36 +0100 Subject: [PATCH 1/2] sale_stock_release_channel_partner_by_date_delivery: fix computation of release channel --- .../models/sale_order.py | 3 +- .../models/sale_order.py | 9 ++ .../tests/test_sale_release_channel.py | 113 ++++++++++++++++-- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/sale_stock_release_channel_partner_by_date/models/sale_order.py b/sale_stock_release_channel_partner_by_date/models/sale_order.py index ebd20dc03c..adea84563b 100644 --- a/sale_stock_release_channel_partner_by_date/models/sale_order.py +++ b/sale_stock_release_channel_partner_by_date/models/sale_order.py @@ -42,7 +42,8 @@ def _compute_release_channel_id(self): if not rec._check_release_channel_partner_date_requirements(): continue channel_date = rec.release_channel_partner_date_id - rec.release_channel_id = channel_date.release_channel_id + if channel_date: + rec.release_channel_id = channel_date.release_channel_id @api.depends( "state", diff --git a/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py b/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py index 09632fe83a..acd0291f78 100644 --- a/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py +++ b/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py @@ -30,3 +30,12 @@ def _get_release_channel_partner_date_domain(self): ] domain = expression.AND([domain, carrier_domain]) return domain + + def _compute_release_channel_id(self): + # pylint: disable=missing-return + super()._compute_release_channel_id() + for rec in self: + # Selected release channel and carrier have to be compatible + if rec.release_channel_id.carrier_ids and rec.carrier_id: + if rec.carrier_id not in rec.release_channel_id.carrier_ids: + rec.release_channel_id = False diff --git a/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py b/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py index f990010fac..08b91d7860 100644 --- a/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py +++ b/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from odoo import fields +from odoo.tests.common import Form from odoo.addons.sale_stock_release_channel_partner_by_date.tests.common import ( SaleReleaseChannelCase, @@ -22,31 +23,41 @@ def setUpClass(cls): } ) cls.carrier_channel.action_wake_up() + cls.carrier2_channel = cls.default_channel.copy( + { + "name": "Test with carrier2", + "sequence": 10, + "carrier_ids": [(6, 0, cls.carrier2.ids)], + } + ) + cls.carrier2_channel.action_wake_up() - def test_sale_order_with_wrong_carrier(self): + def test_sale_order_without_carrier_with_channel_date(self): delivery_date = fields.Datetime.now() + # Create one specific channel that is matching the SO even if no carrier is set + # FIXME: not sure about this one, to check how it should behave channel_date_model = self.env["stock.release.channel.partner.date"] - channel_date_model.create( + channel_date = channel_date_model.create( { "partner_id": self.customer.id, "release_channel_id": self.carrier_channel.id, "date": delivery_date.date(), } ) - # With wrong carrier set: order doesn't detect the specific channel for carrier order = self._create_sale_order(date=delivery_date) - order.carrier_id = self.carrier2 - self.assertFalse(order.release_channel_id) + self.assertFalse(order.carrier_id) + self.assertEqual(order.release_channel_id, self.carrier_channel) order.action_confirm() - self.assertFalse(order.release_channel_id) - self.assertFalse(order._get_release_channel_partner_date()) + self.assertEqual(order.release_channel_id, self.carrier_channel) + self.assertEqual(order._get_release_channel_partner_date(), channel_date) picking_out = order.picking_ids self.assertFalse(picking_out.release_channel_id) # Then delivery gets the default channel + # FIXME it's not the expected channel from the user POV self.env["stock.release.channel"].assign_release_channel(picking_out) self.assertEqual(picking_out.release_channel_id, self.default_channel) - def test_sale_order_with_carrier(self): + def test_sale_order_with_carrier_with_channel_date(self): delivery_date = fields.Datetime.now() channel_date_model = self.env["stock.release.channel.partner.date"] channel_date = channel_date_model.create( @@ -69,3 +80,89 @@ def test_sale_order_with_carrier(self): # Then delivery gets the default channel self.env["stock.release.channel"].assign_release_channel(picking_out) self.assertEqual(picking_out.release_channel_id, self.carrier_channel) + + def test_sale_order_with_carrier_without_channel_date(self): + delivery_date = fields.Datetime.now() + # With carrier set: order doesn't detect any specific channel + order = self._create_sale_order(date=delivery_date) + order.carrier_id = self.carrier + self.assertFalse(order.release_channel_id) + self.assertFalse(order._get_release_channel_partner_date()) + # The user is able to set a release channel on the form + with Form(order) as form: + form.release_channel_id = self.carrier_channel + order.action_confirm() + self.assertEqual(order.release_channel_id, self.carrier_channel) + # A specific channel has been created at order confirmation + self.assertTrue(order._get_release_channel_partner_date()) + picking_out = order.picking_ids + self.assertFalse(picking_out.release_channel_id) + # Then delivery then gets the channel defined on the SO + self.env["stock.release.channel"].assign_release_channel(picking_out) + self.assertEqual(picking_out.release_channel_id, self.carrier_channel) + + def test_sale_order_with_incompatible_channel_and_carrier_1(self): + # Case 1: a release channel having a specific channel configured + # is detected, but incompatible with the selected carrier afterwards. + # => unset the detected release channel + delivery_date = fields.Datetime.now() + channel_date_model = self.env["stock.release.channel.partner.date"] + channel_date_model.create( + { + "partner_id": self.customer.id, + "release_channel_id": self.carrier_channel.id, + "date": delivery_date.date(), + } + ) + order = self._create_sale_order(date=delivery_date) + self.assertEqual(order.release_channel_id, self.carrier_channel) + # => select a carrier + order.carrier_id = self.carrier2 + self.assertFalse(order.release_channel_id) + # Confirm the order and check release channel on delivery + order.action_confirm() + self.assertFalse(order.release_channel_id) + self.assertFalse(order._get_release_channel_partner_date()) + picking_out = order.picking_ids + self.assertFalse(picking_out.release_channel_id) + # Then delivery gets the default channel + self.env["stock.release.channel"].assign_release_channel(picking_out) + self.assertEqual(picking_out.release_channel_id, self.default_channel) + + def test_sale_order_with_incompatible_channel_and_carrier_2(self): + # Case 2: a release channel having a specific channel configured + # is detected, but incompatible with the selected carrier afterwards. + # However another specific channel is compatible with the selected carrier. + # => update the selected release channel to be compatible with the + # selected carrier + delivery_date = fields.Datetime.now() + channel_date_model = self.env["stock.release.channel.partner.date"] + channel_date_model.create( + { + "partner_id": self.customer.id, + "release_channel_id": self.carrier_channel.id, + "date": delivery_date.date(), + } + ) + order = self._create_sale_order(date=delivery_date) + self.assertEqual(order.release_channel_id, self.carrier_channel) + channel_date_model = self.env["stock.release.channel.partner.date"] + channel_date = channel_date_model.create( + { + "partner_id": self.customer.id, + "release_channel_id": self.carrier2_channel.id, + "date": delivery_date.date(), + } + ) + # => select a carrier + order.carrier_id = self.carrier2 + self.assertEqual(order.release_channel_id, self.carrier2_channel) + # Confirm the order and check release channel on delivery + order.action_confirm() + self.assertEqual(order.release_channel_id, self.carrier2_channel) + self.assertEqual(order._get_release_channel_partner_date(), channel_date) + picking_out = order.picking_ids + self.assertFalse(picking_out.release_channel_id) + # Then delivery gets the selected channel + self.env["stock.release.channel"].assign_release_channel(picking_out) + self.assertEqual(picking_out.release_channel_id, self.carrier2_channel) From be46bf4bcb5214310072eb552244e84bb58636bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Fri, 29 Nov 2024 17:10:25 +0100 Subject: [PATCH 2/2] fixup! sale_stock_release_channel_partner_by_date_delivery: fix computation of release channel --- .../models/sale_order.py | 15 ++++++++------ .../tests/test_sale_release_channel.py | 20 ++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py b/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py index acd0291f78..dc7ea9f248 100644 --- a/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py +++ b/sale_stock_release_channel_partner_by_date_delivery/models/sale_order.py @@ -22,12 +22,15 @@ def _get_release_channel_id_depends(self): def _get_release_channel_partner_date_domain(self): domain = super()._get_release_channel_partner_date_domain() - if domain and self.carrier_id: - carrier_domain = [ - "|", - ("release_channel_id.carrier_ids", "in", self.carrier_id.ids), - ("release_channel_id.carrier_ids", "=", False), - ] + if domain: + if self.carrier_id: + carrier_domain = [ + ("release_channel_id.carrier_ids", "in", self.carrier_id.ids), + ] + else: + carrier_domain = [ + ("release_channel_id.carrier_ids", "=", False), + ] domain = expression.AND([domain, carrier_domain]) return domain diff --git a/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py b/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py index 08b91d7860..ecfcb8373d 100644 --- a/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py +++ b/sale_stock_release_channel_partner_by_date_delivery/tests/test_sale_release_channel.py @@ -34,10 +34,9 @@ def setUpClass(cls): def test_sale_order_without_carrier_with_channel_date(self): delivery_date = fields.Datetime.now() - # Create one specific channel that is matching the SO even if no carrier is set - # FIXME: not sure about this one, to check how it should behave + # Create one specific channel not matching the SO regarding the carrier channel_date_model = self.env["stock.release.channel.partner.date"] - channel_date = channel_date_model.create( + channel_date_model.create( { "partner_id": self.customer.id, "release_channel_id": self.carrier_channel.id, @@ -46,14 +45,13 @@ def test_sale_order_without_carrier_with_channel_date(self): ) order = self._create_sale_order(date=delivery_date) self.assertFalse(order.carrier_id) - self.assertEqual(order.release_channel_id, self.carrier_channel) + self.assertFalse(order.release_channel_id) order.action_confirm() - self.assertEqual(order.release_channel_id, self.carrier_channel) - self.assertEqual(order._get_release_channel_partner_date(), channel_date) + self.assertFalse(order.release_channel_id) + self.assertFalse(order._get_release_channel_partner_date()) picking_out = order.picking_ids self.assertFalse(picking_out.release_channel_id) # Then delivery gets the default channel - # FIXME it's not the expected channel from the user POV self.env["stock.release.channel"].assign_release_channel(picking_out) self.assertEqual(picking_out.release_channel_id, self.default_channel) @@ -114,7 +112,9 @@ def test_sale_order_with_incompatible_channel_and_carrier_1(self): "date": delivery_date.date(), } ) - order = self._create_sale_order(date=delivery_date) + order = self._create_sale_order( + date=delivery_date, channel=self.carrier_channel + ) self.assertEqual(order.release_channel_id, self.carrier_channel) # => select a carrier order.carrier_id = self.carrier2 @@ -144,7 +144,9 @@ def test_sale_order_with_incompatible_channel_and_carrier_2(self): "date": delivery_date.date(), } ) - order = self._create_sale_order(date=delivery_date) + order = self._create_sale_order( + date=delivery_date, channel=self.carrier_channel + ) self.assertEqual(order.release_channel_id, self.carrier_channel) channel_date_model = self.env["stock.release.channel.partner.date"] channel_date = channel_date_model.create(