def get_commands(): for form in module.get_suite_forms(): command = Command(id=id_strings.form_command(form, module)) if form.requires_case(): form_datums = self.entries_helper.get_datums_meta_for_form_generic(form, module) var_name = next( meta.datum.id for meta in reversed(form_datums) if meta.action and meta.requires_selection ) case = CaseIDXPath(session_var(var_name)).case() else: case = None if ( getattr(form, "form_filter", None) and not module.put_in_root and (module.all_forms_require_a_case() or is_usercase_in_use(self.app.domain)) ): fixture_xpath = ( session_var(id_strings.fixture_session_var(module)) if module.fixture_select.active else None ) command.relevant = interpolate_xpath(form.form_filter, case, fixture_xpath) if getattr(module, "has_schedule", False) and module.all_forms_require_a_case(): # If there is a schedule and another filter condition, disregard it... # Other forms of filtering are disabled in the UI schedule_filter_condition = MenuContributor._schedule_filter_conditions(form, module, case) if schedule_filter_condition is not None: command.relevant = schedule_filter_condition yield command if hasattr(module, "case_list") and module.case_list.show: yield Command(id=id_strings.case_list_command(module))
def get_module_contributions(self, module): def get_commands(): @memoized def module_uses_case(): return module.all_forms_require_a_case() @memoized def domain_uses_usercase(): return is_usercase_in_use(self.app.domain) for form in module.get_suite_forms(): command = Command(id=id_strings.form_command(form, module)) if form.requires_case(): form_datums = self.entries_helper.get_datums_meta_for_form_generic( form, module) var_name = next(meta.datum.id for meta in reversed(form_datums) if meta.action and meta.requires_selection) case = CaseIDXPath(session_var(var_name)).case() else: case = None if getattr(form, 'form_filter', None): fixture_xpath = (session_var( id_strings.fixture_session_var(module)) if module.fixture_select.active else None) interpolated_xpath = interpolate_xpath(form.form_filter, case, fixture_xpath, module=module, form=form) if xpath_references_case(interpolated_xpath) and \ (not module_uses_case() or module.put_in_root): raise CaseXPathValidationError(module=module, form=form) if xpath_references_user_case( interpolated_xpath) and not domain_uses_usercase(): raise UserCaseXPathValidationError(module=module, form=form) command.relevant = interpolated_xpath if getattr(module, 'has_schedule', False) and module.all_forms_require_a_case(): # If there is a schedule and another filter condition, disregard it... # Other forms of filtering are disabled in the UI schedule_filter_condition = MenuContributor._schedule_filter_conditions( form, module, case) if schedule_filter_condition is not None: command.relevant = schedule_filter_condition yield command if hasattr(module, 'case_list') and module.case_list.show: yield Command(id=id_strings.case_list_command(module))
def get_commands(excluded_form_ids): @memoized def module_uses_case(): return module.all_forms_require_a_case() @memoized def domain_uses_usercase(): return is_usercase_in_use(self.app.domain) for form in module.get_suite_forms(): if form.unique_id in excluded_form_ids: continue command = Command(id=id_strings.form_command(form, module)) if form.requires_case(): form_datums = self.entries_helper.get_datums_meta_for_form_generic(form, module) var_name = next( meta.datum.id for meta in reversed(form_datums) if meta.action and meta.requires_selection ) case = CaseIDXPath(session_var(var_name)).case() else: case = None if getattr(form, 'form_filter', None): fixture_xpath = ( session_var(id_strings.fixture_session_var(module)) if module.fixture_select.active else None ) interpolated_xpath = interpolate_xpath(form.form_filter, case, fixture_xpath, module=module, form=form) if xpath_references_case(interpolated_xpath) and \ (not module_uses_case() or module.put_in_root and not module.root_requires_same_case()): raise CaseXPathValidationError(module=module, form=form) if xpath_references_user_case(interpolated_xpath) and not domain_uses_usercase(): raise UserCaseXPathValidationError(module=module, form=form) command.relevant = interpolated_xpath if getattr(module, 'has_schedule', False) and module.all_forms_require_a_case(): # If there is a schedule and another filter condition, disregard it... # Other forms of filtering are disabled in the UI schedule_filter_condition = MenuContributor._schedule_filter_conditions(form, module, case) if schedule_filter_condition is not None: command.relevant = schedule_filter_condition yield command if hasattr(module, 'case_list') and module.case_list.show: yield Command(id=id_strings.case_list_command(module))
def _add_stack_children_for_target(self, stack_frames, target_module, source_form_datums): """ :param stack_frames: Stack to add children to :param target_module: Module that we're targeting for navigating to :param source_form_datums: List of datums from the source form. """ ids_on_stack = stack_frames.ids_on_stack command = None if len(target_module.forms): command = id_strings.form_command(target_module.get_form(0)) elif target_module.case_list and target_module.case_list.show: command = id_strings.case_list_command(target_module) if command: target_frame_children = self.helper.get_frame_children(command, target_module, module_only=True) remaining_target_frame_children = [fc for fc in target_frame_children if fc.id not in ids_on_stack] frame_children = WorkflowHelper.get_datums_matched_to_source( remaining_target_frame_children, source_form_datums ) stack_frames.add_children(frame_children)
def _add_stack_children_for_target(self, stack_frames, target_module, source_form_datums): """ :param stack_frames: Stack to add children to :param target_module: Module that we're targeting for navigating to :param source_form_datums: List of datums from the source form. """ ids_on_stack = stack_frames.ids_on_stack command = None if len(target_module.forms): command = id_strings.form_command(target_module.get_form(0)) elif target_module.case_list and target_module.case_list.show: command = id_strings.case_list_command(target_module) if command: target_frame_children = self.helper.get_frame_children(command, target_module, module_only=True) remaining_target_frame_children = [fc for fc in target_frame_children if fc.id not in ids_on_stack] frame_children = WorkflowHelper.get_datums_matched_to_source( remaining_target_frame_children, source_form_datums ) stack_frames.add_children(frame_children)
def entry_for_module(self, module): # avoid circular dependency from corehq.apps.app_manager.models import Module, AdvancedModule results = [] for form in module.get_suite_forms(): e = Entry() e.form = form.xmlns # Ideally all of this version check should happen in Command/Display class if self.app.enable_localized_menu_media: e.command = LocalizedCommand( id=id_strings.form_command(form, module), menu_locale_id=id_strings.form_locale(form), media_image=bool(len(form.all_image_paths())), media_audio=bool(len(form.all_audio_paths())), image_locale_id=id_strings.form_icon_locale(form), audio_locale_id=id_strings.form_audio_locale(form), ) else: e.command = Command( id=id_strings.form_command(form, module), locale_id=id_strings.form_locale(form), media_image=form.default_media_image, media_audio=form.default_media_audio, ) config_entry = { 'module_form': self.configure_entry_module_form, 'advanced_form': self.configure_entry_advanced_form, 'careplan_form': self.configure_entry_careplan_form, }[form.form_type] config_entry(module, e, form) if ( self.app.commtrack_enabled and session_var('supply_point_id') in getattr(form, 'source', "") ): from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION datum, assertions = EntriesHelper.get_userdata_autoselect( 'commtrack-supply-point', 'supply_point_id', AUTO_SELECT_LOCATION, ) e.datums.append(datum) e.assertions.extend(assertions) results.append(e) if hasattr(module, 'case_list') and module.case_list.show: e = Entry() if self.app.enable_localized_menu_media: e.command = LocalizedCommand( id=id_strings.case_list_command(module), menu_locale_id=id_strings.case_list_locale(module), media_image=bool(len(module.case_list.all_image_paths())), media_audio=bool(len(module.case_list.all_audio_paths())), image_locale_id=id_strings.case_list_icon_locale(module), audio_locale_id=id_strings.case_list_audio_locale(module), ) else: e.command = Command( id=id_strings.case_list_command(module), locale_id=id_strings.case_list_locale(module), media_image=module.case_list.default_media_image, media_audio=module.case_list.default_media_audio, ) if isinstance(module, Module): for datum_meta in self.get_case_datums_basic_module(module): e.datums.append(datum_meta.datum) elif isinstance(module, AdvancedModule): e.datums.append(SessionDatum( id='case_id_case_%s' % module.case_type, nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, 'case_short'), detail_confirm=self.details_helper.get_detail_id_safe(module, 'case_long'), detail_persistent=self.get_detail_persistent_attr(module, module, "case_short"), detail_inline=self.get_detail_inline_attr(module, module, "case_short"), autoselect=module.auto_select_case, )) if self.app.commtrack_enabled: e.datums.append(SessionDatum( id='product_id', nodeset=ProductInstanceXpath().instance(), value="./@id", detail_select=self.details_helper.get_detail_id_safe(module, 'product_short') )) results.append(e) for entry in module.get_custom_entries(): results.append(entry) return results
class MenuContributor(SuiteContributorByModule): @time_method() def get_module_contributions(self, module, training_menu): menus = [] if hasattr(module, 'get_menus'): for menu in module.get_menus( build_profile_id=self.build_profile_id): menus.append(menu) else: module_is_source_for_v1_shadow = any( m for m in self._v1_shadow_modules() if (m.source_module_id == module.unique_id) or ( getattr(module, 'root_module', False) and m.source_module_id == module.root_module.unique_id)) module_is_v1_shadow = getattr(module, 'shadow_module_version', 0) == 1 if module_is_v1_shadow or module_is_source_for_v1_shadow: for v1_shadow_menu in self._generate_v1_shadow_menus( module, training_menu): menus.append(v1_shadow_menu) else: root_module = None if not module.put_in_root: if module.root_module: root_module = module.root_module elif module.module_type == 'shadow' and module.source_module.root_module: root_module = module.source_module.root_module menu = self._generate_menu(module, root_module, training_menu, module) if len(menu.commands): menus.append(menu) if self.app.grid_display_for_all_modules() or \ self.app.grid_display_for_some_modules() and module.grid_display_style(): self._give_non_root_menus_grid_style(menus) if self.app.use_grid_menus: self._give_root_menu_grid_style(menus) return menus @memoized def _v1_shadow_modules(self): return [ m for m in self.app.get_modules() if m.module_type == 'shadow' and m.shadow_module_version == 1 and m.source_module_id ] def _generate_v1_shadow_menus(self, module, training_menu): # V1 shadow modules create a 'fake' module for any child shadow menus # These child shadow modules don't have a representation in the DB, but # are needed in the suite to add in all the child forms. # This behaviour has been superceded by v2 shadow modules. id_modules = [module] # the current module and all of its shadows root_modules = [ ] # the current module's parent and all of that parent's shadows if not module.put_in_root and module.root_module: root_modules.append(module.root_module) for shadow in self._v1_shadow_modules(): if module.root_module.unique_id == shadow.source_module_id: root_modules.append(shadow) else: root_modules.append(None) if module.put_in_root and module.root_module: for shadow in self._v1_shadow_modules(): if module.root_module.unique_id == shadow.source_module_id: id_modules.append(shadow) for id_module in id_modules: for root_module in root_modules: menu = self._generate_menu(module, root_module, training_menu, id_module) if len(menu.commands): yield menu def _generate_menu(self, module, root_module, training_menu, id_module): # In general, `id_module` and `module` will be the same thing. # In the case of v1 shadow menus, `id_module` is either the current module or one of that module's shadows # For more information, see the note in `_generate_v1_shadow_menus`. from corehq.apps.app_manager.models import ShadowModule menu_kwargs = {} suffix = "" if id_module.is_training_module: menu_kwargs.update({'root': 'training-root'}) elif root_module: menu_kwargs.update({'root': id_strings.menu_id(root_module)}) suffix = id_strings.menu_id(root_module) if isinstance( root_module, ShadowModule) else "" menu_kwargs.update({'id': id_strings.menu_id(id_module, suffix)}) # Determine relevancy if self.app.enable_module_filtering: relevancy = id_module.module_filter # If module has a parent, incorporate the parent's relevancy. # This is only necessary when the child uses display only forms. if id_module.put_in_root and id_module.root_module and id_module.root_module.module_filter: if relevancy: relevancy = str( XPath.and_( XPath(relevancy).paren(force=True), XPath(id_module.root_module.module_filter).paren( force=True))) else: relevancy = id_module.root_module.module_filter if relevancy: menu_kwargs['relevant'] = interpolate_xpath(relevancy) if self.app.enable_localized_menu_media: module_custom_icon = module.custom_icon menu_kwargs.update({ 'menu_locale_id': get_module_locale_id(module), 'media_image': module.uses_image(build_profile_id=self.build_profile_id), 'media_audio': module.uses_audio(build_profile_id=self.build_profile_id), 'image_locale_id': id_strings.module_icon_locale(module), 'audio_locale_id': id_strings.module_audio_locale(module), 'custom_icon_locale_id': (id_strings.module_custom_icon_locale( module, module_custom_icon.form) if module_custom_icon and not module_custom_icon.xpath else None), 'custom_icon_form': (module_custom_icon.form if module_custom_icon else None), 'custom_icon_xpath': (module_custom_icon.xpath if module_custom_icon and module_custom_icon.xpath else None), }) menu = LocalizedMenu(**menu_kwargs) else: menu_kwargs.update({ 'media_image': module.default_media_image, 'media_audio': module.default_media_audio, 'locale_id': get_module_locale_id(module), }) menu = Menu(**menu_kwargs) excluded_form_ids = [] if root_module and isinstance(root_module, ShadowModule): excluded_form_ids = root_module.excluded_form_ids if id_module and isinstance(id_module, ShadowModule): excluded_form_ids = id_module.excluded_form_ids commands = self._get_commands(excluded_form_ids, module) if module.is_training_module and module.put_in_root and training_menu: training_menu.commands.extend(commands) else: menu.commands.extend(commands) return menu @staticmethod def _schedule_filter_conditions(form, module, case): phase = form.get_phase() try: form_xpath = QualifiedScheduleFormXPath(form, phase, module, case_xpath=case) relevant = form_xpath.filter_condition(phase.id) except ScheduleError: relevant = None return relevant @staticmethod def _give_non_root_menus_grid_style(menus): for menu in menus: if not menu.id == id_strings.ROOT: menu.style = "grid" @staticmethod def _give_root_menu_grid_style(menus): for menu in menus: if menu.id == id_strings.ROOT: menu.style = "grid" @staticmethod def _give_all_menus_grid_style(menus): for menu in menus: menu.style = "grid" def _get_commands(self, excluded_form_ids, module): @memoized def module_uses_case(): return module.all_forms_require_a_case() @memoized def domain_uses_usercase(): return is_usercase_in_use(self.app.domain) for form in module.get_suite_forms(): if form.unique_id in excluded_form_ids: continue command = Command(id=id_strings.form_command(form, module)) if form.requires_case(): form_datums = self.entries_helper.get_datums_meta_for_form_generic( form) var_name = next(meta.datum.id for meta in reversed(form_datums) if meta.action and meta.requires_selection) case = CaseIDXPath(session_var(var_name)).case() else: case = None if getattr(form, 'form_filter', None): fixture_xpath = (session_var( id_strings.fixture_session_var(module)) if module.fixture_select.active else None) interpolated_xpath = interpolate_xpath(form.form_filter, case, fixture_xpath, module=module, form=form) if xpath_references_case(interpolated_xpath) and \ (not module_uses_case() or module.put_in_root and not module.root_requires_same_case()): raise CaseXPathValidationError(module=module, form=form) if xpath_references_user_case( interpolated_xpath) and not domain_uses_usercase(): raise UserCaseXPathValidationError(module=module, form=form) command.relevant = interpolated_xpath if getattr(module, 'has_schedule', False) and module.all_forms_require_a_case(): # If there is a schedule and another filter condition, disregard it... # Other forms of filtering are disabled in the UI schedule_filter_condition = MenuContributor._schedule_filter_conditions( form, module, case) if schedule_filter_condition is not None: command.relevant = schedule_filter_condition yield command if hasattr(module, 'case_list') and module.case_list.show: yield Command(id=id_strings.case_list_command(module))
def entry_for_module(self, module): # avoid circular dependency from corehq.apps.app_manager.models import Module, AdvancedModule results = [] for form in module.get_suite_forms(): e = Entry() e.form = form.xmlns # Ideally all of this version check should happen in Command/Display class if self.app.enable_localized_menu_media: e.command = LocalizedCommand( id=id_strings.form_command(form, module), menu_locale_id=id_strings.form_locale(form), media_image=bool(len(form.all_image_paths())), media_audio=bool(len(form.all_audio_paths())), image_locale_id=id_strings.form_icon_locale(form), audio_locale_id=id_strings.form_audio_locale(form), ) else: e.command = Command( id=id_strings.form_command(form, module), locale_id=id_strings.form_locale(form), media_image=form.default_media_image, media_audio=form.default_media_audio, ) config_entry = { "module_form": self.configure_entry_module_form, "advanced_form": self.configure_entry_advanced_form, "careplan_form": self.configure_entry_careplan_form, }[form.form_type] config_entry(module, e, form) if self.app.commtrack_enabled and session_var("supply_point_id") in getattr(form, "source", ""): from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION datum, assertions = EntriesHelper.get_userdata_autoselect( "commtrack-supply-point", "supply_point_id", AUTO_SELECT_LOCATION ) e.datums.append(datum) e.assertions.extend(assertions) results.append(e) if hasattr(module, "case_list") and module.case_list.show: e = Entry() if self.app.enable_localized_menu_media: e.command = LocalizedCommand( id=id_strings.case_list_command(module), menu_locale_id=id_strings.case_list_locale(module), media_image=bool(len(module.case_list.all_image_paths())), media_audio=bool(len(module.case_list.all_audio_paths())), image_locale_id=id_strings.case_list_icon_locale(module), audio_locale_id=id_strings.case_list_audio_locale(module), ) else: e.command = Command( id=id_strings.case_list_command(module), locale_id=id_strings.case_list_locale(module), media_image=module.case_list.default_media_image, media_audio=module.case_list.default_media_audio, ) if isinstance(module, Module): for datum_meta in self.get_datum_meta_module(module, use_filter=False): e.datums.append(datum_meta.datum) elif isinstance(module, AdvancedModule): detail_persistent, detail_inline = self.get_case_tile_datum_attrs(module, module) e.datums.append( SessionDatum( id="case_id_case_%s" % module.case_type, nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, "case_short"), detail_confirm=self.details_helper.get_detail_id_safe(module, "case_long"), detail_persistent=detail_persistent, detail_inline=detail_inline, ) ) if self.app.commtrack_enabled: e.datums.append( SessionDatum( id="product_id", nodeset=ProductInstanceXpath().instance(), value="./@id", detail_select=self.details_helper.get_detail_id_safe(module, "product_short"), ) ) results.append(e) for entry in module.get_custom_entries(): results.append(entry) return results
def _get_module_endpoint(self, module): id_string = id_strings.case_list_command(module) return self._make_session_endpoint(id_string, module, module.session_endpoint_id)
def entry_for_module(self, module): # avoid circular dependency from corehq.apps.app_manager.models import Module, AdvancedModule results = [] for form in module.get_suite_forms(): e = Entry() e.form = form.xmlns # Ideally all of this version check should happen in Command/Display class if self.app.enable_localized_menu_media: form_custom_icon = form.custom_icon e.command = LocalizedCommand( id=id_strings.form_command(form, module), menu_locale_id=id_strings.form_locale(form), media_image=bool(len(form.all_image_paths())), media_audio=bool(len(form.all_audio_paths())), image_locale_id=id_strings.form_icon_locale(form), audio_locale_id=id_strings.form_audio_locale(form), custom_icon_locale_id=(id_strings.form_custom_icon_locale(form, form_custom_icon.form) if form_custom_icon and not form_custom_icon.xpath else None), custom_icon_form=(form_custom_icon.form if form_custom_icon else None), custom_icon_xpath=(form_custom_icon.xpath if form_custom_icon and form_custom_icon.xpath else None), ) else: e.command = Command( id=id_strings.form_command(form, module), locale_id=id_strings.form_locale(form), media_image=form.default_media_image, media_audio=form.default_media_audio, ) config_entry = { 'module_form': self.configure_entry_module_form, 'advanced_form': self.configure_entry_advanced_form, 'shadow_form': self.configure_entry_advanced_form, }[form.form_type] config_entry(module, e, form) if form.uses_usercase(): EntriesHelper.add_usercase_id_assertion(e) EntriesHelper.add_custom_assertions(e, form) if ( self.app.commtrack_enabled and session_var('supply_point_id') in getattr(form, 'source', "") ): from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION datum, assertions = EntriesHelper.get_userdata_autoselect( 'commtrack-supply-point', 'supply_point_id', AUTO_SELECT_LOCATION, ) e.datums.append(datum) e.assertions.extend(assertions) results.append(e) if hasattr(module, 'case_list') and module.case_list.show: e = Entry() if self.app.enable_localized_menu_media: e.command = LocalizedCommand( id=id_strings.case_list_command(module), menu_locale_id=id_strings.case_list_locale(module), media_image=bool(len(module.case_list.all_image_paths())), media_audio=bool(len(module.case_list.all_audio_paths())), image_locale_id=id_strings.case_list_icon_locale(module), audio_locale_id=id_strings.case_list_audio_locale(module), ) else: e.command = Command( id=id_strings.case_list_command(module), locale_id=id_strings.case_list_locale(module), media_image=module.case_list.default_media_image, media_audio=module.case_list.default_media_audio, ) if isinstance(module, Module): for datum_meta in self.get_case_datums_basic_module(module): e.datums.append(datum_meta.datum) elif isinstance(module, AdvancedModule): detail_inline = self.get_detail_inline_attr(module, module, "case_short") detail_confirm = None if not detail_inline: detail_confirm = self.details_helper.get_detail_id_safe(module, 'case_long') e.datums.append(SessionDatum( id='case_id_case_%s' % module.case_type, nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, 'case_short'), detail_confirm=detail_confirm, detail_persistent=self.get_detail_persistent_attr(module, module, "case_short"), detail_inline=detail_inline, autoselect=module.auto_select_case, )) if self.app.commtrack_enabled: e.datums.append(SessionDatum( id='product_id', nodeset=ProductInstanceXpath().instance(), value="./@id", detail_select=self.details_helper.get_detail_id_safe(module, 'product_short') )) results.append(e) for entry in module.get_custom_entries(): results.append(entry) return results