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())
Esempio n. 2
0
    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)
Esempio n. 3
0
    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
            )
Esempio n. 4
0
    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())
Esempio n. 5
0
    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'
        )
Esempio n. 6
0
    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)
            )
        )