diff --git a/python/gmpro/json/cfr_json.py b/python/gmpro/json/cfr_json.py index 5c457b41..735e0e84 100644 --- a/python/gmpro/json/cfr_json.py +++ b/python/gmpro/json/cfr_json.py @@ -121,6 +121,7 @@ class VisitRequest(TypedDict, total=False): timeWindows: list[TimeWindow] duration: DurationString cost: float + avoidUTurns: bool tags: list[str] @@ -235,6 +236,7 @@ class Visit(TypedDict, total=False): detour: str isPickup: bool visitRequestIndex: int + injectedSolutionLocationToken: int class EncodedPolyline(TypedDict, total=False): diff --git a/python/gmpro/two_step_routing/two_step_routing.py b/python/gmpro/two_step_routing/two_step_routing.py index 83aeb87e..c0b92007 100644 --- a/python/gmpro/two_step_routing/two_step_routing.py +++ b/python/gmpro/two_step_routing/two_step_routing.py @@ -1032,6 +1032,7 @@ def _integrate_global_skipped_shipments(self) -> None: visit_detour=None, is_pickup=None, visit_request_index=None, + injected_solution_location_token=None, ) ) case "p": @@ -1185,6 +1186,9 @@ def _integrate_global_routes(self) -> None: visit_detour = global_visit["detour"] is_pickup = global_visit.get("isPickup", False) visit_request_index = global_visit.get("visitRequestIndex", 0) + injected_solution_location_token = global_visit.get( + "injectedSolutionLocationToken" + ) match visit_type: case "s": self._add_integrated_global_shipment( @@ -1194,6 +1198,7 @@ def _integrate_global_routes(self) -> None: visit_detour=visit_detour, is_pickup=is_pickup, visit_request_index=visit_request_index, + injected_solution_location_token=injected_solution_location_token, ) case "p": self._integrate_unmodified_local_route( @@ -1419,6 +1424,7 @@ def _integrate_refined_local_route( # delivery visit request. is_pickup=False, visit_request_index=0, + injected_solution_location_token=None, ) def _integrate_unmodified_local_route( @@ -1484,6 +1490,7 @@ def _integrate_unmodified_local_route( visit_detour=visit_detour, is_pickup=None if add_to_visits is None else False, visit_request_index=None if add_to_visits is None else 0, + injected_solution_location_token=None, ) def _add_integrated_global_shipment( @@ -1496,6 +1503,7 @@ def _add_integrated_global_shipment( # visits are always delivery-only, and they have exactly one delivery # visit request. visit_request_index: int | None, + injected_solution_location_token: int | None, is_pickup: bool | None, ) -> int: """Adds `shipment` to the integrated request and returns its index. @@ -1509,6 +1517,8 @@ def _add_integrated_global_shipment( visit_detour: The detour of the visit for the new shipment in the integrated global model. Must be None exactly when `add_to_visits` is None. + injected_solution_location_token: The location token associated with this + visit or None, if no token is needed. Returns: The index of the newly added integrated shipment. @@ -1537,6 +1547,10 @@ def _add_integrated_global_shipment( "shipmentLabel": shipment.get("label", ""), "isPickup": is_pickup, } + if injected_solution_location_token is not None: + visit["injectedSolutionLocationToken"] = ( + injected_solution_location_token + ) if visit_request_index: visit["visitRequestIndex"] = visit_request_index if is_pickup: