69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
"""
|
|
Flight service module for handling complex flight operations.
|
|
"""
|
|
|
|
from typing import List
|
|
from simulator.models.flight import Flight
|
|
|
|
|
|
def cancel_flight_cascade(flight: Flight) -> List[Flight]:
|
|
"""
|
|
Cancel a flight and all subsequent flights that depend on it.
|
|
|
|
Returns a list of all canceled flights (including the original).
|
|
"""
|
|
canceled_flights = []
|
|
|
|
def cancel_recursive(current_flight: Flight):
|
|
"""Recursively cancel flights that depend on the current flight."""
|
|
if current_flight.canceled:
|
|
return # Already canceled
|
|
|
|
# Mark flight as canceled
|
|
current_flight.canceled = True
|
|
current_flight.save(update_fields=["canceled"])
|
|
canceled_flights.append(current_flight)
|
|
|
|
# Find all flights that depart from this flight's destination
|
|
# after this flight's arrival time
|
|
dependent_flights = Flight.objects.filter(
|
|
equipment=current_flight.equipment,
|
|
origin=current_flight.destination,
|
|
departure_time__gte=current_flight.arrival_time,
|
|
canceled=False,
|
|
).order_by("departure_time")
|
|
|
|
# Check if any of these flights actually depend on this flight
|
|
for next_flight in dependent_flights:
|
|
# Find what the previous non-canceled flight would be if we cancel current_flight
|
|
previous_non_canceled = (
|
|
Flight.objects.filter(
|
|
equipment=current_flight.equipment,
|
|
departure_time__lt=next_flight.departure_time,
|
|
canceled=False,
|
|
)
|
|
.exclude(pk=current_flight.pk)
|
|
.exclude(pk=next_flight.pk)
|
|
)
|
|
|
|
# Find the one that arrives last
|
|
latest_arrival = None
|
|
previous_flight = None
|
|
for pf in previous_non_canceled:
|
|
if latest_arrival is None or pf.arrival_time > latest_arrival:
|
|
latest_arrival = pf.arrival_time
|
|
previous_flight = pf
|
|
|
|
# Determine where the equipment would be
|
|
if previous_flight:
|
|
expected_location = previous_flight.destination
|
|
else:
|
|
expected_location = current_flight.equipment.base_location
|
|
|
|
# If the next flight can't depart from its origin, cancel it
|
|
if expected_location != next_flight.origin:
|
|
cancel_recursive(next_flight)
|
|
|
|
cancel_recursive(flight)
|
|
return canceled_flights
|