From e81e9c79920d7e657d4d39ec5f6d3cbb1661e7ca Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 11 Dec 2023 21:12:34 +0100 Subject: [PATCH 1/3] [FIX] joint_buying_base : Use Case : product availability is after the truck has left, but before it passes through --- .../demo/joint_buying_transport_request.xml | 12 ++++++++++++ .../tests/test_joint_buying_wizard_find_route.py | 12 ++++++++++++ .../wizards/joint_buying_wizard_find_route.py | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/joint_buying_base/demo/joint_buying_transport_request.xml b/joint_buying_base/demo/joint_buying_transport_request.xml index 16161631..f4f66103 100644 --- a/joint_buying_base/demo/joint_buying_transport_request.xml +++ b/joint_buying_base/demo/joint_buying_transport_request.xml @@ -35,6 +35,18 @@ ]]> + + + + + 111 + 22 + + + diff --git a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py index d20a305a..d64fae05 100644 --- a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py +++ b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py @@ -62,6 +62,18 @@ def test_24_transport_request_vev_che_week_2(self): "computed", ) + def test_25_transport_request_vev_LSE_week_1(self): + """Complex case: product availability is after the truck has left, + but before it passes through""" + self._verify_tour_lines_computation( + "joint_buying_base.request_vev_lse_week_1", + [ + "joint_buying_base.tour_lyon_loire_1_line_4", # VEV->CDA + "joint_buying_base.tour_lyon_loire_1_line_6", # CDA->LSE + ], + "computed", + ) + def _verify_tour_lines_computation( self, request_xml_id, tour_line_xml_ids, expected_state ): diff --git a/joint_buying_base/wizards/joint_buying_wizard_find_route.py b/joint_buying_base/wizards/joint_buying_wizard_find_route.py index ad1d2cef..f132e771 100644 --- a/joint_buying_base/wizards/joint_buying_wizard_find_route.py +++ b/joint_buying_base/wizards/joint_buying_wizard_find_route.py @@ -206,7 +206,7 @@ def _populate_tree(self, transport_request): ) tours = self.env["joint.buying.tour"].search( [ - ("start_date", ">=", transport_request.availability_date), + ("end_date", ">=", transport_request.availability_date), ("start_date", "<=", max_date), ], order="start_date", From 3ea731e15623317654a9fbae90e2e9b0f69f07ab Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 11 Dec 2023 21:34:02 +0100 Subject: [PATCH 2/3] [REF] joint_buying_base : allow 8 weeks for the transport of products. Add according test + [REF] add comments in test --- .../test_joint_buying_wizard_find_route.py | 58 ++++++++++++++----- .../wizards/joint_buying_wizard_find_route.py | 2 +- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py index d64fae05..b2b3eb8d 100644 --- a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py +++ b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py @@ -2,6 +2,7 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from datetime import timedelta from odoo.tests import tagged @@ -14,7 +15,9 @@ def test_20_transport_request_vev_cda_week_1(self): """simplest case: direct route""" self._verify_tour_lines_computation( "joint_buying_base.request_vev_cda_week_1", - ["joint_buying_base.tour_lyon_loire_1_line_4"], + [ + "joint_buying_base.tour_lyon_loire_1_line_4", # VEV->CDA + ], "computed", ) @@ -23,10 +26,10 @@ def test_21_transport_request_vev_che_week_1(self): self._verify_tour_lines_computation( "joint_buying_base.request_vev_che_week_1", [ - "joint_buying_base.tour_lyon_loire_1_line_4", - "joint_buying_base.tour_lyon_loire_1_line_6", - "joint_buying_base.tour_lyon_drome_1_line_2", - "joint_buying_base.tour_lyon_drome_1_line_4", + "joint_buying_base.tour_lyon_loire_1_line_4", # VEV->CDA + "joint_buying_base.tour_lyon_loire_1_line_6", # CDA->LSE + "joint_buying_base.tour_lyon_drome_1_line_2", # LSE->C3P + "joint_buying_base.tour_lyon_drome_1_line_4", # C3P->CHE ], "computed", ) @@ -36,10 +39,10 @@ def test_22_transport_request_vev_edc_1(self): self._verify_tour_lines_computation( "joint_buying_base.request_vev_edc_week_1", [ - "joint_buying_base.tour_lyon_loire_1_line_4", - "joint_buying_base.tour_lyon_loire_1_line_6", - "joint_buying_base.tour_lyon_savoie_1_line_2", - "joint_buying_base.tours_savoie_1_line_2", + "joint_buying_base.tour_lyon_loire_1_line_4", # VEV->CDA + "joint_buying_base.tour_lyon_loire_1_line_6", # CDA->LSE + "joint_buying_base.tour_lyon_savoie_1_line_2", # LSE->Cognin + "joint_buying_base.tours_savoie_1_line_2", # Cognin->EDC ], "computed", ) @@ -55,14 +58,14 @@ def test_24_transport_request_vev_che_week_2(self): self._verify_tour_lines_computation( "joint_buying_base.request_vev_che_week_2", [ - "joint_buying_base.tour_lyon_loire_3_line_2", - "joint_buying_base.tour_lyon_drome_2_line_2", - "joint_buying_base.tour_lyon_drome_2_line_4", + "joint_buying_base.tour_lyon_loire_3_line_2", # VEV->LSE + "joint_buying_base.tour_lyon_drome_2_line_2", # LSE->C3P + "joint_buying_base.tour_lyon_drome_2_line_4", # C3P->CHE ], "computed", ) - def test_25_transport_request_vev_LSE_week_1(self): + def test_25_transport_request_vev_lse_week_1(self): """Complex case: product availability is after the truck has left, but before it passes through""" self._verify_tour_lines_computation( @@ -74,6 +77,35 @@ def test_25_transport_request_vev_LSE_week_1(self): "computed", ) + def test_26_transport_request_vev_cda_week_1(self): + """Simple case: Check maximum duration to deliver""" + request = self.env.ref("joint_buying_base.request_vev_lse_week_1") + tour = self.env.ref("joint_buying_base.tour_lyon_loire_1") + max_duration = self.env[ + "joint.buying.wizard.find.route" + ]._MAX_TRANSPORT_DURATION + + # Max duration - 1 should success + request.manual_availability_date = tour.start_date - timedelta( + days=max_duration - 1 + ) + self._verify_tour_lines_computation( + "joint_buying_base.request_vev_lse_week_1", + [ + "joint_buying_base.tour_lyon_loire_1_line_4", # VEV->CDA + "joint_buying_base.tour_lyon_loire_1_line_6", # CDA->LSE + ], + "computed", + ) + + # Max duration + 1 should fail + request.manual_availability_date = tour.start_date - timedelta( + days=max_duration + 1 + ) + self._verify_tour_lines_computation( + "joint_buying_base.request_vev_lse_week_1", [], "not_computable" + ) + def _verify_tour_lines_computation( self, request_xml_id, tour_line_xml_ids, expected_state ): diff --git a/joint_buying_base/wizards/joint_buying_wizard_find_route.py b/joint_buying_base/wizards/joint_buying_wizard_find_route.py index f132e771..b1a0a3ed 100644 --- a/joint_buying_base/wizards/joint_buying_wizard_find_route.py +++ b/joint_buying_base/wizards/joint_buying_wizard_find_route.py @@ -17,7 +17,7 @@ class JointBuyingWizardFindRoute(models.TransientModel): _description = "Joint Buying Wizard Find Route" # 30 Days - _MAX_TRANSPORT_DURATION = 30 + _MAX_TRANSPORT_DURATION = 8 * 7 transport_request_id = fields.Many2one( string="Transport Request", From 3ddf74880e21f91dd4458d8bd12dab88a99400bb Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 12 Dec 2023 09:02:59 +0100 Subject: [PATCH 3/3] [REF] joint_buying_base : replace hardcoded value _MAX_TRANSPORT_DURATION by an ir config parameter : joint_buying_base.tour_max_duration. [REF] joint_buying_base : replace value 30 by 56 (8 weeks) --- joint_buying_base/data/ir_config_parameter.xml | 5 +++++ .../tests/test_joint_buying_wizard_find_route.py | 14 +++++++++----- .../wizards/joint_buying_wizard_find_route.py | 10 ++++++---- .../migrations/12.0.4.0.0/post-migration.py | 7 ++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/joint_buying_base/data/ir_config_parameter.xml b/joint_buying_base/data/ir_config_parameter.xml index 8385d4c2..36c43962 100644 --- a/joint_buying_base/data/ir_config_parameter.xml +++ b/joint_buying_base/data/ir_config_parameter.xml @@ -11,4 +11,9 @@ Your Group Name + + joint_buying_base.tour_max_duration + 56 + + diff --git a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py index b2b3eb8d..3bc950e5 100644 --- a/joint_buying_base/tests/test_joint_buying_wizard_find_route.py +++ b/joint_buying_base/tests/test_joint_buying_wizard_find_route.py @@ -11,6 +11,13 @@ @tagged("post_install", "-at_install", "find_route") class TestJointBuyingWizardFindRoute(TestAbstract): + def setUp(self): + super().setUp() + self.IrConfigParameter = self.env["ir.config_parameter"].sudo() + self.max_duration = int( + self.IrConfigParameter.get_param("joint_buying_base.tour_max_duration", 0) + ) + def test_20_transport_request_vev_cda_week_1(self): """simplest case: direct route""" self._verify_tour_lines_computation( @@ -81,13 +88,10 @@ def test_26_transport_request_vev_cda_week_1(self): """Simple case: Check maximum duration to deliver""" request = self.env.ref("joint_buying_base.request_vev_lse_week_1") tour = self.env.ref("joint_buying_base.tour_lyon_loire_1") - max_duration = self.env[ - "joint.buying.wizard.find.route" - ]._MAX_TRANSPORT_DURATION # Max duration - 1 should success request.manual_availability_date = tour.start_date - timedelta( - days=max_duration - 1 + days=self.max_duration - 1 ) self._verify_tour_lines_computation( "joint_buying_base.request_vev_lse_week_1", @@ -100,7 +104,7 @@ def test_26_transport_request_vev_cda_week_1(self): # Max duration + 1 should fail request.manual_availability_date = tour.start_date - timedelta( - days=max_duration + 1 + days=self.max_duration + 1 ) self._verify_tour_lines_computation( "joint_buying_base.request_vev_lse_week_1", [], "not_computable" diff --git a/joint_buying_base/wizards/joint_buying_wizard_find_route.py b/joint_buying_base/wizards/joint_buying_wizard_find_route.py index b1a0a3ed..2513b5de 100644 --- a/joint_buying_base/wizards/joint_buying_wizard_find_route.py +++ b/joint_buying_base/wizards/joint_buying_wizard_find_route.py @@ -16,9 +16,6 @@ class JointBuyingWizardFindRoute(models.TransientModel): _name = "joint.buying.wizard.find.route" _description = "Joint Buying Wizard Find Route" - # 30 Days - _MAX_TRANSPORT_DURATION = 8 * 7 - transport_request_id = fields.Many2one( string="Transport Request", comodel_name="joint.buying.transport.request", @@ -201,8 +198,13 @@ def get_nodes_optimal_road(self, tree, arrival_partner_id): @api.model def _populate_tree(self, transport_request): # Get all the tours subsequent to the transport request for a given period of time + max_duration = int( + self.env["ir.config_parameter"] + .sudo() + .get_param("joint_buying_base.tour_max_duration", 0) + ) max_date = transport_request.availability_date + datetime.timedelta( - days=self._MAX_TRANSPORT_DURATION + days=max_duration ) tours = self.env["joint.buying.tour"].search( [ diff --git a/joint_buying_product/migrations/12.0.4.0.0/post-migration.py b/joint_buying_product/migrations/12.0.4.0.0/post-migration.py index fbd50373..f5b011f7 100644 --- a/joint_buying_product/migrations/12.0.4.0.0/post-migration.py +++ b/joint_buying_product/migrations/12.0.4.0.0/post-migration.py @@ -31,9 +31,10 @@ def migrate(env, version): partners.write({"joint_buying_is_durable_storage": True}) # Create Transport Requests for recent joint buying purchase orders - min_deposit_date = datetime.today() + timedelta( - days=-env["joint.buying.wizard.find.route"]._MAX_TRANSPORT_DURATION - ) + icp = env["ir.config_parameter"].sudo() + max_duration = int(icp.get_param("joint_buying_base.tour_max_duration", 0)) + + min_deposit_date = datetime.today() + timedelta(days=-max_duration) orders = ( env["joint.buying.purchase.order.grouped"] .search([("deposit_date", ">", min_deposit_date.strftime("%Y-%m-%d %H:%M"))])