Example #1
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
Example #2
0
    def test_replace_session_references_in_stack(self):
        children = [
            CommandId('m0'),
            StackDatum(id='a', value=session_var('new_a')),
            StackDatum(id='b', value=session_var('new_b')),
            StackDatum(
                id='c',
                value="instance('casedb')/case/[@case_id = {a}]/index/parent".
                format(a=session_var('a'))),
            StackDatum(id='d',
                       value="if({c}, {c}, {a}]".format(a=session_var('a'),
                                                        c=session_var('c')))
        ]

        clean = _replace_session_references_in_stack(children)
        clean_raw = []
        for child in clean:
            if isinstance(child, CommandId):
                clean_raw.append(child.id)
            else:
                clean_raw.append((child.id, child.value))

        new_c = "instance('casedb')/case/[@case_id = {a}]/index/parent".format(
            a=session_var('new_a'))
        self.assertEqual(clean_raw, [
            'm0', ('a', session_var('new_a')), ('b', session_var('new_b')),
            ('c', new_c),
            ('d', "if({c}, {c}, {a}]".format(a=session_var('new_a'), c=new_c))
        ])
Example #3
0
def _replace_session_references_in_stack(stack_children, current_session=None):
    """Given a list of stack children (commands and datums)
    replace any references in the datum to session variables that
    have already been added to the session.

    e.g.
    <datum id="case_id_a" value="instance('commcaresession')/session/data/case_id_new_a"/>
    <datum id="case_id_b" value="instance('commcaresession')/session/data/case_id_a"/>
                                                                          ^^^^^^^^^
    In the second datum replace ``case_id_a`` with ``case_id_new_a``.

    We have to do this because stack create blocks do not update the session after each datum
    is added so items put into the session in one step aren't available to later steps.
    """
    current_session_vars = [datum.id for datum in current_session
                            ] if current_session else []
    clean_children = []
    child_map = {}
    for child in stack_children:
        if not isinstance(child, StackDatum):
            clean_children.append(child)
            continue
        session_vars = session_var_regex.findall(child.value)
        new_value = child.value
        for var in session_vars:
            if var in child_map and var not in current_session_vars:
                new_value = new_value.replace(session_var(var), child_map[var])

        child_map[child.id] = new_value
        clean_children.append(StackDatum(id=child.id, value=new_value))

    return clean_children
Example #4
0
 def get_if_clause(case_count_xpath, target_command):
     return_to = session_var(RETURN_TO)
     return XPath.and_(
         return_to.count().eq(1),
         return_to.eq(XPath.string(target_command)),
         case_count_xpath
     )
Example #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
Example #6
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
Example #7
0
    def get_datum_meta_module(self, module, use_filter=False):
        datums = []
        datum_module = module.source_module if module.module_type == 'shadow' else module
        datums_meta = get_select_chain_meta(self.app, datum_module)
        for i, datum in enumerate(datums_meta):
            # get the session var for the previous datum if there is one
            parent_id = datums_meta[i - 1]['session_var'] if i >= 1 else ''
            if parent_id:
                parent_filter = EntriesHelper.get_parent_filter(
                    datum['module'].parent_select.relationship, parent_id
                )
            else:
                parent_filter = ''

            detail_module = module if module.module_type == 'shadow' else datum['module']
            detail_persistent = self.get_detail_persistent_attr(datum['module'], detail_module, "case_short")
            detail_inline = self.get_detail_inline_attr(datum['module'], detail_module, "case_short")

            fixture_select_filter = ''
            if datum['module'].fixture_select.active:
                datums.append(FormDatumMeta(
                    datum=SessionDatum(
                        id=id_strings.fixture_session_var(datum['module']),
                        nodeset=ItemListFixtureXpath(datum['module'].fixture_select.fixture_type).instance(),
                        value=datum['module'].fixture_select.variable_column,
                        detail_select=id_strings.fixture_detail(detail_module)
                    ),
                    case_type=None,
                    requires_selection=True,
                    action='fixture_select'
                ))
                filter_xpath_template = datum['module'].fixture_select.xpath
                fixture_value = session_var(id_strings.fixture_session_var(datum['module']))
                fixture_select_filter = "[{}]".format(
                    filter_xpath_template.replace('$fixture_value', fixture_value)
                )

            filter_xpath = EntriesHelper.get_filter_xpath(detail_module) if use_filter else ''

            datums.append(FormDatumMeta(
                datum=SessionDatum(
                    id=datum['session_var'],
                    nodeset=(EntriesHelper.get_nodeset_xpath(datum['case_type'], filter_xpath=filter_xpath)
                             + parent_filter + fixture_select_filter),
                    value="./@case_id",
                    detail_select=self.details_helper.get_detail_id_safe(detail_module, 'case_short'),
                    detail_confirm=(
                        self.details_helper.get_detail_id_safe(detail_module, 'case_long')
                        if datum['index'] == 0 and not detail_inline else None
                    ),
                    detail_persistent=detail_persistent,
                    detail_inline=detail_inline,
                    autoselect=datum['module'].auto_select_case,
                ),
                case_type=datum['case_type'],
                requires_selection=True,
                action='update_case'
            ))
        return datums
 def test_autoload_supplypoint(self):
     app = Application.wrap(self.get_json('app'))
     app.modules[0].forms[0].source = re.sub('/data/plain',
                                             session_var('supply_point_id'),
                                             app.modules[0].forms[0].source)
     app_xml = app.create_suite()
     self.assertXmlPartialEqual(self.get_xml('autoload_supplypoint'),
                                app_xml, './entry[1]')
Example #9
0
 def get_auto_select_datums_and_assertions(action, auto_select, form):
     from corehq.apps.app_manager.models import AUTO_SELECT_USER, AUTO_SELECT_CASE, \
         AUTO_SELECT_FIXTURE, AUTO_SELECT_RAW, AUTO_SELECT_USERCASE
     if auto_select.mode == AUTO_SELECT_USER:
         return EntriesHelper.get_userdata_autoselect(
             auto_select.value_key,
             action.case_session_var,
             auto_select.mode,
         )
     elif auto_select.mode == AUTO_SELECT_CASE:
         try:
             ref = form.actions.actions_meta_by_tag[auto_select.value_source]['action']
             sess_var = ref.case_session_var
         except KeyError:
             raise ValueError("Case tag not found: %s" % auto_select.value_source)
         xpath = CaseIDXPath(session_var(sess_var)).case().index_id(auto_select.value_key)
         assertions = EntriesHelper.get_auto_select_assertions(xpath, auto_select.mode, [auto_select.value_key])
         return SessionDatum(
             id=action.case_session_var,
             function=xpath
         ), assertions
     elif auto_select.mode == AUTO_SELECT_FIXTURE:
         xpath_base = ItemListFixtureXpath(auto_select.value_source).instance()
         xpath = xpath_base.slash(auto_select.value_key)
         fixture_assertion = EntriesHelper.get_assertion(
             "{0} = 1".format(xpath_base.count()),
             'case_autoload.{0}.exactly_one_fixture'.format(auto_select.mode),
             [auto_select.value_source]
         )
         assertions = EntriesHelper.get_auto_select_assertions(xpath, auto_select.mode, [auto_select.value_key])
         return SessionDatum(
             id=action.case_session_var,
             function=xpath
         ), [fixture_assertion] + assertions
     elif auto_select.mode == AUTO_SELECT_RAW:
         case_id_xpath = auto_select.value_key
         case_count = CaseIDXPath(case_id_xpath).case().count()
         return SessionDatum(
             id=action.case_session_var,
             function=case_id_xpath
         ), [
             EntriesHelper.get_assertion(
                 "{0} = 1".format(case_count),
                 'case_autoload.{0}.case_missing'.format(auto_select.mode)
             )
         ]
     elif auto_select.mode == AUTO_SELECT_USERCASE:
         case = UserCaseXPath().case()
         return SessionDatum(
             id=action.case_session_var,
             function=case.slash('@case_id')
         ), [
             EntriesHelper.get_assertion(
                 "{0} = 1".format(case.count()),
                 'case_autoload.{0}.case_missing'.format(auto_select.mode)
             )
         ]
Example #10
0
 def get_if_clause(case_count_xpath, target_command):
     return_to = session_var(RETURN_TO)
     args = [
         return_to.count().eq(1),
         return_to.eq(XPath.string(target_command)),
     ]
     if case_count_xpath:
         args.append(case_count_xpath)
     return XPath.and_(*args)
Example #11
0
    def get_load_case_from_fixture_datums(self, action, target_module, form):
        datums = []
        load_case_from_fixture = action.load_case_from_fixture

        if (load_case_from_fixture.arbitrary_datum_id and
                load_case_from_fixture.arbitrary_datum_function):
            datums.append(FormDatumMeta(
                SessionDatum(
                    id=load_case_from_fixture.arbitrary_datum_id,
                    function=load_case_from_fixture.arbitrary_datum_function,
                ),
                case_type=action.case_type,
                requires_selection=True,
                action=action,
            ))
        datums.append(FormDatumMeta(
            datum=SessionDatum(
                id=load_case_from_fixture.fixture_tag,
                nodeset=load_case_from_fixture.fixture_nodeset,
                value="./@" + load_case_from_fixture.fixture_variable,
                detail_select=self.details_helper.get_detail_id_safe(target_module, 'case_short'),
                detail_confirm=self.details_helper.get_detail_id_safe(target_module, 'case_long'),
            ),
            case_type=action.case_type,
            requires_selection=True,
            action=action,
        ))

        if action.case_tag:
            if action.case_index.tag:
                parent_action = form.actions.actions_meta_by_tag[action.case_index.tag]['action']
                parent_filter = EntriesHelper.get_parent_filter(
                    action.case_index.reference_id,
                    parent_action.case_session_var
                )
            else:
                parent_filter = ''
            session_var_for_fixture = session_var(load_case_from_fixture.fixture_tag)
            filter_for_casedb = '[{0}={1}]'.format(load_case_from_fixture.case_property, session_var_for_fixture)
            nodeset = EntriesHelper.get_nodeset_xpath(action.case_type, filter_xpath=filter_for_casedb)
            nodeset += parent_filter

            datums.append(FormDatumMeta(
                datum=SessionDatum(
                    id=action.case_tag,
                    nodeset=nodeset,
                    value="./@case_id",
                    autoselect=load_case_from_fixture.auto_select,
                ),
                case_type=action.case_type,
                requires_selection=False,
                action=action,
            ))

        return datums
Example #12
0
 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)
     )
Example #13
0
 def get_userdata_autoselect(key, session_id, mode):
     base_xpath = session_var('data', path='user')
     xpath = session_var(key, path='user/data')
     protected_xpath = XPath.if_(
         XPath.and_(base_xpath.count().eq(1), xpath.count().eq(1)),
         xpath,
         XPath.empty_string(),
     )
     datum = SessionDatum(id=session_id, function=protected_xpath)
     assertions = [
         EntriesHelper.get_assertion(
             XPath.and_(base_xpath.count().eq(1),
                        xpath.count().eq(1)),
             'case_autoload.{0}.property_missing'.format(mode),
             [key],
         ),
         EntriesHelper.get_assertion(
             CaseIDXPath(xpath).case().count().eq(1),
             'case_autoload.{0}.case_missing'.format(mode),
         )
     ]
     return datum, assertions
Example #14
0
 def to_stack_datum(self):
     wanted = (CASE_SEARCH_REGISTRY_ID_KEY, "case_type", "case_id")
     keys = {el.key for el in self.query.data}
     data = [
         QueryData(key=el.key, ref=el.ref) for el in self.query.data
         if el.key in wanted
     ]
     if "case_id" not in keys and self.next_datum:
         data.append(
             QueryData(key="case_id", ref=session_var(self.source_id)))
     url = self.query.url
     if self.is_case_search:
         # we don't need the full search results, just the case that's been selected
         url = url.replace('/phone/search/', '/phone/registry_case/')
     return StackQuery(id=self.query.storage_instance, value=url, data=data)
Example #15
0
    def add_subcase_block(self):

        parent_node = self.xform.data_node
        action = next(self.form.actions.get_open_actions())
        case_id = session_var(action.case_session_var)
        subcase_node = _make_elem('{x}subcase_0')
        parent_node.append(subcase_node)
        subcase_node.insert(0, self.subcase_block.elem)
        self.subcase_block.add_create_block(
            relevance=self.xform.action_relevance(action.open_condition),
            case_name=self.subcase.case_name,
            case_type=self.subcase.case_type,
            delay_case_id=bool(self.subcase.repeat_context),
            autoset_owner_id=autoset_owner_id_for_advanced_action(action),
            has_case_sharing=self.form.get_app().case_sharing,
            case_id=case_id)
        self.subcase_block.add_update_block(self.subcase.case_properties)
Example #16
0
 def build_stack(self):
     stack = Stack()
     rewind_if = None
     if module_uses_smart_links(self.module):
         user_domain_xpath = session_var(COMMCARE_PROJECT, path="user/data")
         # For case in same domain, do a regular case claim rewind
         rewind_if = self._get_case_domain_xpath().eq(user_domain_xpath)
         # For case in another domain, jump to that other domain
         frame = PushFrame(if_clause=XPath.not_(rewind_if))
         frame.add_datum(
             StackJump(url=Text(xpath=TextXPath(
                 function=self.get_smart_link_function(),
                 variables=self.get_smart_link_variables(),
             ), ), ))
         stack.add_frame(frame)
     frame = PushFrame(if_clause=rewind_if)
     frame.add_rewind(QuerySessionXPath(self.case_session_var).instance())
     stack.add_frame(frame)
     return stack
Example #17
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
Example #18
0
    def get_datum_meta_module(self, module, use_filter=False):
        datums = []
        datum_module = module.source_module if module.module_type == 'shadow' else module
        datums_meta = get_select_chain_meta(self.app, datum_module)
        for i, datum in enumerate(datums_meta):
            # get the session var for the previous datum if there is one
            parent_id = datums_meta[i - 1]['session_var'] if i >= 1 else ''
            if parent_id:
                parent_filter = EntriesHelper.get_parent_filter(
                    datum['module'].parent_select.relationship, parent_id
                )
            else:
                parent_filter = ''

            # Figure out which module will supply the details (select, confirm, etc.)
            # for this datum. Normally this is the datum's own module.
            detail_module = datum['module']

            # Shadow modules are different because datums_meta is generated based on the source module,
            # but the various details should be supplied based on the shadow's own configuration.
            if module.module_type == 'shadow':
                if datum['module'].unique_id == module.source_module_id:
                    # We're looking at the datum that corresponds to the original module,
                    # so use that module for details
                    detail_module = module
                else:
                    # Check for case list parent child selection. If both shadow and source use parent case
                    # selection, datums_meta will contain a datum for the parent case, based on the SOURCE's
                    # parent select, and when we see that datum, we need to use the SHADOW's parent select
                    # to supply the details.
                    shadow_active = hasattr(module, 'parent_select') and module.parent_select.active
                    source_active = hasattr(datum_module, 'parent_select') and datum_module.parent_select.active
                    if shadow_active and source_active:
                        if datum['module'].unique_id == datum_module.parent_select.module_id:
                            detail_module = self.app.get_module_by_unique_id(module.parent_select.module_id)

            detail_persistent = self.get_detail_persistent_attr(datum['module'], detail_module, "case_short")
            detail_inline = self.get_detail_inline_attr(datum['module'], detail_module, "case_short")

            fixture_select_filter = ''
            if datum['module'].fixture_select.active:
                datums.append(FormDatumMeta(
                    datum=SessionDatum(
                        id=id_strings.fixture_session_var(datum['module']),
                        nodeset=ItemListFixtureXpath(datum['module'].fixture_select.fixture_type).instance(),
                        value=datum['module'].fixture_select.variable_column,
                        detail_select=id_strings.fixture_detail(detail_module)
                    ),
                    case_type=None,
                    requires_selection=True,
                    action='fixture_select'
                ))
                filter_xpath_template = datum['module'].fixture_select.xpath
                fixture_value = session_var(id_strings.fixture_session_var(datum['module']))
                fixture_select_filter = "[{}]".format(
                    filter_xpath_template.replace('$fixture_value', fixture_value)
                )

            filter_xpath = EntriesHelper.get_filter_xpath(detail_module) if use_filter else ''

            datums.append(FormDatumMeta(
                datum=SessionDatum(
                    id=datum['session_var'],
                    nodeset=(EntriesHelper.get_nodeset_xpath(datum['case_type'], filter_xpath=filter_xpath)
                             + parent_filter + fixture_select_filter),
                    value="./@case_id",
                    detail_select=self.details_helper.get_detail_id_safe(detail_module, 'case_short'),
                    detail_confirm=(
                        self.details_helper.get_detail_id_safe(detail_module, 'case_long')
                        if datum['index'] == 0 and not detail_inline else None
                    ),
                    detail_persistent=detail_persistent,
                    detail_inline=detail_inline,
                    autoselect=datum['module'].auto_select_case,
                ),
                case_type=datum['case_type'],
                requires_selection=True,
                action='update_case'
            ))
        return datums
Example #19
0
 def _get_case_domain_xpath(self):
     case_id_xpath = CaseIDXPath(session_var(self.case_session_var))
     return case_id_xpath.case(
         instance_name=RESULTS_INSTANCE).slash(COMMCARE_PROJECT)
Example #20
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'))
Example #21
0
 def _apply_change_to_datum_attr(datum, attr, change):
     xpath = getattr(datum, attr, None)
     if xpath:
         old = session_var(change['old_id'])
         new = session_var(change['new_id'])
         setattr(datum, attr, xpath.replace(old, new))
Example #22
0
 def to_stack_datum(self):
     value = session_var(
         self.source_id) if self.requires_selection else self.function
     return StackDatum(id=self.id, value=value)
Example #23
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
Example #24
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