Skip to content
Snippets Groups Projects
Commit 083ee3ea authored by Carlos Vega's avatar Carlos Vega
Browse files

added endpoint_reached option #303

parent 08739dea
No related branches found
No related tags found
1 merge request!211Improvements/more options
......@@ -67,6 +67,7 @@ def get_subject_columns(request, subject_list_type):
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, "Endpoint Reached", "endpoint_reached", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Postponed", "postponed", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Excluded", "excluded", study_subject_columns, "yes_no_filter", study.columns)
add_column(result, "Info sent", "information_sent", study_subject_columns, "yes_no_filter", study.columns)
......@@ -128,6 +129,8 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction, co
result = subjects_to_be_ordered.order_by(order_direction + 'subject__dead')
elif order_column == "resigned":
result = subjects_to_be_ordered.order_by(order_direction + 'resigned')
elif order_column == "endpoint_reached":
result = subjects_to_be_ordered.order_by(order_direction + 'endpoint_reached')
elif order_column == "information_sent":
result = subjects_to_be_ordered.order_by(order_direction + 'information_sent')
elif order_column == "health_partner_first_name":
......@@ -244,6 +247,8 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
result = result.filter(subject__dead=(value == "true"))
elif column == "resigned":
result = result.filter(resigned=(value == "true"))
elif column == "endpoint_reached":
result = result.filter(endpoint_reached=(value == "true"))
elif column == "postponed":
result = result.filter(postponed=(value == "true"))
elif column == "excluded":
......@@ -401,6 +406,7 @@ def serialize_subject(study_subject):
"flying_team": flying_team,
"dead": bool_to_yes_no(study_subject.subject.dead),
"resigned": bool_to_yes_no(study_subject.resigned),
"endpoint_reached": bool_to_yes_no(study_subject.endpoint_reached),
"postponed": bool_to_yes_no(study_subject.postponed),
"excluded": bool_to_yes_no(study_subject.excluded),
"information_sent": bool_to_yes_no(study_subject.information_sent),
......
......@@ -29,7 +29,7 @@ class StudySubjectAddForm(StudySubjectForm):
class Meta:
model = StudySubject
fields = '__all__'
exclude = ['resigned', 'resign_reason']
exclude = ['resigned', 'resign_reason', 'endpoint_reached', 'endpoint_reached_reason']
def __init__(self, *args, **kwargs):
self.user = get_worker_from_args(kwargs)
......@@ -117,17 +117,16 @@ def get_study_from_study_subject_instance(study_subject):
class StudySubjectEditForm(StudySubjectForm):
def __init__(self, *args, **kwargs):
was_resigned = kwargs.get('was_resigned', False)
if 'was_resigned' in kwargs:
kwargs.pop('was_resigned')
was_resigned = kwargs.pop('was_resigned', False)
endpoint_was_reached = kwargs.pop('endpoint_was_reached', False)
super(StudySubjectEditForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.id:
self.fields['screening_number'].widget.attrs['readonly'] = True
self.study = get_study_from_study_subject_instance(instance)
if was_resigned:
self.fields['resigned'].disabled = True
self.fields['resigned'].disabled = was_resigned
self.fields['endpoint_reached'].disabled = endpoint_was_reached
prepare_study_subject_fields(fields=self.fields, study=self.study)
......@@ -162,7 +161,6 @@ def prepare_study_subject_fields(fields, study):
prepare_field(fields, study.columns, 'nd_number')
prepare_field(fields, study.columns, 'datetime_contact_reminder')
prepare_field(fields, study.columns, 'postponed')
prepare_field(fields, study.columns, 'excluded')
prepare_field(fields, study.columns, 'flying_team')
prepare_field(fields, study.columns, 'mpower_id')
prepare_field(fields, study.columns, 'comments')
......@@ -171,6 +169,8 @@ def prepare_study_subject_fields(fields, study):
prepare_field(fields, study.columns, 'year_of_diagnosis')
prepare_field(fields, study.columns, 'information_sent')
prepare_field(fields, study.columns, 'pd_in_family')
prepare_field(fields, study.columns, 'endpoint_reached')
prepare_field(fields, study.columns, 'excluded')
prepare_field(fields, study.columns, 'resigned')
prepare_field(fields, study.columns, 'resign_reason')
prepare_field(fields, study.columns, 'referral_letter')
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2019-03-21 10:24
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0136_merge_20190109_1041'),
]
operations = [
migrations.AddField(
model_name='studycolumns',
name='endpoint_reached',
field=models.BooleanField(default=True, verbose_name=b'Endpoint reached'),
),
migrations.AddField(
model_name='studysubject',
name='endpoint_reached',
field=models.BooleanField(default=False, verbose_name=b'Endpoint Reached'),
),
migrations.AddField(
model_name='studysubject',
name='endpoint_reached_reason',
field=models.TextField(blank=True, max_length=2000, verbose_name=b'Endpoint reached comments'),
),
migrations.AlterField(
model_name='studycolumns',
name='resign_reason',
field=models.BooleanField(default=True, verbose_name=b'Endpoint reached comments'),
),
]
......@@ -80,6 +80,10 @@ class StudyColumns(models.Model):
excluded = models.BooleanField(default=False, verbose_name='Excluded')
endpoint_reached = models.BooleanField(default=True, verbose_name='Endpoint reached')
resign_reason = models.BooleanField(default=True, verbose_name='Endpoint reached comments')
referral_letter = models.BooleanField(
default=False,
verbose_name='Referral letter'
......
......@@ -39,6 +39,11 @@ class StudySubject(models.Model):
self.finish_all_visits()
self.finish_all_appointments()
def mark_as_endpoint_reached(self):
self.endpoint_reached = True
self.finish_all_visits()
self.finish_all_appointments()
subject = models.ForeignKey("web.Subject",
verbose_name='Subject',
editable=False,
......@@ -177,6 +182,15 @@ class StudySubject(models.Model):
blank=True,
verbose_name='Exclude reason'
)
endpoint_reached = models.BooleanField(
verbose_name='Endpoint Reached',
default=False,
editable=True
)
endpoint_reached_reason = models.TextField(max_length=2000,
blank=True,
verbose_name='Endpoint reached comments'
)
def sort_matched_screening_first(self, pattern, reverse=False):
if self.screening_number is None:
......@@ -224,8 +238,10 @@ class StudySubject(models.Model):
#SIGNALS
@receiver(post_save, sender=StudySubject)
def set_as_resigned_or_excluded(sender, instance, **kwargs):
def set_as_resigned_or_excluded_or_endpoint_reached(sender, instance, **kwargs):
if instance.excluded:
instance.mark_as_excluded()
if instance.resigned:
instance.mark_as_resigned()
\ No newline at end of file
instance.mark_as_resigned()
if instance.endpoint_reached:
instance.mark_as_endpoint_reached()
\ No newline at end of file
......@@ -64,6 +64,8 @@ class Visit(models.Model):
create_follow_up = False
elif self.subject.excluded:
create_follow_up = False
elif self.subject.endpoint_reached:
create_follow_up = False
elif not self.subject.study.auto_create_follow_up:
create_follow_up = False
......
......@@ -279,6 +279,17 @@ class TestSubjectApi(LoggedInWithWorkerTestCase):
self.check_subject_ordered("resigned", [subject2, subject])
def test_subjects_sort_endpoint_reached(self):
subject = self.study_subject
subject.endpoint_reached = True
subject.save()
subject2 = create_study_subject(2)
subject2.endpoint_reached = False
subject2.save()
self.check_subject_ordered("endpoint_reached", [subject2, subject])
def test_subjects_sort_postponed(self):
subject = self.study_subject
subject.postponed = True
......@@ -347,6 +358,18 @@ class TestSubjectApi(LoggedInWithWorkerTestCase):
self.check_subject_filtered([["resigned", "true"]], [subject])
self.check_subject_filtered([["resigned", "false"]], [subject2])
def test_subjects_filter_endpoint_reached(self):
subject = self.study_subject
subject.endpoint_reached = True
subject.save()
subject2 = create_study_subject(2)
subject2.endpoint_reached = False
subject2.save()
self.check_subject_filtered([["endpoint_reached", "true"]], [subject])
self.check_subject_filtered([["endpoint_reached", "false"]], [subject2])
def test_subjects_filter_postponed(self):
subject = self.study_subject
subject.postponed = True
......
......@@ -57,6 +57,7 @@ def create_empty_study_columns():
information_sent=False,
pd_in_family=False,
resigned=False,
endpoint_reached=False,
excluded=False,
resign_reason=False,
)
......
......@@ -9,6 +9,37 @@ from web.tests.functions import create_visit
class SubjectModelTests(TestCase):
def test_signal_mark_as_endpoint_reached(self):
subject = create_study_subject()
visit = create_visit(subject)
appointment = create_appointment(visit)
subject.endpoint_reached = True
subject.save()
appointment_status = Appointment.objects.filter(id=appointment.id)[
0].status
visit_finished = Visit.objects.filter(id=visit.id)[0].is_finished
self.assertTrue(subject.endpoint_reached)
self.assertTrue(visit_finished)
self.assertEquals(
Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
def test_mark_as_endpoint_reached(self):
subject = create_study_subject()
visit = create_visit(subject)
appointment = create_appointment(visit)
subject.mark_as_endpoint_reached()
appointment_status = Appointment.objects.filter(id=appointment.id)[
0].status
visit_finished = Visit.objects.filter(id=visit.id)[0].is_finished
self.assertTrue(subject.endpoint_reached)
self.assertTrue(visit_finished)
self.assertEquals(
Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
def test_signal_mark_as_resigned(self):
subject = create_study_subject()
visit = create_visit(subject)
......
......@@ -129,6 +129,17 @@ class VisitModelTests(TestCase):
visit_count = Visit.objects.filter(subject=subject).count()
self.assertEquals(1, visit_count)
def test_mark_as_finished_4(self):
subject = create_study_subject()
visit = create_visit(subject)
subject.endpoint_reached = True
subject.save()
visit.mark_as_finished()
visit_count = Visit.objects.filter(subject=subject).count()
self.assertEquals(1, visit_count)
def test_mark_as_finished_for_follow_up_visit(self):
subject = create_study_subject()
subject.type = SUBJECT_TYPE_CHOICES_PATIENT
......
......@@ -342,6 +342,15 @@ class NotificationViewTests(LoggedInTestCase):
notification = get_subject_with_no_visit_notifications_count(self.user)
self.assertEquals(original_notification.count, notification.count)
def test_get_subject_with_no_visit_notifications_count_6(self):
original_notification = get_subject_with_no_visit_notifications_count(self.user)
subject = create_study_subject()
subject.endpoint_reached = True
subject.save()
notification = get_subject_with_no_visit_notifications_count(self.user)
self.assertEquals(original_notification.count, notification.count)
def test_get_unfinished_appointments_count(self):
original_notification = get_unfinished_appointments_count(self.user)
subject = create_study_subject()
......
......@@ -162,6 +162,7 @@ def get_subjects_with_no_visit(user):
unfinished_visit_count=Count(Case(When(visit__is_finished=False, then=1)))).filter(
subject__dead=False,
resigned=False,
endpoint_reached=False,
unfinished_visit_count=0,
default_location__in=get_filter_locations(user),
postponed=False,
......@@ -179,6 +180,7 @@ def get_subjects_with_almost_expired_vouchers(user):
result = StudySubject.objects.filter(
subject__dead=False,
resigned=False,
endpoint_reached=False,
excluded=False,
default_location__in=get_filter_locations(user),
).annotate(last_contact=Max(Case(When(contactattempt__success=True, then="contactattempt__datetime_when")))).filter(
......@@ -193,6 +195,7 @@ def get_subjects_with_reminder(user):
result = StudySubject.objects.filter(
subject__dead=False,
resigned=False,
endpoint_reached=False,
excluded=False,
default_location__in=get_filter_locations(user),
datetime_contact_reminder__lt=tomorrow,
......
......@@ -68,10 +68,11 @@ def subject_edit(request, id):
contact_attempts = study_subject.contactattempt_set.order_by('-datetime_when').all()
was_dead = study_subject.subject.dead
was_resigned = study_subject.resigned
endpoint_was_reached = study_subject.endpoint_reached
if request.method == 'POST':
study_subject_form = StudySubjectEditForm(request.POST, request.FILES, instance=study_subject,
was_resigned=was_resigned, prefix="study_subject"
)
was_resigned=was_resigned, prefix="study_subject",
endpoint_was_reached=endpoint_was_reached)
subject_form = SubjectEditForm(request.POST, request.FILES, instance=study_subject.subject,
was_dead=was_dead, prefix="subject"
)
......@@ -84,6 +85,9 @@ def subject_edit(request, id):
if study_subject.study.columns.resigned \
and study_subject_form.cleaned_data['resigned'] and not was_resigned:
study_subject.mark_as_resigned()
if study_subject.study.columns.endpoint_reached \
and study_subject_form.cleaned_data['endpoint_reached'] and not endpoint_was_reached:
study_subject.mark_as_endpoint_reached()
messages.success(request, "Modifications saved")
if '_continue' in request.POST:
return redirect('web.views.subject_edit', id=study_subject.id)
......@@ -92,7 +96,7 @@ def subject_edit(request, id):
messages.add_message(request, messages.ERROR, 'Invalid data. Please fix data and try again.')
else:
study_subject_form = StudySubjectEditForm(instance=study_subject, was_resigned=was_resigned,
prefix="study_subject")
prefix="study_subject", endpoint_was_reached=endpoint_was_reached)
subject_form = SubjectEditForm(instance=study_subject.subject, was_dead=was_dead, prefix="subject")
languages = []
......
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