Skip to content
Snippets Groups Projects
Commit 8dc8830c authored by Valentin Groues's avatar Valentin Groues :eyes:
Browse files

fixes #97: cannot filter by patient type when visit is set

parent 3166b31c
No related branches found
No related tags found
No related merge requests found
Pipeline #
...@@ -12,28 +12,32 @@ from .models import AppointmentType, Appointment, Visit ...@@ -12,28 +12,32 @@ from .models import AppointmentType, Appointment, Visit
__author__ = 'Valentin Grouès' __author__ = 'Valentin Grouès'
QUERY_VISITS_RANKS = """ QUERY_VISITS_RANKS = """
SELECT DISTINCT(rank() OVER (PARTITION BY subject_id ORDER BY datetime_begin)) AS rank FROM web_visit SELECT DISTINCT(rank() OVER (PARTITION BY subject_id ORDER BY datetime_begin)) AS rank FROM web_visit
""" """
QUERY_APPOINTMENTS_COUNT = """ QUERY_APPOINTMENTS_COUNT = """
SELECT count(*) FROM web_appointment LEFT JOIN (SELECT id, rank() SELECT count(*) FROM web_appointment LEFT JOIN (SELECT id, subject_id, rank()
OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit) OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit)
a ON a.id = web_appointment.visit_id WHERE a.rnk = %s a ON a.id = web_appointment.visit_id
LEFT JOIN web_subject ON web_subject.id = subject_id
WHERE a.rnk = %s
AND EXTRACT(MONTH FROM web_appointment.datetime_when) = %s AND EXTRACT(MONTH FROM web_appointment.datetime_when) = %s
AND EXTRACT(YEAR FROM web_appointment.datetime_when) = %s AND EXTRACT(YEAR FROM web_appointment.datetime_when) = %s
""" """
QUERY_VISITS_ENDED_COUNT = """ QUERY_VISITS_ENDED_COUNT = """
SELECT count(*) FROM (SELECT id, datetime_begin, datetime_end, rank() SELECT count(*) FROM (SELECT id, subject_id, datetime_begin, datetime_end, rank()
OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit) a OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit) a
LEFT JOIN web_subject ON web_subject.id = subject_id
WHERE a.rnk = %s AND WHERE a.rnk = %s AND
EXTRACT(MONTH FROM a.datetime_end) = %s AND EXTRACT(MONTH FROM a.datetime_end) = %s AND
EXTRACT(YEAR FROM a.datetime_end) = %s EXTRACT(YEAR FROM a.datetime_end) = %s
""" """
QUERY_VISITS_STARTED_COUNT = """ QUERY_VISITS_STARTED_COUNT = """
SELECT count(*) FROM (SELECT id, datetime_begin, datetime_end, rank() SELECT count(*) FROM (SELECT id, subject_id, datetime_begin, datetime_end, rank()
OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit) a OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk FROM web_visit) a
LEFT JOIN web_subject ON web_subject.id = subject_id
WHERE a.rnk = %s AND WHERE a.rnk = %s AND
EXTRACT(MONTH FROM a.datetime_begin) = %s AND EXTRACT(MONTH FROM a.datetime_begin) = %s AND
EXTRACT(YEAR FROM a.datetime_begin) = %s EXTRACT(YEAR FROM a.datetime_begin) = %s
...@@ -41,12 +45,15 @@ EXTRACT(YEAR FROM a.datetime_begin) = %s ...@@ -41,12 +45,15 @@ EXTRACT(YEAR FROM a.datetime_begin) = %s
QUERY_APPOINTMENTS = """ QUERY_APPOINTMENTS = """
SELECT types.appointmenttype_id, web_appointment.status, count(*) FROM web_appointment SELECT types.appointmenttype_id, web_appointment.status, count(*) FROM web_appointment
LEFT JOIN (SELECT id, rank() OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk LEFT JOIN (SELECT id, subject_id, rank() OVER (PARTITION BY subject_id ORDER BY datetime_begin) AS rnk
FROM web_visit) a ON a.id = web_appointment.visit_id LEFT JOIN web_appointment_appointment_types types FROM web_visit) a ON a.id = web_appointment.visit_id LEFT JOIN web_appointment_appointment_types types
ON types.appointment_id = web_appointment.id WHERE a.rnk = %s ON types.appointment_id = web_appointment.id
LEFT JOIN web_subject ON web_subject.id = subject_id
WHERE a.rnk = %s
AND EXTRACT(MONTH FROM web_appointment.datetime_when) = %s AND EXTRACT(MONTH FROM web_appointment.datetime_when) = %s
AND EXTRACT(YEAR FROM web_appointment.datetime_when) = %s AND EXTRACT(YEAR FROM web_appointment.datetime_when) = %s
GROUP BY types.appointmenttype_id, web_appointment.status {}
GROUP BY TYPES.appointmenttype_id, web_appointment.status
""" """
...@@ -54,11 +61,11 @@ class StatisticsManager(object): ...@@ -54,11 +61,11 @@ class StatisticsManager(object):
def __init__(self): def __init__(self):
self.appointment_types = {appointment_type.id: appointment_type for appointment_type in self.appointment_types = {appointment_type.id: appointment_type for appointment_type in
AppointmentType.objects.all()} AppointmentType.objects.all()}
self.visits_ranks = self._get_visits_ranks()
self.statuses_list = Appointment.objects.filter().values_list('status', flat=True).distinct().order_by( self.statuses_list = Appointment.objects.filter().values_list('status', flat=True).distinct().order_by(
'status').all() 'status').all()
self.statuses_labels = [Appointment.APPOINTMENT_STATUS_CHOICES.get(status, status.title()) for status in self.statuses_labels = [Appointment.APPOINTMENT_STATUS_CHOICES.get(status, status.title()) for status in
self.statuses_list] self.statuses_list]
self.visits_ranks = self._get_visits_ranks()
def get_statistics_for_month(self, month, year, subject_type=None, visit=None): def get_statistics_for_month(self, month, year, subject_type=None, visit=None):
""" """
...@@ -85,10 +92,12 @@ class StatisticsManager(object): ...@@ -85,10 +92,12 @@ class StatisticsManager(object):
filters_month_year_appointments, filters_month_year_visits_ended, filters_month_year_visits_started = self._build_filters( filters_month_year_appointments, filters_month_year_visits_ended, filters_month_year_visits_started = self._build_filters(
month, subject_type, year) month, subject_type, year)
number_of_appointments = self._get_number_of_appointments(filters_month_year_appointments, visit, month, year) number_of_appointments = self._get_number_of_appointments(filters_month_year_appointments, visit, month, year,
subject_type)
number_of_visits_started = self._get_number_visits_started(filters_month_year_visits_started, visit, month, number_of_visits_started = self._get_number_visits_started(filters_month_year_visits_started, visit, month,
year) year, subject_type)
number_of_visits_ended = self._get_number_visits_ended(filters_month_year_visits_ended, visit, month, year) number_of_visits_ended = self._get_number_visits_ended(filters_month_year_visits_ended, visit, month, year,
subject_type)
general_results["appointments"] = number_of_appointments general_results["appointments"] = number_of_appointments
general_results["visits_started"] = number_of_visits_started general_results["visits_started"] = number_of_visits_started
...@@ -97,7 +106,7 @@ class StatisticsManager(object): ...@@ -97,7 +106,7 @@ class StatisticsManager(object):
results["general"] = general_results results["general"] = general_results
results_appointments = self.get_appointments_per_type_and_status(filters_month_year_appointments, month, results_appointments = self.get_appointments_per_type_and_status(filters_month_year_appointments, month,
self.statuses_list, visit, year) self.statuses_list, visit, year, subject_type)
results["appointments"] = results_appointments results["appointments"] = results_appointments
results["statuses_list"] = self.statuses_labels results["statuses_list"] = self.statuses_labels
appointment_types_values = map(attrgetter('code'), self.appointment_types.values()) appointment_types_values = map(attrgetter('code'), self.appointment_types.values())
...@@ -105,7 +114,8 @@ class StatisticsManager(object): ...@@ -105,7 +114,8 @@ class StatisticsManager(object):
results["appointments_types_list"] = sorted_appointment_types_values results["appointments_types_list"] = sorted_appointment_types_values
return results return results
def get_appointments_per_type_and_status(self, filters_month_year_appointments, month, statuses_list, visit, year): def get_appointments_per_type_and_status(self, filters_month_year_appointments, month, statuses_list, visit, year,
subject_type=None):
if not visit: if not visit:
results_appointments = {} results_appointments = {}
for appointment_type in self.appointment_types.values(): for appointment_type in self.appointment_types.values():
...@@ -123,8 +133,13 @@ class StatisticsManager(object): ...@@ -123,8 +133,13 @@ class StatisticsManager(object):
results_appointments[appointment_type.code] = results_appointment results_appointments[appointment_type.code] = results_appointment
else: else:
results_appointment_set = defaultdict(dict) results_appointment_set = defaultdict(dict)
query = QUERY_APPOINTMENTS
subject_type_clause = ""
if subject_type is not None:
subject_type_clause = " AND web_subject.type = '{}'".format(subject_type)
query = query.format(subject_type_clause)
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute(QUERY_APPOINTMENTS, [visit, month, year]) cursor.execute(query, [visit, month, year])
rows = cursor.fetchall() rows = cursor.fetchall()
for row in rows: for row in rows:
appointment_type_id, status, count = row appointment_type_id, status, count = row
...@@ -141,8 +156,10 @@ class StatisticsManager(object): ...@@ -141,8 +156,10 @@ class StatisticsManager(object):
return results_appointments return results_appointments
@staticmethod @staticmethod
def _get_count_from_filters_or_sql(model, filters, query, visit, month, year): def _get_count_from_filters_or_sql(model, filters, query, visit, month, year, subject_type):
if visit: if visit:
if subject_type is not None:
query += " AND web_subject.type = '{}'".format(subject_type)
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute( cursor.execute(
query, query,
...@@ -153,16 +170,17 @@ class StatisticsManager(object): ...@@ -153,16 +170,17 @@ class StatisticsManager(object):
count = model.objects.filter(filters).count() count = model.objects.filter(filters).count()
return count return count
def _get_number_visits_started(self, filters_month_year_visits_started, visit, month, year): def _get_number_visits_started(self, filters_month_year_visits_started, visit, month, year, subject_type=None):
return self._get_count_from_filters_or_sql(Visit, filters_month_year_visits_started, QUERY_VISITS_STARTED_COUNT, return self._get_count_from_filters_or_sql(Visit, filters_month_year_visits_started, QUERY_VISITS_STARTED_COUNT,
visit, month, year) visit, month, year, subject_type)
def _get_number_visits_ended(self, filters_month_year_visits_ended, visit, month, year): def _get_number_visits_ended(self, filters_month_year_visits_ended, visit, month, year, subject_type=None):
return self._get_count_from_filters_or_sql(Visit, filters_month_year_visits_ended, QUERY_VISITS_ENDED_COUNT, return self._get_count_from_filters_or_sql(Visit, filters_month_year_visits_ended, QUERY_VISITS_ENDED_COUNT,
visit, month, year) visit, month, year, subject_type)
def _get_number_of_appointments(self, filters, visit, month, year): def _get_number_of_appointments(self, filters, visit, month, year, subject_type=None):
return self._get_count_from_filters_or_sql(Appointment, filters, QUERY_APPOINTMENTS_COUNT, visit, month, year) return self._get_count_from_filters_or_sql(Appointment, filters, QUERY_APPOINTMENTS_COUNT, visit, month, year,
subject_type)
@staticmethod @staticmethod
def _build_filters(month, subject_type, year): def _build_filters(month, subject_type, year):
...@@ -187,10 +205,14 @@ class StatisticsManager(object): ...@@ -187,10 +205,14 @@ class StatisticsManager(object):
return filters_month_year_appointments, filters_month_year_visits_ended, filters_month_year_visits_started return filters_month_year_appointments, filters_month_year_visits_ended, filters_month_year_visits_started
@staticmethod @staticmethod
def _get_visits_ranks(): def _get_visits_ranks(subject_type=None):
query = QUERY_VISITS_RANKS
if subject_type is not None:
query += " LEFT JOIN web_subject ON web_subject.id = web_visit.subject_id WHERE web_subject.type = '{}'".format(
subject_type)
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute( cursor.execute(
QUERY_VISITS_RANKS, query,
[]) [])
rows = cursor.fetchall() rows = cursor.fetchall()
......
...@@ -57,6 +57,15 @@ class TestStatistics(TestCase): ...@@ -57,6 +57,15 @@ class TestStatistics(TestCase):
statistics = self.statistics_manager.get_statistics_for_month(self.now.month, self.now.year, subject_type="P") statistics = self.statistics_manager.get_statistics_for_month(self.now.month, self.now.year, subject_type="P")
self.check_statistics(statistics, 0, 0, 0, {"C": [0, 0]}, ['Scheduled']) self.check_statistics(statistics, 0, 0, 0, {"C": [0, 0]}, ['Scheduled'])
def test_get_statistics_for_month_one_appointment_subject_type_and_visit(self):
statistics = self.statistics_manager.get_statistics_for_month(self.now.month, self.now.year, subject_type="C",
visit='1')
self.check_statistics(statistics, 0, 0, 1, {"C": [1, 1]}, ['Scheduled'])
statistics = self.statistics_manager.get_statistics_for_month(self.now.month, self.now.year, subject_type="P",
visit='1')
self.check_statistics(statistics, 0, 0, 0, {"C": [0, 0]}, ['Scheduled'])
def test_get_statistics_for_month_multiple_visits(self): def test_get_statistics_for_month_multiple_visits(self):
second_visit = Visit.objects.create(datetime_begin=self.now + datetime.timedelta(days=-32), second_visit = Visit.objects.create(datetime_begin=self.now + datetime.timedelta(days=-32),
datetime_end=self.now + datetime.timedelta(days=31), datetime_end=self.now + datetime.timedelta(days=31),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment