Skip to content

Commit

Permalink
Merge branch 'release/0.1.9'
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvw committed Sep 27, 2018
2 parents 640d2b6 + b8e59fd commit e913063
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 52 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.8
0.1.9
41 changes: 30 additions & 11 deletions ambition_prn/action_items.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.apps import apps as django_apps
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.utils.safestring import mark_safe
from edc_action_item import Action, HIGH_PRIORITY, site_action_items
Expand Down Expand Up @@ -52,10 +53,18 @@ class DeathReportAction(Action):
admin_site_name = 'ambition_prn_admin'
priority = HIGH_PRIORITY
singleton = True
email_contacts = [settings.EMAIL_CONTACTS.get('tmg')]

def get_next_actions(self):
self.delete_if_new(action_cls=DeathReportTmgAction)
next_actions = [DeathReportTmgAction]

if self.action_item_model_cls().objects.filter(
related_reference_identifier=self.reference_obj.action_identifier,
action_type__name=DeathReportTmgAction.name).count() < 2:
next_actions = [DeathReportTmgAction]
else:
next_actions = []

on_schedule_w10_model_cls = django_apps.get_model(
'ambition_prn.onschedulew10')
try:
Expand All @@ -81,24 +90,34 @@ class DeathReportTmgAction(Action):
admin_site_name = 'ambition_prn_admin'
instructions = mark_safe(
f'This report is to be completed by the TMG only.')
email_recipients = [settings.EMAIL_CONTACTS.get('tmg')]

def close_action_item_on_save(self):
self.delete_if_new(action_cls=self)
return self.reference_obj.report_status == CLOSED

def get_next_actions(self):
"""Returns a next DeathReportTmgAction if the
submitted report does not match the cause of death
of the original death report.
Also, no more than two DeathReportTmgAction can exist.
"""
next_actions = []
self.delete_if_new(action_cls=self)
try:
self.reference_model_cls().objects.get(
death_report=self.reference_obj.death_report)
except MultipleObjectsReturned:
pass
else:
if self.reference_obj.report_status == CLOSED:
if (self.reference_obj.death_report.cause_of_death
!= self.reference_obj.cause_of_death):
next_actions = [self]
if self.action_item_model_cls().objects.filter(
action_identifier=self.reference_obj.action_identifier,
action_type__name=self.name).count() < 2:
try:
self.reference_model_cls().objects.get(
death_report=self.reference_obj.death_report)
except MultipleObjectsReturned:
pass
else:
if self.reference_obj.report_status == CLOSED:
if (self.reference_obj.death_report.cause_of_death
!= self.reference_obj.cause_of_death):
next_actions = [self]
return next_actions


Expand Down
5 changes: 3 additions & 2 deletions ambition_prn/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .constants import AZT_3TC_with_EFV_NVP_or_DTG, TDF_3TC_FTC_with_ATZ_r_or_Lopinavir_r
from .constants import TDF_3TC_FTC_with_EFV_or_NVP
from .constants import TUBERCULOSIS, DEVIATION, VIOLATION, CONSENT_WITHDRAWAL
from .constants import CRYTOCOCCAL_MENINGITIS, MALIGNANCY

ACTION_REQUIRED = (
('remain_on_study', 'Participant to remain on trial'),
Expand All @@ -15,13 +16,13 @@


CAUSE_OF_DEATH = (
('cryptococcal_meningitis', 'Cryptococcal meningitis'),
(CRYTOCOCCAL_MENINGITIS, 'Cryptococcal meningitis'),
('Cryptococcal_meningitis_relapse_IRIS',
'Cryptococcal meningitis relapse/IRIS'),
(TUBERCULOSIS, 'TB'),
('bacteraemia', 'Bacteraemia'),
('bacterial_pneumonia', 'Bacterial pneumonia'),
('malignancy', 'Malignancy'),
(MALIGNANCY, 'Malignancy'),
('art_toxicity', 'ART toxicity'),
('IRIS_non_CM', 'IRIS non-CM'),
('diarrhea_wasting', 'Diarrhea/wasting'),
Expand Down
3 changes: 3 additions & 0 deletions ambition_prn/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
AZT_3TC_with_ATZ_r_or_Lopinavir_r = 'AZT_3TC_with_ATZ_r_or_Lopinavir_r'
AZT_3TC_with_EFV_NVP_or_DTG = 'AZT_3TC_with_EFV_NVP_or_DTG'
CONSENT_WITHDRAWAL = 'consent_withdrawn'
CRYTOCOCCAL_MENINGITIS = 'cryptococcal_meningitis'
CRYTOCOCCAL_MENINGITIS = 'cryptococcal_meningitis'
DEVIATION = 'protocol_deviation'
MALIGNANCY = 'malignancy'
MEDICATION_NONCOMPLIANCE = 'medication_noncompliance'
TDF_3TC_FTC_with_ATZ_r_or_Lopinavir_r = 'TDF_3TC_FTC_with_ATZ_r_or_Lopinavir_r'
TDF_3TC_FTC_with_EFV_or_NVP = 'TDF_3TC_FTC_with_EFV_or_NVP'
Expand Down
14 changes: 8 additions & 6 deletions ambition_prn/mommy_recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from faker import Faker
from model_mommy.recipe import Recipe

from .constants import CRYTOCOCCAL_MENINGITIS
from .models import DeathReport, StudyTerminationConclusion, StudyTerminationConclusionW10
from .models import ProtocolDeviationViolation, DeathReportTmg

Expand All @@ -11,13 +12,13 @@
DeathReport,
study_day=1,
death_as_inpatient=YES,
cause_of_death='art_toxicity',
cause_of_death=CRYTOCOCCAL_MENINGITIS,
cause_of_death_other=None,
action_identifier=None,
tracking_identifier=None,
tb_site='meningitis',
narrative=(
'adverse event resulted in death due to cryptococcal meningitis'))
tracking_identifier=None)
# tb_site='meningitis',
# narrative=(
# 'adverse event resulted in death due to cryptococcal meningitis'))

studyterminationconclusion = Recipe(
StudyTerminationConclusion,
Expand All @@ -29,7 +30,6 @@
action_identifier=None,
tracking_identifier=None)


protocoldeviationviolation = Recipe(
ProtocolDeviationViolation,
action_identifier=None,
Expand All @@ -38,4 +38,6 @@
deathreporttmg = Recipe(
DeathReportTmg,
action_identifier=None,
cause_of_death=CRYTOCOCCAL_MENINGITIS,
cause_of_death_agreed=YES,
tracking_identifier=None)
1 change: 1 addition & 0 deletions ambition_prn/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
COUNTRY = 'botswana'
HOLIDAY_FILE = os.path.join(BASE_DIR, APP_NAME, 'tests', 'holidays.csv')

EMAIL_CONTACTS = {}

if 'test' in sys.argv:

Expand Down
28 changes: 0 additions & 28 deletions ambition_prn/tests/models.py

This file was deleted.

136 changes: 132 additions & 4 deletions ambition_prn/tests/test_action.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from ambition_rando.tests import AmbitionTestCaseMixin
from django.core.exceptions import ObjectDoesNotExist
from django.db.utils import IntegrityError
from django.test import TestCase, tag
from edc_action_item import SingletonActionItemError
from edc_action_item.models.action_item import ActionItem
from edc_constants.constants import CLOSED, NEW
from edc_base.utils import get_utcnow
from edc_constants.constants import CLOSED, NEW, NO
from edc_facility.import_holidays import import_holidays
from edc_registration.models import RegisteredSubject
from model_mommy import mommy

from ..action_items import DeathReportAction
from django.db.utils import IntegrityError
from ..action_items import DeathReportAction, DEATH_REPORT_TMG_ACTION
from ..constants import CRYTOCOCCAL_MENINGITIS, MALIGNANCY


class TestDeathReport(AmbitionTestCaseMixin, TestCase):
Expand Down Expand Up @@ -89,3 +91,129 @@ def test_death_report_closes_action(self):
obj = ActionItem.objects.get(
action_identifier=death_report.action_identifier)
self.assertEqual(obj.status, CLOSED)

def test_add_tmg_death_report_action_cause_matches(self):

death_report_action = DeathReportAction(
subject_identifier=self.subject_identifier)
death_report = mommy.make_recipe(
'ambition_prn.deathreport',
subject_identifier=self.subject_identifier,
cause_of_death=CRYTOCOCCAL_MENINGITIS)
self.assertEqual(death_report_action.action_identifier,
death_report.action_identifier)

# assert death report creates one TMG Death Report Action
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 1)

# fill in TMG report with matching cause of death
death_report_tmg = mommy.make_recipe(
'ambition_prn.deathreporttmg',
subject_identifier=self.subject_identifier,
death_report=death_report,
cause_of_death=CRYTOCOCCAL_MENINGITIS,
related_reference_identifier=death_report_action.action_identifier,
parent_reference_identifier=death_report_action.action_identifier
)
self.assertEqual(
death_report_tmg.parent_reference_identifier,
death_report.action_identifier)

self.assertEqual(
death_report_tmg.related_reference_identifier,
death_report.action_identifier)

# assert a second TMG Death Report Action is NOT created
# because the cause of death matches
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 1)

def test_add_two_tmg_death_report_action_cause_not_matching(self):

death_report_action = DeathReportAction(
subject_identifier=self.subject_identifier)
death_report = mommy.make_recipe(
'ambition_prn.deathreport',
subject_identifier=self.subject_identifier,
cause_of_death=CRYTOCOCCAL_MENINGITIS)

# assert death report creates one TMG Death Report Action
try:
action_item = ActionItem.objects.get(
action_type__name=DEATH_REPORT_TMG_ACTION)
except ObjectDoesNotExist:
self.fail('Action item unexpectedly does not exist')

self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 1)

# fill in TMG report with non-matching cause of death
death_report_tmg1 = mommy.make_recipe(
'ambition_prn.deathreporttmg',
subject_identifier=self.subject_identifier,
death_report=death_report,
cause_of_death=MALIGNANCY,
cause_of_death_agreed=NO,
report_status=CLOSED,
report_closed_datetime=get_utcnow(),
action_identifier=action_item.action_identifier,
related_reference_identifier=death_report.action_identifier,
parent_reference_identifier=death_report.action_identifier)

action_item = ActionItem.objects.get(
action_identifier=death_report_tmg1.action_identifier,
action_type__name=DEATH_REPORT_TMG_ACTION)

# assert a second TMG Death Report Action is created
# by death_report_tmg because the cause of death matches
self.assertEqual(ActionItem.objects.filter(
related_reference_identifier=death_report.action_identifier,
action_type__name=DEATH_REPORT_TMG_ACTION,
status=CLOSED).count(), 1)
self.assertEqual(ActionItem.objects.filter(
related_reference_identifier=death_report.action_identifier,
action_type__name=DEATH_REPORT_TMG_ACTION,
status=NEW).count(), 1)
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

# resave
death_report_tmg1.save()

# still 2
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

# fill in second TMG report with any cause of death
death_report_tmg2 = mommy.make_recipe(
'ambition_prn.deathreporttmg',
subject_identifier=self.subject_identifier,
death_report=death_report,
cause_of_death=MALIGNANCY,
related_reference_identifier=death_report_action.action_identifier,
parent_reference_identifier=death_report_tmg1.action_identifier)

# still 2
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

death_report_tmg2.save()

# still 2
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

# resave
death_report.save()

# still 2
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

# resave
death_report_tmg1.save()

# still 2
self.assertEqual(ActionItem.objects.filter(
action_type__name=DEATH_REPORT_TMG_ACTION).count(), 2)

0 comments on commit e913063

Please sign in to comment.