diff --git a/smash/web/api_views/subject.py b/smash/web/api_views/subject.py index d598319e01a1ace5687fff85bd28cac28d2e8b51..02bd657c15b2fb1ed366f1100b8f1643ae86f3a2 100644 --- a/smash/web/api_views/subject.py +++ b/smash/web/api_views/subject.py @@ -1,7 +1,8 @@ import logging -from django.db.models import Q from django.contrib.auth.decorators import login_required +from django.db.models import Count, Case, When, Min +from django.db.models import Q from django.http import JsonResponse from web.models import Subject, Visit, Appointment @@ -10,8 +11,6 @@ from web.views import e500_error from web.views.notifications import get_subjects_with_no_visit, get_subjects_with_reminder, get_today_midnight_date from web.views.subject import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT -from django.db.models import Count, Case, When, Min - logger = logging.getLogger(__name__) @@ -103,46 +102,58 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction): def filter_by_visit(result, visit_number, visit_type): + # we need to give custom names for filtering params that contain visit_number in it + # because we might want to filter by few visits and they shouldn't collide datetime_begin_filter = 'visit_' + str(visit_number) + '_datetime_begin' datetime_end_filter = 'visit_' + str(visit_number) + '_datetime_end' is_finished_filter = 'visit_' + str(visit_number) + '_is_finished' finished_appointments_filter = 'visit_' + str(visit_number) + '_finished_appointments' scheduled_appointments_filter = 'visit_' + str(visit_number) + '_scheduled_appointments' + # this is hack... instead of providing True/False value this field contain 1/0 value, the problem is that we need + # to provide aggregate function for the interacting parameter + # If we try to assign it with pure Case(When...) (without Count/Min/Max/Avg) we obtain duplicates + # of the results which are later on messing up with the subject list result = result.annotate(**{ - is_finished_filter: Case(When(visit__visit_number=visit_number, then='visit__is_finished')) + is_finished_filter: Count(Case(When(Q(visit__is_finished=True) & Q(visit__visit_number=visit_number), then=1))) }) + + # number of finished appointments result = result.annotate(**{finished_appointments_filter: Count(Case(When( Q(visit__appointment__status=Appointment.APPOINTMENT_STATUS_FINISHED) & Q(visit__visit_number=visit_number), then=1)))}) + # number of scheduled appointments result = result.annotate(**{scheduled_appointments_filter: Count(Case(When( Q(visit__appointment__status=Appointment.APPOINTMENT_STATUS_SCHEDULED) & Q(visit__visit_number=visit_number), then=1)))}) + + # when visit starts result = result.annotate( - **{datetime_begin_filter: Case(When(visit__visit_number=visit_number, then='visit__datetime_begin'))}) + **{datetime_begin_filter: Min(Case(When(visit__visit_number=visit_number, then='visit__datetime_begin')))}) + # when visit finish result = result.annotate( - **{datetime_end_filter: Case(When(visit__visit_number=visit_number, then='visit__datetime_end'))}) + **{datetime_end_filter: Min(Case(When(visit__visit_number=visit_number, then='visit__datetime_end')))}) if visit_type == "DONE": result = result.filter(**{datetime_begin_filter + "__lt": get_today_midnight_date()}). \ - filter(**{is_finished_filter: True}). \ + filter(**{is_finished_filter + "__gt": 0}). \ filter(**{finished_appointments_filter + "__gt": 0}) elif visit_type == "MISSED": result = result.filter(**{datetime_begin_filter + "__lt": get_today_midnight_date()}). \ - filter(**{is_finished_filter: True}). \ + filter(**{is_finished_filter + "__gt": 0}). \ filter(**{finished_appointments_filter: 0}) elif visit_type == "EXCEED": result = result.filter(**{datetime_begin_filter + "__lt": get_today_midnight_date()}). \ - filter(**{is_finished_filter: False}). \ + filter(**{is_finished_filter: 0}). \ filter(**{datetime_end_filter + "__lt": get_today_midnight_date()}) elif visit_type == "IN_PROGRESS": result = result.filter(**{datetime_begin_filter + "__lt": get_today_midnight_date()}). \ - filter(**{is_finished_filter: False}). \ + filter(**{is_finished_filter: 0}). \ filter(**{datetime_end_filter + "__gt": get_today_midnight_date()}). \ filter(**{scheduled_appointments_filter + "__gt": 0}) elif visit_type == "SHOULD_BE_IN_PROGRESS": result = result.filter(**{datetime_begin_filter + "__lt": get_today_midnight_date()}). \ - filter(**{is_finished_filter: False}). \ + filter(**{is_finished_filter: 0}). \ filter(**{datetime_end_filter + "__gt": get_today_midnight_date()}). \ filter(**{scheduled_appointments_filter: 0}) elif visit_type == "UPCOMING": @@ -202,7 +213,6 @@ def get_subjects_filtered(subjects_to_be_filtered, filters): message += str(column) logger.warn(message) - print result.query return result