Example #1
0
class ChildProtectionData(AgeGenderFilteredReport):
    title = 'Number and Type of Incidents of Abuse Reported at CVSU'
    chart_x_label = 'CVSU Location'
    chart_y_label = 'Number of incidents'
    table_name = make_ctable_table_name('cvsulive_UnicefMalawiFluff')

    @property
    def columns(self):
        cat_group = DataTablesColumnGroup("Category of abuse")
        return [
            self.location_column,
            DatabaseColumn("Physical",
                           SumColumn('abuse_category_physical_total'),
                           header_group=cat_group),
            DatabaseColumn("Sexual",
                           SumColumn('abuse_category_sexual_total'),
                           header_group=cat_group),
            DatabaseColumn("Emotional",
                           SumColumn('abuse_category_psychological_total'),
                           header_group=cat_group),
            DatabaseColumn("Neglect",
                           SumColumn('abuse_category_neglect_total'),
                           header_group=cat_group),
            DatabaseColumn("Exploitation",
                           SumColumn('abuse_category_exploitation_total'),
                           header_group=cat_group),
            DatabaseColumn("Other",
                           SumColumn('abuse_category_other_total'),
                           header_group=cat_group),
            DatabaseColumn("Total incidents reported",
                           SumColumn('abuse_category_total_total'),
                           header_group=cat_group)
        ]
Example #2
0
class CVSUIncidentResolutionData(BaseSqlData):
    title = 'Incident Resolution'
    chart_x_label = 'CVSU Location'
    chart_y_label = 'Number of incidents'
    table_name = make_ctable_table_name('cvsulive_UnicefMalawiFluff')

    @property
    def columns(self):
        return [
            self.location_column,
            DatabaseColumn("Resolved at CVSU",
                           SumColumn('resolution_resolved_at_cvsu_total')),
            DatabaseColumn("Referred to TA",
                           SumColumn('resolution_referred_ta_total')),
            DatabaseColumn("Referred to TA Court",
                           SumColumn('resolution_referral_ta_court_total')),
            DatabaseColumn("Referred to Police",
                           SumColumn('resolution_referral_police_total')),
            DatabaseColumn(
                "Referred to Social Welfare",
                SumColumn('resolution_referral_social_welfare_total')),
            DatabaseColumn("Referred to NGO",
                           SumColumn('resolution_referral_ngo_total')),
            DatabaseColumn("Referred to Other",
                           SumColumn('resolution_referral_other_total')),
            DatabaseColumn("Unresolved",
                           SumColumn('resolution_unresolved_total')),
            DatabaseColumn("Case Withdrawn",
                           SumColumn('resolution_case_withdrawn_total')),
            DatabaseColumn("Other", SumColumn('resolution_other_total')),
            DatabaseColumn("Total", SumColumn('resolution_total_total')),
        ]
class PSISQLEventsReport(PSISQLReport):
    fields = [
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'psi.reports.StateDistrictField',
        'psi.reports.AASD',
    ]
    name = "Event Demonstration Report (SQL)"
    exportable = True
    emailable = True
    slug = "event_demonstations_sql"
    section_name = "event demonstrations"
    default_aggregation = 'district'
    table_name = make_ctable_table_name('psi-unicef_psi_events')

    @property
    def columns(self):
        return self.initial_columns + [
            DatabaseColumn("Number of events", SumColumn('events')),
            DatabaseColumn("Number of male attendees", SumColumn('males')),
            DatabaseColumn("Number of female attendees", SumColumn('females')),
            DatabaseColumn("Total number of attendees",
                           SumColumn('attendees')),
            DatabaseColumn("Total number of leaflets distributed",
                           SumColumn('leaflets')),
            DatabaseColumn("Total number of gifts distributed",
                           SumColumn('gifts'))
        ]
class PSISQLSensitizationReport(PSISQLReport):
    name = "Sensitization Sessions Report (SQL)"
    exportable = True
    emailable = True
    slug = "sensitization_sessions_sql"
    section_name = "sensitization sessions"
    fields = [
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'psi.reports.StateDistrictBlockField',
        'psi.reports.AASDB',
    ]
    default_aggregation = 'block'

    table_name = make_ctable_table_name('psi-unicef_psi_sensitization')

    @property
    def columns(self):
        return self.initial_columns + [
            DatabaseColumn("Number of Sessions", SumColumn("sessions")),
            DatabaseColumn("Ayush Sensitized", SumColumn("ayush_doctors")),
            DatabaseColumn("MBBS Sensitized", SumColumn("mbbs_doctors")),
            DatabaseColumn("Asha Supervisors Sensitized",
                           SumColumn("asha_supervisors")),
            DatabaseColumn("Ashas Sensitized", SumColumn("ashas")),
            DatabaseColumn("AWW Sensitized", SumColumn("awws")),
            DatabaseColumn("Others (ANM, MPW, etc.)", SumColumn("other")),
            DatabaseColumn("VHND Attendees", SumColumn('attendees'))
        ]
Example #5
0
class ChildrenInHouseholdData(AgeGenderFilteredReport):
    title = 'Number of Children in Survivor Household'
    chart_x_label = 'CVSU Location'
    chart_y_label = 'Number of children'
    table_name = make_ctable_table_name('cvsulive_UnicefMalawiFluff')
    has_total_column = False

    @property
    def columns(self):
        return [
            self.location_column,
            DatabaseColumn("Children per household experiencing abuse", SumColumn('abuse_children_abused_total')),
            DatabaseColumn("Total number of children in household", SumColumn('abuse_children_in_household_total')),
        ]
class PSISQLTrainingReport(PSISQLReport):
    name = "Training Sessions Report (SQL)"
    exportable = True
    emailable = True
    slug = "training_sessions_sql"
    section_name = "training sessions"
    fields = [
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'psi.reports.StateDistrictField',
        'psi.reports.AASD',
    ]
    default_aggregation = 'district'
    table_name = make_ctable_table_name("psi-unicef_psi_training")

    @property
    def columns(self):
        return self.initial_columns + [
            DatabaseColumn("Private: Number of Trainings",
                           SumColumn("priv_trained")),
            DatabaseColumn("Private: Ayush trained",
                           SumColumn("priv_ayush_trained")),
            DatabaseColumn("Private: Allopathics trained",
                           SumColumn("priv_allo_trained")),
            DatabaseColumn("Private: Learning changed",
                           SumColumn("priv_avg_diff")),
            DatabaseColumn("Private: Num > 80%", SumColumn("priv_gt80")),
            DatabaseColumn("Public: Number of Trainings",
                           SumColumn("pub_trained")),
            DatabaseColumn("Public: Ayush trained",
                           SumColumn("pub_ayush_trained")),
            DatabaseColumn("Public: Allopathics trained",
                           SumColumn("pub_allo_trained")),
            DatabaseColumn("Public: Learning changed",
                           SumColumn("pub_avg_diff")),
            DatabaseColumn("Public: Num > 80%", SumColumn("pub_gt80")),
            DatabaseColumn("Depot: Number of Trainings",
                           SumColumn("dep_trained")),
            DatabaseColumn("Depot: Number of Personnel Trained",
                           SumColumn("dep_pers_trained")),
            DatabaseColumn("Depot: Learning changed",
                           SumColumn("dep_avg_diff")),
            DatabaseColumn("Depot: Num > 80%", SumColumn("dep_gt80")),
            DatabaseColumn("FLW: Number of Trainings",
                           SumColumn("flw_trained")),
            DatabaseColumn("FLW: Number of Personnel Trained",
                           SumColumn("flw_pers_trained")),
            DatabaseColumn("FLW: Learning changed", SumColumn("flw_avg_diff")),
            DatabaseColumn("FLW: Num > 80%", SumColumn("flw_gt80")),
        ]
class PSISQLHouseholdReport(PSISQLReport):
    name = "Household Demonstrations Report (SQL)"
    exportable = True
    emailable = True
    slug = "household_demonstrations_sql"
    section_name = "household demonstrations"
    fields = [
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'psi.reports.AsyncPlaceField',
        'psi.reports.DemoTypeField',
        'psi.reports.AASDBV',
    ]
    default_aggregation = 'village'
    table_name = make_ctable_table_name(
        "psi-unicef_psi_household_demonstrations")

    @property
    @memoized
    def selected_dt(self):
        return self.request.GET.get('demo_type', "")

    @property
    def keys(self):
        combos = get_unique_combinations(self.domain,
                                         place_types=self.place_types,
                                         place=self.selected_fixture())
        selected_demo_type = self.request.GET.get('demo_type', "")
        for c in combos:
            if self.selected_dt:
                if self.selected_dt == '_all':
                    for dt in DEMO_TYPES:
                        yield [c[pt] for pt in self.place_types] + [dt]
                else:
                    yield [c[pt]
                           for pt in self.place_types] + [selected_demo_type]
            else:
                yield [c[pt] for pt in self.place_types]

    @property
    def columns(self):
        return self.initial_columns + [
            DatabaseColumn("Number of demonstrations done",
                           SumColumn("demonstrations")),
            DatabaseColumn("Number of 0-6 year old children",
                           SumColumn("children")),
            DatabaseColumn("Total number of leaflets distributed",
                           SumColumn("leaflets")),
            DatabaseColumn("Number of kits sold", SumColumn("kits"))
        ]
Example #8
0
class CVSUServicesData(BaseSqlData):
    title = 'Services Provided'
    chart_x_label = 'CVSU Location'
    chart_y_label = 'Number of incidents'
    table_name = make_ctable_table_name('cvsulive_UnicefMalawiFluff')

    @property
    def columns(self):
        return [
            self.location_column,
            DatabaseColumn("Counselling", SumColumn('service_counselling_total')),
            DatabaseColumn("Psychosocial Support", SumColumn('service_psychosocial_support_total')),
            DatabaseColumn("First Aid", SumColumn('service_first_aid_total')),
            DatabaseColumn("Shelter", SumColumn('service_shelter_total')),
            DatabaseColumn("Referral", SumColumn('service_referral_total')),
            DatabaseColumn("Mediation", SumColumn('service_mediation_total')),
            DatabaseColumn("Other", SumColumn('service_other_total')),
            DatabaseColumn("Total", SumColumn('service_total_total')),
        ]
Example #9
0
class CVSUActivityData(BaseSqlData):
    title = 'Activities Performed'
    chart_x_label = 'CVSU Location'
    chart_y_label = 'Number of reports'
    table_name = make_ctable_table_name('cvsulive_UnicefMalawiFluff')

    @property
    def columns(self):
        return [
            self.location_column,
            DatabaseColumn("Incidents of Abuse", SumColumn('incidents_total')),
            DatabaseColumn("Outreach activities", SumColumn('outreach_total')),
            DatabaseColumn("IGA Reports", SumColumn('iga_total')),
            AggregateColumn(
                "Total", self.sum,
                [AliasColumn('incidents_total'), AliasColumn('outreach_total')]),
        ]

    def sum(self, no_incidents, outreach):
        return (no_incidents or 0) + (outreach or 0)
Example #10
0
class CareReport(SqlTabularReport, CustomProjectReport, DatespanMixin):
    exportable = True
    emailable = True
    table_name = make_ctable_table_name("care-ihapc-live_CareSAFluff")
    report_template_path = "care_sa/reports/grouped.html"

    fields = [
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'custom.reports.care_sa.reports.sql.ProvinceField',
        'custom.reports.care_sa.reports.sql.CBOField',
        'custom.reports.care_sa.reports.sql.ShowAgeField',
        'custom.reports.care_sa.reports.sql.ShowGenderField',
    ]

    def selected_province(self):
        fixture = self.request.GET.get('fixture_id', "")
        return fixture.split(':')[1] if fixture else None

    def selected_cbo(self):
        group = self.request.GET.get('group', '')
        return group

    def show_age(self):
        show_age_field = self.request.GET.get('show_age_field', '')
        return show_age_field == 'on'

    def show_gender(self):
        show_gender_field = self.request.GET.get('show_gender_field', '')
        return show_gender_field == 'on'

    @property
    def filters(self):
        filters = [
            "domain = :domain",
            "date between :startdate and :enddate",
        ]

        if self.selected_province():
            filters.append("province = :province")
        if self.selected_cbo():
            filters.append("cbo = :cbo")

        return filters

    @property
    def group_by(self):
        groups = []
        if not self.selected_province():
            groups.append('province')
        elif not self.selected_cbo():
            groups.append('cbo')
        else:
            groups.append('user_id')

        if self.show_age():
            groups.append('age_group')
        if self.show_gender():
            groups.append('gender')

        return groups

    @property
    def filter_values(self):
        return dict(
            domain=self.domain,
            startdate=self.datespan.startdate_param_utc,
            enddate=self.datespan.enddate_param_utc,
            province=self.selected_province(),
            cbo=self.selected_cbo(),
        )

    def first_indicator_column_index(self):
        return len(self.columns) - len(self.report_columns)

    @property
    def headers(self):
        """
        Override the headers method to be able to add male/female sub
        header columns.
        """
        header_columns = []
        for idx, column in enumerate(self.columns):
            if idx >= self.first_indicator_column_index() and self.show_gender(
            ):
                group = DataTablesColumnGroup(column.header)
                group.add_column(DataTablesColumn("male", sortable=False))
                group.add_column(DataTablesColumn("female", sortable=False))
                header_columns.append(group)
            else:
                # gender is included in the columns to populate data
                # but we don't show it on the page
                if column.header != 'Gender':
                    header_columns.append(
                        DataTablesColumn(column.header, sortable=False))

        # insert a blank header to display the "all genders/ages" message
        if not self.show_gender() and not self.show_age():
            header_columns.insert(1, DataTablesColumn('', sortable=False))

        return DataTablesHeader(*header_columns)

    @property
    def columns(self):
        if not self.selected_province():
            columns = [
                DatabaseColumn("Province",
                               SimpleColumn('province'),
                               sortable=False)
            ]
        elif not self.selected_cbo():
            columns = [
                DatabaseColumn("CBO", SimpleColumn('cbo'), sortable=False)
            ]
        else:
            columns = [
                DatabaseColumn("User", SimpleColumn('user_id'), sortable=False)
            ]

        if self.show_gender():
            columns.append(
                DatabaseColumn("Gender",
                               SimpleColumn('gender'),
                               sortable=False))
        if self.show_age():
            columns.append(
                DatabaseColumn("Age",
                               SimpleColumn('age_group'),
                               sortable=False))

        for column_attrs in self.report_columns:
            text, name = column_attrs[:2]
            name = '%s_total' % name
            if len(column_attrs) == 2:
                column = DatabaseColumn(text,
                                        CountColumn(name),
                                        sortable=False)
            elif column_attrs[2] == 'SumColumn':
                column = DatabaseColumn(text, SumColumn(name), sortable=False)

            columns.append(column)

        return columns

    @property
    def keys(self):
        [self.domain]

    @property
    def export_table(self):
        headers = self.headers
        rows = self.rows
        formatted_rows = []
        for row in rows:
            if not self.show_age() and not self.show_gender():
                if 'total_width' not in row:
                    formatted_rows.append([row['username']] +
                                          ['All genders and ages'] +
                                          row['row_data'])
            elif not self.show_age() and self.show_gender():
                if 'total_width' not in row:
                    formatted_rows.append([row['username']] + row['row_data'])
            else:
                # both groups with age get built the same
                if 'total_width' not in row:
                    formatted_rows.append([row['username']] +
                                          [row['age_display']] +
                                          row['row_data'])
                else:
                    formatted_rows.append(['Total:', ''] + row['row_data'])

        def _unformat_row(row):
            return [
                col.get("sort_key", col) if isinstance(col, dict) else col
                for col in row
            ]

        table = headers.as_export_table
        rows = [_unformat_row(row) for row in formatted_rows]
        table.extend(rows)
        if self.total_row:
            table.append(_unformat_row(self.total_row))
        if self.statistics_rows:
            table.extend([_unformat_row(row) for row in self.statistics_rows])

        return [[self.export_sheet_name, table]]

    def empty_row(self):
        return ['--'] * len(self.report_columns)

    def gender_seperated_dict(self):
        return {'male': self.empty_row(), 'female': self.empty_row()}

    def age_seperated_dict(self, default):
        """ Build a dictionary with a copy of default for each age group """
        return dict((str(i), copy(default)) for i in range(4))

    def initialize_user_stuff(self):
        """
        Return a dictionary appropriately formatted based on the
        set filter options

        Used to seperate a given users/province/cbo's data into
        a dictionary seperated by age group and gender as
        needed
        """
        if self.show_age() and self.show_gender():
            return self.age_seperated_dict(self.gender_seperated_dict())

        if self.show_age() and not self.show_gender():
            return self.age_seperated_dict(self.empty_row())

        if not self.show_age() and self.show_gender():
            return self.gender_seperated_dict()

        if not self.show_age() and not self.show_gender():
            return self.empty_row()

    def add_row_to_total(self, total, row):
        # initialize it if it hasn't been used yet
        if len(total) == 0:
            total = [0] * len(row)

        return [
            a if isinstance(b, str) else a + b for (a, b) in zip(total, row)
        ]

    def add_row_to_row(self, base_row, row_to_add):
        for i in range(len(base_row)):
            if isinstance(row_to_add[i], int) or isinstance(
                    row_to_add[i], long):
                if isinstance(base_row[i], int):
                    base_row[i] = base_row[i] + int(row_to_add[i])
                else:
                    base_row[i] = row_to_add[i]

        return base_row

    def get_data_grouping_id(self, row):
        if not self.selected_province() or not self.selected_cbo():
            grouping_id = row.pop(0)
        else:
            # if it's a user we need to get the username
            user = CommCareUser.get_by_user_id(row.pop(0))
            grouping_id = user.username

        return grouping_id

    def add_row_to_grouping_data(self, built_data, row, grouping_id, age_group,
                                 gender):
        """
        Take whatever was left in row and add it to the appropriate spot in
        the data we are building for this grouping_id
        """
        if self.show_age() and self.show_gender():
            built_data[grouping_id][age_group][gender] = row
        elif self.show_age() and not self.show_gender():
            built_data[grouping_id][age_group] = \
                self.add_row_to_row(built_data[grouping_id][age_group], row)
        elif not self.show_age() and self.show_gender():
            built_data[grouping_id][gender] = \
                self.add_row_to_row(built_data[grouping_id][gender], row)
        elif not self.show_age() and not self.show_gender():
            built_data[grouping_id] = \
                self.add_row_to_row(built_data[grouping_id], row)

    def build_data(self, rows):
        """
        Take all of the individual data from the rows and collect it into
        a dict (built_data) that is used to group the values by gender/age
        """
        built_data = {}

        for row in rows:
            gender = age_group = None

            try:
                grouping_id = self.get_data_grouping_id(row)
            except AttributeError:
                continue

            if grouping_id not in built_data:
                # If we haven't seen this id yet we need to create
                # an empty row/dict (depending on selected filters)
                built_data[grouping_id] = self.initialize_user_stuff()

            if self.show_gender():
                gender = row.pop(0)
                if gender == 'refuses_answer':
                    continue

            if self.show_age():
                age_group = row.pop(0)

            self.add_row_to_grouping_data(built_data, row, grouping_id,
                                          age_group, gender)

        return built_data

    def age_group_text(self, age_group_val):
        if age_group_val == '0':
            return '0-14 years'
        elif age_group_val == '1':
            return '15-24 years'
        elif age_group_val == '2':
            return '25+ years'
        else:
            return 'Unknown'

    def get_grouping_name(self, user):
        """
        Get the name of province/cbo/user (depending on what is selected)
        """
        if not self.selected_province():
            return FixtureDataItem.get(user).fields_without_attributes['name']
        elif not self.selected_cbo():
            return Group.get(user).name
        else:
            return CommCareUser.get_by_username(user).name

    def merge_gender_data(self, data):
        return [
            val for pair in zip(data['male'], data['female']) for val in pair
        ]

    @property
    def rows(self):
        """
        Override rows method to be able to properly group data
        """
        # use super to get the raw rows from the report
        stock_rows = list(super(CareReport, self).rows)

        # pack these rows into a dict representing the currently
        # configured report structure
        rows = self.build_data(stock_rows)

        # set up with for total rows
        if (not self.show_age() and self.show_gender()):
            total_width = 1
        else:
            total_width = 2

        rows_for_table = []
        overall_total_row = []
        age_group_totals = {'0': [], '1': [], '2': [], '3': []}

        # for every group of data, unpack back to individual rows
        # and set up the information the template needs to render this
        # stuff
        for user in rows:
            u = self.get_grouping_name(user)

            total_row = []
            if self.show_age() and self.show_gender():
                for age_group in sorted(rows[user]):
                    age_display = self.age_group_text(age_group)

                    row_data = self.merge_gender_data(rows[user][age_group])

                    rows_for_table.append({
                        'username':
                        u if age_group == '0' else '',
                        'gender':
                        True,
                        'age_display':
                        age_display,
                        'row_data':
                        row_data
                    })

                    age_group_totals[age_group] = self.add_row_to_total(
                        age_group_totals[age_group], row_data)

                    total_row = self.add_row_to_total(total_row, row_data)
            elif not self.show_age() and self.show_gender():
                row_data = self.merge_gender_data(rows[user])

                rows_for_table.append({
                    'username': u,
                    'gender': True,
                    'row_data': row_data
                })

            elif self.show_age() and not self.show_gender():
                for age_group in sorted(rows[user]):
                    row_data = rows[user][age_group]

                    rows_for_table.append({
                        'username':
                        u if age_group == '0' else '',
                        'age_display':
                        self.age_group_text(age_group),
                        'row_data':
                        row_data
                    })

                    age_group_totals[age_group] = self.add_row_to_total(
                        age_group_totals[age_group], row_data)

                    total_row = self.add_row_to_total(total_row, row_data)
            else:
                row_data = rows[user]
                rows_for_table.append({
                    'username': u,
                    'gender': 'no_grouping',  # magic
                    'row_data': row_data
                })

            if total_row:
                overall_total_row = self.add_row_to_total(
                    overall_total_row, total_row)
            else:
                # there is no total_row if we aren't grouping by age
                overall_total_row = self.add_row_to_total(
                    overall_total_row, row_data)

            rows_for_table.append({
                'username': '******',
                'total_width': total_width,
                'gender': self.show_gender(),
                'row_data': total_row,
            })

        if self.show_age():
            for group in ['0', '1', '2', '3']:
                rows_for_table.append({
                    'username': '******',
                    'total_width': total_width,
                    'age_display': self.age_group_text(group),
                    'gender': self.show_gender(),
                    'row_data': age_group_totals[group]
                })

        rows_for_table.append({
            'username': '******',
            'total_width': total_width,
            'gender': self.show_gender(),
            'row_data': overall_total_row,
        })

        return rows_for_table
Example #11
0
class GSIDSQLReport(SummingSqlTabularReport, CustomProjectReport,
                    DatespanMixin):
    fields = [
        'custom.apps.gsid.reports.TestField',
        'corehq.apps.reports.filters.dates.DatespanFilter',
        'custom.apps.gsid.reports.AsyncClinicField',
        'custom.apps.gsid.reports.AggregateAtField'
    ]

    exportable = True
    emailable = True
    table_name = make_ctable_table_name("gsid_patient_summary")
    default_aggregation = "clinic"

    def __init__(self, request, base_context=None, domain=None, **kwargs):
        self.is_map = kwargs.pop('map', False)
        super(GSIDSQLReport, self).__init__(request,
                                            base_context=base_context,
                                            domain=domain,
                                            **kwargs)

    @property
    def daterange_display(self):
        format = "%d %b %Y"
        st = self.datespan.startdate.strftime(format)
        en = self.datespan.enddate.strftime(format)
        return "%s to %s" % (st, en)

    @property
    def report_subtitles(self):
        if self.needs_filters:
            return []

        subtitles = ["Date range: %s" % self.daterange_display]
        if self.selected_fixture():
            tag, id = self.selected_fixture()
            location = FixtureDataItem.get(id).fields_without_attributes[
                '%s_name' % tag]
            subtitles.append('Location: %s' % location)

        if self.disease:
            location = FixtureDataItem.get(
                self.disease[1]).fields_without_attributes['disease_name']
            subtitles.append('Disease: %s' % location)

        if self.test_version:
            test_version = FixtureDataItem.get(
                self.test_version[1]
            ).fields_without_attributes['visible_test_name']
            subtitles.append('Test Version: %s' % test_version)

        return subtitles

    @property
    @memoized
    def diseases(self):
        disease_fixtures = FixtureDataItem.by_data_type(
            self.domain,
            FixtureDataType.by_domain_tag(self.domain, "diseases").one())
        return {
            "ids": [
                d.fields_without_attributes["disease_id"]
                for d in disease_fixtures
            ],
            "names": [
                d.fields_without_attributes["disease_name"]
                for d in disease_fixtures
            ]
        }

    @property
    def test_types(self):
        test_fixtures = FixtureDataItem.by_data_type(
            self.domain,
            FixtureDataType.by_domain_tag(self.domain, "test").one())
        return [
            t.fields_without_attributes["test_name"] for t in test_fixtures
        ]

    @property
    def filter_values(self):
        ret = dict(domain=self.domain,
                   startdate=self.datespan.startdate_param,
                   enddate=self.datespan.enddate_param,
                   male="male",
                   female="female",
                   positive="POSITIVE")

        DISEASES = self.diseases["ids"]
        TESTS = self.test_types

        ret.update(zip(DISEASES, DISEASES))
        ret.update(zip(TESTS, TESTS))

        return ret

    @property
    def filters(self):
        return [
            EQ("domain", "domain"),
            BETWEEN("date", "startdate", "enddate")
        ] + self.disease_filters

    @property
    def disease(self):
        disease = self.request.GET.get('test_type_disease', '')
        return disease.split(':') if disease else None

    @property
    def test_version(self):
        test = self.request.GET.get('test_type_test', '')
        return test.split(':') if test else None

    @property
    def disease_filters(self):
        disease = self.disease
        test = self.test_version

        filters = []
        if test:
            filters.append(EQ("test_version", test[0]))
        elif disease:
            filters.append(EQ("disease_name", disease[0]))

        return filters

    @property
    @memoized
    def gps_key(self):
        gps_key = "gps"
        agg_at = self.request.GET.get('aggregate_at', None)
        if agg_at and not agg_at == "clinic":
            gps_key = "gps_" + agg_at
        return gps_key

    @property
    def group_by(self):
        return self.place_types

    @property
    def keys(self):
        combos = get_unique_combinations(self.domain,
                                         place_types=self.place_types,
                                         place=self.selected_fixture())
        for c in combos:
            yield [c[pt] for pt in self.place_types]

    def selected_fixture(self):
        fixture = self.request.GET.get('fixture_id', "")
        return fixture.split(':') if fixture else None

    @property
    @memoized
    def place_types(self):
        opts = ['country', 'province', 'district', 'clinic']
        agg_at = self.request.GET.get('aggregate_at', None)
        agg_at = agg_at if agg_at and opts.index(agg_at) <= opts.index(
            self.default_aggregation) else self.default_aggregation
        place = self.selected_fixture()
        agg_at = place[0] if place and opts.index(agg_at) < opts.index(
            place[0]) else agg_at
        return opts[:opts.index(agg_at) + 1]

    @property
    def common_columns(self):
        columns = []
        for place in self.place_types:
            columns.append(
                DatabaseColumn(place.capitalize(),
                               SimpleColumn(place),
                               format_fn=capitalize_fn))

        return columns
Example #12
0
class McSqlData(SqlData):

    table_name = make_ctable_table_name("mc-inscale_MalariaConsortiumFluff")

    def __init__(self, sections, format_class, domain, datespan, fixture_type,
                 fixture_item):
        self.format_class = format_class
        self.domain = domain
        self.datespan = datespan
        self.fixture_type = fixture_type
        self.fixture_item = fixture_item
        self._sections = sections

    @property
    @memoized
    def format(self):
        return self.format_class([], self.get_users())

    def get_headers(self):
        return self.format.get_headers()

    @memoized
    def get_data(self, slugs=None):
        # only overridden to memoize
        return super(McSqlData, self).get_data(slugs)

    @memoized
    def get_users(self):
        def _is_ape(user):
            return user.user_data.get('level') == 'APE'

        def _matches_location(user):
            def _tag_to_user_data(tag):
                return {
                    'hf': 'health_facility',
                }.get(tag) or tag

            if self.fixture_type and self.fixture_item:
                return user.user_data.get(
                    _tag_to_user_data(self.fixture_type.tag),
                    None) == self.fixture_item.fields_without_attributes.get(
                        'name')
            else:
                return True

        unfiltered_users = CommCareUser.by_domain(self.domain)
        filtered_users = filter(
            lambda u: _is_ape(u) and _matches_location(u),
            unfiltered_users,
        )
        return sorted(filtered_users, key=lambda u: u.username)

    @property
    def group_by(self):
        return ['user_id']

    @property
    def filters(self):
        base_filters = [
            "domain = :domain", "date between :startdate and :enddate"
        ]
        if self.fixture_item is not None:
            base_filters.append('"user_id" in :userids')
        return base_filters

    @property
    @memoized
    def sections(self):
        def _section_class(section_def):
            return {
                'form_lookup': FormPropertySection,
            }.get(section_def.get('type'), SqlSection)

        return [
            _section_class(section)(self, section, self.format_class)
            for section in self._sections
        ]

    @memoized
    def all_rows(self):
        return [value for s in self.sections for value in s.rows]

    @property
    def filter_values(self):
        base_filter_values = {
            'domain': self.domain,
            'startdate': self.datespan.startdate_param_utc,
            'enddate': self.datespan.enddate_param_utc,
        }
        if self.fixture_item is not None:
            user_ids = tuple(u._id for u in self.get_users())
            if user_ids:
                base_filter_values['userids'] = user_ids
            else:
                base_filter_values['userids'] = ('__EMPTY__', )
        return base_filter_values

    @property
    def user_column(self):
        return DatabaseColumn("User", SimpleColumn("user_id"), sortable=False)

    @property
    def columns(self):
        columns = [self.user_column]
        for section in self.sections:
            columns.extend(section.columns)
        return columns

    @memoized
    def get_user_ids(self):
        return [u._id for u in self.get_users()]