Exemplo n.º 1
0
    def __init__(self, **kwargs):
        self.callbacks = {}
        self.im = IdentifierManager()
        self.request = None
        self.facility_count_aggregator = Count('facility', distinct=True)

        super(JsonDataView, self).__init__(**kwargs)
class IdentifierManagerTestCase(TestCase):
    VALID_VALUE = 'xxxxx'
    VALID_IDENTIFIER = 'valid_identfier'

    def setUp(self):
        self.im = IdentifierManager()
        self.im.data_elements[self.VALID_IDENTIFIER] = self.VALID_VALUE
        self.im.category_option_combos[self.VALID_IDENTIFIER] = self.VALID_VALUE

    def test_raise_error_data_element_not_found(self):
        with patch.object(self.im, 'load_identifiers', return_value=None) as mocked:
            self.assertRaises(Exception, self.im.de, 'invalid_identifier')

    def test_no_error_raise_when_data_element_exists(self):
        with patch.object(self.im, 'load_identifiers', return_value=None) as mocked:
            try:
                self.im.de('valid_identfier')
            except Exception:
                self.fail("Unexpected exception")

    def test_raise_error_category_option_combo_not_found(self):
        with patch.object(self.im, 'load_identifiers', return_value=None) as mocked:
            self.assertRaises(Exception, self.im.coc, 'invalid_identifier')

    def test_no_error_raise_when_category_option_combo_exists(self):
        with patch.object(self.im, 'load_identifiers', return_value=None) as mocked:
            try:
                self.im.coc('valid_identfier')
            except Exception:
                self.fail("Unexpected exception")

    def test_data_element_is_retured(self):
        self.assertEqual(self.VALID_VALUE, self.im.de(self.VALID_IDENTIFIER))

    def test_category_option_combo_is_retured(self):
        self.assertEqual(self.VALID_VALUE, self.im.coc(self.VALID_IDENTIFIER))
 def setUp(self):
     self.im = IdentifierManager()
     self.im.data_elements[self.VALID_IDENTIFIER] = self.VALID_VALUE
     self.im.category_option_combos[self.VALID_IDENTIFIER] = self.VALID_VALUE
Exemplo n.º 4
0
class JsonDataView(View):
    def __init__(self, **kwargs):
        self.callbacks = {}
        self.im = IdentifierManager()
        self.request = None
        self.facility_count_aggregator = Count('facility', distinct=True)

        super(JsonDataView, self).__init__(**kwargs)

    def get_int_with_default(self, request, name, default):
        try:
            result = int(request.GET.get(name, default))
        except ValueError:
            result = default
        return result

    def filter_on_request(self, request, partial_filter, enable_age_group=True, aggregate=None):
        start_period = int(request.GET['from_date'])
        end_period = int(request.GET['to_date'])
        group_by_column = request.GET['group']

        group_by_column = get_actual_group_by_column(group_by_column)

        region = self.get_int_with_default(request, 'region', 0)
        district = self.get_int_with_default(request, 'district', 0)
        age_group = self.get_int_with_default(request, 'age_group', 0)

        if aggregate is None:
            aggregate = Sum('value')

        results = partial_filter.filter(period__gte=start_period, period__lte=end_period) \
            .values(group_by_column).annotate(value_aggregate=aggregate)

        if region > 0 and district > 0:
            results = results.filter(Q(region=region) | Q(district=district))
        elif region == 0 and district > 0:
            results = results.filter(district=district)
        elif district == 0 and region > 0:
            results = results.filter(region=region)

        if enable_age_group and age_group != 0:
            results = results.filter(age_group=age_group)

        return results

    def get_population(self, request):
        start_period = request.GET['from_date']
        end_period = request.GET['to_date']
        group_by_column = request.GET['group']

        region = self.get_int_with_default(request, 'region', 0)
        district = self.get_int_with_default(request, 'district', 0)

        results = []
        if group_by_column == 'period':
            total_population = District.objects

            if region == 0 and district > 0:
                total_population = total_population.filter(pk=district)
            elif district == 0 and region > 0:
                total_population = total_population.filter(region=region)

            total_population = total_population.aggregate(Sum('population'))

            actual_group_by_column = get_actual_group_by_column(group_by_column)
            for period in periods_in_ranges(start_period, end_period):

                results.append({actual_group_by_column: period,
                                'value_aggregate': total_population['population__sum']})

                (year, month) = get_year_and_month_from_period(period)
                for week in month_to_weeks(year, month):
                    weekly_period = "%sW%s" % (year, week)
                    results.append({actual_group_by_column: weekly_period,
                                    'value_aggregate': total_population['population__sum']})

        elif group_by_column == 'district':
            districts = District.objects.all()
            for district in districts:
                results.append({'district': district.pk, 'value_aggregate': district.population})

        return results

    def get_months_from_weeks(self, request):
        start_period = request.GET['from_date']
        end_period = request.GET['to_date']
        group_by_column = request.GET['group']

        actual_group_by_column = get_actual_group_by_column(group_by_column)

        results = []
        if group_by_column == 'period':
            for period in periods_in_ranges(start_period, end_period):
                (year, month) = get_year_and_month_from_period(period)
                for week in month_to_weeks(year, month):
                    weekly_period = "%sW%s" % (year, week)
                    year_month = "%s'%s" % (get_month_from_int(month), str(year)[2:])

                    results.append({actual_group_by_column: weekly_period,
                                    'value_aggregate': year_month})

        return results

    def get_rdt_positive(self, request):
        coc_filters = self.get_coc_filters(
            'Number Positive, Under 5 years',
            'Number Positive, 5 years and above'
        )

        return self.get_values(request, '105-7.3 Lab Malaria RDTs', coc_filters)

    def get_rdt_done(self, request):
        coc_filters = self.get_coc_filters(
            'Number Done, Under 5 years',
            'Number Done, 5 years and above'
        )

        return self.get_values(request, '105-7.3 Lab Malaria RDTs', coc_filters)

    def get_microscopy_positive(self, request):
        coc_filters = self.get_coc_filters(
            'Number Positive, Under 5 years',
            'Number Positive, 5 years and above'
        )

        return self.get_values(request, '105-7.3 Lab Malaria Microscopy', coc_filters)

    def get_microscopy_done(self, request):
        coc_filters = self.get_coc_filters(
            'Number Done, Under 5 years',
            'Number Done, 5 years and above'
        )

        return self.get_values(request, '105-7.3 Lab Malaria Microscopy', coc_filters)

    def get_inpatient_malaria_deaths(self, request):
        coc_filters = self.get_coc_filters(
            'Under 5 years, Death, Female',
            'Under 5 years, Death, Male',
            '5 years and above, Death, Female',
            '5 years and above, Death, Male'
        )

        return self.get_values(request, '108-6 Malaria total', coc_filters)

    def get_malaria_admissions(self, request):
        coc_filters = self.get_coc_filters(
            'Under 5 years, Case, Female',
            'Under 5 years, Case, Male',
            '5 years and above, Case, Female',
            '5 years and above, Case, Male'
        )

        return self.get_values(request, '108-6 Malaria total', coc_filters)

    def get_total_inpatient_deaths(self, request):
        return self.get_values(request, '108-1 Deaths', None)

    def get_opd_malaria_cases(self, request):
        return self.get_values(request, '105-1.3 OPD Malaria (Total)', None)

    def get_malaria_cases_wep(self, request):
        return self.get_values(request, 'Malaria Cases - WEP', None)

    def get_number_tested(self, request):
        coc_filters = self.get_coc_filters(
            'Microscopy Tested Cases',
            'RDT Tested Cases')

        return self.get_values(request, 'Malaria tests - WEP', coc_filters)

    def get_number_tested_positive(self, request):
        coc_filters = self.get_coc_filters(
            'Microscopy Positive Cases',
            'RDT Positve Cases')

        return self.get_values(request, 'Malaria tests - WEP', coc_filters)

    def get_number_receiving_ipt2(self, request):
        coc_filters = self.get_coc_filters(
            '10-19 Years',
            '20-24 Years',
            '>=25 Years'
        )

        return self.get_values(request, '105-2.1 A7:Second dose IPT (IPT2)', coc_filters)

    def get_number_attending_anc1(self, request):
        return self.get_values(request, '105-2.1 A1:ANC 1st Visit for women', None)

    def get_number_of_facilities_with_stock_outs_of_sp(self, request):
        coc_filters = self.get_coc_filters('Days out of stock')

        return self.get_values(request, '105-6 Sulfadoxine / Pyrimethamine tablet',
                               coc_filters, self.facility_count_aggregator, False, value__gt=7)

    def get_number_of_facilities_submitted_sp(self, request):
        coc_filters = self.get_coc_filters('Days out of stock')

        return self.get_values(request, '105-6 Sulfadoxine / Pyrimethamine tablet',
                               coc_filters, self.facility_count_aggregator, False)

    def get_number_of_facilities_with_stock_outs_of_act(self, request):
        coc_filters = self.get_coc_filters('Days out of stock')

        return self.get_values(request, '105-6 Artemether/ Lumefantrine 100/20mg tablet',
                               coc_filters, self.facility_count_aggregator, False, value__gt=7)

    def get_number_of_facilities_submitted_act(self, request):
        coc_filters = self.get_coc_filters('Days out of stock')

        return self.get_values(request, '105-6 Artemether/ Lumefantrine 100/20mg tablet',
                               coc_filters, self.facility_count_aggregator, False)

    def add_to_final(self, data, partial_data, key, group_by_column, create=True):
        group_by_column = get_actual_group_by_column(group_by_column)

        for result in partial_data:
            group_column_value = result[group_by_column]

            if group_column_value not in data:
                if not create:
                    continue

                data[group_column_value] = {}

            data[group_column_value][key] = result['value_aggregate']

        return data

    def generate_final(self, callbacks):
        callback_keys = self.request.GET.get('callbacks', None)

        if callback_keys is None:
            callback_keys = callbacks.keys()
        else:
            callback_keys = callback_keys.split(',')

        data = {}
        for key in callback_keys:
            create = True
            if key in ("population", "months_from_weeks"):
                create = False

            callback_result = callbacks[key](self.request)
            self.add_to_final(data, callback_result, key, self.request.GET['group'], create)

        return OrderedDict(natsorted(data.items(), key=lambda t: t[0]))

    def get_coc_filters(self, *names):
        f = None
        for name in names:
            if f is None:
                f = Q(category_option_combo__identifier=self.im.coc(name))
            else:
                f = f | Q(category_option_combo__identifier=self.im.coc(name))
        return f

    def get_values(self, request, data_element, coc_filters, aggregate=None, enable_age_group=True, **extra_filters):
        if coc_filters is not None:
            data_filter = DataValue.objects.filter(data_element__identifier=self.im.de(data_element)) \
                .filter(coc_filters)
        else:
            data_filter = DataValue.objects.filter(data_element__identifier=self.im.de(data_element))

        if extra_filters:
            data_filter = data_filter.filter(**extra_filters)

        return self.filter_on_request(request, data_filter, aggregate=aggregate, enable_age_group=enable_age_group)

    def get(self, request):
        self.request = request

        self.callbacks['rdt_positive'] = self.get_rdt_positive
        self.callbacks['rdt_done'] = self.get_rdt_done
        self.callbacks['microscopy_positive'] = self.get_microscopy_positive
        self.callbacks['microscopy_done'] = self.get_microscopy_done
        self.callbacks['inpatient_malaria_deaths'] = self.get_inpatient_malaria_deaths
        self.callbacks['malaria_admissions'] = self.get_malaria_admissions
        self.callbacks['total_inpatient_deaths'] = self.get_total_inpatient_deaths
        self.callbacks['opd_malaria_cases'] = self.get_opd_malaria_cases
        self.callbacks['number_receiving_ipt2'] = self.get_number_receiving_ipt2
        self.callbacks['number_attending_anc1'] = self.get_number_attending_anc1
        self.callbacks['population'] = self.get_population
        self.callbacks['months_from_weeks'] = self.get_months_from_weeks
        self.callbacks['stock_outs_of_sp'] = self.get_number_of_facilities_with_stock_outs_of_sp
        self.callbacks['stock_outs_of_act'] = self.get_number_of_facilities_with_stock_outs_of_act
        self.callbacks['submitted_sp'] = self.get_number_of_facilities_submitted_sp
        self.callbacks['submitted_act'] = self.get_number_of_facilities_submitted_act
        self.callbacks['malaria_cases_wep'] = self.get_malaria_cases_wep
        self.callbacks['number_tested_positive'] = self.get_number_tested_positive
        self.callbacks['number_tested'] = self.get_number_tested

        return HttpResponse(json.dumps(self.generate_final(self.callbacks)))