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

Merge branch '176-subjects-without-visit-list' into 'master'

Resolve "Subjects without visit list"

Closes #176

See merge request NCER-PD/scheduling-system!106
parents cf5e92f8 c049563a
No related branches found
No related tags found
1 merge request!106Resolve "Subjects without visit list"
Pipeline #
......@@ -16,7 +16,7 @@ Including another URLconf
from django.conf.urls import url
from web.api_views import worker, location, subject, appointment_type, appointment, configuration, daily_planning, \
redcap
redcap, flying_team
urlpatterns = [
# appointments
......@@ -41,6 +41,9 @@ urlpatterns = [
# locations
url(r'^locations$', location.locations, name='web.api.locations'),
# flying_teams
url(r'^flying_teams$', flying_team.flying_teams, name='web.api.flying_teams'),
# worker data
url(r'^specializations$', worker.specializations, name='web.api.specializations'),
url(r'^units$', worker.units, name='web.api.units'),
......
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from web.models import FlyingTeam
@login_required
def flying_teams(request):
all_flying_teams = FlyingTeam.objects.all()
data = []
for flying_team in all_flying_teams:
data.append({"id": flying_team.id, "name": flying_team.place})
return JsonResponse({
"flying_teams": data
})
......@@ -31,12 +31,14 @@ def referrals(request):
})
def add_column(result, name, field_name, column_list, param, columns_used_in_study=None):
def add_column(result, name, field_name, column_list, param, columns_used_in_study=None, visible_param=None):
add = True
if columns_used_in_study:
add = getattr(columns_used_in_study, field_name)
if add:
if column_list is None:
if visible_param is not None:
visible = visible_param
elif column_list is None:
visible = True
else:
visible = getattr(column_list, field_name)
......@@ -67,23 +69,22 @@ def get_subject_columns(request, subject_list_type):
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, "Date of birth", "date_born", subject_columns, None)
add_column(result, "Contact on", "datetime_contact_reminder", study_subject_columns, None)
add_column(result, "Contact on", "datetime_contact_reminder", study_subject_columns, None, study.columns)
add_column(result, "Last contact attempt", "last_contact_attempt", study_subject_list, None)
add_column(result, "Referred by", "referral", study_subject_columns, "string_filter", study.columns)
add_column(result, "Location", "default_location", study_subject_columns, "location_filter", study.columns)
add_column(result, "Flying team location", "flying_team", study_subject_columns, "flying_team_filter",
study.columns)
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, "Postponed", "postponed", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Info sent", "information_sent", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Type", "type", study_subject_columns, "type_filter", study.columns)
add_column(result, "Edit", "edit", None, None)
add_column(result, "Visit 1", "visit_1", None, "visit_filter")
add_column(result, "Visit 2", "visit_2", None, "visit_filter")
add_column(result, "Visit 3", "visit_3", None, "visit_filter")
add_column(result, "Visit 4", "visit_4", None, "visit_filter")
add_column(result, "Visit 5", "visit_5", None, "visit_filter")
add_column(result, "Visit 6", "visit_6", None, "visit_filter")
add_column(result, "Visit 7", "visit_7", None, "visit_filter")
add_column(result, "Visit 8", "visit_8", None, "visit_filter")
for visit_number in range(1, 9):
visit_key = "visit_" + str(visit_number)
add_column(result, "Visit " + str(visit_number), visit_key, None, "visit_filter",
visible_param=study_subject_list.visits)
return JsonResponse({"columns": result})
......@@ -118,10 +119,14 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
result = subjects_to_be_ordered.order_by(order_direction + 'subject__last_name')
elif order_column == "nd_number":
result = subjects_to_be_ordered.order_by(order_direction + 'nd_number')
elif order_column == "referral":
result = subjects_to_be_ordered.order_by(order_direction + 'referral')
elif order_column == "screening_number":
result = subjects_to_be_ordered.order_by(order_direction + 'screening_number')
elif order_column == "default_location":
result = subjects_to_be_ordered.order_by(order_direction + 'default_location')
elif order_column == "flying_team":
result = subjects_to_be_ordered.order_by(order_direction + 'flying_team')
elif order_column == "dead":
result = subjects_to_be_ordered.order_by(order_direction + 'subject__dead')
elif order_column == "resigned":
......@@ -226,6 +231,8 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
result = result.filter(subject__last_name__icontains=value)
elif column == "nd_number":
result = result.filter(nd_number__icontains=value)
elif column == "referral":
result = result.filter(referral__icontains=value)
elif column == "screening_number":
result = result.filter(screening_number__icontains=value)
elif column == "dead":
......@@ -238,6 +245,8 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
result = result.filter(information_sent=(value == "true"))
elif column == "default_location":
result = result.filter(default_location=value)
elif column == "flying_team":
result = result.filter(flying_team=value)
elif column == "type":
result = result.filter(type=value)
elif str(column).startswith("visit_"):
......@@ -323,6 +332,9 @@ def serialize_subject(study_subject):
location = ""
if study_subject.default_location is not None:
location = study_subject.default_location.name
flying_team = ""
if study_subject.flying_team is not None:
flying_team = unicode(study_subject.flying_team)
visits = Visit.objects.filter(subject=study_subject).order_by('visit_number')
serialized_visits = []
for visit in visits:
......@@ -370,7 +382,9 @@ def serialize_subject(study_subject):
"last_contact_attempt": last_contact_attempt_string,
"nd_number": study_subject.nd_number,
"screening_number": study_subject.screening_number,
"referral": study_subject.referral,
"default_location": location,
"flying_team": flying_team,
"dead": get_yes_no(study_subject.subject.dead),
"resigned": get_yes_no(study_subject.resigned),
"postponed": get_yes_no(study_subject.postponed),
......
......@@ -5,16 +5,81 @@ from __future__ import unicode_literals
from django.db import migrations, models
# noinspection PyUnusedLocal
# noinspection PyPep8Naming
def create_default_columns_for_SUBJECT_LIST_NO_VISIT(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 = False
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 = False
study_columns.type = True
study_columns.default_location = True
study_columns.flying_team = True
study_columns.screening_number = True
study_columns.nd_number = False
study_columns.mpower_id = False
study_columns.comments = False
study_columns.referral = True
study_columns.diagnosis = False
study_columns.year_of_diagnosis = False
study_columns.information_sent = True
study_columns.pd_in_family = False
study_columns.resigned = False
study_columns.resign_reason = False
study_columns.save()
class Migration(migrations.Migration):
dependencies = [
('web', '0080_auto_20171204_1341'),
]
operations = [
migrations.AddField(
model_name='studysubjectlist',
name='visits',
field=models.BooleanField(default=True, verbose_name=b'Visits summary'),
),
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'"),
migrations.RunPython(create_default_columns_for_SUBJECT_LIST_NO_VISIT),
migrations.RunSQL('INSERT INTO web_studysubjectlist (' +
'study_id, ' +
'visible_subject_study_columns_id, ' +
'visible_subject_columns_id, ' +
'last_contact_attempt,'
'visits,'
'type) ' +
"SELECT " +
"1, " +
"max(web_studycolumns.id), " +
"max(web_subjectcolumns.id), " +
"false, " +
"false, " +
"'NO_VISIT' FROM web_studycolumns, web_subjectcolumns;"),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-04 16:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0081_studysubjectlist_last_contact_attempt'),
]
operations = [
]
......@@ -41,6 +41,11 @@ class StudySubjectList(models.Model):
verbose_name='Last contact attempt'
)
visits = models.BooleanField(
default=True,
verbose_name='Visits summary'
)
type = models.CharField(max_length=50,
choices=SUBJECT_LIST_CHOICES.items(),
verbose_name='Type o list',
......
......@@ -128,9 +128,9 @@ function createVisibilityCheckboxes(checkboxesElement, columns) {
function createSubjectsTable(params) {
var tableElement = params.tableElement;
var worker_locations = params.worker_locations;
var getSubjectEditUrl = params.getSubjectEditUrl;
var subject_types_url = params.subject_types_url;
var locations_url = params.locations_url;
var flying_teams_url = params.flying_teams_url;
var subjects_url = params.subjects_url;
var columnsDefinition = params.columns;
......@@ -173,8 +173,24 @@ function createSubjectsTable(params) {
select.val(worker_locations[0].id);
}
});
});
$(tableElement).find('tfoot div[name="flying_team_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
var select = $('select', obj);
$.get(flying_teams_url, function (data) {
$.each(data.flying_teams, function (index, flying_team) {
select.append('<option value="' + flying_team.id + '">' + flying_team.name + '</option>');
});
if (worker_locations.length === 1) {
select.val(worker_locations[0].id);
}
});
});
$(tableElement).find('tfoot div[name="type_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
......
......@@ -58,6 +58,7 @@
subject_types_url: "{% url 'web.api.subject_types' %}",
locations_url: "{% url 'web.api.locations' %}",
subjects_url: "{% url 'web.api.subjects' list_type %}",
flying_teams_url: "{% url 'web.api.flying_teams' %}",
tableElement: document.getElementById("table"),
columns: getColumns(data.columns, getSubjectEditUrl),
checkboxesElement: document.getElementById("visible-column-checkboxes")
......
# coding=utf-8
import json
from django.contrib.auth.models import User
from django.test import Client
from django.test import TestCase
from django.urls import reverse
from web.tests.functions import create_worker, create_flying_team
class TestFlyingTeamApi(TestCase):
def setUp(self):
self.client = Client()
username = 'piotr'
password = 'top_secret'
self.user = User.objects.create_user(
username=username, email='jacob@bla', password=password)
self.worker = create_worker(self.user)
self.client.login(username=username, password=password)
def test_flying_teams(self):
flying_team_name = "some flying_team"
response = self.client.get(reverse('web.api.flying_teams'))
self.assertEqual(response.status_code, 200)
create_flying_team(flying_team_name)
response = self.client.get(reverse('web.api.flying_teams'))
flying_teams = json.loads(response.content)['flying_teams']
found = False
for flying_team in flying_teams:
if flying_team['name'] == flying_team_name:
found = True
self.assertTrue(found)
......@@ -10,11 +10,11 @@ from django.urls import reverse
from web.api_views.subject import get_subjects_order, get_subjects_filtered, serialize_subject
from web.models import StudySubject, Appointment, Study
from web.models.constants import GLOBAL_STUDY_ID
from web.models.constants import GLOBAL_STUDY_ID, SUBJECT_TYPE_CHOICES_PATIENT, SUBJECT_TYPE_CHOICES_CONTROL
from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \
StudySubjectList
from web.tests.functions import create_study_subject, create_worker, create_get_suffix, create_visit, \
create_appointment, create_empty_study_columns, create_contact_attempt
create_appointment, create_empty_study_columns, create_contact_attempt, create_flying_team
from web.views.notifications import get_today_midnight_date
logger = logging.getLogger(__name__)
......@@ -207,6 +207,13 @@ class TestApi(TestCase):
self.check_subject_ordered("default_location", [subject])
def test_subjects_sort_flying_team(self):
subject = self.study_subject
subject.flying_team = create_flying_team()
subject.save()
self.check_subject_ordered("flying_team", [subject])
def test_subjects_sort_screening_number(self):
subject = self.study_subject
subject.screening_number = "PPP"
......@@ -229,6 +236,17 @@ class TestApi(TestCase):
self.check_subject_ordered("last_name", [subject, subject2])
def test_subjects_sort_referral(self):
subject = self.study_subject
subject.referral = "XXX"
subject.save()
subject2 = create_study_subject(2)
subject2.referral = "YYY"
subject2.save()
self.check_subject_ordered("referral", [subject, subject2])
def test_subjects_sort_dead(self):
study_subject = self.study_subject
study_subject.subject.dead = True
......@@ -337,15 +355,50 @@ class TestApi(TestCase):
self.check_subject_filtered([["default_location", str(subject.default_location.id)]], [subject])
self.check_subject_filtered([["default_location", "-1"]], [])
def test_subjects_filter_flying_team(self):
subject = self.study_subject
subject.flying_team = create_flying_team()
subject.save()
self.check_subject_filtered([["flying_team", str(subject.flying_team.id)]], [subject])
self.check_subject_filtered([["flying_team", "-1"]], [])
def test_subjects_filter_information_sent(self):
subject = self.study_subject
subject.information_sent = True
subject.save()
self.check_subject_filtered([["information_sent", "true"]], [subject])
self.check_subject_filtered([["information_sent", "false"]], [])
def test_subjects_filter_referral(self):
subject = self.study_subject
subject.referral = "xyz"
subject.save()
self.check_subject_filtered([["referral", "xyz"]], [subject])
self.check_subject_filtered([["referral", "false"]], [])
def test_subjects_filter_type(self):
subject = self.study_subject
subject.type = SUBJECT_TYPE_CHOICES_PATIENT
subject.save()
self.check_subject_filtered([["type", SUBJECT_TYPE_CHOICES_PATIENT]], [subject])
self.check_subject_filtered([["type", SUBJECT_TYPE_CHOICES_CONTROL]], [])
def test_subjects_filter_unknown(self):
subject = self.study_subject
self.check_subject_filtered([["some_unknown", "unknown data"]], [subject])
self.check_subject_filtered([["", ""]], [subject])
self.check_subject_filtered([["", None]], [subject])
def test_serialize_subject(self):
study_subject = self.study_subject
study_subject.subject.dead = True
study_subject.flying_team = create_flying_team()
study_subject.datetime_contact_reminder = get_today_midnight_date()
create_contact_attempt(subject=study_subject)
create_visit(subject=study_subject)
......
......@@ -214,7 +214,7 @@ def create_configuration_item():
def create_flying_team(place=None):
if place is None:
place = "CHEM"
place = "CHEM "
result = FlyingTeam.objects.create(place=place)
return result
......
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