def get_frame_children(self, target_form, module_only=False, include_target_root=False): """ For a form return the list of stack frame children that are required to navigate to that form. This is based on the following algorithm: * Add the module the form is in to the stack (we'll call this `m`) * Walk through all forms in the module, determine what datum selections are present in all of the forms (this may be an empty set) * Basically if there are three forms that respectively load * f1: v1, v2, v3, v4 * f2: v1, v2, v4 * f3: v1, v2 * The longest common chain is v1, v2 * Add a datum for each of those values to the stack * Add the form "command id" for the <entry> to the stack * Add the remainder of the datums for the current form to the stack * For the three forms above, the stack entries for "last element" would be * m, v1, v2, f1, v3, v4 * m, v1, v2, f2, v4 * m, v1, v2, f3 :returns: list of strings and DatumMeta objects. String represent stack commands and DatumMeta's represent stack datums. """ target_form_command = id_strings.form_command(target_form) target_module_id, target_form_id = target_form_command.split('-') module_command = id_strings.menu_id(target_form.get_module()) module_datums = self.get_module_datums(target_module_id) form_datums = module_datums[target_form_id] if module_command == id_strings.ROOT: datums_list = self.root_module_datums else: datums_list = list(module_datums.values() ) # [ [datums for f0], [datums for f1], ...] root_module = target_form.get_module().root_module if root_module and include_target_root: datums_list = datums_list + list( self.get_module_datums( id_strings.menu_id(root_module)).values()) common_datums = commonprefix(datums_list) remaining_datums = form_datums[len(common_datums):] frame_children = [CommandId(module_command) ] if module_command != id_strings.ROOT else [] frame_children.extend(common_datums) if not module_only: frame_children.append(CommandId(target_form_command)) frame_children.extend(remaining_datums) return frame_children
def get_frame_children(self, command, target_module, module_only=False, include_target_root=False): """ For a form return the list of stack frame children that are required to navigate to that form. Given command may be a form (mX-fY) or case list menu item (mX-case-list). This is based on the following algorithm: * Add the module the form is in to the stack (we'll call this `m`) * Walk through all forms in the module, determine what datum selections are present in all of the forms (this may be an empty set) * Basically if there are three forms that respectively load * f1: v1, v2, v3, v4 * f2: v1, v2, v4 * f3: v1, v2 * The longest common chain is v1, v2 * Add a datum for each of those values to the stack * Add the form "command id" for the <entry> to the stack * Add the remainder of the datums for the current form to the stack * For the three forms above, the stack entries for "last element" would be * m, v1, v2, f1, v3, v4 * m, v1, v2, f2, v4 * m, v1, v2, f3 :returns: list of strings and DatumMeta objects. String represent stack commands and DatumMeta's represent stack datums. """ match = re.search(r'^(m\d+)-(.*)', command) if not match: raise Exception("Unrecognized command: {}".format(command)) target_module_id = match.group(1) target_form_id = match.group(2) module_command = id_strings.menu_id(target_module) module_datums = self.get_module_datums(target_module_id) form_datums = module_datums[target_form_id] if module_command == id_strings.ROOT: datums_list = self.root_module_datums else: datums_list = list(module_datums.values()) # [ [datums for f0], [datums for f1], ...] root_module = target_module.root_module if root_module and include_target_root: datums_list = datums_list + list(self.get_module_datums(id_strings.menu_id(root_module)).values()) common_datums = commonprefix(datums_list) remaining_datums = form_datums[len(common_datums):] frame_children = [CommandId(module_command)] if module_command != id_strings.ROOT else [] frame_children.extend(common_datums) if not module_only: frame_children.append(CommandId(command)) frame_children.extend(remaining_datums) return frame_children
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ from corehq.apps.app_manager.const import WORKFLOW_CASE_LIST source_session_var = self._get_source_session_var(form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) if target_module.case_list_form.post_form_workflow == WORKFLOW_CASE_LIST: frame_case_created = None frame_case_not_created = StackFrameMeta( self.get_if_clause(None, target_command), current_session=source_form_datums ) else: frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums ) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums ) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created ) stack_frames.source_session_var = source_session_var return stack_frames
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ from corehq.apps.app_manager.const import WORKFLOW_CASE_LIST source_session_var = self._get_source_session_var( form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) if target_module.case_list_form.post_form_workflow == WORKFLOW_CASE_LIST: frame_case_created = None frame_case_not_created = StackFrameMeta( self.get_if_clause(None, target_command), current_session=source_form_datums) else: frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created) stack_frames.source_session_var = source_session_var return stack_frames
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 _add_action_to_detail(self, detail, module): # add form action to detail 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 detail.action = LocalizedAction( menu_locale_id=id_strings.case_list_form_locale(module), media_image=bool(len(case_list_form.all_image_paths())), media_audio=bool(len(case_list_form.all_audio_paths())), 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: detail.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 = 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: message = _( "The '{form}' form selected as the case list registration form " "for the '{module}' module requires a '{case_type}' case. " "The '{module}' must load a case of this type.").format( form=form.default_name(), module=module.default_name(), case_type=target_meta.case_type ) raise SuiteValidationError(message) 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)))) detail.action.stack.add_frame(frame)
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=bool(len(case_list_form.all_image_paths())), media_audio=bool(len(case_list_form.all_audio_paths())), 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_module_contributions(self, module): # avoid circular dependency from corehq.apps.app_manager.models import CareplanModule menus = [] if isinstance(module, CareplanModule): update_menu = Menu( id=id_strings.menu_id(module), locale_id=id_strings.module_locale(module), ) if not module.display_separately: parent = self.app.get_module_by_unique_id( module.parent_select.module_id) create_goal_form = module.get_form_by_type( CAREPLAN_GOAL, 'create') create_menu = Menu( id=id_strings.menu_id(parent), locale_id=id_strings.module_locale(parent), ) create_menu.commands.append( Command(id=id_strings.form_command(create_goal_form))) menus.append(create_menu) update_menu.root = id_strings.menu_id(parent) else: update_menu.commands.extend([ Command(id=id_strings.form_command( module.get_form_by_type(CAREPLAN_GOAL, 'create'))), ]) update_menu.commands.extend([ Command(id=id_strings.form_command( module.get_form_by_type(CAREPLAN_GOAL, 'update'))), Command(id=id_strings.form_command( module.get_form_by_type(CAREPLAN_TASK, 'create'))), Command(id=id_strings.form_command( module.get_form_by_type(CAREPLAN_TASK, 'update'))), ]) menus.append(update_menu) return menus
def get_module_contributions(self, module): # avoid circular dependency from corehq.apps.app_manager.models import CareplanModule menus = [] if isinstance(module, CareplanModule): update_menu = Menu( id=id_strings.menu_id(module), locale_id=id_strings.module_locale(module), ) if not module.display_separately: parent = self.app.get_module_by_unique_id(module.parent_select.module_id, error=_("Could not find module '{}' is attached to.").format(module.default_name())) create_goal_form = module.get_form_by_type(CAREPLAN_GOAL, 'create') create_menu = Menu( id=id_strings.menu_id(parent), locale_id=id_strings.module_locale(parent), ) create_menu.commands.append(Command(id=id_strings.form_command(create_goal_form))) menus.append(create_menu) update_menu.root = id_strings.menu_id(parent) else: update_menu.commands.extend([ Command(id=id_strings.form_command(module.get_form_by_type(CAREPLAN_GOAL, 'create'))), ]) update_menu.commands.extend([ Command(id=id_strings.form_command(module.get_form_by_type(CAREPLAN_GOAL, 'update'))), Command(id=id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, 'create'))), Command(id=id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, 'update'))), ]) menus.append(update_menu) return menus
def frame_children_for_module(module_, include_user_selections=True): frame_children = [] if module_.root_module: frame_children.extend(frame_children_for_module(module_.root_module)) if include_user_selections: this_module_children = self.helper.get_frame_children(module_.get_form(0), module_only=True) for child in this_module_children: if child not in frame_children: frame_children.append(child) else: module_command = id_strings.menu_id(module_) if module_command != id_strings.ROOT: frame_children.append(CommandId(module_command)) return frame_children
def frame_children_for_module(module_, include_user_selections=True): frame_children = [] if module_.root_module: frame_children.extend(frame_children_for_module(module_.root_module)) if include_user_selections: this_module_children = self.helper.get_frame_children(module_.get_form(0), module_only=True) for child in this_module_children: if child not in frame_children: frame_children.append(child) else: module_command = id_strings.menu_id(module_) if module_command != id_strings.ROOT: frame_children.append(CommandId(module_command)) return frame_children
def get_frame_children(self, target_form, module_only=False): """ For a form return the list of stack frame children that are required to navigate to that form. This is based on the following algorithm: * Add the module the form is in to the stack (we'll call this `m`) * Walk through all forms in the module, determine what datum selections are present in all of the forms (this may be an empty set) * Basically if there are three forms that respectively load * f1: v1, v2, v3, v4 * f2: v1, v2, v4 * f3: v1, v2 * The longest common chain is v1, v2 * Add a datum for each of those values to the stack * Add the form "command id" for the <entry> to the stack * Add the remainder of the datums for the current form to the stack * For the three forms above, the stack entries for "last element" would be * m, v1, v2, f1, v3, v4 * m, v1, v2, f2, v4 * m, v1, v2, f3 :returns: list of strings and DatumMeta objects. String represent stack commands and DatumMeta's represent stack datums. """ target_form_command = id_strings.form_command(target_form) target_module_id, target_form_id = target_form_command.split('-') module_command = id_strings.menu_id(target_form.get_module()) module_datums = self.get_module_datums(target_module_id) form_datums = module_datums[target_form_id] if module_command == id_strings.ROOT: datums_list = self.root_module_datums else: datums_list = module_datums.values() # [ [datums for f0], [datums for f1], ...] common_datums = commonprefix(datums_list) remaining_datums = form_datums[len(common_datums):] frame_children = [CommandId(module_command)] if module_command != id_strings.ROOT else [] frame_children.extend(common_datums) if not module_only: frame_children.append(CommandId(target_form_command)) frame_children.extend(remaining_datums) return frame_children
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ source_session_var = self._get_source_session_var(form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums ) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums ) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created ) stack_frames.source_session_var = source_session_var return stack_frames
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ source_session_var = self._get_source_session_var(form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums ) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums ) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created ) stack_frames.source_session_var = source_session_var return stack_frames
class MenuContributor(SuiteContributorByModule): def get_module_contributions(self, 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)) supports_module_filter = self.app.enable_module_filtering and getattr( module, 'module_filter', None) menus = [] if hasattr(module, 'get_menus'): for menu in module.get_menus( supports_module_filter=supports_module_filter): menus.append(menu) else: from corehq.apps.app_manager.models import ShadowModule id_modules = [module] root_modules = [] shadow_modules = [ m for m in self.app.get_modules() if isinstance(m, ShadowModule) and m.source_module_id ] put_in_root = getattr(module, 'put_in_root', False) if not put_in_root and getattr(module, 'root_module', False): root_modules.append(module.root_module) for shadow in shadow_modules: if module.root_module.unique_id == shadow.source_module_id: root_modules.append(shadow) else: root_modules.append(None) if put_in_root and getattr(module, 'root_module', False): for shadow in 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_kwargs = {} suffix = "" if 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)}) if supports_module_filter: menu_kwargs['relevant'] = interpolate_xpath( module.module_filter) if self.app.enable_localized_menu_media: module_custom_icon = module.custom_icon menu_kwargs.update({ 'menu_locale_id': id_strings.module_locale(module), 'media_image': bool(len(module.all_image_paths())), 'media_audio': bool(len(module.all_audio_paths())), '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({ 'locale_id': id_strings.module_locale(module), 'media_image': module.default_media_image, 'media_audio': module.default_media_audio, }) 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 menu.commands.extend(get_commands(excluded_form_ids)) 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
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
def get_module_contributions(self, module): 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)) supports_module_filter = ( self.app.domain and MODULE_FILTER.enabled(self.app.domain) and self.app.enable_module_filtering and getattr(module, 'module_filter', None) ) menus = [] if hasattr(module, 'get_menus'): for menu in module.get_menus(supports_module_filter=supports_module_filter): menus.append(menu) elif module.module_type != 'careplan': id_modules = [module] root_modules = [] shadow_modules = [m for m in self.app.get_modules() if m.doc_type == "ShadowModule" and m.source_module_id] put_in_root = getattr(module, 'put_in_root', False) if not put_in_root and getattr(module, 'root_module', False): root_modules.append(module.root_module) for shadow in shadow_modules: if module.root_module.unique_id == shadow.source_module_id: root_modules.append(shadow) else: root_modules.append(None) if put_in_root and getattr(module, 'root_module', False): for shadow in 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_kwargs = {} suffix = "" if root_module: menu_kwargs.update({'root': id_strings.menu_id(root_module)}) suffix = id_strings.menu_id(root_module) if root_module.doc_type == 'ShadowModule' else "" menu_kwargs.update({'id': id_strings.menu_id(id_module, suffix)}) if supports_module_filter: menu_kwargs['relevant'] = interpolate_xpath(module.module_filter) if self.app.enable_localized_menu_media: menu_kwargs.update({ 'menu_locale_id': id_strings.module_locale(module), 'media_image': bool(len(module.all_image_paths())), 'media_audio': bool(len(module.all_audio_paths())), 'image_locale_id': id_strings.module_icon_locale(module), 'audio_locale_id': id_strings.module_audio_locale(module), }) menu = LocalizedMenu(**menu_kwargs) else: menu_kwargs.update({ 'locale_id': id_strings.module_locale(module), 'media_image': module.default_media_image, 'media_audio': module.default_media_audio, }) menu = Menu(**menu_kwargs) menu.commands.extend(get_commands()) menus.append(menu) if self.app.use_grid_menus: self._give_root_menus_grid_style(menus) return menus
def get_module_contributions(self, 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): 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)) supports_module_filter = self.app.enable_module_filtering and getattr(module, 'module_filter', None) menus = [] if hasattr(module, 'get_menus'): for menu in module.get_menus(supports_module_filter=supports_module_filter): menus.append(menu) elif module.module_type != 'careplan': from corehq.apps.app_manager.models import ShadowModule id_modules = [module] root_modules = [] shadow_modules = [m for m in self.app.get_modules() if isinstance(m, ShadowModule) and m.source_module_id] put_in_root = getattr(module, 'put_in_root', False) if not put_in_root and getattr(module, 'root_module', False): root_modules.append(module.root_module) for shadow in shadow_modules: if module.root_module.unique_id == shadow.source_module_id: root_modules.append(shadow) else: root_modules.append(None) if put_in_root and getattr(module, 'root_module', False): for shadow in 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_kwargs = {} suffix = "" if 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)}) if supports_module_filter: menu_kwargs['relevant'] = interpolate_xpath(module.module_filter) if self.app.enable_localized_menu_media: menu_kwargs.update({ 'menu_locale_id': id_strings.module_locale(module), 'media_image': bool(len(module.all_image_paths())), 'media_audio': bool(len(module.all_audio_paths())), 'image_locale_id': id_strings.module_icon_locale(module), 'audio_locale_id': id_strings.module_audio_locale(module), }) menu = LocalizedMenu(**menu_kwargs) else: menu_kwargs.update({ 'locale_id': id_strings.module_locale(module), 'media_image': module.default_media_image, 'media_audio': module.default_media_audio, }) 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 menu.commands.extend(get_commands(excluded_form_ids)) 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.grid_menu_toggle_enabled() and self.app.use_grid_menus: self._give_root_menu_grid_style(menus) return menus
class MenuContributor(SuiteContributorByModule): def get_module_contributions(self, module, training_menu): 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) 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)) menus = [] if hasattr(module, 'get_menus'): for menu in module.get_menus(build_profile_id=self.build_profile_id): menus.append(menu) else: from corehq.apps.app_manager.models import ShadowModule 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 shadow_modules = [m for m in self.app.get_modules() if isinstance(m, ShadowModule) and m.source_module_id] if not module.put_in_root and module.root_module: root_modules.append(module.root_module) for shadow in 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 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_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), 'menu_enum_text': get_module_enum_text(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), 'enum_text': get_module_enum_text(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 = get_commands(excluded_form_ids) if module.is_training_module and module.put_in_root and training_menu: training_menu.commands.extend(commands) else: menu.commands.extend(commands) 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
def configure_entry_careplan_form(self, module, e, form=None, **kwargs): parent_module = self.app.get_module_by_unique_id(module.parent_select.module_id) e.datums.append( SessionDatum( id="case_id", nodeset=EntriesHelper.get_nodeset_xpath(parent_module.case_type), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(parent_module, "case_short"), detail_confirm=self.details_helper.get_detail_id_safe(parent_module, "case_long"), ) ) def session_datum(datum_id, case_type, parent_ref, parent_val): nodeset = ( CaseTypeXpath(case_type) .case() .select("index/%s" % parent_ref, session_var(parent_val), quote=False) .select("@status", "open") ) return SessionDatum( id=datum_id, nodeset=nodeset, value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, "%s_short" % case_type), detail_confirm=self.details_helper.get_detail_id_safe(module, "%s_long" % case_type), ) e.stack = Stack() frame = CreateFrame() e.stack.add_frame(frame) if form.case_type == CAREPLAN_GOAL: if form.mode == "create": new_goal_id_var = "case_id_goal_new" e.datums.append(SessionDatum(id=new_goal_id_var, function="uuid()")) elif form.mode == "update": new_goal_id_var = "case_id_goal" e.datums.append(session_datum(new_goal_id_var, CAREPLAN_GOAL, "parent", "case_id")) if not module.display_separately: open_goal = CaseIDXPath(session_var(new_goal_id_var)).case().select("@status", "open") frame.if_clause = "{count} = 1".format(count=open_goal.count()) frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id="case_id", value=session_var("case_id"))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id="case_id_goal", value=session_var(new_goal_id_var))) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id="case_id", value=session_var("case_id"))) elif form.case_type == CAREPLAN_TASK: if not module.display_separately: frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id="case_id", value=session_var("case_id"))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id="case_id_goal", value=session_var("case_id_goal"))) if form.mode == "update": count = ( CaseTypeXpath(CAREPLAN_TASK) .case() .select("index/goal", session_var("case_id_goal"), quote=False) .select("@status", "open") .count() ) frame.if_clause = "{count} >= 1".format(count=count) frame.add_command( XPath.string(id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, "update"))) ) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id="case_id", value=session_var("case_id"))) if form.mode == "create": e.datums.append(session_datum("case_id_goal", CAREPLAN_GOAL, "parent", "case_id")) elif form.mode == "update": e.datums.append(session_datum("case_id_goal", CAREPLAN_GOAL, "parent", "case_id")) e.datums.append(session_datum("case_id_task", CAREPLAN_TASK, "goal", "case_id_goal"))
def get_module_contributions(self, module): if module_offers_search(module): domain = self.app.domain details_helper = DetailsHelper(self.app) remote_request = RemoteRequest( post=RemoteRequestPost( url=absolute_reverse('claim_case', args=[domain]), relevant=module.search_config.relevant, data=[ QueryData( key='case_id', ref=QuerySessionXPath('case_id').instance(), # e.g. instance('querysession')/session/data/case_id ), ]), command=Command( id=id_strings.search_command(module), display=Display(text=Text( locale_id=id_strings.case_search_locale(module)), ), ), instances=[ Instance(id=SESSION_INSTANCE, src='jr://instance/session'), Instance(id='casedb', src='jr://instance/casedb'), ], session=RemoteRequestSession( queries=[ RemoteRequestQuery( url=absolute_reverse('remote_search', args=[domain]), storage_instance=RESULTS_INSTANCE, data=[ QueryData(key='case_type', ref="'{}'".format(module.case_type)), ], prompts=[ QueryPrompt( key=p.name, display=Display( text=Text(locale_id=id_strings. search_property_locale( module, p.name)), ), ) for p in module.search_config.properties ]) ], data=[ SessionDatum( id='case_id', nodeset=(CaseTypeXpath(module.case_type).case( instance_name=RESULTS_INSTANCE).select( u'@status', u'open', quote=True)), value='./@case_id', detail_select=details_helper.get_detail_id_safe( module, 'case_short'), detail_confirm=details_helper.get_detail_id_safe( module, 'case_long'), ) ], ), stack=Stack(), ) frame = CreateFrame() # Open first form in module frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum( StackDatum(id='case_id', value=QuerySessionXPath('case_id').instance())) remote_request.stack.add_frame(frame) return [remote_request] return []
def get_stack_frames_for_case_list_form_target(self, target_module, form): stack_frames = [] target_command = id_strings.menu_id(target_module) if form.form_type == 'module_form': [reg_action ] = form.get_registration_actions(target_module.case_type) source_session_var = form.session_var_for_action(reg_action) if form.form_type == 'advanced_form': # match case session variable reg_action = form.get_registration_actions( target_module.case_type)[0] source_session_var = reg_action.case_session_var source_case_id = session_var(source_session_var) source_form_datums = self.helper.get_form_datums(form) case_count = CaseIDXPath(source_case_id).case().count() frame_case_created = StackFrameMeta(self.get_if_clause( case_count.gt(0), target_command), current_session=source_form_datums) stack_frames.append(frame_case_created) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums) stack_frames.append(frame_case_not_created) def add_datums_for_target(module, source_form_dm, allow_missing=False): """ Given a target module and a list of datums from the source module add children to the stack frames that are required by the target module and present in the source datums list. """ target_form_dm = self.helper.get_frame_children(module.get_form(0), module_only=True) used = set() for source_meta in source_form_dm: if source_meta.case_type: # This is true for registration forms where the case being created is a subcase target_dm = self.get_target_dm(target_form_dm, source_meta.case_type, module) if target_dm: used.add(source_meta) meta = WorkflowDatumMeta.from_session_datum( source_meta) frame_case_created.add_child( meta.to_stack_datum(datum_id=target_dm.id)) frame_case_not_created.add_child( meta.to_stack_datum(datum_id=target_dm.id)) else: source_case_type = self.get_case_type_created_by_form( form, target_module) target_dm = self.get_target_dm(target_form_dm, source_case_type, module) if target_dm: used.add(source_meta) datum_meta = WorkflowDatumMeta.from_session_datum( target_dm) frame_case_created.add_child( datum_meta.to_stack_datum( source_id=source_meta.id)) elif not allow_missing: raise SuiteValidationError( u"The '{}' module is not properly configured to have a Case List Registration Form. " u"All forms in the module should have the same case management configuration." .format(module.default_name())) # return any source datums that were not already added to the target return [dm for dm in source_form_dm if dm not in used] source_form_dm = self.helper.get_form_datums(form) if target_module.root_module_id: # add stack children for the root module before adding any for the child module. root_module = target_module.root_module root_module_command = CommandId(id_strings.menu_id(root_module)) frame_case_created.add_child(root_module_command) frame_case_not_created.add_child(root_module_command) source_form_dm = add_datums_for_target(root_module, source_form_dm, allow_missing=True) frame_case_created.add_child(CommandId(target_command)) frame_case_not_created.add_child(CommandId(target_command)) add_datums_for_target(target_module, source_form_dm) return stack_frames
def get_stack_frames_for_case_list_form_target(self, target_module, form): stack_frames = [] target_command = id_strings.menu_id(target_module) if form.form_type == 'module_form': [reg_action] = form.get_registration_actions(target_module.case_type) source_session_var = form.session_var_for_action(reg_action) if form.form_type == 'advanced_form': # match case session variable reg_action = form.get_registration_actions(target_module.case_type)[0] source_session_var = reg_action.case_session_var source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() frame_case_created = StackFrameMeta(self.get_if_clause(case_count.gt(0), target_command)) stack_frames.append(frame_case_created) frame_case_not_created = StackFrameMeta(self.get_if_clause(case_count.eq(0), target_command)) stack_frames.append(frame_case_not_created) def add_datums_for_target(module, source_form_dm, allow_missing=False): """ Given a target module and a list of datums from the source module add children to the stack frames that are required by the target module and present in the source datums list. """ target_form_dm = self.helper.get_frame_children(module.get_form(0), module_only=True) used = set() for source_meta in source_form_dm: if source_meta.case_type: # This is true for registration forms where the case being created is a subcase try: target_dm = self.get_target_dm(target_form_dm, source_meta.case_type, module) except SuiteError: if source_meta.requires_selection: raise else: used.add(source_meta) meta = WorkflowDatumMeta.from_session_datum(source_meta) frame_case_created.add_child(meta.to_stack_datum(datum_id=target_dm.id)) frame_case_not_created.add_child(meta.to_stack_datum(datum_id=target_dm.id)) else: source_case_type = self.get_case_type_created_by_form(form, target_module) try: target_dm = self.get_target_dm(target_form_dm, source_case_type, module) except SuiteError: if not allow_missing: raise else: used.add(source_meta) datum_meta = WorkflowDatumMeta.from_session_datum(target_dm) frame_case_created.add_child(datum_meta.to_stack_datum(source_id=source_meta.id)) # return any source datums that were not already added to the target return [dm for dm in source_form_dm if dm not in used] source_form_dm = self.helper.get_form_datums(form) if target_module.root_module_id: # add stack children for the root module before adding any for the child module. root_module = target_module.root_module root_module_command = CommandId(id_strings.menu_id(root_module)) frame_case_created.add_child(root_module_command) frame_case_not_created.add_child(root_module_command) source_form_dm = add_datums_for_target(root_module, source_form_dm, allow_missing=True) frame_case_created.add_child(CommandId(target_command)) frame_case_not_created.add_child(CommandId(target_command)) add_datums_for_target(target_module, source_form_dm) return stack_frames
def configure_entry_careplan_form(self, module, e, form=None, **kwargs): parent_module = self.app.get_module_by_unique_id(module.parent_select.module_id, error=_("Could not find module '{}' is attached to.").format(module.default_name())) e.datums.append(SessionDatum( id='case_id', nodeset=EntriesHelper.get_nodeset_xpath(parent_module.case_type), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(parent_module, 'case_short'), detail_confirm=self.details_helper.get_detail_id_safe(parent_module, 'case_long') )) def session_datum(datum_id, case_type, parent_ref, parent_val): nodeset = CaseTypeXpath(case_type).case().select( 'index/%s' % parent_ref, session_var(parent_val), quote=False ).select('@status', 'open') return SessionDatum( id=datum_id, nodeset=nodeset, value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, '%s_short' % case_type), detail_confirm=self.details_helper.get_detail_id_safe(module, '%s_long' % case_type) ) e.stack = Stack() frame = CreateFrame() e.stack.add_frame(frame) if form.case_type == CAREPLAN_GOAL: if form.mode == 'create': new_goal_id_var = 'case_id_goal_new' e.datums.append(SessionDatum(id=new_goal_id_var, function='uuid()')) elif form.mode == 'update': new_goal_id_var = 'case_id_goal' e.datums.append(session_datum(new_goal_id_var, CAREPLAN_GOAL, 'parent', 'case_id')) if not module.display_separately: open_goal = CaseIDXPath(session_var(new_goal_id_var)).case().select('@status', 'open') frame.if_clause = '{count} = 1'.format(count=open_goal.count()) frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var(new_goal_id_var))) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) elif form.case_type == CAREPLAN_TASK: if not module.display_separately: frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var('case_id_goal'))) if form.mode == 'update': count = CaseTypeXpath(CAREPLAN_TASK).case().select( 'index/goal', session_var('case_id_goal'), quote=False ).select('@status', 'open').count() frame.if_clause = '{count} >= 1'.format(count=count) frame.add_command(XPath.string( id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, 'update')) )) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) if form.mode == 'create': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) elif form.mode == 'update': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) e.datums.append(session_datum('case_id_task', CAREPLAN_TASK, 'goal', 'case_id_goal'))
def get_frame_children(self, command, target_module, module_only=False, include_target_root=False): """ For a form return the list of stack frame children that are required to navigate to that form. Given command may be a form (mX-fY) or case list menu item (mX-case-list). This is based on the following algorithm: * Add the module the form is in to the stack (we'll call this `m`) * Walk through all forms in the module, determine what datum selections are present in all of the forms (this may be an empty set) * Basically if there are three forms that respectively load * f1: v1, v2, v3, v4 * f2: v1, v2, v4 * f3: v1, v2 * The longest common chain is v1, v2 * Add a datum for each of those values to the stack * Add the form "command id" for the <entry> to the stack * Add the remainder of the datums for the current form to the stack * For the three forms above, the stack entries for "last element" would be * m, v1, v2, f1, v3, v4 * m, v1, v2, f2, v4 * m, v1, v2, f3 :returns: list of strings and DatumMeta objects. String represent stack commands and DatumMeta's represent stack datums. """ match = re.search(r'^(m\d+)-(.*)', command) if not match: raise Exception("Unrecognized command: {}".format(command)) target_module_id = match.group(1) target_form_id = match.group(2) frame_children = [] module_command = id_strings.menu_id(target_module) module_datums = self.get_module_datums(target_module_id) form_datums = module_datums[target_form_id] frame_children = [] if module_command == id_strings.ROOT: datums_list = self.root_module_datums else: datums_list = list(module_datums.values()) # [ [datums for f0], [datums for f1], ...] root_module = target_module.root_module if root_module and include_target_root: datums_list = datums_list + list(self.get_module_datums(id_strings.menu_id(root_module)).values()) root_module_command = id_strings.menu_id(target_module.root_module) if root_module_command != id_strings.ROOT: frame_children.append(CommandId(root_module_command)) frame_children.append(CommandId(module_command)) common_datums = commonprefix(datums_list) remaining_datums = form_datums[len(common_datums):] frame_children.extend(common_datums) if not module_only: frame_children.append(CommandId(command)) frame_children.extend(remaining_datums) return frame_children
def get_module_contributions(self, module): if module_offers_search(module): domain = self.app.domain details_helper = DetailsHelper(self.app) sync_request = SyncRequest( post=SyncRequestPost( url=absolute_reverse('claim_case', args=[domain]), # Check whether the case to be claimed already exists in casedb: # count( # instance('casedb')/casedb/case[@case_id=instance('querysession')/session/data/case_id] # ) = 0 relevant=XPath.count( CaseIDXPath(QuerySessionXPath('case_id').instance()).case() ) + ' = 0', data=[ QueryData( key='case_id', ref=QuerySessionXPath('case_id').instance(), # e.g. instance('querysession')/session/data/case_id ), ] ), command=Command( id=id_strings.search_command(module), display=Display( text=Text(locale_id=id_strings.case_search_locale(module)), ), ), instances=[Instance( id=SESSION_INSTANCE, src='jr://instance/session' )], session=SyncRequestSession( queries=[ SyncRequestQuery( url=absolute_reverse('sync_search', args=[domain]), storage_instance=RESULTS_INSTANCE, data=[ QueryData( key='case_type', ref="'{}'".format(module.case_type) ), ], prompts=[ QueryPrompt( key=p.name, display=Display( text=Text(locale_id=id_strings.search_property_locale(module, p.name)), ), ) for p in module.search_config.properties ] ) ], data=[SessionDatum( id='case_id', nodeset=(CaseTypeXpath(module.case_type) .case(instance_name=RESULTS_INSTANCE) .select(u'@status', u'open', quote=True)), value='./@case_id', detail_select=details_helper.get_detail_id_safe(module, 'case_short'), detail_confirm=details_helper.get_detail_id_safe(module, 'case_long'), )], ), stack=Stack(), ) frame = PushFrame() # Open first form in module frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id=CALCULATED_DATA, value=XPath.string(MARK_AS_CLAIMED))) sync_request.stack.add_frame(frame) return [sync_request] return []
def get_frame_children(self, module, form=None, include_root_module=False): """ For a form or module return the list of stack frame children that are required to navigate there; a mix of commands and datum declarations. This is based on the following algorithm: * Add the module (or form's module) to the stack (we'll call this `m`) * Walk through all forms in the module, determine what datum selections are present in all of the forms (this may be an empty set) * Basically if there are three forms that respectively load * f1: v1, v2, v3, v4 * f2: v1, v2, v4 * f3: v1, v2 * The longest common chain is v1, v2 * Add a datum for each of those values to the stack For forms: * Add the form "command id" for the <entry> to the stack * Add the remainder of the datums for the current form to the stack * For the three forms above, the stack entries for "last element" would be * m, v1, v2, f1, v3, v4 * m, v1, v2, f2, v4 * m, v1, v2, f3 :returns: list of strings and DatumMeta objects. String represent stack commands and DatumMeta's represent stack datums. """ module_command = id_strings.menu_id(module) if form is None and module.module_type == "shadow": module_datums = self.get_module_datums( f'm{module.source_module.id}') else: module_datums = self.get_module_datums(f'm{module.id}') frame_children = [] if module_command == id_strings.ROOT: datums_list = self._root_module_datums else: datums_list = list(module_datums.values() ) # [ [datums for f0], [datums for f1], ...] root_module = module.root_module if root_module and include_root_module: datums_list.extend( self.get_module_datums( id_strings.menu_id(root_module)).values()) root_module_command = id_strings.menu_id(root_module) if root_module_command != id_strings.ROOT: frame_children.append(CommandId(root_module_command)) frame_children.append(CommandId(module_command)) common_datums = commonprefix(datums_list) frame_children.extend(common_datums) if form: frame_children.append( CommandId(id_strings.form_command(form, module))) form_datums = module_datums[f'f{form.id}'] remaining_datums = form_datums[len(common_datums):] frame_children.extend(remaining_datums) return frame_children
def configure_entry_careplan_form(self, module, e, form=None, **kwargs): parent_module = self.app.get_module_by_unique_id(module.parent_select.module_id) e.datums.append(SessionDatum( id='case_id', nodeset=EntriesHelper.get_nodeset_xpath(parent_module.case_type), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(parent_module, 'case_short'), detail_confirm=self.details_helper.get_detail_id_safe(parent_module, 'case_long') )) def session_datum(datum_id, case_type, parent_ref, parent_val): nodeset = CaseTypeXpath(case_type).case().select( 'index/%s' % parent_ref, session_var(parent_val), quote=False ).select('@status', 'open') return SessionDatum( id=datum_id, nodeset=nodeset, value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, '%s_short' % case_type), detail_confirm=self.details_helper.get_detail_id_safe(module, '%s_long' % case_type) ) e.stack = Stack() frame = CreateFrame() e.stack.add_frame(frame) if form.case_type == CAREPLAN_GOAL: if form.mode == 'create': new_goal_id_var = 'case_id_goal_new' e.datums.append(SessionDatum(id=new_goal_id_var, function='uuid()')) elif form.mode == 'update': new_goal_id_var = 'case_id_goal' e.datums.append(session_datum(new_goal_id_var, CAREPLAN_GOAL, 'parent', 'case_id')) if not module.display_separately: open_goal = CaseIDXPath(session_var(new_goal_id_var)).case().select('@status', 'open') frame.if_clause = '{count} = 1'.format(count=open_goal.count()) frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var(new_goal_id_var))) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) elif form.case_type == CAREPLAN_TASK: if not module.display_separately: frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var('case_id_goal'))) if form.mode == 'update': count = CaseTypeXpath(CAREPLAN_TASK).case().select( 'index/goal', session_var('case_id_goal'), quote=False ).select('@status', 'open').count() frame.if_clause = '{count} >= 1'.format(count=count) frame.add_command(XPath.string( id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, 'update')) )) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) if form.mode == 'create': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) elif form.mode == 'update': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) e.datums.append(session_datum('case_id_task', CAREPLAN_TASK, 'goal', 'case_id_goal'))