def get_section_elements(self): def include_sort(detail_type, detail): return detail_type.endswith( 'short') or detail.sort_nodeset_columns_for_detail() 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_type, detail, include_sort=include_sort(detail_type, detail), ) # list of DetailColumnInfo named tuples if detail_column_infos: if detail.use_case_tiles: helper = CaseTileHelper( self.app, module, detail, detail_type, self.build_profile_id) r.append(helper.build_case_tile_detail()) else: print_template_path = None if detail.print_template: print_template_path = detail.print_template[ 'path'] locale_id = id_strings.detail_title_locale( detail_type) title = Text(locale_id=locale_id ) if locale_id else Text() d = self.build_detail( module, detail_type, detail, detail_column_infos, tabs=list(detail.get_tabs()), id=id_strings.detail( module, detail_type), title=title, print_template=print_template_path, ) if d: r.append(d) # add the persist case context if needed and if # case tiles are present and have their own persistent block if (detail.persist_case_context and not (detail.use_case_tiles and detail.persist_tile_on_forms)): d = self._get_persistent_case_context_detail( module, detail.persistent_case_context_xml) r.append(d) if module.fixture_select.active: d = self._get_fixture_detail(module) r.append(d) return r
def _build_query_prompts(self): prompts = [] for prop in self.module.search_config.properties: text = Text(locale_id=id_strings.search_property_locale( self.module, prop.name)) if prop.hint: display = Display( text=text, hint=Hint(text=Text( locale_id=id_strings.search_property_hint_locale( self.module, prop.name)))) else: display = Display(text=text) kwargs = {'key': prop.name, 'display': display} if not prop.appearance or prop.itemset.nodeset: kwargs['receive'] = prop.receiver_expression if prop.appearance and self.app.enable_search_prompt_appearance: if prop.appearance == 'address': kwargs['input_'] = prop.appearance else: kwargs['appearance'] = prop.appearance if prop.input_: kwargs['input_'] = prop.input_ if prop.default_value and self.app.enable_default_value_expression: kwargs['default_value'] = prop.default_value if prop.itemset.nodeset: kwargs['itemset'] = Itemset( nodeset=prop.itemset.nodeset, label_ref=prop.itemset.label, value_ref=prop.itemset.value, sort_ref=prop.itemset.sort, ) prompts.append(QueryPrompt(**kwargs)) return prompts
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 Xpath( function=xpath_function.format(column_id=col.column_id), variables=[ XpathVariable(name='lang', locale_id='lang.current') ], ) else: if new_mobile_ucr_restore: return Xpath(function="{}".format(col.column_id), ) 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), )), )
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_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)) )
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_select_details(config, filter_slug, domain): return models.Detail(custom_xml=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())
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_pair in word_translations: lang = lang_translation_pair[0] translation = lang_translation_pair[1] 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(): xpath_function = _get_conditional( u"{value} = '{word}'".format( value=default_val, word=word, ), _get_word_eval(translations, default_val), 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), )), )
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 update_suite(self): """ Ensure that there exists at least one menu where id="root". """ if not self._contains_root_menu(self.suite.menus): self.suite.menus.append( Menu(id=id_strings.ROOT, text=Text(), style="grid"))
def _build_command(self): return Command( id=id_strings.search_command(self.module), display=Display( text=Text(locale_id=id_strings.case_search_locale(self.module)), ), )
def _get_reg_form_action(self, module): """ Returns registration form action """ form = self.app.get_form(module.case_list_form.form_id) if self.app.enable_localized_menu_media: case_list_form = module.case_list_form action = LocalizedAction( menu_locale_id=id_strings.case_list_form_locale(module), media_image=case_list_form.uses_image( build_profile_id=self.build_profile_id), media_audio=case_list_form.uses_audio( build_profile_id=self.build_profile_id), image_locale_id=id_strings.case_list_form_icon_locale(module), audio_locale_id=id_strings.case_list_form_audio_locale(module), stack=Stack(), for_action_menu=True, ) else: action = Action(display=Display( text=Text(locale_id=id_strings.case_list_form_locale(module)), media_image=module.case_list_form.default_media_image, media_audio=module.case_list_form.default_media_audio, ), stack=Stack()) frame = PushFrame() frame.add_command(XPath.string(id_strings.form_command(form))) target_form_dm = self.entries_helper.get_datums_meta_for_form_generic( form) source_form_dm = [] if len(module.forms): source_form_dm = self.entries_helper.get_datums_meta_for_form_generic( module.get_form(0)) for target_meta in target_form_dm: if target_meta.requires_selection: # This is true for registration forms where the case being created is a subcase try: [source_dm] = [ source_meta for source_meta in source_form_dm if source_meta.case_type == target_meta.case_type ] except ValueError: pass else: frame.add_datum( StackDatum(id=target_meta.datum.id, value=session_var(source_dm.datum.id))) else: s_datum = target_meta.datum frame.add_datum( StackDatum(id=s_datum.id, value=s_datum.function)) frame.add_datum( StackDatum(id=RETURN_TO, value=XPath.string(id_strings.menu_id(module)))) action.stack.add_frame(frame) return action
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_config_entry(config, domain): return Entry( command=Command( id='reports.{}'.format(config.uuid), text=Text(locale=Locale(id=id_strings.report_name(config.uuid)), ), ), datums=[ SessionDatum( detail_select=MobileSelectFilterHelpers.get_select_detail_id( config, filter_slug), id=MobileSelectFilterHelpers.get_datum_id(config, filter_slug), nodeset=MobileSelectFilterHelpers.get_options_nodeset( config, filter_slug), value='./@value', ) for filter_slug, f in MobileSelectFilterHelpers.get_filters( config, domain) ] + [ SessionDatum( detail_confirm=_get_summary_detail_id(config), detail_select=_get_select_detail_id(config), id='report_id_{}'.format(config.uuid), nodeset="instance('reports')/reports/report[@id='{}']".format( config.uuid), value='./@id', autoselect="true"), ])
def generate_suite(self): # Note: the order in which things happen in this function matters self._add_sections([ FormResourceContributor(self.suite, self.app, self.modules, self.build_profile_id), LocaleResourceContributor(self.suite, self.app, self.modules, self.build_profile_id), DetailContributor(self.suite, self.app, self.modules, self.build_profile_id), ]) if self.app.supports_practice_users and self.app.get_practice_user( self.build_profile_id): self._add_sections([ PracticeUserRestoreContributor(self.suite, self.app, self.modules, self.build_profile_id) ]) # by module entries = EntriesContributor(self.suite, self.app, self.modules, self.build_profile_id) menus = MenuContributor(self.suite, self.app, self.modules, self.build_profile_id) remote_requests = RemoteRequestContributor(self.suite, self.app, self.modules) if any(module.is_training_module for module in self.modules): training_menu = LocalizedMenu(id='training-root') training_menu.text = Text( locale_id=id_strings.training_module_locale()) else: training_menu = None for module in self.modules: self.suite.entries.extend(entries.get_module_contributions(module)) self.suite.menus.extend( menus.get_module_contributions(module, training_menu)) self.suite.remote_requests.extend( remote_requests.get_module_contributions(module)) if training_menu: self.suite.menus.append(training_menu) self._add_sections([ FixtureContributor(self.suite, self.app, self.modules), SchedulerFixtureContributor(self.suite, self.app, self.modules), ]) # post process if self.app.enable_post_form_workflow: WorkflowHelper(self.suite, self.app, self.modules).update_suite() if self.app.use_grid_menus: GridMenuHelper(self.suite, self.app, self.modules).update_suite() EntryInstances(self.suite, self.app, self.modules).update_suite() return self.suite.serializeDocument(pretty=True)
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.uuid) 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_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 _build_query_prompts(self): return [ QueryPrompt( key=p.name, display=Display( text=Text(locale_id=id_strings.search_property_locale( self.module, p.name)), ), ) for p in self.module.search_config.properties ]
def _get_case_search_action(module): action = Action(display=Display(text=Text( locale_id=id_strings.case_search_locale(module))), stack=Stack()) frame = PushFrame() frame.add_mark() frame.add_command(XPath.string(id_strings.search_command(module))) action.stack.add_frame(frame) return action
def get_form_enum_text(form): if not _form_uses_name_enum(form): return None return Text(xpath=XpathEnum.build( enum=form.name_enum, template='if({key_as_condition}, {key_as_var_name}', get_template_context=lambda item, i: { 'key_as_condition': item.key_as_condition(), 'key_as_var_name': item.ref_to_key_variable(i, 'display') }, get_value=lambda key: id_strings.form_name_enum_variable(form, key)))
def _get_lookup_element(self, detail, module): if detail.lookup_display_results: field = Field( header=Header( width=None if detail.lookup_field_header else 0, text=Text(locale_id=callout_header_locale(module)) if detail.lookup_field_header else None, ), template=Template(text=Text( xpath_function=detail.lookup_field_template)), ) else: field = None return Lookup( name=detail.lookup_name or None, auto_launch=detail.lookup_autolaunch or False, action=detail.lookup_action, image=detail.lookup_image or None, extras=[Extra(**e) for e in detail.lookup_extras], responses=[Response(**r) for r in detail.lookup_responses], field=field, )
def _get_case_search_action(module): relevant_kwarg = {} if module.search_config.search_button_display_condition: relevant_kwarg = dict(relevant=XPath( module.search_config.search_button_display_condition), ) action = Action(display=Display(text=Text( locale_id=id_strings.case_search_locale(module))), stack=Stack(), **relevant_kwarg) frame = PushFrame() frame.add_mark() frame.add_command(XPath.string(id_strings.search_command(module))) action.stack.add_frame(frame) return action
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'), ) # list of DetailColumnInfo named tuples if detail_column_infos: if detail.use_case_tiles: helper = CaseTileHelper( self.app, module, detail, detail_type, self.build_profile_id) r.append(helper.build_case_tile_detail()) else: print_template_path = None if detail.print_template: print_template_path = detail.print_template[ 'path'] d = self.build_detail( module, detail_type, detail, detail_column_infos, tabs=list(detail.get_tabs()), id=id_strings.detail( module, detail_type), title=Text(locale_id=id_strings. detail_title_locale( module, detail_type)), print_template=print_template_path, ) if d: r.append(d) if detail.persist_case_context and not detail.persist_tile_on_forms: d = self._get_persistent_case_context_detail( module, detail.persistent_case_context_xml) r.append(d) if module.fixture_select.active: d = self._get_fixture_detail(module) r.append(d) return r
def get_module_enum_text(module): if _should_use_root_display(module): module = module.root_module if not _module_uses_name_enum(module): return None return Text(xpath=XpathEnum.build( enum=module.name_enum, template='if({key_as_condition}, {key_as_var_name}', get_template_context=lambda item, i: { 'key_as_condition': item.key_as_condition(), 'key_as_var_name': item.ref_to_key_variable(i, 'display') }, get_value=lambda key: id_strings.module_name_enum_variable( module, key)))
def _get_case_search_action(module, in_search=False): action_kwargs = DetailContributor._get_action_kwargs(module, in_search) action = Action( display=Display(text=Text(locale_id=( id_strings.case_search_again_locale(module) if in_search else id_strings.case_search_locale(module)))), stack=Stack(), auto_launch=DetailContributor._get_auto_launch_expression( module, in_search), redo_last=in_search, **action_kwargs) frame = PushFrame() frame.add_mark() frame.add_command(XPath.string(id_strings.search_command(module))) action.stack.add_frame(frame) return action
def _get_case_search_action(module): relevant_kwarg = {} if module.search_config.search_button_display_condition: relevant_kwarg = dict(relevant=XPath( module.search_config.search_button_display_condition), ) allow_auto_launch = toggles.CASE_CLAIM_AUTOLAUNCH.enabled( module.get_app().domain) action = Action(display=Display(text=Text( locale_id=id_strings.case_search_locale(module))), stack=Stack(), auto_launch=allow_auto_launch and module.search_config.auto_launch, **relevant_kwarg) frame = PushFrame() frame.add_mark() frame.add_command(XPath.string(id_strings.search_command(module))) action.stack.add_frame(frame) return action
def build_stack(self): stack = Stack() rewind_if = None if module_uses_smart_links(self.module): user_domain_xpath = session_var(COMMCARE_PROJECT, path="user/data") # For case in same domain, do a regular case claim rewind rewind_if = self._get_case_domain_xpath().eq(user_domain_xpath) # For case in another domain, jump to that other domain frame = PushFrame(if_clause=XPath.not_(rewind_if)) frame.add_datum( StackJump(url=Text(xpath=TextXPath( function=self.get_smart_link_function(), variables=self.get_smart_link_variables(), ), ), )) stack.add_frame(frame) frame = PushFrame(if_clause=rewind_if) frame.add_rewind(QuerySessionXPath(self.case_session_var).instance()) stack.add_frame(frame) return stack
def _build_query_prompts(self): prompts = [] for prop in self.module.search_config.properties: kwargs = { 'key': prop.name, 'display': Display(text=Text(locale_id=id_strings.search_property_locale(self.module, prop.name))), } if prop.appearance and self.app.enable_search_prompt_appearance: kwargs['appearance'] = prop.appearance if prop.input_: kwargs['input_'] = prop.input_ if prop.itemset.nodeset: kwargs['itemset'] = Itemset( nodeset=prop.itemset.nodeset, label_ref=prop.itemset.label, value_ref=prop.itemset.value, sort_ref=prop.itemset.sort, ) prompts.append(QueryPrompt(**kwargs)) return prompts
def _get_case_search_action(module, in_search=False): relevant_kwarg = {} if not in_search and module.search_config.search_button_display_condition: relevant_kwarg = dict(relevant=XPath( module.search_config.search_button_display_condition), ) allow_auto_launch = toggles.USH_CASE_CLAIM_UPDATES.enabled( module.get_app().domain) and not in_search action = Action(display=Display(text=Text( locale_id=(id_strings.case_search_again_locale(module) if in_search else id_strings.case_search_locale(module)))), stack=Stack(), auto_launch=allow_auto_launch and module.search_config.auto_launch, redo_last=in_search, **relevant_kwarg) frame = PushFrame() frame.add_mark() frame.add_command(XPath.string(id_strings.search_command(module))) action.stack.add_frame(frame) return action