diff --git a/trainvel/api/views.py b/trainvel/api/views.py index 4e031d8..4289c70 100644 --- a/trainvel/api/views.py +++ b/trainvel/api/views.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta, date -from django.db.models import F, Q, Value, When, Case, Exists, OuterRef +from django.db.models import Exists, Case, F, Min, OuterRef, Q, Value, When from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_control from django.views.decorators.http import last_modified @@ -167,6 +167,10 @@ class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet): near_stops = station.get_near_stops() stop_filter = Q(stop_id__in=near_stops.values_list('id', flat=True)) + not_last_stop = ~Q(stop_sequence=StopTime.objects.filter(trip_id=OuterRef('trip_id')) + .filter(pickup_type=PickupType.REGULAR) + .order_by('-stop_sequence')[:1].values_list('stop_sequence')) + def calendar_filter(d: date): return Q(trip__service_id__in=CalendarDate.objects.filter(date=d, exception_type=1) .values_list('service_id')) \ @@ -195,6 +199,7 @@ class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet): return Exists(stop_time_update_qs(d).filter(Q(schedule_relationship=1) | Q(schedule_relationship=3))) qs_today = StopTime.objects.filter(stop_filter) \ + .filter(not_last_stop) \ .annotate(departure_time_real=departure_time_real(query_date)) \ .filter(departure_time_real__gte=query_time) \ .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(query_date)) \ @@ -203,17 +208,19 @@ class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet): .annotate(departure_time_24h=F('departure_time')) qs_yesterday = StopTime.objects.filter(stop_filter) \ + .filter(not_last_stop) \ .annotate(departure_time_real=departure_time_real(query_date)) \ .filter(departure_time_real__gte=time_yesterday) \ - .filter(Q(pickup_type=0) | canceled_filter(yesterday)) \ + .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(yesterday)) \ .filter(calendar_filter(yesterday)) \ .annotate(departure_date=Value(yesterday)) \ .annotate(departure_time_24h=F('departure_time') - timedelta(days=1)) qs_tomorrow = StopTime.objects.filter(stop_filter) \ + .filter(not_last_stop) \ .annotate(departure_time_real=departure_time_real(query_date)) \ .filter(departure_time_real__gte=timedelta(0)) \ - .filter(Q(pickup_type=0) | canceled_filter(tomorrow)) \ + .filter(Q(pickup_type=PickupType.REGULAR) | canceled_filter(tomorrow)) \ .filter(calendar_filter(tomorrow)) \ .annotate(departure_date=Value(tomorrow)) \ .annotate(departure_time_24h=F('departure_time') + timedelta(days=1)) @@ -247,6 +254,10 @@ class NextArrivalsViewSet(viewsets.ReadOnlyModelViewSet): near_stops = station.get_near_stops() stop_filter = Q(stop_id__in=near_stops.values_list('id', flat=True)) + not_first_stop = ~Q(stop_sequence=StopTime.objects.filter(trip_id=OuterRef('trip_id')) + .filter(drop_off_type=PickupType.REGULAR) + .order_by('stop_sequence')[:1].values_list('stop_sequence')) + def calendar_filter(d: date): return Q(trip__service_id__in=CalendarDate.objects.filter(date=d, exception_type=1) .values_list('service_id')) \ @@ -275,25 +286,28 @@ class NextArrivalsViewSet(viewsets.ReadOnlyModelViewSet): return Exists(stop_time_update_qs(d).filter(Q(schedule_relationship=1) | Q(schedule_relationship=3))) qs_today = StopTime.objects.filter(stop_filter) \ + .filter(not_first_stop) \ .annotate(arrival_time_real=arrival_time_real(query_date)) \ .filter(arrival_time_real__gte=query_time) \ - .filter(Q(drop_off_type=0) | canceled_filter(query_date)) \ + .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(query_date)) \ .filter(calendar_filter(query_date)) \ .annotate(arrival_date=Value(query_date)) \ .annotate(arrival_time_24h=F('arrival_time')) qs_yesterday = StopTime.objects.filter(stop_filter) \ + .filter(not_first_stop) \ .annotate(arrival_time_real=arrival_time_real(yesterday)) \ .filter(arrival_time_real__gte=time_yesterday) \ - .filter(Q(drop_off_type=0) | canceled_filter(yesterday)) \ + .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(yesterday)) \ .filter(calendar_filter(yesterday)) \ .annotate(arrival_date=Value(yesterday)) \ .annotate(arrival_time_24h=F('arrival_time') - timedelta(days=1)) qs_tomorrow = StopTime.objects.filter(stop_filter) \ + .filter(not_first_stop) \ .annotate(arrival_time_real=arrival_time_real(tomorrow)) \ .filter(arrival_time_real__gte=timedelta(0)) \ - .filter(Q(drop_off_type=0) | canceled_filter(tomorrow)) \ + .filter(Q(drop_off_type=PickupType.REGULAR) | canceled_filter(tomorrow)) \ .filter(calendar_filter(tomorrow)) \ .annotate(arrival_date=Value(tomorrow)) \ .annotate(arrival_time_24h=F('arrival_time') + timedelta(days=1))