Skip to content
Snippets Groups Projects
Commit cf5e92f8 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '177-subject-required-contact-list' into 'master'

Resolve "Subject required contact list"

Closes #177

See merge request NCER-PD/scheduling-system!105
parents 695d7c5f ba72b7af
No related branches found
No related tags found
1 merge request!105Resolve "Subject required contact list"
Pipeline #
import logging import logging
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Count, Case, When, Min from django.db.models import Count, Case, When, Min, Max
from django.db.models import Q from django.db.models import Q
from django.http import JsonResponse from django.http import JsonResponse
from web.models import StudySubject, Visit, Appointment, Subject, SubjectColumns, StudyColumns, Study from web.models import StudySubject, Visit, Appointment, Subject, SubjectColumns, StudyColumns, Study, ContactAttempt
from web.models.constants import SUBJECT_TYPE_CHOICES, GLOBAL_STUDY_ID from web.models.constants import SUBJECT_TYPE_CHOICES, GLOBAL_STUDY_ID
from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \ from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \
StudySubjectList StudySubjectList
...@@ -51,11 +51,13 @@ def add_column(result, name, field_name, column_list, param, columns_used_in_stu ...@@ -51,11 +51,13 @@ def add_column(result, name, field_name, column_list, param, columns_used_in_stu
@login_required @login_required
def get_subject_columns(request, subject_list_type): def get_subject_columns(request, subject_list_type):
study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0]
study_subject_list = StudySubjectList.objects.filter(study=study, type=subject_list_type) study_subject_lists = StudySubjectList.objects.filter(study=study, type=subject_list_type)
if len(study_subject_list) > 0: if len(study_subject_lists) > 0:
subject_columns = study_subject_list[0].visible_subject_columns study_subject_list = study_subject_lists[0]
study_subject_columns = study_subject_list[0].visible_subject_study_columns subject_columns = study_subject_list.visible_subject_columns
study_subject_columns = study_subject_list.visible_subject_study_columns
else: else:
study_subject_list = StudySubjectList()
subject_columns = SubjectColumns() subject_columns = SubjectColumns()
study_subject_columns = StudyColumns() study_subject_columns = StudyColumns()
...@@ -65,6 +67,8 @@ def get_subject_columns(request, subject_list_type): ...@@ -65,6 +67,8 @@ def get_subject_columns(request, subject_list_type):
add_column(result, "First name", "first_name", subject_columns, "string_filter") add_column(result, "First name", "first_name", subject_columns, "string_filter")
add_column(result, "Last name", "last_name", subject_columns, "string_filter") add_column(result, "Last name", "last_name", subject_columns, "string_filter")
add_column(result, "Date of birth", "date_born", subject_columns, None) add_column(result, "Date of birth", "date_born", subject_columns, None)
add_column(result, "Contact on", "datetime_contact_reminder", study_subject_columns, None)
add_column(result, "Last contact attempt", "last_contact_attempt", study_subject_list, None)
add_column(result, "Location", "default_location", study_subject_columns, "location_filter", study.columns) add_column(result, "Location", "default_location", study_subject_columns, "location_filter", study.columns)
add_column(result, "Deceased", "dead", subject_columns, "yes_no_filter") add_column(result, "Deceased", "dead", subject_columns, "yes_no_filter")
add_column(result, "Resigned", "resigned", study_subject_columns, "yes_no_filter", study.columns) add_column(result, "Resigned", "resigned", study_subject_columns, "yes_no_filter", study.columns)
...@@ -132,6 +136,12 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction): ...@@ -132,6 +136,12 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
result = subjects_to_be_ordered.order_by(order_direction + 'id') result = subjects_to_be_ordered.order_by(order_direction + 'id')
elif order_column == "date_born": elif order_column == "date_born":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__date_born') result = subjects_to_be_ordered.order_by(order_direction + 'subject__date_born')
elif order_column == "datetime_contact_reminder":
result = subjects_to_be_ordered.order_by(order_direction + 'datetime_contact_reminder')
elif order_column == "last_contact_attempt":
# noinspection SpellCheckingInspection
result = subjects_to_be_ordered.annotate(sort_contact_attempt=Max("contactattempt__datetime_when")).order_by(
order_direction + 'sort_contact_attempt')
elif str(order_column).startswith("visit_"): elif str(order_column).startswith("visit_"):
visit_number = get_visit_number_from_visit_x_string(order_column) visit_number = get_visit_number_from_visit_x_string(order_column)
result = order_by_visit(subjects_to_be_ordered, order_direction, visit_number) result = order_by_visit(subjects_to_be_ordered, order_direction, visit_number)
...@@ -340,11 +350,24 @@ def serialize_subject(study_subject): ...@@ -340,11 +350,24 @@ def serialize_subject(study_subject):
"datetime_start": visit.datetime_begin.strftime('%Y-%m-%d'), "datetime_start": visit.datetime_begin.strftime('%Y-%m-%d'),
"datetime_end": visit.datetime_end.strftime('%Y-%m-%d'), "datetime_end": visit.datetime_end.strftime('%Y-%m-%d'),
}) })
contact_reminder = study_subject.datetime_contact_reminder
if contact_reminder is not None:
contact_reminder = contact_reminder.strftime('%Y-%m-%d %H:%M')
contact_attempts = ContactAttempt.objects.filter(subject=study_subject).order_by("-datetime_when")
if len(contact_attempts) > 0:
last_contact_attempt = contact_attempts[0]
last_contact_attempt_string = last_contact_attempt.datetime_when.strftime(
'%Y-%m-%d %H:%M') + "<br/>" + str(last_contact_attempt.worker) + "<br/> Success: " + get_yes_no(
last_contact_attempt.success) + "<br/>" + last_contact_attempt.comment
else:
last_contact_attempt_string = ""
result = { result = {
"first_name": study_subject.subject.first_name, "first_name": study_subject.subject.first_name,
"last_name": study_subject.subject.last_name, "last_name": study_subject.subject.last_name,
"date_born": study_subject.subject.date_born, "date_born": study_subject.subject.date_born,
"datetime_contact_reminder": contact_reminder,
"last_contact_attempt": last_contact_attempt_string,
"nd_number": study_subject.nd_number, "nd_number": study_subject.nd_number,
"screening_number": study_subject.screening_number, "screening_number": study_subject.screening_number,
"default_location": location, "default_location": location,
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-04 13:41
from __future__ import unicode_literals
from django.db import migrations, models
# noinspection PyUnusedLocal
# noinspection PyPep8Naming
def create_default_columns_for_SUBJECT_LIST_REQUIRE_CONTACT(apps, schema_editor):
# We can't import the Study model directly as it may be a newer
# version than this migration expects. We use the historical version.
SubjectColumns = apps.get_model("web", "SubjectColumns")
subject_columns = SubjectColumns.objects.create()
subject_columns.sex = False
subject_columns.first_name = True
subject_columns.last_name = True
subject_columns.languages = False
subject_columns.default_written_communication_language = True
subject_columns.phone_number = False
subject_columns.phone_number_2 = False
subject_columns.phone_number_3 = False
subject_columns.email = False
subject_columns.date_born = False
subject_columns.address = False
subject_columns.postal_code = False
subject_columns.city = False
subject_columns.country = False
subject_columns.dead = False
subject_columns.save()
StudyColumns = apps.get_model("web", "StudyColumns")
study_columns = StudyColumns.objects.create()
study_columns.postponed = False
study_columns.datetime_contact_reminder = True
study_columns.type = False
study_columns.default_location = False
study_columns.flying_team = False
study_columns.screening_number = False
study_columns.nd_number = False
study_columns.mpower_id = False
study_columns.comments = False
study_columns.referral = False
study_columns.diagnosis = False
study_columns.year_of_diagnosis = False
study_columns.information_sent = False
study_columns.pd_in_family = False
study_columns.resigned = False
study_columns.resign_reason = False
study_columns.save()
class Migration(migrations.Migration):
dependencies = [
('web', '0079_auto_20171204_1235'),
]
operations = [
migrations.AlterField(
model_name='studycolumns',
name='datetime_contact_reminder',
field=models.BooleanField(choices=[(True, b'Yes'), (False, b'No')], default=True,
verbose_name=b'Last contact attempt'),
),
migrations.RunSQL('UPDATE web_studycolumns SET datetime_contact_reminder =FALSE WHERE ' +
'NOT(id IN (SELECT columns_id FROM web_study));'),
migrations.RunPython(create_default_columns_for_SUBJECT_LIST_REQUIRE_CONTACT),
migrations.RunSQL('INSERT INTO web_studysubjectlist (' +
'study_id, ' +
'visible_subject_study_columns_id, ' +
'visible_subject_columns_id, ' +
'type) ' +
"SELECT " +
"1, " +
"max(web_studycolumns.id), " +
"max(web_subjectcolumns.id), " +
"'REQUIRE_CONTACT' FROM web_studycolumns, web_subjectcolumns;"),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-04 14:31
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0080_auto_20171204_1341'),
]
operations = [
migrations.AddField(
model_name='studysubjectlist',
name='last_contact_attempt',
field=models.BooleanField(default=False, verbose_name=b'Last contact attempt'),
),
migrations.RunSQL("UPDATE web_studysubjectlist SET last_contact_attempt=TRUE WHERE type='REQUIRE_CONTACT'"),
]
...@@ -77,3 +77,8 @@ class StudyColumns(models.Model): ...@@ -77,3 +77,8 @@ class StudyColumns(models.Model):
default=True, default=True,
verbose_name='Resign reason' verbose_name='Resign reason'
) )
datetime_contact_reminder = models.BooleanField(choices=BOOL_CHOICES,
default=True,
verbose_name='Last contact attempt'
)
...@@ -36,6 +36,11 @@ class StudySubjectList(models.Model): ...@@ -36,6 +36,11 @@ class StudySubjectList(models.Model):
null=False, null=False,
) )
last_contact_attempt = models.BooleanField(
default=False,
verbose_name='Last contact attempt'
)
type = models.CharField(max_length=50, type = models.CharField(max_length=50,
choices=SUBJECT_LIST_CHOICES.items(), choices=SUBJECT_LIST_CHOICES.items(),
verbose_name='Type o list', verbose_name='Type o list',
......
...@@ -14,7 +14,7 @@ from web.models.constants import GLOBAL_STUDY_ID ...@@ -14,7 +14,7 @@ from web.models.constants import GLOBAL_STUDY_ID
from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \ from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \
StudySubjectList StudySubjectList
from web.tests.functions import create_study_subject, create_worker, create_get_suffix, create_visit, \ from web.tests.functions import create_study_subject, create_worker, create_get_suffix, create_visit, \
create_appointment, create_empty_study_columns create_appointment, create_empty_study_columns, create_contact_attempt
from web.views.notifications import get_today_midnight_date from web.views.notifications import get_today_midnight_date
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -57,6 +57,18 @@ class TestApi(TestCase): ...@@ -57,6 +57,18 @@ class TestApi(TestCase):
columns = json.loads(response.content)['columns'] columns = json.loads(response.content)['columns']
self.assertTrue(len(columns) >= 20) self.assertTrue(len(columns) >= 20)
def test_get_columns_for_require_contact(self):
response = self.client.get(
reverse('web.api.subjects.columns', kwargs={'subject_list_type': SUBJECT_LIST_REQUIRE_CONTACT}))
self.assertEqual(response.status_code, 200)
columns = json.loads(response.content)['columns']
visible_columns = 0
for column in columns:
if column["visible"]:
visible_columns += 1
self.assertTrue(visible_columns < 20)
def test_get_columns_when_no_list_is_available(self): def test_get_columns_when_no_list_is_available(self):
StudySubjectList.objects.all().delete() StudySubjectList.objects.all().delete()
response = self.client.get( response = self.client.get(
...@@ -179,6 +191,17 @@ class TestApi(TestCase): ...@@ -179,6 +191,17 @@ class TestApi(TestCase):
self.check_subject_ordered("date_born", [subject, subject2]) self.check_subject_ordered("date_born", [subject, subject2])
def test_subjects_sort_contact_on(self):
subject = self.study_subject
subject.datetime_contact_reminder = get_today_midnight_date()
subject.save()
subject2 = create_study_subject(2)
subject2.datetime_contact_reminder = get_today_midnight_date() + datetime.timedelta(days=1)
subject2.save()
self.check_subject_ordered("datetime_contact_reminder", [subject, subject2])
def test_subjects_sort_default_location(self): def test_subjects_sort_default_location(self):
subject = self.study_subject subject = self.study_subject
...@@ -323,6 +346,8 @@ class TestApi(TestCase): ...@@ -323,6 +346,8 @@ class TestApi(TestCase):
def test_serialize_subject(self): def test_serialize_subject(self):
study_subject = self.study_subject study_subject = self.study_subject
study_subject.subject.dead = True study_subject.subject.dead = True
create_contact_attempt(subject=study_subject)
create_visit(subject=study_subject)
subject_json = serialize_subject(study_subject) subject_json = serialize_subject(study_subject)
self.assertEqual("YES", subject_json["dead"]) self.assertEqual("YES", subject_json["dead"])
...@@ -456,3 +481,11 @@ class TestApi(TestCase): ...@@ -456,3 +481,11 @@ class TestApi(TestCase):
def test_invalid_order(self): def test_invalid_order(self):
self.check_subject_ordered(None, [self.study_subject]) self.check_subject_ordered(None, [self.study_subject])
def test_subjects_ordered_by_contact_attempt(self):
subject = self.study_subject
subject2 = create_study_subject(2)
create_contact_attempt(subject=subject)
self.check_subject_ordered("last_contact_attempt", [subject, subject2])
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