示例#1
0
def get_static_report_mapping(from_domain, to_domain):
    from corehq.apps.userreports.models import StaticReportConfiguration, STATIC_PREFIX, \
        CUSTOM_REPORT_PREFIX

    report_map = {}

    for static_report in StaticReportConfiguration.by_domain(from_domain):
        if static_report.get_id.startswith(STATIC_PREFIX):
            report_id = static_report.get_id.replace(
                STATIC_PREFIX + from_domain + '-', '')
            is_custom_report = False
        else:
            report_id = static_report.get_id.replace(
                CUSTOM_REPORT_PREFIX + from_domain + '-', '')
            is_custom_report = True
        new_id = StaticReportConfiguration.get_doc_id(to_domain, report_id,
                                                      is_custom_report)
        # check that new report is in new domain's list of static reports
        try:
            StaticReportConfiguration.by_id(new_id, to_domain)
        except (BadSpecError, DocumentNotFound):
            pass
        else:
            report_map[static_report.get_id] = new_id
    return report_map
示例#2
0
def get_static_report_mapping(from_domain, to_domain):
    from corehq.apps.userreports.models import StaticReportConfiguration, STATIC_PREFIX, \
        CUSTOM_REPORT_PREFIX

    report_map = {}

    for static_report in StaticReportConfiguration.by_domain(from_domain):
        if static_report.get_id.startswith(STATIC_PREFIX):
            report_id = static_report.get_id.replace(
                STATIC_PREFIX + from_domain + '-',
                ''
            )
            is_custom_report = False
        else:
            report_id = static_report.get_id.replace(
                CUSTOM_REPORT_PREFIX + from_domain + '-',
                ''
            )
            is_custom_report = True
        new_id = StaticReportConfiguration.get_doc_id(
            to_domain, report_id, is_custom_report
        )
        # check that new report is in new domain's list of static reports
        try:
            StaticReportConfiguration.by_id(new_id, to_domain)
        except (BadSpecError, DocumentNotFound):
            pass
        else:
            report_map[static_report.get_id] = new_id
    return report_map
示例#3
0
    def copy_ucr_reports(self, datasource_map):
        report_map = {}
        reports = get_report_configs_for_domain(self.existing_domain)
        for report in reports:
            old_datasource_id = report.config_id
            try:
                report.config_id = datasource_map[old_datasource_id]
            except KeyError:
                pass  # datasource not found

            old_id, new_id = self.save_couch_copy(report, self.new_domain)
            report_map[old_id] = new_id
        for static_report in StaticReportConfiguration.by_domain(
                self.existing_domain):
            if static_report.get_id.startswith(STATIC_PREFIX):
                report_id = static_report.get_id.replace(
                    STATIC_PREFIX + self.existing_domain + '-', '')
                is_custom_report = False
            else:
                report_id = static_report.get_id.replace(
                    CUSTOM_REPORT_PREFIX + self.existing_domain + '-', '')
                is_custom_report = True
            new_id = StaticReportConfiguration.get_doc_id(
                self.new_domain, report_id, is_custom_report)
            # check that new report is in new domain's list of static reports
            StaticReportConfiguration.by_id(new_id)
            report_map[static_report.get_id] = new_id
        return report_map
示例#4
0
    def copy_ucr_reports(self, datasource_map):
        report_map = {}
        reports = get_report_configs_for_domain(self.existing_domain)
        for report in reports:
            old_datasource_id = report.config_id
            try:
                report.config_id = datasource_map[old_datasource_id]
            except KeyError:
                pass  # datasource not found

            old_id, new_id = self.save_couch_copy(report, self.new_domain)
            report_map[old_id] = new_id
        for static_report in StaticReportConfiguration.by_domain(self.existing_domain):
            if static_report.get_id.startswith(STATIC_PREFIX):
                report_id = static_report.get_id.replace(
                    STATIC_PREFIX + self.existing_domain + '-',
                    ''
                )
                is_custom_report = False
            else:
                report_id = static_report.get_id.replace(
                    CUSTOM_REPORT_PREFIX + self.existing_domain + '-',
                    ''
                )
                is_custom_report = True
            new_id = StaticReportConfiguration.get_doc_id(
                self.new_domain, report_id, is_custom_report
            )
            # check that new report is in new domain's list of static reports
            StaticReportConfiguration.by_id(new_id)
            report_map[static_report.get_id] = new_id
        return report_map
示例#5
0
 def _get_static_report_configuration_without_owner_transform(self, report_id, domain):
     static_report_configuration = StaticReportConfiguration.by_id(report_id, domain)
     for report_column in static_report_configuration.report_columns:
         transform = report_column.transform
         if transform.get('type') == 'custom' and transform.get('custom_type') == 'owner_display':
             report_column.transform = {}
     return static_report_configuration
示例#6
0
 def test_for_report_id_conflicts(self):
     counts = Counter(rc.get_id for rc in StaticReportConfiguration.all())
     duplicates = [k for k, v in counts.items() if v > 1]
     msg = "The following report configs have duplicate generated report_ids:\n{}".format(
         "\n".join("report_id: {}".format(report_id)
                   for report_id in duplicates))
     self.assertEqual(0, len(duplicates), msg)
示例#7
0
def _get_configurable_reports(project):
    """
    User configurable reports
    """
    configs = ReportConfiguration.by_domain(project.name) + StaticReportConfiguration.by_domain(project.name)
    if configs:
        def _make_report_class(config):
            from corehq.apps.reports.generic import GenericReportView

            # this is really annoying.
            # the report metadata should really be pulled outside of the report classes
            @classmethod
            def get_url(cls, domain, **kwargs):
                from corehq.apps.userreports.models import CUSTOM_REPORT_PREFIX
                slug = (
                    ConfigurableReport.slug
                    if not config._id.startswith(CUSTOM_REPORT_PREFIX)
                    else CustomConfigurableReportDispatcher.slug
                )
                return reverse(slug, args=[domain, config._id])

            @classmethod
            def show_in_navigation(cls, domain=None, project=None, user=None):
                return config.visible or (user and toggles.USER_CONFIGURABLE_REPORTS.enabled(user.username))

            return type('DynamicReport{}'.format(config._id), (GenericReportView, ), {
                'name': config.title,
                'description': config.description or None,
                'get_url': get_url,
                'show_in_navigation': show_in_navigation,
            })

        yield (_('Reports'), [_make_report_class(config) for config in configs])
示例#8
0
def _get_report_module_context(app, module):
    def _report_to_config(report):
        return {
            'report_id':
            report._id,
            'title':
            report.title,
            'description':
            report.description,
            'charts':
            [chart for chart in report.charts if chart.type == 'multibar'],
            'filter_structure':
            report.filters_without_prefilters,
        }

    all_reports = ReportConfiguration.by_domain(app.domain) + \
                  StaticReportConfiguration.by_domain(app.domain)
    warnings = []
    validity = module.check_report_validity()

    # We're now proactively deleting these references, so after that's been
    # out for a while, this can be removed (say June 2016 or later)
    if not validity.is_valid:
        module.report_configs = validity.valid_report_configs
        warnings.append(
            gettext_lazy('Your app contains references to reports that are '
                         'deleted. These will be removed on save.'))

    return {
        'all_reports': [_report_to_config(r) for r in all_reports],
        'current_reports': [r.to_json() for r in module.report_configs],
        'warnings': warnings,
    }
示例#9
0
 def _get_static_report_configuration_without_owner_transform(self, report_id, domain):
     static_report_configuration = StaticReportConfiguration.by_id(report_id, domain)
     for report_column in static_report_configuration.report_columns:
         transform = report_column.transform
         if transform.get('type') == 'custom' and transform.get('custom_type') == 'owner_display':
             report_column.transform = {}
     return static_report_configuration
示例#10
0
 def spec(self):
     if self.is_static:
         return StaticReportConfiguration.by_id(self.report_config_id,
                                                domain=self.domain)
     else:
         return get_document_or_not_found(ReportConfiguration, self.domain,
                                          self.report_config_id)
示例#11
0
def _get_report_module_context(app, module):
    def _report_to_config(report):
        return {
            'report_id': report._id,
            'title': report.title,
            'description': report.description,
            'charts': [chart for chart in report.charts if
                       chart.type == 'multibar'],
            'filter_structure': report.filters,
        }

    all_reports = ReportConfiguration.by_domain(app.domain) + \
                  StaticReportConfiguration.by_domain(app.domain)
    warnings = []
    validity = module.check_report_validity()

    # We're now proactively deleting these references, so after that's been
    # out for a while, this can be removed (say June 2016 or later)
    if not validity.is_valid:
        module.report_configs = validity.valid_report_configs
        warnings.append(
            gettext_lazy('Your app contains references to reports that are '
                         'deleted. These will be removed on save.')
        )

    return {
        'all_reports': [_report_to_config(r) for r in all_reports],
        'current_reports': [r.to_json() for r in module.report_configs],
        'warnings': warnings,
    }
示例#12
0
def _get_report_module_context(app, module):
    def _report_to_config(report):
        return {
            'report_id': report._id,
            'title': report.title,
            'description': report.description,
            'charts': [chart for chart in report.charts if
                       chart.type == 'multibar'],
            'filter_structure': report.filters_without_prefilters,
        }

    all_reports = ReportConfiguration.by_domain(app.domain) + \
                  StaticReportConfiguration.by_domain(app.domain)
    validity = module.check_report_validity()

    # We're now proactively deleting these references, so after that's been
    # out for a while, this can be removed (say June 2016 or later)
    if not validity.is_valid:
        module.report_configs = validity.valid_report_configs

    filter_choices = [
        {'slug': f.doc_type, 'description': f.short_description} for f in get_all_mobile_filter_configs()
    ]
    auto_filter_choices = [
        {'slug': f.slug, 'description': f.short_description} for f in get_auto_filter_configurations()

    ]
    return {
        'all_reports': [_report_to_config(r) for r in all_reports],
        'current_reports': [r.to_json() for r in module.report_configs],
        'filter_choices': filter_choices,
        'auto_filter_choices': auto_filter_choices,
        'daterange_choices': [choice._asdict() for choice in get_simple_dateranges()],
    }
示例#13
0
def _shared_context(domain):
    static_reports = list(StaticReportConfiguration.by_domain(domain))
    static_data_sources = list(StaticDataSourceConfiguration.by_domain(domain))
    return {
        'domain': domain,
        'reports': ReportConfiguration.by_domain(domain) + static_reports,
        'data_sources': DataSourceConfiguration.by_domain(domain) + static_data_sources,
    }
示例#14
0
 def test_for_report_id_conflicts(self):
     counts = Counter(rc.get_id for rc in
                      StaticReportConfiguration.all())
     duplicates = [k for k, v in counts.items() if v > 1]
     msg = "The following report configs have duplicate generated report_ids:\n{}".format(
         "\n".join("report_id: {}".format(report_id) for report_id in duplicates)
     )
     self.assertEqual(0, len(duplicates), msg)
示例#15
0
 def test_get_all(self):
     with override_settings(STATIC_UCR_REPORTS=[self.get_path('static_report_config', 'json')]):
         all = list(StaticReportConfiguration.all())
         self.assertEqual(2, len(all))
         example, dimagi = all
         self.assertEqual('example', example.domain)
         self.assertEqual('dimagi', dimagi.domain)
         for config in all:
             self.assertEqual('Custom Title', config.title)
示例#16
0
 def test_get_all(self):
     with override_settings(STATIC_UCR_REPORTS=[self.get_path('static_report_config', 'json')]):
         all = list(StaticReportConfiguration.all())
         self.assertEqual(2, len(all))
         example, dimagi = all
         self.assertEqual('example', example.domain)
         self.assertEqual('dimagi', dimagi.domain)
         for config in all:
             self.assertEqual('Custom Title', config.title)
示例#17
0
    def test_static_reports(self):
        with override_settings(STATIC_UCR_REPORTS=[
                self.get_path('static_report_config', 'json'),
                self.get_path('static_report_2_config', 'json')
        ]):
            reports = get_report_configs([
                StaticReportConfiguration.get_doc_id('example',
                                                     'a-custom-report', False)
            ], 'example')
            self.assertEqual(len(reports), 1)

            reports = get_report_configs([
                StaticReportConfiguration.get_doc_id('example',
                                                     'a-custom-report', False),
                StaticReportConfiguration.get_doc_id(
                    'example', 'another-custom-report', False),
            ], 'example')
            self.assertEqual(len(reports), 2)
示例#18
0
 def main_context(self):
     static_reports = list(StaticReportConfiguration.by_domain(self.domain))
     static_data_sources = list(StaticDataSourceConfiguration.by_domain(self.domain))
     context = super(BaseUserConfigReportsView, self).main_context
     context.update({
         'reports': ReportConfiguration.by_domain(self.domain) + static_reports,
         'data_sources': DataSourceConfiguration.by_domain(self.domain) + static_data_sources,
     })
     return context
示例#19
0
def clean_columns(json_spec):
    static_config = StaticReportConfiguration.wrap(deepcopy(json_spec))
    report_config = ReportConfiguration.wrap(static_config.config)
    cleaned_columns = []
    for col_spec, wrapped_col in zip(json_spec['config']['columns'],
                                     report_config.report_columns):
        print("Checking column '{}'".format(col_spec['column_id']))
        new_col_spec = clean_spec(col_spec, wrapped_col)
        cleaned_columns.append(order_dict(new_col_spec, COLUMN_PARAMS_ORDER))
    return cleaned_columns
    def test_static_reports(self):
        with override_settings(STATIC_UCR_REPORTS=[
            self.get_path('static_report_config', 'json'),
            self.get_path('static_report_2_config', 'json')
        ]):
            reports = get_report_configs(
                [StaticReportConfiguration.get_doc_id('example', 'a-custom-report', False)],
                'example'
            )
            self.assertEqual(len(reports), 1)

            reports = get_report_configs(
                [
                    StaticReportConfiguration.get_doc_id('example', 'a-custom-report', False),
                    StaticReportConfiguration.get_doc_id('example', 'another-custom-report', False),
                ],
                'example'
            )
            self.assertEqual(len(reports), 2)
示例#21
0
def clean_columns(json_spec):
    static_config = StaticReportConfiguration.wrap(deepcopy(json_spec))
    report_config = ReportConfiguration.wrap(static_config.config)
    cleaned_columns = []
    for col_spec, wrapped_col in zip(json_spec['config']['columns'],
                                     report_config.report_columns):
        print("Checking column '{}'".format(col_spec['column_id']))
        new_col_spec = clean_spec(col_spec, wrapped_col)
        cleaned_columns.append(order_dict(new_col_spec, COLUMN_PARAMS_ORDER))
    return cleaned_columns
示例#22
0
 def test_get_all_yaml(self):
     with patch("corehq.apps.userreports.models.static_ucr_report_paths", return_value=[]), \
          override_settings(STATIC_UCR_REPORTS=[self.get_path('static_report_config', 'yml')]):
         all = list(StaticReportConfiguration.all())
         self.assertEqual(2, len(all))
         example, dimagi = all
         self.assertEqual('example', example.domain)
         self.assertEqual('dimagi', dimagi.domain)
         for config in all:
             self.assertEqual('Custom Title', config.title)
示例#23
0
def _get_report_module_context(app, module):
    def _report_to_config(report):
        return {
            'report_id': report._id,
            'title': report.title,
            'description': report.description,
            'charts': [chart for chart in report.charts if
                       chart.type == 'multibar'],
            'filter_structure': report.filters_without_prefilters,
        }

    all_reports = ReportConfiguration.by_domain(app.domain) + \
                  StaticReportConfiguration.by_domain(app.domain)
    validity = module.check_report_validity()

    # We're now proactively deleting these references, so after that's been
    # out for a while, this can be removed (say June 2016 or later)
    if not validity.is_valid:
        module.report_configs = validity.valid_report_configs

    filter_choices = [
        {'slug': f.doc_type, 'description': f.short_description} for f in get_all_mobile_filter_configs()
    ]
    auto_filter_choices = [
        {'slug': f.slug, 'description': f.short_description} for f in get_auto_filter_configurations()

    ]
    from corehq.apps.app_manager.suite_xml.features.mobile_ucr import get_column_xpath_client_template, get_data_path
    data_path_placeholders = {}
    for r in module.report_configs:
        data_path_placeholders[r.report_id] = {}
        for chart_id in r.complete_graph_configs.keys():
            data_path_placeholders[r.report_id][chart_id] = get_data_path(r, app.domain)

    context = {
        'report_module_options': {
            'moduleName': module.name,
            'moduleFilter': module.module_filter,
            'availableReports': [_report_to_config(r) for r in all_reports],  # structure for all reports
            'currentReports': [r.to_json() for r in module.report_configs],  # config data for app reports
            'columnXpathTemplate': get_column_xpath_client_template(app.mobile_ucr_restore_version),
            'dataPathPlaceholders': data_path_placeholders,
            'languages': app.langs,
            'mobileUcrV1': app.mobile_ucr_restore_version == MOBILE_UCR_VERSION_1,
            'globalSyncDelay': Domain.get_by_name(app.domain).default_mobile_ucr_sync_interval,
        },
        'static_data_options': {
            'filterChoices': filter_choices,
            'autoFilterChoices': auto_filter_choices,
            'dateRangeOptions': [choice._asdict() for choice in get_simple_dateranges()],
        },
        'uuids_by_instance_id': get_uuids_by_instance_id(app.domain),
        'legacy_select2': True,
    }
    return context
示例#24
0
def _shared_context(domain):
    static_reports = list(StaticReportConfiguration.by_domain(domain))
    static_data_sources = list(StaticDataSourceConfiguration.by_domain(domain))
    return {
        'domain':
        domain,
        'reports':
        ReportConfiguration.by_domain(domain) + static_reports,
        'data_sources':
        DataSourceConfiguration.by_domain(domain) + static_data_sources,
    }
示例#25
0
def _get_report_module_context(app, module):
    def _report_to_config(report):
        return {
            'report_id': report._id,
            'title': report.title,
            'description': report.description,
            'charts': [chart for chart in report.charts if
                       chart.type == 'multibar'],
            'filter_structure': report.filters_without_prefilters,
        }

    all_reports = ReportConfiguration.by_domain(app.domain) + \
                  StaticReportConfiguration.by_domain(app.domain)
    validity = module.check_report_validity()

    # We're now proactively deleting these references, so after that's been
    # out for a while, this can be removed (say June 2016 or later)
    if not validity.is_valid:
        module.report_configs = validity.valid_report_configs

    filter_choices = [
        {'slug': f.doc_type, 'description': f.short_description} for f in get_all_mobile_filter_configs()
    ]
    auto_filter_choices = [
        {'slug': f.slug, 'description': f.short_description} for f in get_auto_filter_configurations()

    ]
    from corehq.apps.app_manager.suite_xml.features.mobile_ucr import get_column_xpath_client_template, get_data_path
    data_path_placeholders = {}
    for r in module.report_configs:
        data_path_placeholders[r.report_id] = {}
        for chart_id in r.complete_graph_configs.keys():
            data_path_placeholders[r.report_id][chart_id] = get_data_path(r, app.domain)

    context = {
        'report_module_options': {
            'moduleName': module.name,
            'moduleFilter': module.module_filter,
            'availableReports': [_report_to_config(r) for r in all_reports],  # structure for all reports
            'currentReports': [r.to_json() for r in module.report_configs],  # config data for app reports
            'columnXpathTemplate': get_column_xpath_client_template(app.mobile_ucr_restore_version),
            'dataPathPlaceholders': data_path_placeholders,
            'languages': app.langs,
            'supportSyncDelay': app.mobile_ucr_restore_version != MOBILE_UCR_VERSION_1,
            'globalSyncDelay': Domain.get_by_name(app.domain).default_mobile_ucr_sync_interval,
        },
        'static_data_options': {
            'filterChoices': filter_choices,
            'autoFilterChoices': auto_filter_choices,
            'dateRangeOptions': [choice._asdict() for choice in get_simple_dateranges()],
        },
    }
    return context
示例#26
0
 def main_context(self):
     static_reports = list(StaticReportConfiguration.by_domain(self.domain))
     static_data_sources = list(
         StaticDataSourceConfiguration.by_domain(self.domain))
     context = super(BaseUserConfigReportsView, self).main_context
     context.update({
         'reports':
         ReportConfiguration.by_domain(self.domain) + static_reports,
         'data_sources':
         DataSourceConfiguration.by_domain(self.domain) +
         static_data_sources,
     })
     return context
示例#27
0
    def _get_static_report_configuration_without_owner_transform(self, report_id, domain, override_agg_column):
        report_id = report_id.format(domain=domain)
        static_report_configuration = StaticReportConfiguration.by_id(report_id, domain)

        if override_agg_column and override_agg_column != 'awc_id':
            static_report_configuration = self._override_agg(static_report_configuration, override_agg_column)

        # this is explicitly after override, otherwise 'report_columns' attrib gets memoized too early
        for report_column in static_report_configuration.report_columns:
            transform = report_column.transform
            if transform.get('type') == 'custom' and transform.get('custom_type') == 'owner_display':
                report_column.transform = {}
        return static_report_configuration
示例#28
0
 def _get_report_configuration(self, id_, domain):
     """
     Fetch the required ReportConfiguration object
     :param id_: The id of the ReportConfiguration
     :param domain: The domain of the ReportConfiguration
     :return: A ReportConfiguration
     """
     try:
         if report_config_id_is_static(id_):
             return StaticReportConfiguration.by_id(id_, domain=domain)
         else:
             return get_document_or_not_found(ReportConfiguration, domain, id_)
     except DocumentNotFound:
         raise NotFound
示例#29
0
 def _get_report_configuration(self, id_, domain):
     """
     Fetch the required ReportConfiguration object
     :param id_: The id of the ReportConfiguration
     :param domain: The domain of the ReportConfiguration
     :return: A ReportConfiguration
     """
     try:
         if report_config_id_is_static(id_):
             return StaticReportConfiguration.by_id(id_, domain=domain)
         else:
             return get_document_or_not_found(ReportConfiguration, domain, id_)
     except DocumentNotFound:
         raise NotFound
示例#30
0
    def ucr_report(self):
        spec = StaticReportConfiguration.by_id('static-%s-adherence' % self.domain)
        report = ReportFactory.from_spec(
            spec, include_prefilters=True
        )

        filter_values = get_filter_values(spec.ui_filters, self.request_params, self.request.couch_user)
        locations_id = [
            Choice(value=location_id, display='') for location_id in self.report_config.locations_id
            if location_id
        ]

        if locations_id:
            filter_values['village'] = locations_id

        report.set_filter_values(filter_values)
        return report
示例#31
0
    def test_data_sources_actually_exist(self):

        data_sources_on_domain = defaultdict(set)
        for data_source in StaticDataSourceConfiguration.all():
            data_sources_on_domain[data_source.domain].add(data_source.get_id)

        def has_no_data_source(report_config):
            available_data_sources = data_sources_on_domain[report_config.domain]
            return report_config.config_id not in available_data_sources

        all_configs = StaticReportConfiguration.all()
        configs_missing_data_source = list(filter(has_no_data_source, all_configs))

        msg = ("There are {} report configs which reference data sources that "
               "don't exist (or which don't exist on that domain):\n{}".format(
                   len(configs_missing_data_source),
                   "\n".join(config.get_id for config in configs_missing_data_source)))
        self.assertEqual(0, len(configs_missing_data_source), msg)
示例#32
0
def _safely_get_report_configs(project_name):
    try:
        configs = ReportConfiguration.by_domain(project_name)
    except BadSpecError as e:
        logging.exception(e)

        # Pick out the UCRs that don't have spec errors
        configs = []
        for config_id in get_doc_ids_in_domain_by_class(project_name, ReportConfiguration):
            try:
                configs.append(ReportConfiguration.get(config_id))
            except BadSpecError as e:
                logging.error("%s with report config %s" % (e.message, config_id))

    try:
        configs.extend(StaticReportConfiguration.by_domain(project_name))
    except BadSpecError as e:
        logging.exception(e)

    return configs
示例#33
0
def _safely_get_report_configs(project_name):
    try:
        configs = ReportConfiguration.by_domain(project_name)
    except BadSpecError as e:
        logging.exception(e)

        # Pick out the UCRs that don't have spec errors
        configs = []
        for config_id in get_doc_ids_in_domain_by_class(project_name, ReportConfiguration):
            try:
                configs.append(ReportConfiguration.get(config_id))
            except BadSpecError as e:
                logging.error("%s with report config %s" % (e.message, config_id))

    try:
        configs.extend(StaticReportConfiguration.by_domain(project_name))
    except BadSpecError as e:
        logging.exception(e)

    return configs
示例#34
0
    def handle(self, **options):
        config_ids = get_doc_ids_by_class(ReportConfiguration)

        builder_count, ucr_count = 0, 0
        for doc in iter_docs(ReportConfiguration.get_db(), config_ids):
            if doc['report_meta']['created_by_builder']:
                builder_count += 1
            else:
                ucr_count += 1

        static_count = len(list(StaticReportConfiguration.all()))
        total_count = builder_count + ucr_count + static_count

        print(textwrap.dedent("""
            As of {}, on {} there are {} total UCRs:
            {} Report Builder Reports
            {} UCR Report Configs
            {} Static Report Configs enabled for the environment
        """.format(datetime.utcnow().date(), settings.SERVER_ENVIRONMENT, total_count,
                   builder_count, ucr_count, static_count)))
示例#35
0
    def handle(self, **options):
        config_ids = get_doc_ids_by_class(ReportConfiguration)

        builder_count, ucr_count = 0, 0
        for doc in iter_docs(ReportConfiguration.get_db(), config_ids):
            if doc['report_meta']['created_by_builder']:
                builder_count += 1
            else:
                ucr_count += 1

        static_count = len(list(StaticReportConfiguration.all()))
        total_count = builder_count + ucr_count + static_count

        print(
            textwrap.dedent("""
            As of {}, on {} there are {} total UCRs:
            {} Report Builder Reports
            {} UCR Report Configs
            {} Static Report Configs enabled for the environment
        """.format(datetime.utcnow().date(), settings.SERVER_ENVIRONMENT,
                   total_count, builder_count, ucr_count, static_count)))
示例#36
0
    def test_data_sources_actually_exist(self):

        data_sources_on_domain = defaultdict(set)
        for data_source in StaticDataSourceConfiguration.all():
            data_sources_on_domain[data_source.domain].add(data_source.get_id)

        def has_no_data_source(report_config):
            available_data_sources = data_sources_on_domain[
                report_config.domain]
            return report_config.config_id not in available_data_sources

        all_configs = StaticReportConfiguration.all()
        configs_missing_data_source = list(
            filter(has_no_data_source, all_configs))

        msg = ("There are {} report configs which reference data sources that "
               "don't exist (or which don't exist on that domain):\n{}".format(
                   len(configs_missing_data_source),
                   "\n".join(config.get_id
                             for config in configs_missing_data_source)))
        self.assertEqual(0, len(configs_missing_data_source), msg)
    def test_mixed_reports(self):
        dynamic_report_id = uuid.uuid4().hex
        dynamic_report = ReportConfiguration(
            _id=dynamic_report_id,
            domain='example',
            config_id=uuid.uuid4().hex

        )

        def get_docs_mock(db, ids):
            if ids == [dynamic_report_id]:
                return [dynamic_report.to_json()]
            return []

        with patch('corehq.apps.userreports.models.get_docs', new=get_docs_mock):
            with override_settings(STATIC_UCR_REPORTS=[self.get_path('static_report_config', 'json')]):
                configs = get_report_configs(
                    [dynamic_report_id, StaticReportConfiguration.get_doc_id('example', 'a-custom-report', False)],
                    'example'
                )
                self.assertEqual(len(configs), 2)
示例#38
0
    def test_mixed_reports(self):
        dynamic_report_id = uuid.uuid4().hex
        dynamic_report = ReportConfiguration(_id=dynamic_report_id,
                                             domain='example',
                                             config_id=uuid.uuid4().hex)

        def get_docs_mock(db, ids):
            if ids == [dynamic_report_id]:
                return [dynamic_report.to_json()]
            return []

        with patch('corehq.apps.userreports.models.get_docs',
                   new=get_docs_mock):
            with override_settings(STATIC_UCR_REPORTS=[
                    self.get_path('static_report_config', 'json')
            ]):
                configs = get_report_configs([
                    dynamic_report_id,
                    StaticReportConfiguration.get_doc_id(
                        'example', 'a-custom-report', False)
                ], 'example')
                self.assertEqual(len(configs), 2)
示例#39
0
def get_configurable_and_static_reports(domain):
    from corehq.apps.userreports.models import StaticReportConfiguration
    return get_existing_reports(domain) + StaticReportConfiguration.by_domain(
        domain)
示例#40
0
 def test_production_config(self):
     for report_config in StaticReportConfiguration.all():
         report_config.validate()
示例#41
0
 def _report_class(domain, config_id):
     class_path = StaticReportConfiguration.report_class_by_domain_and_id(
         domain, config_id
     )
     return to_function(class_path)
示例#42
0
    def charts(self):
        case_finding_sql_data = self.case_finding_sql_data[0]
        sputum_conversion_report = ReportFactory.from_spec(
            StaticReportConfiguration.by_id('static-%s-sputum_conversion' %
                                            self.domain),
            include_prefilters=True)

        filter_values = {'date': self.datespan}

        locations_id = [
            Choice(value=location_id, display='')
            for location_id in self.report_config.locations_id if location_id
        ]

        if locations_id:
            filter_values['village'] = locations_id

        if self.report_config.is_migrated is not None:
            filter_values['is_migrated'] = Choice(
                value=self.report_config.is_migrated, display='')

        sputum_conversion_report.set_filter_values(filter_values)
        sputum_conversion_data = sputum_conversion_report.get_data()[0]
        charts_sql_data = self.charts_sql_data[0]
        treatment_outcome_sql_data = self.treatment_outcome_sql_data[0]

        default_value = {'sort_key': 0}

        chart = PieChart(title=_('Cases by Gender'), key='gender', values=[])
        chart.data = [{
            'label':
            _('Male'),
            'value':
            case_finding_sql_data.get('male_total', default_value)['sort_key']
        }, {
            'label':
            _('Female'),
            'value':
            case_finding_sql_data.get('female_total',
                                      default_value)['sort_key']
        }, {
            'label':
            _('Transgender'),
            'value':
            case_finding_sql_data.get('transgender_total',
                                      default_value)['sort_key']
        }]

        chart2 = MultiBarChart(_('Cases By Type'),
                               x_axis=Axis(''),
                               y_axis=Axis(''))
        chart2.stacked = False
        chart2.showLegend = False

        positive_smear = case_finding_sql_data.get('new_positive_tb_pulmonary',
                                                   default_value)['sort_key']
        negative_smear = case_finding_sql_data.get('new_negative_tb_pulmonary',
                                                   default_value)['sort_key']
        positive_extra_pulmonary = case_finding_sql_data.get(
            'new_positive_tb_extrapulmonary', default_value)['sort_key']

        relapse_cases = case_finding_sql_data.get('recurrent_positive_tb',
                                                  default_value)['sort_key']
        failure_cases = case_finding_sql_data.get('failure_positive_tb',
                                                  default_value)['sort_key']
        lfu_cases = case_finding_sql_data.get('lfu_positive_tb',
                                              default_value)['sort_key']
        others_cases = case_finding_sql_data.get('others_positive_tb',
                                                 default_value)['sort_key']

        chart2.add_dataset(_('New'), [{
            'x': 'Smear +ve',
            'y': positive_smear
        }, {
            'x': 'Smear -ve',
            'y': negative_smear
        }, {
            'x': 'EP',
            'y': positive_extra_pulmonary
        }])

        chart2.add_dataset(_('Retreatment'), [{
            'x': 'Relapse',
            'y': relapse_cases
        }, {
            'x': 'Failure',
            'y': failure_cases
        }, {
            'x': 'Treatment After Default',
            'y': lfu_cases
        }, {
            'x': 'Others',
            'y': others_cases
        }])

        chart3 = MultiBarChart('Sputum Conversion By Patient Type', Axis(''),
                               Axis(''))
        chart3.stacked = True

        chart3.add_dataset('Positive', [
            {
                'x':
                _('New Sputum +ve (2 month IP)'),
                'y':
                sputum_conversion_data.get(
                    'new_sputum_positive_patient_2months_ip', 0)
            },
            {
                'x':
                _('New Sputum +ve (3 month IP)'),
                'y':
                sputum_conversion_data.get(
                    'new_sputum_positive_patient_3months_ip', 0)
            },
            {
                'x':
                _('Cat II (3 month IP)'),
                'y':
                sputum_conversion_data.get('positive_endofip_patients_cat2', 0)
            },
        ])

        chart3.add_dataset(_('Negative'), [
            {
                'x':
                _('New Sputum +ve (2 month IP)'),
                'y':
                sputum_conversion_data.get(
                    'new_sputum_negative_patient_2months_ip', 0)
            },
            {
                'x':
                _('New Sputum +ve (3 month IP)'),
                'y':
                sputum_conversion_data.get(
                    'new_sputum_negative_patient_3months_ip', 0)
            },
            {
                'x':
                _('Cat II (3 month IP)'),
                'y':
                sputum_conversion_data.get('negative_endofip_patients_cat2', 0)
            },
        ])

        chart3.add_dataset('NA', [
            {
                'x':
                _('New Sputum +ve (2 month IP)'),
                'y':
                sputum_conversion_data.get('new_sputum_na_patient_2months_ip',
                                           0)
            },
            {
                'x':
                _('New Sputum +ve (3 month IP)'),
                'y':
                sputum_conversion_data.get('new_sputum_na_patient_3months_ip',
                                           0)
            },
            {
                'x': _('Cat II (3 month IP)'),
                'y': sputum_conversion_data.get('na_endofip_patients_cat2', 0)
            },
        ])

        chart4 = PieChart(title=_('Total number of patients by category'),
                          key='',
                          values=[])
        chart4.data = [{
            'label':
            _('Cat1'),
            'value':
            charts_sql_data.get('cat1_patients', default_value)['sort_key']
        }, {
            'label':
            _('Cat2'),
            'value':
            charts_sql_data.get('cat2_patients', default_value)['sort_key']
        }]

        chart5 = MultiBarChart('Outcome By Type', Axis(''), Axis(''))
        chart5.stacked = True

        chart5.add_dataset(_('Cured'), [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_cured',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get('recurrent_patients_cured',
                                           default_value)['sort_key']
        }])
        chart5.add_dataset('Treatment Complete', [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_treatment_complete',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get(
                'recurrent_patients_treatment_complete',
                default_value)['sort_key']
        }])
        chart5.add_dataset('Died', [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_died',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get('recurrent_patients_died',
                                           default_value)['sort_key']
        }])
        chart5.add_dataset(_('Failure'), [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_treatment_failure',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get(
                'recurrent_patients_treatment_failure',
                default_value)['sort_key']
        }])
        chart5.add_dataset(_('Loss to Follow-up'), [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_loss_to_follow_up',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get(
                'recurrent_patients_loss_to_follow_up',
                default_value)['sort_key']
        }])
        chart5.add_dataset(_('Regimen Changed'), [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_regimen_changed',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get(
                'recurrent_patients_regimen_changed',
                default_value)['sort_key']
        }])
        chart5.add_dataset('Not Evaluated', [{
            'x':
            _('New'),
            'y':
            treatment_outcome_sql_data.get('new_patients_not_evaluated',
                                           default_value)['sort_key']
        }, {
            'x':
            _('Retreatment'),
            'y':
            treatment_outcome_sql_data.get('recurrent_patients_not_evaluated',
                                           default_value)['sort_key']
        }])

        return [chart, chart2, chart3, chart4, chart5]
示例#43
0
def _safely_get_static_report_configs(project_name):
    try:
        return StaticReportConfiguration.by_domain(project_name)
    except (BadSpecError, BadValueError) as e:
        logging.exception(e)
示例#44
0
 def spec(self):
     if self.is_static:
         return StaticReportConfiguration.by_id(self.report_config_id, domain=self.domain)
     else:
         return get_document_or_not_found(ReportConfiguration, self.domain, self.report_config_id)
示例#45
0
 def __init__(self, domain, filters, report_id):
     report_config = ReportFactory.from_spec(
         StaticReportConfiguration.by_id(report_id.format(domain=domain))
     )
     report_config.set_filter_values(filters)
     self.report_config = report_config
示例#46
0
 def test_production_config(self):
     for data_source in StaticReportConfiguration.all(
             ignore_server_environment=True):
         data_source.validate()
示例#47
0
 def test_production_config(self):
     for report_config in StaticReportConfiguration.all():
         report_config.validate()
示例#48
0
 def test_wrap(self):
     wrapped = StaticReportConfiguration.wrap(self.get_json('static_report_config'))
     self.assertEqual(["example", "dimagi"], wrapped.domains)
示例#49
0
    def charts(self):
        case_finding_sql_data = self.case_finding_sql_data[0]
        sputum_conversion_report = ReportFactory.from_spec(
            StaticReportConfiguration.by_id('static-%s-sputum_conversion' % self.domain), include_prefilters=True
        )

        filter_values = {'date': QuarterFilter.get_value(self.request, self.domain)}

        locations_id = [
            Choice(value=location_id, display='') for location_id in self.report_config.locations_id
            if location_id
        ]

        if locations_id:
            filter_values['village'] = locations_id

        sputum_conversion_report.set_filter_values(filter_values)
        sputum_conversion_data = sputum_conversion_report.get_data()[0]
        charts_sql_data = self.charts_sql_data[0]
        treatment_outcome_sql_data = self.treatment_outcome_sql_data[0]

        default_value = {'sort_key': 0}

        chart = PieChart(title=_('Cases by Gender'), key='gender', values=[])
        chart.data = [
            {'label': _('Male'), 'value': case_finding_sql_data.get('male_total', default_value)['sort_key']},
            {
                'label': _('Female'),
                'value': case_finding_sql_data.get('female_total', default_value)['sort_key']
            },
            {
                'label': _('Transgender'),
                'value': case_finding_sql_data.get('transgender_total', default_value)['sort_key']
            }
        ]

        chart2 = MultiBarChart(_('Cases By Type'), x_axis=Axis(''), y_axis=Axis(''))
        chart2.stacked = False
        chart2.showLegend = False

        positive_smear = case_finding_sql_data.get('new_positive_tb_pulmonary', default_value)['sort_key']
        negative_smear = case_finding_sql_data.get('new_negative_tb_pulmonary', default_value)['sort_key']
        positive_extra_pulmonary = case_finding_sql_data.get(
            'new_positive_tb_extrapulmonary', default_value
        )['sort_key']

        relapse_cases = case_finding_sql_data.get('recurrent_positive_tb', default_value)['sort_key']
        failure_cases = case_finding_sql_data.get('failure_positive_tb', default_value)['sort_key']
        lfu_cases = case_finding_sql_data.get('lfu_positive_tb', default_value)['sort_key']
        others_cases = case_finding_sql_data.get('others_positive_tb', default_value)['sort_key']

        chart2.add_dataset(
            _('New'),
            [
                {'x': 'Smear +ve', 'y': positive_smear},
                {'x': 'Smear -ve', 'y': negative_smear},
                {'x': 'EP', 'y': positive_extra_pulmonary}
            ]
        )

        chart2.add_dataset(
            _('Retreatment'), [
                {'x': 'Relapse', 'y': relapse_cases},
                {'x': 'Failure', 'y': failure_cases},
                {'x': 'Treatment After Default', 'y': lfu_cases},
                {'x': 'Others', 'y': others_cases}
            ]
        )

        chart3 = MultiBarChart('Sputum Conversion By Patient Type', Axis(''), Axis(''))
        chart3.stacked = True

        chart3.add_dataset('Positive', [
            {
                'x': _('New Sputum +ve (2 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_positive_patient_2months_ip', 0)
            },
            {
                'x': _('New Sputum +ve (3 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_positive_patient_3months_ip', 0)
            },
            {
                'x': _('Cat II (3 month IP)'),
                'y': sputum_conversion_data.get('positive_endofip_patients_cat2', 0)
            },
        ])

        chart3.add_dataset(_('Negative'), [
            {
                'x': _('New Sputum +ve (2 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_negative_patient_2months_ip', 0)
            },
            {
                'x': _('New Sputum +ve (3 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_negative_patient_3months_ip', 0)
            },
            {
                'x': _('Cat II (3 month IP)'),
                'y': sputum_conversion_data.get('negative_endofip_patients_cat2', 0)
            },
        ])

        chart3.add_dataset('NA', [
            {
                'x': _('New Sputum +ve (2 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_na_patient_2months_ip', 0)
            },
            {
                'x': _('New Sputum +ve (3 month IP)'),
                'y': sputum_conversion_data.get('new_sputum_na_patient_3months_ip', 0)
            },
            {
                'x': _('Cat II (3 month IP)'),
                'y': sputum_conversion_data.get('na_endofip_patients_cat2', 0)
            },
        ])

        chart4 = PieChart(
            title=_('Total number of patients by category'), key='', values=[]
        )
        chart4.data = [
            {
                'label': _('Cat1'),
                'value': charts_sql_data.get('cat1_patients', default_value)['sort_key']
            },
            {
                'label': _('Cat2'),
                'value': charts_sql_data.get('cat2_patients', default_value)['sort_key']
            }
        ]

        chart5 = MultiBarChart('Outcome By Type', Axis(''), Axis(''))
        chart5.stacked = True

        chart5.add_dataset(_('Cured'), [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_cured', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get('recurrent_patients_cured', default_value)['sort_key']
            }
        ])
        chart5.add_dataset('Treatment Complete', [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_treatment_complete', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get(
                    'recurrent_patients_treatment_complete', default_value)['sort_key']
            }
        ])
        chart5.add_dataset('Died', [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_died', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get('recurrent_patients_died', default_value)['sort_key']
            }
        ])
        chart5.add_dataset(_('Failure'), [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_treatment_failure', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get(
                    'recurrent_patients_treatment_failure', default_value
                )['sort_key']
            }
        ])
        chart5.add_dataset(_('Loss to Follow-up'), [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_loss_to_follow_up', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get(
                    'recurrent_patients_loss_to_follow_up', default_value
                )['sort_key']
            }
        ])
        chart5.add_dataset(_('Regimen Changed'), [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_regimen_changed', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get(
                    'recurrent_patients_regimen_changed', default_value
                )['sort_key']
            }
        ])
        chart5.add_dataset('Not Evaluated', [
            {
                'x': _('New'),
                'y': treatment_outcome_sql_data.get('new_patients_not_evaluated', default_value)['sort_key']
            },
            {
                'x': _('Retreatment'),
                'y': treatment_outcome_sql_data.get('recurrent_patients_not_evaluated', default_value)['sort_key']
            }
        ])

        return [
            chart,
            chart2,
            chart3,
            chart4,
            chart5
        ]
示例#50
0
 def _report_class(domain, config_id):
     class_path = StaticReportConfiguration.report_class_by_domain_and_id(
         domain, config_id
     )
     return to_function(class_path)
示例#51
0
 def __init__(self, domain, filters, report_id):
     report_config = ReportFactory.from_spec(
         StaticReportConfiguration.by_id(report_id.format(domain=domain)))
     report_config.set_filter_values(filters)
     self.report_config = report_config
示例#52
0
 def test_wrap(self):
     wrapped = StaticReportConfiguration.wrap(
         self.get_json('static_report_config'))
     self.assertEqual(["example", "dimagi"], wrapped.domains)
示例#53
0
 def test_production_config(self):
     for data_source in StaticReportConfiguration.all():
         data_source.validate()