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
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)) ])
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
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 )
def _get_reg_form_action(self, module): """ Returns registration form action """ form = self.app.get_form(module.case_list_form.form_id) if self.app.enable_localized_menu_media: case_list_form = module.case_list_form action = LocalizedAction( menu_locale_id=id_strings.case_list_form_locale(module), media_image=case_list_form.uses_image( build_profile_id=self.build_profile_id), media_audio=case_list_form.uses_audio( build_profile_id=self.build_profile_id), image_locale_id=id_strings.case_list_form_icon_locale(module), audio_locale_id=id_strings.case_list_form_audio_locale(module), stack=Stack(), for_action_menu=True, ) else: action = Action(display=Display( text=Text(locale_id=id_strings.case_list_form_locale(module)), media_image=module.case_list_form.default_media_image, media_audio=module.case_list_form.default_media_audio, ), stack=Stack()) frame = PushFrame() frame.add_command(XPath.string(id_strings.form_command(form))) target_form_dm = self.entries_helper.get_datums_meta_for_form_generic( form) source_form_dm = [] if len(module.forms): source_form_dm = self.entries_helper.get_datums_meta_for_form_generic( module.get_form(0)) for target_meta in target_form_dm: if target_meta.requires_selection: # This is true for registration forms where the case being created is a subcase try: [source_dm] = [ source_meta for source_meta in source_form_dm if source_meta.case_type == target_meta.case_type ] except ValueError: pass else: frame.add_datum( StackDatum(id=target_meta.datum.id, value=session_var(source_dm.datum.id))) else: s_datum = target_meta.datum frame.add_datum( StackDatum(id=s_datum.id, value=s_datum.function)) frame.add_datum( StackDatum(id=RETURN_TO, value=XPath.string(id_strings.menu_id(module)))) action.stack.add_frame(frame) return action
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ from corehq.apps.app_manager.const import WORKFLOW_CASE_LIST source_session_var = self._get_source_session_var( form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) if target_module.case_list_form.post_form_workflow == WORKFLOW_CASE_LIST: frame_case_created = None frame_case_not_created = StackFrameMeta( self.get_if_clause(None, target_command), current_session=source_form_datums) else: frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created) stack_frames.source_session_var = source_session_var return stack_frames
def get_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]')
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) ) ]
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)
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
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) )
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
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)
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)
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
def _get_stack_frames(self, target_module, form, source_form_datums): """ Set up the stack blocks for a single case list form action. :param target_module: Module that the user is returning to :param form: Case list form :param source_form_datums: List of datum from the case list form :return: CaseListFormStackFrames object """ source_session_var = self._get_source_session_var(form, target_module.case_type) source_case_id = session_var(source_session_var) case_count = CaseIDXPath(source_case_id).case().count() target_command = id_strings.menu_id(target_module) frame_case_created = StackFrameMeta( self.get_if_clause(case_count.gt(0), target_command), current_session=source_form_datums ) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums ) stack_frames = CaseListFormStackFrames( case_created=frame_case_created, case_not_created=frame_case_not_created ) stack_frames.source_session_var = source_session_var return stack_frames
def get_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
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)
def configure_entry_careplan_form(self, module, e, form=None, **kwargs): parent_module = self.app.get_module_by_unique_id(module.parent_select.module_id, error=_("Could not find module '{}' is attached to.").format(module.default_name())) e.datums.append(SessionDatum( id='case_id', nodeset=EntriesHelper.get_nodeset_xpath(parent_module.case_type), value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(parent_module, 'case_short'), detail_confirm=self.details_helper.get_detail_id_safe(parent_module, 'case_long') )) def session_datum(datum_id, case_type, parent_ref, parent_val): nodeset = CaseTypeXpath(case_type).case().select( 'index/%s' % parent_ref, session_var(parent_val), quote=False ).select('@status', 'open') return SessionDatum( id=datum_id, nodeset=nodeset, value="./@case_id", detail_select=self.details_helper.get_detail_id_safe(module, '%s_short' % case_type), detail_confirm=self.details_helper.get_detail_id_safe(module, '%s_long' % case_type) ) e.stack = Stack() frame = CreateFrame() e.stack.add_frame(frame) if form.case_type == CAREPLAN_GOAL: if form.mode == 'create': new_goal_id_var = 'case_id_goal_new' e.datums.append(SessionDatum(id=new_goal_id_var, function='uuid()')) elif form.mode == 'update': new_goal_id_var = 'case_id_goal' e.datums.append(session_datum(new_goal_id_var, CAREPLAN_GOAL, 'parent', 'case_id')) if not module.display_separately: open_goal = CaseIDXPath(session_var(new_goal_id_var)).case().select('@status', 'open') frame.if_clause = '{count} = 1'.format(count=open_goal.count()) frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var(new_goal_id_var))) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) elif form.case_type == CAREPLAN_TASK: if not module.display_separately: frame.add_command(XPath.string(id_strings.menu_id(parent_module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id_goal', value=session_var('case_id_goal'))) if form.mode == 'update': count = CaseTypeXpath(CAREPLAN_TASK).case().select( 'index/goal', session_var('case_id_goal'), quote=False ).select('@status', 'open').count() frame.if_clause = '{count} >= 1'.format(count=count) frame.add_command(XPath.string( id_strings.form_command(module.get_form_by_type(CAREPLAN_TASK, 'update')) )) else: frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum(StackDatum(id='case_id', value=session_var('case_id'))) if form.mode == 'create': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) elif form.mode == 'update': e.datums.append(session_datum('case_id_goal', CAREPLAN_GOAL, 'parent', 'case_id')) e.datums.append(session_datum('case_id_task', CAREPLAN_TASK, 'goal', 'case_id_goal'))
def _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))
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)
def get_stack_frames_for_case_list_form_target(self, target_module, form): stack_frames = [] target_command = id_strings.menu_id(target_module) if form.form_type == 'module_form': [reg_action ] = form.get_registration_actions(target_module.case_type) source_session_var = form.session_var_for_action(reg_action) if form.form_type == 'advanced_form': # match case session variable reg_action = form.get_registration_actions( target_module.case_type)[0] source_session_var = reg_action.case_session_var source_case_id = session_var(source_session_var) source_form_datums = self.helper.get_form_datums(form) case_count = CaseIDXPath(source_case_id).case().count() frame_case_created = StackFrameMeta(self.get_if_clause( case_count.gt(0), target_command), current_session=source_form_datums) stack_frames.append(frame_case_created) frame_case_not_created = StackFrameMeta( self.get_if_clause(case_count.eq(0), target_command), current_session=source_form_datums) stack_frames.append(frame_case_not_created) def add_datums_for_target(module, source_form_dm, allow_missing=False): """ Given a target module and a list of datums from the source module add children to the stack frames that are required by the target module and present in the source datums list. """ target_form_dm = self.helper.get_frame_children(module.get_form(0), module_only=True) used = set() for source_meta in source_form_dm: if source_meta.case_type: # This is true for registration forms where the case being created is a subcase target_dm = self.get_target_dm(target_form_dm, source_meta.case_type, module) if target_dm: used.add(source_meta) meta = WorkflowDatumMeta.from_session_datum( source_meta) frame_case_created.add_child( meta.to_stack_datum(datum_id=target_dm.id)) frame_case_not_created.add_child( meta.to_stack_datum(datum_id=target_dm.id)) else: source_case_type = self.get_case_type_created_by_form( form, target_module) target_dm = self.get_target_dm(target_form_dm, source_case_type, module) if target_dm: used.add(source_meta) datum_meta = WorkflowDatumMeta.from_session_datum( target_dm) frame_case_created.add_child( datum_meta.to_stack_datum( source_id=source_meta.id)) elif not allow_missing: raise SuiteValidationError( u"The '{}' module is not properly configured to have a Case List Registration Form. " u"All forms in the module should have the same case management configuration." .format(module.default_name())) # return any source datums that were not already added to the target return [dm for dm in source_form_dm if dm not in used] source_form_dm = self.helper.get_form_datums(form) if target_module.root_module_id: # add stack children for the root module before adding any for the child module. root_module = target_module.root_module root_module_command = CommandId(id_strings.menu_id(root_module)) frame_case_created.add_child(root_module_command) frame_case_not_created.add_child(root_module_command) source_form_dm = add_datums_for_target(root_module, source_form_dm, allow_missing=True) frame_case_created.add_child(CommandId(target_command)) frame_case_not_created.add_child(CommandId(target_command)) add_datums_for_target(target_module, source_form_dm) return stack_frames
def 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