def assert_update(self, purge_date, adherence_schedule_date_start, adherence_schedule_id, adherence_cases, episode_properties=None, date_today_in_india=None, output=None): adherence_cases = [{ "name": adherence_case[0], "adherence_value": adherence_case[1], "adherence_source": "enikshay", "adherence_report_source": "treatment_supervisor" } for adherence_case in adherence_cases] episode = self.create_episode_case( adherence_schedule_date_start, adherence_schedule_id, adherence_cases, extra_properties=episode_properties, ) updater = EpisodeAdherenceUpdate(self.domain, episode) updater.purge_date = purge_date if date_today_in_india is not None: updater.date_today_in_india = date_today_in_india return self.assert_properties_equal(output, updater.update_json())
def get_doses(self): adherence_cases = [] for day, cases in self.get_adherence_cases_dict().iteritems(): adherence_cases.extend(cases) doses_taken_by_date = EpisodeAdherenceUpdate.calculate_doses_taken_by_day( [c.to_json() for c in adherence_cases]) return EpisodeAdherenceUpdate.count_doses_taken(doses_taken_by_date)
def test_missed_and_unknown_doses(self): adherence_cases = [{ "name": str(i), "adherence_source": "enikshay", "adherence_value": adherence_value, "adherence_date": date, } for i, (adherence_value, date) in enumerate([ # one month (DOSE_MISSED, datetime.date(2016, 1, 13)), ('unobserved_dose', datetime.date(2016, 1, 15)), # two weeks ('directly_observed_dose', datetime.date(2016, 1, 17)), (DOSE_UNKNOWN, datetime.date(2016, 1, 18)), # one week ('directly_observed_dose', datetime.date(2016, 1, 26)), # three days ('directly_observed_dose', datetime.date(2016, 1, 29)), (DOSE_MISSED, datetime.date(2016, 1, 31)), ('', datetime.date(2016, 1, 30)), # blank should be treated as unknown ])] episode = self.create_episode_case( adherence_schedule_date_start=datetime.date(2015, 12, 1), adherence_schedule_id='schedule1', adherence_cases=adherence_cases, ) updater = EpisodeAdherenceUpdate(self.domain, episode) updater.date_today_in_india = datetime.date(2016, 1, 31) expected = { 'three_day_score_count_taken': 1, 'one_week_score_count_taken': 2, 'two_week_score_count_taken': 3, 'month_score_count_taken': 4, 'three_day_unknown_count': 3 - 2, 'one_week_unknown_count': 7 - 3, 'two_week_unknown_count': 14 - 4, 'month_unknown_count': 30 - 6, 'three_day_missed_count': 1, 'one_week_missed_count': 1, 'two_week_missed_count': 1, 'month_missed_count': 2, 'three_day_unknown_score': 33.33, 'one_week_unknown_score': 57.14, 'two_week_unknown_score': 71.43, 'month_unknown_score': 80.0, 'three_day_missed_score': 33.33, 'one_week_missed_score': 14.29, 'two_week_missed_score': 7.14, 'month_missed_score': 6.67, } actual = updater.update_json() self.assert_properties_equal(expected, actual) readable_day_names = { 3: 'three_day', 7: 'one_week', 14: 'two_week', 30: 'month', } for days, period in readable_day_names.items(): self.assertEqual( days, (actual["{}_score_count_taken".format(period)] + actual["{}_unknown_count".format(period)] + actual["{}_missed_count".format(period)]) ) self.assertAlmostEqual( 100, (actual["{}_adherence_score".format(period)] + actual["{}_unknown_score".format(period)] + actual["{}_missed_score".format(period)]), places=1 )
def test_adherence_score_by_source(self): adherence_cases = [ { "name": '1', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2015, 12, 31), }, { "name": '2', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2016, 1, 15), }, { "name": '5', "adherence_source": "enikshay", "adherence_report_source": "other", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2016, 1, 17), }, { "name": '3', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2016, 1, 20), }, { "name": '4', "adherence_source": "MERM", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2016, 1, 30), }, ] episode = self.create_episode_case( adherence_schedule_date_start=datetime.date(2015, 12, 1), adherence_schedule_id='schedule1', adherence_cases=adherence_cases, ) updater = EpisodeAdherenceUpdate(self.domain, episode) updater.date_today_in_india = datetime.date(2016, 1, 31) expected = { 'three_day_score_count_taken_99DOTS': 0, 'one_week_score_count_taken_99DOTS': 0, 'two_week_score_count_taken_99DOTS': 1, 'month_score_count_taken_99DOTS': 2, 'three_day_adherence_score_99DOTS': 0.0, 'one_week_adherence_score_99DOTS': 0.0, 'two_week_adherence_score_99DOTS': 7.14, 'month_adherence_score_99DOTS': 6.67, 'three_day_score_count_taken_MERM': 1, 'one_week_score_count_taken_MERM': 1, 'two_week_score_count_taken_MERM': 1, 'month_score_count_taken_MERM': 1, 'three_day_adherence_score_MERM': 33.33, 'one_week_adherence_score_MERM': 14.29, 'two_week_adherence_score_MERM': 7.14, 'month_adherence_score_MERM': 3.33, 'three_day_score_count_taken_other': 0, 'one_week_score_count_taken_other': 0, 'two_week_score_count_taken_other': 1, 'month_score_count_taken_other': 1, 'three_day_adherence_score_other': 0.0, 'one_week_adherence_score_other': 0.0, 'two_week_adherence_score_other': 7.14, 'month_adherence_score_other': 3.33, 'three_day_score_count_taken_treatment_supervisor': 0, 'one_week_score_count_taken_treatment_supervisor': 0, 'two_week_score_count_taken_treatment_supervisor': 0, 'month_score_count_taken_treatment_supervisor': 0, 'three_day_adherence_score_treatment_supervisor': 0.0, 'one_week_adherence_score_treatment_supervisor': 0.0, 'two_week_adherence_score_treatment_supervisor': 0.0, 'month_adherence_score_treatment_supervisor': 0.0, } self.assert_properties_equal(expected, updater.update_json())
def test_count_taken_by_day(self): episode = self.create_episode_case( adherence_schedule_date_start=datetime.date(2016, 1, 10), adherence_schedule_id='schedule1', adherence_cases=[] ) episode_update = EpisodeAdherenceUpdate(self.domain, episode) episode_update.purge_date = datetime.date(2016, 1, 20) def dose_source_by_day(cases, day): # cases a list of tuples # (case_id, adherence_date, modified_on, adherence_value, source, closed, closure_reason) return calculate_dose_status_by_day( [ { 'adherence_source': source, 'adherence_date': str(dose_date), # the code expects string format 'adherence_value': dose_value, 'closed': closed, 'adherence_closure_reason': closure_reason, 'modified_on': modified_on, } for (_, dose_date, modified_on, dose_value, source, closed, closure_reason) in cases ] )[day].source ## test enikshay only source, open cases # not-taken - latest_modified_on case says no dose taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 21), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', False, None), ('some_id', datetime.date(2016, 1, 21), datetime.date(2016, 2, 22), DOSE_UNKNOWN, 'enikshay', False, None), ], datetime.date(2016, 1, 21)), False ) # taken - latest_modified_on case says dose taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 22), datetime.date(2016, 2, 22), DTIndicators[0], 'enikshay', False, None), ('some_id', datetime.date(2016, 1, 22), datetime.date(2016, 2, 21), DOSE_UNKNOWN, 'enikshay', False, None), ], datetime.date(2016, 1, 22)), 'enikshay' ) ## test enikshay only source, closed/closure_reason cases # not taken - as 1st case is not relevant because closed, closure_reason. 2nd case says no dose taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 23), datetime.date(2016, 2, 22), DTIndicators[0], 'enikshay', True, None), ('some_id', datetime.date(2016, 1, 23), datetime.date(2016, 2, 21), DOSE_UNKNOWN, 'enikshay', False, None), ], datetime.date(2016, 1, 23)), False ) # taken - as 1st case is not relevant because closed, closure_reason. 2nd case says dose taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 24), datetime.date(2016, 2, 22), DOSE_UNKNOWN, 'enikshay', True, None), ('some_id', datetime.date(2016, 1, 24), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', False, None), ], datetime.date(2016, 1, 24)), 'enikshay' ) # not taken - as 1st case is relevent case with latest_modified_on and says dose not taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 25), datetime.date(2016, 2, 22), DOSE_UNKNOWN, 'enikshay', True, HISTORICAL_CLOSURE_REASON), ('some_id', datetime.date(2016, 1, 25), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', False, None), ], datetime.date(2016, 1, 25)), False ) # taken - as 1st case is relevent case with latest_modified_on and says dose is taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 26), datetime.date(2016, 2, 22), DTIndicators[0], 'enikshay', True, HISTORICAL_CLOSURE_REASON), ('some_id', datetime.date(2016, 1, 26), datetime.date(2016, 2, 21), DOSE_UNKNOWN, 'enikshay', False, None), ], datetime.date(2016, 1, 26)), 'enikshay' ) ## test non-enikshay source only cases # not taken - non-enikshay source, so consider latest_modified_on self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 27), datetime.date(2016, 2, 22), DOSE_UNKNOWN, 'non-enikshay', True, 'a'), ('some_id', datetime.date(2016, 1, 27), datetime.date(2016, 2, 21), DTIndicators[0], '99dots', False, None), ], datetime.date(2016, 1, 27)), False ) # taken - non-enikshay source, so consider latest_modified_on self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 28), datetime.date(2016, 2, 22), DTIndicators[0], '99DOTS', True, 'a'), ('some_id', datetime.date(2016, 1, 28), datetime.date(2016, 2, 21), DOSE_UNKNOWN, '99DOTS', False, None), ], datetime.date(2016, 1, 28)), '99DOTS' ) ## test mix of enikshay, non-enikshay sources # taken - as enikshay source case says taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 29), datetime.date(2016, 2, 22), DTIndicators[0], '99', True, 'a'), ('some_id', datetime.date(2016, 1, 29), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', False, None), ], datetime.date(2016, 1, 29)), 'enikshay' ) # not taken - as enikshay source case says not taken self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 1), datetime.date(2016, 2, 22), DTIndicators[0], '99', True, 'a'), ('some_id', datetime.date(2016, 1, 1), datetime.date(2016, 2, 21), DOSE_UNKNOWN, 'enikshay', False, None), ], datetime.date(2016, 1, 1)), False ) # not taken - as the only enikshay source case is closed without valid-reason self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 2), datetime.date(2016, 2, 22), DTIndicators[0], '99', True, 'a'), ('some_id', datetime.date(2016, 1, 2), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', True, None), ], datetime.date(2016, 1, 2)), False ) # taken - as the only enikshay source case is closed with right closure_reason self.assertEqual( dose_source_by_day([ ('some_id', datetime.date(2016, 1, 3), datetime.date(2016, 2, 22), DOSE_UNKNOWN, '99', True, 'a'), ('some_id', datetime.date(2016, 1, 3), datetime.date(2016, 2, 21), DTIndicators[0], 'enikshay', True, HISTORICAL_CLOSURE_REASON), ], datetime.date(2016, 1, 3)), 'enikshay' )
def test_count_doses_taken_by_source(self): adherence_cases = [ { "name": 'Bad source shouldnt show up', "adherence_source": "enikshay", "adherence_report_source": "Bad source", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2017, 8, 14), }, { "name": '1', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2017, 8, 15), }, { "name": '2', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2017, 8, 16), }, { "name": '3', "adherence_source": "99DOTS", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2017, 8, 17), }, { "name": '4', "adherence_source": "MERM", "adherence_value": 'unobserved_dose', "adherence_date": datetime.date(2017, 8, 18), }, { "name": 'overwrites 99DOTS case', "adherence_source": "enikshay", "adherence_value": 'unobserved_dose', "adherence_report_source": "treatment_supervisor", "adherence_date": datetime.date(2017, 8, 16), # overwrites the 99DOTS case of this date } ] episode = self.create_episode_case( adherence_schedule_date_start=datetime.date(2017, 8, 12), adherence_schedule_id='schedule1', adherence_cases=adherence_cases, ) updater = EpisodeAdherenceUpdate(self.domain, episode) updater.purge_date = datetime.date(2017, 8, 10), dose_status_by_day = calculate_dose_status_by_day(updater.get_valid_adherence_cases()) self.assertDictEqual( { '99DOTS': 2, 'MERM': 1, 'treatment_supervisor': 1, }, EpisodeAdherenceUpdate.count_doses_taken_by_source(dose_status_by_day) ) self.assertDictEqual( { '99DOTS': 1, 'MERM': 1, }, EpisodeAdherenceUpdate.count_doses_taken_by_source( dose_status_by_day, start_date=datetime.date(2017, 8, 17), end_date=datetime.date(2017, 8, 18) ) )