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
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
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
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
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
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)
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])
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, }
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)
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, }
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()], }
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, }
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)
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)
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)
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
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)
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)
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
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
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
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
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
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
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 _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
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)))
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)))
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)
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)
def get_configurable_and_static_reports(domain): from corehq.apps.userreports.models import StaticReportConfiguration return get_existing_reports(domain) + StaticReportConfiguration.by_domain( domain)
def test_production_config(self): for report_config in StaticReportConfiguration.all(): report_config.validate()
def _report_class(domain, config_id): class_path = StaticReportConfiguration.report_class_by_domain_and_id( domain, config_id ) return to_function(class_path)
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]
def _safely_get_static_report_configs(project_name): try: return StaticReportConfiguration.by_domain(project_name) except (BadSpecError, BadValueError) as e: logging.exception(e)
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
def test_production_config(self): for data_source in StaticReportConfiguration.all( ignore_server_environment=True): data_source.validate()
def test_wrap(self): wrapped = StaticReportConfiguration.wrap(self.get_json('static_report_config')) self.assertEqual(["example", "dimagi"], wrapped.domains)
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 ]
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
def test_wrap(self): wrapped = StaticReportConfiguration.wrap( self.get_json('static_report_config')) self.assertEqual(["example", "dimagi"], wrapped.domains)
def test_production_config(self): for data_source in StaticReportConfiguration.all(): data_source.validate()