コード例 #1
0
    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
コード例 #2
0
ファイル: workflow.py プロジェクト: kkrampa/commcare-hq
    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
コード例 #3
0
ファイル: workflow.py プロジェクト: kkrampa/commcare-hq
    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
コード例 #4
0
    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
コード例 #5
0
    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
コード例 #6
0
ファイル: details.py プロジェクト: tlwakwella/commcare-hq
    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)
コード例 #7
0
ファイル: details.py プロジェクト: kkrampa/commcare-hq
    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
コード例 #8
0
    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
コード例 #9
0
    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
コード例 #10
0
        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
コード例 #11
0
ファイル: workflow.py プロジェクト: rodneylubwama/commcare-hq
        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
コード例 #12
0
    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
コード例 #13
0
 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
コード例 #14
0
ファイル: workflow.py プロジェクト: rodneylubwama/commcare-hq
 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
コード例 #15
0
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
コード例 #16
0
    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
コード例 #17
0
ファイル: menus.py プロジェクト: ansarbek/commcare-hq
    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
コード例 #18
0
    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
コード例 #19
0
ファイル: menus.py プロジェクト: twymer/commcare-hq
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
コード例 #20
0
ファイル: entries.py プロジェクト: johan--/commcare-hq
    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"))
コード例 #21
0
    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 []
コード例 #22
0
    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
コード例 #23
0
ファイル: workflow.py プロジェクト: saketkanth/commcare-hq
    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
コード例 #24
0
    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'))
コード例 #25
0
    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
コード例 #26
0
    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 []
コード例 #27
0
ファイル: workflow.py プロジェクト: soitun/commcare-hq
    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
コード例 #28
0
ファイル: entries.py プロジェクト: tlwakwella/commcare-hq
    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'))