def _get_fixture_detail(module): d = Detail(id=id_strings.fixture_detail(module), title=Text()) xpath = Xpath(function=module.fixture_select.display_column) if module.fixture_select.localize: template_text = Text(locale=Locale(child_id=Id(xpath=xpath))) else: template_text = Text(xpath_function=module.fixture_select.display_column) fields = [Field(header=Header(text=Text()), template=Template(text=template_text), sort_node="")] d.fields = fields return d
def get_section_elements(self): r = [] if not self.app.use_custom_suite: for module in self.modules: for detail_type, detail, enabled in module.get_details(): if enabled: if detail.custom_xml: d = load_xmlobject_from_string( detail.custom_xml, xmlclass=Detail ) r.append(d) else: detail_column_infos = get_detail_column_infos( detail, include_sort=detail_type.endswith('short'), ) if detail_column_infos: if detail.use_case_tiles: r.append(self.build_case_tile_detail( module, detail, detail_type )) else: d = self.build_detail( module, detail_type, detail, detail_column_infos, list(detail.get_tabs()), id_strings.detail(module, detail_type), Text(locale_id=id_strings.detail_title_locale( module, detail_type )), 0, len(detail_column_infos) ) if d: r.append(d) if module.fixture_select.active: d = Detail( id=id_strings.fixture_detail(module), title=Text(), ) xpath = Xpath(function=module.fixture_select.display_column) if module.fixture_select.localize: template_text = Text(locale=Locale(child_id=Id(xpath=xpath))) else: template_text = Text(xpath_function=module.fixture_select.display_column) fields = [Field(header=Header(text=Text()), template=Template(text=template_text), sort_node='')] d.fields = fields r.append(d) return r
def get_select_details(config, filter_slug, domain): detail = Detail( id=MobileSelectFilterHelpers.get_select_detail_id( config, filter_slug), title=Text(config.report(domain).get_ui_filter(filter_slug).label), fields=[ Field( header=Header(text=Text( config.report(domain).get_ui_filter( filter_slug).label)), template=Template(text=Text(xpath_function='.')), ) ]).serialize() return models.Detail(custom_xml=detail.decode('utf-8'))
def _get_data_detail(config, domain): def _column_to_field(column): def _get_xpath(col): def _get_conditional(condition, if_true, if_false): return u'if({condition}, {if_true}, {if_false})'.format( condition=condition, if_true=if_true, if_false=if_false, ) def _get_word_eval(word_translations, default_value): word_eval = default_value for lang, translation in word_translations.items(): word_eval = _get_conditional( "$lang = '{lang}'".format(lang=lang, ), u"'{translation}'".format( translation=translation.replace("'", "''"), ), word_eval) return word_eval transform = col['transform'] if transform.get('type') == 'translation': default_val = "column[@id='{column_id}']" xpath_function = default_val for word, translations in transform['translations'].items(): if isinstance(translations, basestring): # This is a flat mapping, not per-language translations word_eval = "'{}'".format(translations) else: word_eval = _get_word_eval(translations, default_val) xpath_function = _get_conditional( u"{value} = '{word}'".format( value=default_val, word=word, ), word_eval, xpath_function) return Xpath( function=xpath_function.format(column_id=col.column_id), variables=[ XpathVariable(name='lang', locale_id='lang.current') ], ) else: return Xpath(function="column[@id='{}']".format( col.column_id), ) return Field( header=Header( text=Text(locale=Locale(id=id_strings.report_column_header( config.uuid, column.column_id)), )), template=Template(text=Text(xpath=_get_xpath(column), )), ) return Detail( id='reports.{}.data'.format(config.uuid), nodeset='rows/row{}'.format( _MobileSelectFilterHelpers.get_data_filter_xpath(config, domain)), title=Text(locale=Locale(id=id_strings.report_data_table()), ), fields=[ _column_to_field(c) for c in config.report(domain).report_columns ])
def _get_report_context_tile_detail(): from corehq.apps.app_manager.suite_xml.features.mobile_ucr import MOBILE_UCR_TILE_DETAIL_ID return Detail( id=MOBILE_UCR_TILE_DETAIL_ID, title=Text(), fields=[ Field( style=Style( horz_align="left", font_size="small", grid_height=1, grid_width=12, grid_x=0, grid_y=0, ), header=Header(text=Text()), template=Template(text=Text(xpath=Xpath( function= "concat($message, ' ', format-date(date(instance('commcare-reports:index')/report_index/reports/@last_update), '%e/%n/%Y'))", variables=[ XpathVariable( name='message', locale_id=id_strings.reports_last_updated_on()) ], ))), ) ])
def get_select_details(config, filter_slug, domain): detail = Detail( id=_MobileSelectFilterHelpers.get_select_detail_id(config, filter_slug), title=Text(config.report(domain).get_ui_filter(filter_slug).label), fields=[ Field( header=Header( text=Text(config.report(domain).get_ui_filter(filter_slug).label) ), template=Template( text=Text(xpath_function='.') ), ) ] ).serialize() return models.Detail(custom_xml=detail.decode('utf-8'))
def _get_fixture_detail(module): d = Detail( id=id_strings.fixture_detail(module), title=Text(), ) xpath = Xpath(function=module.fixture_select.display_column) if module.fixture_select.localize: template_text = Text(locale=Locale(child_id=Id(xpath=xpath))) else: template_text = Text( xpath_function=module.fixture_select.display_column) fields = [Field(header=Header(text=Text()), template=Template(text=template_text), sort_node='')] d.fields = fields return d
def _get_select_details(config): return models.Detail(custom_xml=Detail( id=_get_select_detail_id(config), title=Text(locale=Locale(id=id_strings.report_menu()), ), fields=[ Field( header=Header(text=Text(locale=Locale( id=id_strings.report_name_header()), )), template=Template(text=Text(locale=Locale( id=id_strings.report_name(config.uuid)))), ) ]).serialize().decode('utf-8'))
def _get_persistent_case_context_detail(module, xml): return Detail(id=id_strings.persistent_case_context_detail(module), title=Text(), fields=[ Field( style=Style( horz_align="center", font_size="large", grid_height=1, grid_width=12, grid_x=0, grid_y=0, ), header=Header(text=Text()), template=Template(text=Text(xpath_function=xml)), ) ])
def _get_summary_details(config, domain, module, new_mobile_ucr_restore=False): def _get_graph_fields(): from corehq.apps.userreports.reports.specs import MultibarChartSpec from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries def _locale_config(key): return id_strings.mobile_ucr_configuration( module, config.uuid, key ) def _locale_series_config(index, key): return id_strings.mobile_ucr_series_configuration( module, config.uuid, index, key ) def _locale_annotation(index): return id_strings.mobile_ucr_annotation( module, config.uuid, index ) for chart_config in config.report(domain).charts: if isinstance(chart_config, MultibarChartSpec): graph_config = config.complete_graph_configs.get(chart_config.chart_id, GraphConfiguration( series=[GraphSeries() for c in chart_config.y_axis_columns], )) # Reconcile graph_config.series with any additions/deletions in chart_config.y_axis_columns while len(chart_config.y_axis_columns) > len(graph_config.series): graph_config.series.append(GraphSeries()) if len(chart_config.y_axis_columns) < len(graph_config.series): graph_config.series = graph_config.series[:len(chart_config.y_axis_columns)] for index, column in enumerate(chart_config.y_axis_columns): graph_config.series[index].data_path = ( graph_config.series[index].data_path or get_data_path(config, domain, new_mobile_ucr_restore) ) graph_config.series[index].x_function = ( graph_config.series[index].x_function or _get_column_xpath_template(new_mobile_ucr_restore).format(chart_config.x_axis_column) ) graph_config.series[index].y_function = ( graph_config.series[index].y_function or _get_column_xpath_template(new_mobile_ucr_restore).format(column.column_id) ) yield Field( header=Header(text=Text()), template=GraphTemplate.build('graph', graph_config, locale_config=_locale_config, locale_series_config=_locale_series_config, locale_annotation=_locale_annotation) ) def _get_last_sync(report_config): if new_mobile_ucr_restore: last_sync_string = "format-date(date(instance('commcare-reports:{}')/@last_sync), '%Y-%m-%d %H:%M')" last_sync_string = last_sync_string.format(report_config.instance_id) else: last_sync_string = "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')" return Text( xpath=Xpath( function=last_sync_string ) ) def _get_description_text(report_config): if report_config.use_xpath_description: return Text( xpath=Xpath(function=config.xpath_description) ) else: return Text( locale=Locale(id=id_strings.report_description(report_config.uuid)) ) detail_id = 'reports.{}.summary'.format(config.uuid) detail = Detail( title=Text( locale=Locale(id=id_strings.report_menu()), ), fields=[ Field( header=Header( text=Text( locale=Locale(id=id_strings.report_name_header()) ) ), template=Template( text=Text( locale=Locale(id=id_strings.report_name(config.uuid)) ) ), ), Field( header=Header( text=Text( locale=Locale(id=id_strings.report_description_header()), ) ), template=Template( text=_get_description_text(config) ), ), ] + [ Field( header=Header( text=Text( locale=Locale(id=id_strings.report_last_sync()) ) ), template=Template(text=_get_last_sync(config)) ), ] + list(_get_graph_fields()), ) if config.show_data_table: return models.Detail(custom_xml=Detail( id=detail_id, title=Text( locale=Locale(id=id_strings.report_menu()), ), details=[detail, _get_data_detail(config, domain, new_mobile_ucr_restore)] ).serialize().decode('utf-8')) else: detail.id = detail_id return models.Detail(custom_xml=detail.serialize().decode('utf-8'))
def build_detail(self, module, detail_type, detail, detail_column_infos, tabs=None, id=None, title=None, nodeset=None, print_template=None, start=0, end=None, relevant=None): """ Recursively builds the Detail object. (Details can contain other details for each of their tabs) """ from corehq.apps.app_manager.detail_screen import get_column_generator d = Detail(id=id, title=title, nodeset=nodeset, print_template=print_template, relevant=relevant) self._add_custom_variables(detail, d) if tabs: tab_spans = detail.get_tab_spans() for tab in tabs: # relevant should be set to None even in case its '' tab_relevant = None if tab.relevant and toggles.DISPLAY_CONDITION_ON_TABS.enabled( module.get_app().domain): tab_relevant = tab.relevant sub_detail = self.build_detail( module, detail_type, detail, detail_column_infos, title=Text(locale_id=id_strings.detail_tab_title_locale( module, detail_type, tab)), nodeset=tab.nodeset if tab.has_nodeset else None, start=tab_spans[tab.id][0], end=tab_spans[tab.id][1], relevant=tab_relevant, ) if sub_detail: d.details.append(sub_detail) if len(d.details): helper = EntriesHelper(self.app) datums = helper.get_datum_meta_module(module) d.variables.extend([ DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums ]) return d else: return None # Base case (has no tabs) else: # Add lookup if detail.lookup_enabled and detail.lookup_action: d.lookup = self._get_lookup_element(detail, module) # Add variables variables = list( schedule_detail_variables(module, detail, detail_column_infos)) if variables: d.variables.extend(variables) # Add fields if end is None: end = len(detail_column_infos) for column_info in detail_column_infos[start:end]: # column_info is an instance of DetailColumnInfo named tuple. It has the following properties: # column_info.column: an instance of app_manager.models.DetailColumn # column_info.sort_element: an instance of app_manager.models.SortElement # column_info.order: an integer fields = get_column_generator(self.app, module, detail, parent_tab_nodeset=nodeset, detail_type=detail_type, *column_info).fields for field in fields: d.fields.append(field) # Add actions if detail_type.endswith('short') and not module.put_in_root: if module.case_list_form.form_id: target_form = self.app.get_form( module.case_list_form.form_id) if target_form.is_registration_form(module.case_type): d.actions.append(self._get_reg_form_action(module)) if module_offers_search(module): d.actions.append( self._get_case_search_action(module, in_search="search" in id)) try: if not self.app.enable_multi_sort: d.fields[0].sort = 'default' except IndexError: pass else: # only yield the Detail if it has Fields return d
def build_detail(self, module, detail_type, detail, detail_column_infos, tabs, id, title, start, end): """ Recursively builds the Detail object. (Details can contain other details for each of their tabs) """ from corehq.apps.app_manager.detail_screen import get_column_generator d = Detail(id=id, title=title) if tabs: tab_spans = detail.get_tab_spans() for tab in tabs: sub_detail = self.build_detail( module, detail_type, detail, detail_column_infos, [], None, Text(locale_id=id_strings.detail_tab_title_locale( module, detail_type, tab )), tab_spans[tab.id][0], tab_spans[tab.id][1] ) if sub_detail: d.details.append(sub_detail) if len(d.details): return d else: return None # Base case (has no tabs) else: # Add lookup if detail.lookup_enabled and detail.lookup_action: d.lookup = Lookup( name=detail.lookup_name or None, action=detail.lookup_action, image=detail.lookup_image or None, ) d.lookup.extras = [Extra(**e) for e in detail.lookup_extras] d.lookup.responses = [Response(**r) for r in detail.lookup_responses] # Add variables variables = list( schedule_detail_variables(module, detail, detail_column_infos) ) if variables: d.variables.extend(variables) # Add fields for column_info in detail_column_infos[start:end]: fields = get_column_generator( self.app, module, detail, detail_type=detail_type, *column_info ).fields d.fields.extend(fields) # Add actions if module.case_list_form.form_id and detail_type.endswith('short')\ and not module.put_in_root: target_form = self.app.get_form(module.case_list_form.form_id) if target_form.is_registration_form(module.case_type): self._add_action_to_detail(d, module) try: if not self.app.enable_multi_sort: d.fields[0].sort = 'default' except IndexError: pass else: # only yield the Detail if it has Fields return d
def build_detail(self, module, detail_type, detail, detail_column_infos, tabs=None, id=None, title=None, nodeset=None, start=0, end=None): """ Recursively builds the Detail object. (Details can contain other details for each of their tabs) """ from corehq.apps.app_manager.detail_screen import get_column_generator d = Detail(id=id, title=title, nodeset=nodeset) if tabs: tab_spans = detail.get_tab_spans() for tab in tabs: sub_detail = self.build_detail( module, detail_type, detail, detail_column_infos, title=Text(locale_id=id_strings.detail_tab_title_locale( module, detail_type, tab)), nodeset=tab.nodeset if tab.has_nodeset else None, start=tab_spans[tab.id][0], end=tab_spans[tab.id][1]) if sub_detail: d.details.append(sub_detail) if len(d.details): helper = EntriesHelper(self.app) datums = helper.get_datum_meta_module(module) d.variables.extend([ DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums ]) return d else: return None # Base case (has no tabs) else: # Add lookup if detail.lookup_enabled and detail.lookup_action: d.lookup = self._get_lookup_element(detail, module) # Add variables variables = list( schedule_detail_variables(module, detail, detail_column_infos)) if variables: d.variables.extend(variables) # Add fields if end is None: end = len(detail_column_infos) for column_info in detail_column_infos[start:end]: fields = get_column_generator(self.app, module, detail, detail_type=detail_type, *column_info).fields d.fields.extend(fields) # Add actions if module.case_list_form.form_id and detail_type.endswith('short')\ and not module.put_in_root: target_form = self.app.get_form(module.case_list_form.form_id) if target_form.is_registration_form(module.case_type): d.actions.append(self._get_reg_form_action(module)) if module_offers_search(module) and detail_type.endswith( 'short') and not module.put_in_root: d.actions.append(self._get_case_search_action(module)) try: if not self.app.enable_multi_sort: d.fields[0].sort = 'default' except IndexError: pass else: # only yield the Detail if it has Fields return d
def _get_summary_details(config, domain, module): def _get_graph_fields(): from corehq.apps.userreports.reports.specs import MultibarChartSpec from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries def _locale_config(key): return id_strings.mobile_ucr_configuration(module, config.uuid, key) def _locale_series_config(index, key): return id_strings.mobile_ucr_series_configuration( module, config.uuid, index, key) def _locale_annotation(index): return id_strings.mobile_ucr_annotation(module, config.uuid, index) for chart_config in config.report(domain).charts: if isinstance(chart_config, MultibarChartSpec): graph_config = config.complete_graph_configs.get( chart_config.chart_id, GraphConfiguration(series=[ GraphSeries() for c in chart_config.y_axis_columns ], )) for index, column in enumerate(chart_config.y_axis_columns): graph_config.series[index].data_path = ( graph_config.series[index].data_path or get_data_path(config, domain)) graph_config.series[index].x_function = ( graph_config.series[index].x_function or COLUMN_XPATH_TEMPLATE.format( chart_config.x_axis_column)) graph_config.series[index].y_function = ( graph_config.series[index].y_function or COLUMN_XPATH_TEMPLATE.format(column.column_id)) yield Field(header=Header(text=Text()), template=GraphTemplate.build( 'graph', graph_config, locale_config=_locale_config, locale_series_config=_locale_series_config, locale_annotation=_locale_annotation)) def _get_description_text(report_config): if report_config.use_xpath_description: return Text(xpath=Xpath(function=config.xpath_description)) else: return Text(locale=Locale( id=id_strings.report_description(report_config.uuid))) detail_id = 'reports.{}.summary'.format(config.uuid) detail = Detail( title=Text(locale=Locale(id=id_strings.report_menu()), ), fields=[ Field( header=Header(text=Text(locale=Locale( id=id_strings.report_name_header()))), template=Template(text=Text(locale=Locale( id=id_strings.report_name(config.uuid)))), ), Field( header=Header(text=Text(locale=Locale( id=id_strings.report_description_header()), )), template=Template(text=_get_description_text(config)), ), ] + [ Field( header=Header(text=Text(locale=Locale( id=id_strings.report_last_sync()))), template=Template(text=Text(xpath=Xpath( function= "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')" )))), ] + list(_get_graph_fields()), ) if config.show_data_table: return models.Detail(custom_xml=Detail( id=detail_id, title=Text(locale=Locale(id=id_strings.report_menu()), ), details=[detail, _get_data_detail(config, domain) ]).serialize().decode('utf-8')) else: detail.id = detail_id return models.Detail(custom_xml=detail.serialize().decode('utf-8'))
def build_detail(self, module, detail_type, detail, detail_column_infos, tabs=None, id=None, title=None, nodeset=None, start=0, end=None): """ Recursively builds the Detail object. (Details can contain other details for each of their tabs) """ from corehq.apps.app_manager.detail_screen import get_column_generator d = Detail(id=id, title=title, nodeset=nodeset) self._add_custom_variables(detail, d) if tabs: tab_spans = detail.get_tab_spans() for tab in tabs: sub_detail = self.build_detail( module, detail_type, detail, detail_column_infos, title=Text(locale_id=id_strings.detail_tab_title_locale( module, detail_type, tab )), nodeset=tab.nodeset if tab.has_nodeset else None, start=tab_spans[tab.id][0], end=tab_spans[tab.id][1] ) if sub_detail: d.details.append(sub_detail) if len(d.details): helper = EntriesHelper(self.app) datums = helper.get_datum_meta_module(module) d.variables.extend([DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums]) return d else: return None # Base case (has no tabs) else: # Add lookup if detail.lookup_enabled and detail.lookup_action: d.lookup = self._get_lookup_element(detail, module) # Add variables variables = list( schedule_detail_variables(module, detail, detail_column_infos) ) if variables: d.variables.extend(variables) # Add fields if end is None: end = len(detail_column_infos) for column_info in detail_column_infos[start:end]: fields = get_column_generator( self.app, module, detail, detail_type=detail_type, *column_info ).fields d.fields.extend(fields) # Add actions if module.case_list_form.form_id and detail_type.endswith('short')\ and not module.put_in_root: target_form = self.app.get_form(module.case_list_form.form_id) if target_form.is_registration_form(module.case_type): d.actions.append(self._get_reg_form_action(module)) if module_offers_search(module) and detail_type.endswith('short') and not module.put_in_root: d.actions.append(self._get_case_search_action(module)) try: if not self.app.enable_multi_sort: d.fields[0].sort = 'default' except IndexError: pass else: # only yield the Detail if it has Fields return d
def _get_summary_details(config, domain): def _get_graph_fields(): from corehq.apps.userreports.reports.specs import MultibarChartSpec # todo: make this less hard-coded for chart_config in config.report(domain).charts: if isinstance(chart_config, MultibarChartSpec): graph_config = config.graph_configs.get( chart_config.chart_id, ReportGraphConfig()) def _column_to_series(column): return Series(nodeset=( "instance('reports')/reports/report[@id='{}']/rows/row[@is_total_row='False']{}" .format( config.uuid, _MobileSelectFilterHelpers.get_data_filter_xpath( config, domain))), x_function="column[@id='{}']".format( chart_config.x_axis_column), y_function="column[@id='{}']".format(column), configuration=ConfigurationGroup(configs=[ ConfigurationItem(id=key, xpath_function=value) for key, value in graph_config. series_configs.get(column, {}).items() ])) yield Field( header=Header(text=Text()), template=GraphTemplate( form='graph', graph=Graph( type=graph_config.graph_type, series=[ _column_to_series(c.column_id) for c in chart_config.y_axis_columns ], configuration=ConfigurationGroup(configs=[ ConfigurationItem(id=key, xpath_function=value) for key, value in graph_config.config.items() ]), ), )) def _get_description_text(report_config): if report_config.use_xpath_description: return Text(xpath=Xpath(function=config.xpath_description)) else: return Text(locale=Locale( id=id_strings.report_description(report_config.uuid))) return models.Detail(custom_xml=Detail( id='reports.{}.summary'.format(config.uuid), title=Text(locale=Locale(id=id_strings.report_menu()), ), details=[ Detail( title=Text(locale=Locale(id=id_strings.report_menu()), ), fields=[ Field( header=Header(text=Text(locale=Locale( id=id_strings.report_name_header()))), template=Template(text=Text(locale=Locale( id=id_strings.report_name(config.uuid)))), ), Field( header=Header(text=Text(locale=Locale( id=id_strings.report_description_header()), )), template=Template(text=_get_description_text(config)), ), ] + [ Field( header=Header(text=Text(locale=Locale(id=id_strings. report_last_sync( )))), template=Template(text=Text(xpath=Xpath( function= "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')" )))), ] + list(_get_graph_fields()), ), _get_data_detail(config, domain), ], ).serialize().decode('utf-8'))
def _get_data_detail(config, domain, new_mobile_ucr_restore): """ Adds a data table to the report """ def get_xpath(column_id): if new_mobile_ucr_restore: return TextXPath(function="{}".format(column_id), ) else: return TextXPath(function="column[@id='{}']".format(column_id), ) def _column_to_field(column): def _get_xpath(col): def _get_conditional(condition, if_true, if_false): return 'if({condition}, {if_true}, {if_false})'.format( condition=condition, if_true=if_true, if_false=if_false, ) def _get_word_eval(word_translations, default_value): word_eval = default_value for lang, translation in word_translations.items(): word_eval = _get_conditional( "$lang = '{lang}'".format(lang=lang, ), "'{translation}'".format( translation=translation.replace("'", "''"), ), word_eval) return word_eval try: transform = col['transform'] except KeyError: transform = {} if transform.get('type') == 'translation': if new_mobile_ucr_restore: default_val = "{column_id}" else: default_val = "column[@id='{column_id}']" xpath_function = default_val for word, translations in transform['translations'].items(): if isinstance(translations, str): # This is a flat mapping, not per-language translations word_eval = "'{}'".format(translations) else: word_eval = _get_word_eval(translations, default_val) xpath_function = _get_conditional( "{value} = '{word}'".format( value=default_val, word=word, ), word_eval, xpath_function) return TextXPath( function=xpath_function.format(column_id=col.column_id), variables=[ XPathVariable(name='lang', locale_id='lang.current') ], ) else: return get_xpath(col.column_id) return Field( header=Header( text=Text(locale=Locale(id=id_strings.report_column_header( config.uuid, column.column_id)), )), template=Template(text=Text(xpath=_get_xpath(column), )), ) nodeset_string = 'row{}' if new_mobile_ucr_restore else 'rows/row{}' if toggles.ADD_ROW_INDEX_TO_MOBILE_UCRS.enabled(domain): fields = [ Field(header=Header( text=Text(), width=0, ), template=Template( text=Text(), width=0, ), sort_node=Sort( type='int', direction='ascending', order='1', text=Text(xpath=get_xpath("row_index")), )) ] else: fields = [] return Detail( id='reports.{}.data'.format(config.uuid), nodeset=(nodeset_string.format( MobileSelectFilterHelpers.get_data_filter_xpath( config, domain, new_mobile_ucr_restore))), title=Text(locale=Locale(id=id_strings.report_data_table()), ), fields=fields + [ _column_to_field(c) for c in config.report(domain).report_columns if c.type != 'expanded' and c.visible ])
def _get_summary_details(config, domain, module, new_mobile_ucr_restore=False): def _get_graph_fields(): from corehq.apps.userreports.reports.specs import MultibarChartSpec from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries def _locale_config(key): return id_strings.mobile_ucr_configuration(module, config.uuid, key) def _locale_series_config(index, key): return id_strings.mobile_ucr_series_configuration( module, config.uuid, index, key) def _locale_annotation(index): return id_strings.mobile_ucr_annotation(module, config.uuid, index) for chart_config in config.report(domain).charts: if isinstance(chart_config, MultibarChartSpec): graph_config = config.complete_graph_configs.get( chart_config.chart_id, GraphConfiguration(series=[ GraphSeries() for c in chart_config.y_axis_columns ], )) # Reconcile graph_config.series with any additions/deletions in chart_config.y_axis_columns while len(chart_config.y_axis_columns) > len( graph_config.series): graph_config.series.append(GraphSeries()) if len(chart_config.y_axis_columns) < len(graph_config.series): graph_config.series = graph_config.series[:len( chart_config.y_axis_columns)] for index, column in enumerate(chart_config.y_axis_columns): graph_config.series[index].data_path = ( graph_config.series[index].data_path or get_data_path( config, domain, new_mobile_ucr_restore)) graph_config.series[index].x_function = ( graph_config.series[index].x_function or _get_column_xpath_template(new_mobile_ucr_restore). format(chart_config.x_axis_column)) graph_config.series[index].y_function = ( graph_config.series[index].y_function or _get_column_xpath_template( new_mobile_ucr_restore).format(column.column_id)) yield Field(header=Header(text=Text()), template=GraphTemplate.build( 'graph', graph_config, locale_config=_locale_config, locale_series_config=_locale_series_config, locale_annotation=_locale_annotation)) def _get_last_sync(report_config): if new_mobile_ucr_restore: last_sync_string = "format-date(date(instance('commcare-reports:{}')/@last_sync), '%Y-%m-%d %H:%M')" last_sync_string = last_sync_string.format( report_config.instance_id) else: last_sync_string = "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')" return Text(xpath=TextXPath(function=last_sync_string)) def _get_description_text(report_config): if report_config.use_xpath_description: return Text(xpath=TextXPath(function=config.xpath_description)) else: return Text(locale=Locale( id=id_strings.report_description(report_config.uuid))) detail_id = 'reports.{}.summary'.format(config.uuid) fields = [ Field( header=Header(text=Text(locale=Locale( id=id_strings.report_name_header()))), template=Template(text=Text(locale=Locale( id=id_strings.report_name(config.uuid)))), ), Field( header=Header(text=Text(locale=Locale( id=id_strings.report_description_header()), )), template=Template(text=_get_description_text(config)), ), ] if not getattr(module, 'report_context_tile', False): # Don't add "Last Sync" if the module already contains the similar-looking # "Reports last updated on" tile fields.append( Field(header=Header(text=Text(locale=Locale( id=id_strings.report_last_sync()))), template=Template(text=_get_last_sync(config)))) fields += list(_get_graph_fields()) detail = Detail( title=Text(locale=Locale(id=id_strings.report_menu()), ), fields=fields, ) if config.show_data_table: return models.Detail(custom_xml=Detail( id=detail_id, title=Text(locale=Locale(id=id_strings.report_menu()), ), details=[ detail, _get_data_detail(config, domain, new_mobile_ucr_restore) ]).serialize().decode('utf-8')) else: detail.id = detail_id return models.Detail(custom_xml=detail.serialize().decode('utf-8'))
def build_detail(self, module, detail_type, detail, detail_column_infos, tabs=None, id=None, title=None, nodeset=None, print_template=None, start=0, end=None, relevant=None): """ Recursively builds the Detail object. (Details can contain other details for each of their tabs) """ from corehq.apps.app_manager.detail_screen import get_column_generator d = Detail(id=id, title=title, nodeset=nodeset, print_template=print_template, relevant=relevant) self._add_custom_variables(detail, d) if tabs: tab_spans = detail.get_tab_spans() for tab in tabs: # relevant should be set to None even in case its '' tab_relevant = None if tab.relevant and toggles.DISPLAY_CONDITION_ON_TABS.enabled(module.get_app().domain): tab_relevant = tab.relevant sub_detail = self.build_detail( module, detail_type, detail, detail_column_infos, title=Text(locale_id=id_strings.detail_tab_title_locale( module, detail_type, tab )), nodeset=tab.nodeset if tab.has_nodeset else None, start=tab_spans[tab.id][0], end=tab_spans[tab.id][1], relevant=tab_relevant, ) if sub_detail: d.details.append(sub_detail) if len(d.details): helper = EntriesHelper(self.app) datums = helper.get_datum_meta_module(module) d.variables.extend([DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums]) return d else: return None # Base case (has no tabs) else: # Add lookup if detail.lookup_enabled and detail.lookup_action: d.lookup = self._get_lookup_element(detail, module) # Add variables variables = list( schedule_detail_variables(module, detail, detail_column_infos) ) if variables: d.variables.extend(variables) # Add fields if end is None: end = len(detail_column_infos) for column_info in detail_column_infos[start:end]: # column_info is an instance of DetailColumnInfo named tuple. It has the following properties: # column_info.column: an instance of app_manager.models.DetailColumn # column_info.sort_element: an instance of app_manager.models.SortElement # column_info.order: an integer fields = get_column_generator( self.app, module, detail, parent_tab_nodeset=nodeset, detail_type=detail_type, *column_info ).fields for field in fields: d.fields.append(field) # Add actions if detail_type.endswith('short') and not module.put_in_root: if module.case_list_form.form_id: target_form = self.app.get_form(module.case_list_form.form_id) if target_form.is_registration_form(module.case_type): d.actions.append(self._get_reg_form_action(module)) if module_offers_search(module) and "search" not in id: # Add the search action only if this isn't a search detail d.actions.append(self._get_case_search_action(module)) try: if not self.app.enable_multi_sort: d.fields[0].sort = 'default' except IndexError: pass else: # only yield the Detail if it has Fields return d