コード例 #1
0
ファイル: menus.py プロジェクト: nnestle/commcare-hq
        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))
コード例 #2
0
        def _get_static_stack_frame(form_workflow, xpath=None):
            if form_workflow == WORKFLOW_ROOT:
                return StackFrameMeta(xpath, [], allow_empty_frame=True)
            elif form_workflow == WORKFLOW_MODULE:
                frame_children = frame_children_for_module(
                    module, include_user_selections=False)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PARENT_MODULE:
                root_module = module.root_module
                frame_children = frame_children_for_module(root_module)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PREVIOUS:
                frame_children = self.helper.get_frame_children(
                    id_strings.form_command(form),
                    module,
                    include_target_root=True)

                # since we want to go the 'previous' screen we need to drop the last
                # datum
                last = frame_children.pop()
                while isinstance(
                        last,
                        WorkflowDatumMeta) and not last.requires_selection:
                    # keep removing last element until we hit a command
                    # or a non-autoselect datum
                    last = frame_children.pop()

                return StackFrameMeta(xpath, frame_children)
コード例 #3
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
コード例 #4
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)
コード例 #5
0
        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
コード例 #6
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
コード例 #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
ファイル: menus.py プロジェクト: kkrampa/commcare-hq
        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))
コード例 #10
0
ファイル: workflow.py プロジェクト: soitun/commcare-hq
 def update_suite(self):
     """
     Add stack elements to form entry elements to configure app workflow. This updates
     the Entry objects in place.
     """
     for module in self.modules:
         for form in module.get_suite_forms():
             frames = self._get_stack_frames(form, module)
             if frames:
                 entry = self._get_form_entry(
                     id_strings.form_command(form, module))
                 self._add_frames_to_entry(entry, frames)
コード例 #11
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
コード例 #12
0
ファイル: workflow.py プロジェクト: rodneylubwama/commcare-hq
    def update_suite(self):
        """
        Add stack elements to form entry elements to configure app workflow. This updates
        the Entry objects in place.
        """
        for module in self.modules:
            for form in module.get_suite_forms():
                form_command = id_strings.form_command(form, module)
                stack_frames = []
                end_of_form_frames = EndOfFormNavigationWorkflow(self).form_workflow_frames(module, form)
                if end_of_form_frames:
                    stack_frames.extend(end_of_form_frames)
                else:
                    stack_frames.extend(CaseListFormWorkflow(self).case_list_forms_frames(form))

                self.create_workflow_stack(form_command, stack_frames)
コード例 #13
0
    def update_suite(self):
        """
        Add stack elements to form entry elements to configure app workflow. This updates
        the Entry objects in place.
        """
        for module in self.modules:
            for form in module.get_suite_forms():
                form_command = id_strings.form_command(form, module)
                stack_frames = []
                end_of_form_frames = EndOfFormNavigationWorkflow(self).form_workflow_frames(module, form)
                if end_of_form_frames:
                    stack_frames.extend(end_of_form_frames)
                else:
                    stack_frames.extend(CaseListFormWorkflow(self).case_list_forms_frames(form))

                self.create_workflow_stack(form_command, stack_frames)
コード例 #14
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
コード例 #15
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(id_strings.form_command(module_.get_form(0)),
                                                                      module_, 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
コード例 #16
0
ファイル: workflow.py プロジェクト: kkrampa/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(id_strings.form_command(module_.get_form(0)),
                                                                      module_, 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
コード例 #17
0
ファイル: workflow.py プロジェクト: tlwakwella/commcare-hq
    def update_suite(self):
        """
        Add stack elements to form entry elements to configure app workflow. This updates
        the Entry objects in place.
        """
        for module in self.modules:
            for form in module.get_suite_forms():
                form_command = id_strings.form_command(form, module)
                if_prefix = None
                stack_frames = []
                case_list_form_frames = CaseListFormWorkflow(self).case_list_forms_frames(form)
                stack_frames.extend(case_list_form_frames)

                if case_list_form_frames:
                    if_prefix = session_var(RETURN_TO).count().eq(0)

                stack_frames.extend(EndOfFormNavigationWorkflow(self).form_workflow_frames(if_prefix, module, form))

                self.create_workflow_stack(form_command, stack_frames)
コード例 #18
0
    def _add_stack_children_for_target(self, stack_frames, target_module, source_form_datums):
        """
        :param stack_frames: Stack to add children to
        :param target_module: Module that we're targeting for navigating to
        :param source_form_datums: List of datums from the source form.
        """
        ids_on_stack = stack_frames.ids_on_stack
        command = None
        if len(target_module.forms):
            command = id_strings.form_command(target_module.get_form(0))
        elif target_module.case_list and target_module.case_list.show:
            command = id_strings.case_list_command(target_module)

        if command:
            target_frame_children = self.helper.get_frame_children(command, target_module, module_only=True)
            remaining_target_frame_children = [fc for fc in target_frame_children if fc.id not in ids_on_stack]
            frame_children = WorkflowHelper.get_datums_matched_to_source(
                remaining_target_frame_children, source_form_datums
            )
            stack_frames.add_children(frame_children)
コード例 #19
0
ファイル: workflow.py プロジェクト: kkrampa/commcare-hq
    def _add_stack_children_for_target(self, stack_frames, target_module, source_form_datums):
        """
        :param stack_frames: Stack to add children to
        :param target_module: Module that we're targeting for navigating to
        :param source_form_datums: List of datums from the source form.
        """
        ids_on_stack = stack_frames.ids_on_stack
        command = None
        if len(target_module.forms):
            command = id_strings.form_command(target_module.get_form(0))
        elif target_module.case_list and target_module.case_list.show:
            command = id_strings.case_list_command(target_module)

        if command:
            target_frame_children = self.helper.get_frame_children(command, target_module, module_only=True)
            remaining_target_frame_children = [fc for fc in target_frame_children if fc.id not in ids_on_stack]
            frame_children = WorkflowHelper.get_datums_matched_to_source(
                remaining_target_frame_children, source_form_datums
            )
            stack_frames.add_children(frame_children)
コード例 #20
0
ファイル: workflow.py プロジェクト: kkrampa/commcare-hq
        def _get_static_stack_frame(form_workflow, xpath=None):
            if form_workflow == WORKFLOW_ROOT:
                return StackFrameMeta(xpath, [], allow_empty_frame=True)
            elif form_workflow == WORKFLOW_MODULE:
                frame_children = frame_children_for_module(module, include_user_selections=False)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PARENT_MODULE:
                root_module = module.root_module
                frame_children = frame_children_for_module(root_module)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PREVIOUS:
                frame_children = self.helper.get_frame_children(id_strings.form_command(form),
                                                                module, include_target_root=True)

                # since we want to go the 'previous' screen we need to drop the last
                # datum
                last = frame_children.pop()
                while isinstance(last, WorkflowDatumMeta) and not last.requires_selection:
                    # keep removing last element until we hit a command
                    # or a non-autoselect datum
                    last = frame_children.pop()

                return StackFrameMeta(xpath, frame_children)
コード例 #21
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'))
コード例 #22
0
    def entry_for_module(self, module):
        # avoid circular dependency
        from corehq.apps.app_manager.models import Module, AdvancedModule
        results = []
        for form in module.get_suite_forms():
            e = Entry()
            e.form = form.xmlns
            # Ideally all of this version check should happen in Command/Display class
            if self.app.enable_localized_menu_media:
                e.command = LocalizedCommand(
                    id=id_strings.form_command(form, module),
                    menu_locale_id=id_strings.form_locale(form),
                    media_image=bool(len(form.all_image_paths())),
                    media_audio=bool(len(form.all_audio_paths())),
                    image_locale_id=id_strings.form_icon_locale(form),
                    audio_locale_id=id_strings.form_audio_locale(form),
                )
            else:
                e.command = Command(
                    id=id_strings.form_command(form, module),
                    locale_id=id_strings.form_locale(form),
                    media_image=form.default_media_image,
                    media_audio=form.default_media_audio,
                )
            config_entry = {
                'module_form': self.configure_entry_module_form,
                'advanced_form': self.configure_entry_advanced_form,
                'careplan_form': self.configure_entry_careplan_form,
            }[form.form_type]
            config_entry(module, e, form)

            if (
                self.app.commtrack_enabled and
                session_var('supply_point_id') in getattr(form, 'source', "")
            ):
                from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION
                datum, assertions = EntriesHelper.get_userdata_autoselect(
                    'commtrack-supply-point',
                    'supply_point_id',
                    AUTO_SELECT_LOCATION,
                )
                e.datums.append(datum)
                e.assertions.extend(assertions)

            results.append(e)

        if hasattr(module, 'case_list') and module.case_list.show:
            e = Entry()
            if self.app.enable_localized_menu_media:
                e.command = LocalizedCommand(
                    id=id_strings.case_list_command(module),
                    menu_locale_id=id_strings.case_list_locale(module),
                    media_image=bool(len(module.case_list.all_image_paths())),
                    media_audio=bool(len(module.case_list.all_audio_paths())),
                    image_locale_id=id_strings.case_list_icon_locale(module),
                    audio_locale_id=id_strings.case_list_audio_locale(module),
                )
            else:
                e.command = Command(
                    id=id_strings.case_list_command(module),
                    locale_id=id_strings.case_list_locale(module),
                    media_image=module.case_list.default_media_image,
                    media_audio=module.case_list.default_media_audio,
                )
            if isinstance(module, Module):
                for datum_meta in self.get_case_datums_basic_module(module):
                    e.datums.append(datum_meta.datum)
            elif isinstance(module, AdvancedModule):
                e.datums.append(SessionDatum(
                    id='case_id_case_%s' % module.case_type,
                    nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)),
                    value="./@case_id",
                    detail_select=self.details_helper.get_detail_id_safe(module, 'case_short'),
                    detail_confirm=self.details_helper.get_detail_id_safe(module, 'case_long'),
                    detail_persistent=self.get_detail_persistent_attr(module, module, "case_short"),
                    detail_inline=self.get_detail_inline_attr(module, module, "case_short"),
                    autoselect=module.auto_select_case,
                ))
                if self.app.commtrack_enabled:
                    e.datums.append(SessionDatum(
                        id='product_id',
                        nodeset=ProductInstanceXpath().instance(),
                        value="./@id",
                        detail_select=self.details_helper.get_detail_id_safe(module, 'product_short')
                    ))
            results.append(e)

        for entry in module.get_custom_entries():
            results.append(entry)

        return results
コード例 #23
0
 def _get_first_command(self, module):
     if module.module_type == "shadow":
         module = module.source_module
     return id_strings.form_command(module.get_form(0))
コード例 #24
0
ファイル: entries.py プロジェクト: johan--/commcare-hq
    def entry_for_module(self, module):
        # avoid circular dependency
        from corehq.apps.app_manager.models import Module, AdvancedModule

        results = []
        for form in module.get_suite_forms():
            e = Entry()
            e.form = form.xmlns
            # Ideally all of this version check should happen in Command/Display class
            if self.app.enable_localized_menu_media:
                e.command = LocalizedCommand(
                    id=id_strings.form_command(form, module),
                    menu_locale_id=id_strings.form_locale(form),
                    media_image=bool(len(form.all_image_paths())),
                    media_audio=bool(len(form.all_audio_paths())),
                    image_locale_id=id_strings.form_icon_locale(form),
                    audio_locale_id=id_strings.form_audio_locale(form),
                )
            else:
                e.command = Command(
                    id=id_strings.form_command(form, module),
                    locale_id=id_strings.form_locale(form),
                    media_image=form.default_media_image,
                    media_audio=form.default_media_audio,
                )
            config_entry = {
                "module_form": self.configure_entry_module_form,
                "advanced_form": self.configure_entry_advanced_form,
                "careplan_form": self.configure_entry_careplan_form,
            }[form.form_type]
            config_entry(module, e, form)

            if self.app.commtrack_enabled and session_var("supply_point_id") in getattr(form, "source", ""):
                from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION

                datum, assertions = EntriesHelper.get_userdata_autoselect(
                    "commtrack-supply-point", "supply_point_id", AUTO_SELECT_LOCATION
                )
                e.datums.append(datum)
                e.assertions.extend(assertions)

            results.append(e)

        if hasattr(module, "case_list") and module.case_list.show:
            e = Entry()
            if self.app.enable_localized_menu_media:
                e.command = LocalizedCommand(
                    id=id_strings.case_list_command(module),
                    menu_locale_id=id_strings.case_list_locale(module),
                    media_image=bool(len(module.case_list.all_image_paths())),
                    media_audio=bool(len(module.case_list.all_audio_paths())),
                    image_locale_id=id_strings.case_list_icon_locale(module),
                    audio_locale_id=id_strings.case_list_audio_locale(module),
                )
            else:
                e.command = Command(
                    id=id_strings.case_list_command(module),
                    locale_id=id_strings.case_list_locale(module),
                    media_image=module.case_list.default_media_image,
                    media_audio=module.case_list.default_media_audio,
                )
            if isinstance(module, Module):
                for datum_meta in self.get_datum_meta_module(module, use_filter=False):
                    e.datums.append(datum_meta.datum)
            elif isinstance(module, AdvancedModule):
                detail_persistent, detail_inline = self.get_case_tile_datum_attrs(module, module)
                e.datums.append(
                    SessionDatum(
                        id="case_id_case_%s" % module.case_type,
                        nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)),
                        value="./@case_id",
                        detail_select=self.details_helper.get_detail_id_safe(module, "case_short"),
                        detail_confirm=self.details_helper.get_detail_id_safe(module, "case_long"),
                        detail_persistent=detail_persistent,
                        detail_inline=detail_inline,
                    )
                )
                if self.app.commtrack_enabled:
                    e.datums.append(
                        SessionDatum(
                            id="product_id",
                            nodeset=ProductInstanceXpath().instance(),
                            value="./@id",
                            detail_select=self.details_helper.get_detail_id_safe(module, "product_short"),
                        )
                    )
            results.append(e)

        for entry in module.get_custom_entries():
            results.append(entry)

        return results
コード例 #25
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"))
コード例 #26
0
 def get_form_datums(self, form):
     """
     :return: List of DatumMeta objects for this form
     """
     module_id, form_id = id_strings.form_command(form).split('-')
     return self.get_module_datums(module_id)[form_id]
コード例 #27
0
ファイル: entries.py プロジェクト: kkrampa/commcare-hq
    def entry_for_module(self, module):
        # avoid circular dependency
        from corehq.apps.app_manager.models import Module, AdvancedModule
        results = []
        for form in module.get_suite_forms():
            e = Entry()
            e.form = form.xmlns
            # Ideally all of this version check should happen in Command/Display class
            if self.app.enable_localized_menu_media:
                form_custom_icon = form.custom_icon
                e.command = LocalizedCommand(
                    id=id_strings.form_command(form, module),
                    menu_locale_id=id_strings.form_locale(form),
                    media_image=bool(len(form.all_image_paths())),
                    media_audio=bool(len(form.all_audio_paths())),
                    image_locale_id=id_strings.form_icon_locale(form),
                    audio_locale_id=id_strings.form_audio_locale(form),
                    custom_icon_locale_id=(id_strings.form_custom_icon_locale(form, form_custom_icon.form)
                                           if form_custom_icon and not form_custom_icon.xpath else None),
                    custom_icon_form=(form_custom_icon.form if form_custom_icon else None),
                    custom_icon_xpath=(form_custom_icon.xpath
                                       if form_custom_icon and form_custom_icon.xpath else None),
                )
            else:
                e.command = Command(
                    id=id_strings.form_command(form, module),
                    locale_id=id_strings.form_locale(form),
                    media_image=form.default_media_image,
                    media_audio=form.default_media_audio,
                )
            config_entry = {
                'module_form': self.configure_entry_module_form,
                'advanced_form': self.configure_entry_advanced_form,
                'shadow_form': self.configure_entry_advanced_form,
            }[form.form_type]
            config_entry(module, e, form)

            if form.uses_usercase():
                EntriesHelper.add_usercase_id_assertion(e)

            EntriesHelper.add_custom_assertions(e, form)

            if (
                self.app.commtrack_enabled and
                session_var('supply_point_id') in getattr(form, 'source', "")
            ):
                from corehq.apps.app_manager.models import AUTO_SELECT_LOCATION
                datum, assertions = EntriesHelper.get_userdata_autoselect(
                    'commtrack-supply-point',
                    'supply_point_id',
                    AUTO_SELECT_LOCATION,
                )
                e.datums.append(datum)
                e.assertions.extend(assertions)

            results.append(e)

        if hasattr(module, 'case_list') and module.case_list.show:
            e = Entry()
            if self.app.enable_localized_menu_media:
                e.command = LocalizedCommand(
                    id=id_strings.case_list_command(module),
                    menu_locale_id=id_strings.case_list_locale(module),
                    media_image=bool(len(module.case_list.all_image_paths())),
                    media_audio=bool(len(module.case_list.all_audio_paths())),
                    image_locale_id=id_strings.case_list_icon_locale(module),
                    audio_locale_id=id_strings.case_list_audio_locale(module),
                )
            else:
                e.command = Command(
                    id=id_strings.case_list_command(module),
                    locale_id=id_strings.case_list_locale(module),
                    media_image=module.case_list.default_media_image,
                    media_audio=module.case_list.default_media_audio,
                )
            if isinstance(module, Module):
                for datum_meta in self.get_case_datums_basic_module(module):
                    e.datums.append(datum_meta.datum)
            elif isinstance(module, AdvancedModule):
                detail_inline = self.get_detail_inline_attr(module, module, "case_short")
                detail_confirm = None
                if not detail_inline:
                    detail_confirm = self.details_helper.get_detail_id_safe(module, 'case_long')
                e.datums.append(SessionDatum(
                    id='case_id_case_%s' % module.case_type,
                    nodeset=(EntriesHelper.get_nodeset_xpath(module.case_type)),
                    value="./@case_id",
                    detail_select=self.details_helper.get_detail_id_safe(module, 'case_short'),
                    detail_confirm=detail_confirm,
                    detail_persistent=self.get_detail_persistent_attr(module, module, "case_short"),
                    detail_inline=detail_inline,
                    autoselect=module.auto_select_case,
                ))
                if self.app.commtrack_enabled:
                    e.datums.append(SessionDatum(
                        id='product_id',
                        nodeset=ProductInstanceXpath().instance(),
                        value="./@id",
                        detail_select=self.details_helper.get_detail_id_safe(module, 'product_short')
                    ))
            results.append(e)

        for entry in module.get_custom_entries():
            results.append(entry)

        return results
コード例 #28
0
 def get_form_datums(self, form):
     """
     :return: List of DatumMeta objects for this form
     """
     module_id, form_id = id_strings.form_command(form).split('-')
     return self.get_module_datums(module_id)[form_id]
コード例 #29
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
コード例 #30
0
 def _get_form_endpoint(self, form, module):
     id_string = id_strings.form_command(form)
     return self._make_session_endpoint(id_string, module,
                                        form.session_endpoint_id)
コード例 #31
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'))
コード例 #32
0
ファイル: workflow.py プロジェクト: kkrampa/commcare-hq
    def form_workflow_frames(self, module, form):
        """
        post_form_workflow = 'module':
          * Add stack frame and a command with value = "module command"

        post_form_workflow = 'previous_screen':
          * Add stack frame and a command with value = "module command"
          * Find longest list of common datums between form entries for the module and add datums
            to the stack frame for each.
          * Add a command to the frame with value = "form command"
          * Add datums to the frame for any remaining datums for that form.
          * Remove any autoselect items from the end of the stack frame.
          * Finally remove the last item from the stack frame.
        """
        from corehq.apps.app_manager.const import (
            WORKFLOW_PREVIOUS, WORKFLOW_MODULE, WORKFLOW_ROOT, WORKFLOW_FORM, WORKFLOW_PARENT_MODULE
        )

        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(id_strings.form_command(module_.get_form(0)),
                                                                      module_, 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_static_stack_frame(form_workflow, xpath=None):
            if form_workflow == WORKFLOW_ROOT:
                return StackFrameMeta(xpath, [], allow_empty_frame=True)
            elif form_workflow == WORKFLOW_MODULE:
                frame_children = frame_children_for_module(module, include_user_selections=False)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PARENT_MODULE:
                root_module = module.root_module
                frame_children = frame_children_for_module(root_module)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PREVIOUS:
                frame_children = self.helper.get_frame_children(id_strings.form_command(form),
                                                                module, include_target_root=True)

                # since we want to go the 'previous' screen we need to drop the last
                # datum
                last = frame_children.pop()
                while isinstance(last, WorkflowDatumMeta) and not last.requires_selection:
                    # keep removing last element until we hit a command
                    # or a non-autoselect datum
                    last = frame_children.pop()

                return StackFrameMeta(xpath, frame_children)

        stack_frames = []

        if form.post_form_workflow == WORKFLOW_FORM:
            source_form_datums = self.helper.get_form_datums(form)

            for link in form.form_links:
                target_form = self.helper.app.get_form(link.form_id)
                target_module = target_form.get_module()

                target_frame_children = self.helper.get_frame_children(id_strings.form_command(target_form),
                                                                       target_module)
                if link.datums:
                    frame_children = EndOfFormNavigationWorkflow.get_datums_matched_to_manual_values(
                        target_frame_children, link.datums, form
                    )
                else:
                    frame_children = WorkflowHelper.get_datums_matched_to_source(
                        target_frame_children, source_form_datums
                    )

                if target_module in module.get_child_modules():
                    parent_frame_children = self.helper.get_frame_children(
                        id_strings.form_command(module.get_form(0)), module, module_only=True)

                    # exclude frame children from the child module if they are already
                    # supplied by the parent module
                    parent_ids = {parent.id for parent in parent_frame_children}
                    frame_children = parent_frame_children + [
                        child for child in frame_children
                        if child.id not in parent_ids
                    ]

                stack_frames.append(StackFrameMeta(link.xpath, frame_children, current_session=source_form_datums))
            if form.post_form_workflow_fallback:
                # for the fallback negative all if conditions/xpath expressions and use that as the xpath for this
                link_xpaths = [link.xpath for link in form.form_links]
                # remove any empty string
                link_xpaths = [x for x in link_xpaths if x.strip()]
                if link_xpaths:
                    negate_of_all_link_paths = (
                        ' and '.join(
                            ['not(' + link_xpath + ')' for link_xpath in link_xpaths]
                        )
                    )
                    static_stack_frame_for_fallback = _get_static_stack_frame(
                        form.post_form_workflow_fallback,
                        negate_of_all_link_paths
                    )
                    if static_stack_frame_for_fallback:
                        stack_frames.append(static_stack_frame_for_fallback)
        else:
            static_stack_frame = _get_static_stack_frame(form.post_form_workflow)
            if static_stack_frame:
                stack_frames.append(static_stack_frame)
        return stack_frames
コード例 #33
0
    def form_workflow_frames(self, module, form):
        """
        post_form_workflow = 'module':
          * Add stack frame and a command with value = "module command"

        post_form_workflow = 'previous_screen':
          * Add stack frame and a command with value = "module command"
          * Find longest list of common datums between form entries for the module and add datums
            to the stack frame for each.
          * Add a command to the frame with value = "form command"
          * Add datums to the frame for any remaining datums for that form.
          * Remove any autoselect items from the end of the stack frame.
          * Finally remove the last item from the stack frame.
        """
        from corehq.apps.app_manager.const import (WORKFLOW_PREVIOUS,
                                                   WORKFLOW_MODULE,
                                                   WORKFLOW_ROOT,
                                                   WORKFLOW_FORM,
                                                   WORKFLOW_PARENT_MODULE)

        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(
                    id_strings.form_command(module_.get_form(0)),
                    module_,
                    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_static_stack_frame(form_workflow, xpath=None):
            if form_workflow == WORKFLOW_ROOT:
                return StackFrameMeta(xpath, [], allow_empty_frame=True)
            elif form_workflow == WORKFLOW_MODULE:
                frame_children = frame_children_for_module(
                    module, include_user_selections=False)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PARENT_MODULE:
                root_module = module.root_module
                frame_children = frame_children_for_module(root_module)
                return StackFrameMeta(xpath, frame_children)
            elif form_workflow == WORKFLOW_PREVIOUS:
                frame_children = self.helper.get_frame_children(
                    id_strings.form_command(form),
                    module,
                    include_target_root=True)

                # since we want to go the 'previous' screen we need to drop the last
                # datum
                last = frame_children.pop()
                while isinstance(
                        last,
                        WorkflowDatumMeta) and not last.requires_selection:
                    # keep removing last element until we hit a command
                    # or a non-autoselect datum
                    last = frame_children.pop()

                return StackFrameMeta(xpath, frame_children)

        stack_frames = []

        if form.post_form_workflow == WORKFLOW_FORM:
            source_form_datums = self.helper.get_form_datums(form)

            for link in form.form_links:
                target_form = self.helper.app.get_form(link.form_id)
                target_module = target_form.get_module()

                target_frame_children = self.helper.get_frame_children(
                    id_strings.form_command(target_form), target_module)
                if link.datums:
                    frame_children = EndOfFormNavigationWorkflow.get_datums_matched_to_manual_values(
                        target_frame_children, link.datums, form)
                else:
                    frame_children = WorkflowHelper.get_datums_matched_to_source(
                        target_frame_children, source_form_datums)

                if target_module in module.get_child_modules():
                    parent_frame_children = self.helper.get_frame_children(
                        id_strings.form_command(module.get_form(0)),
                        module,
                        module_only=True)

                    # exclude frame children from the child module if they are already
                    # supplied by the parent module
                    parent_ids = {
                        parent.id
                        for parent in parent_frame_children
                    }
                    frame_children = parent_frame_children + [
                        child for child in frame_children
                        if child.id not in parent_ids
                    ]

                stack_frames.append(
                    StackFrameMeta(link.xpath,
                                   frame_children,
                                   current_session=source_form_datums))
            if form.post_form_workflow_fallback:
                # for the fallback negative all if conditions/xpath expressions and use that as the xpath for this
                link_xpaths = [link.xpath for link in form.form_links]
                # remove any empty string
                link_xpaths = [x for x in link_xpaths if x.strip()]
                if link_xpaths:
                    negate_of_all_link_paths = (' and '.join([
                        'not(' + link_xpath + ')' for link_xpath in link_xpaths
                    ]))
                    static_stack_frame_for_fallback = _get_static_stack_frame(
                        form.post_form_workflow_fallback,
                        negate_of_all_link_paths)
                    if static_stack_frame_for_fallback:
                        stack_frames.append(static_stack_frame_for_fallback)
        else:
            static_stack_frame = _get_static_stack_frame(
                form.post_form_workflow)
            if static_stack_frame:
                stack_frames.append(static_stack_frame)
        return stack_frames