def get_form_data_schema(request, domain, form_unique_id): """Get data schema One of `app_id` or `form_unique_id` is required. `app_id` is ignored if `form_unique_id` is provided. :returns: A list of data source schema definitions. A data source schema definition is a dictionary. For details on the content of the dictionary, see https://github.com/dimagi/Vellum/blob/master/src/datasources.js """ data = [] try: form, app = Form.get_form(form_unique_id, and_app=True) except ResourceConflict: raise Http404() if app.domain != domain: raise Http404() try: data.append(get_session_schema(form)) if form.requires_case() or is_usercase_in_use(domain): data.append(get_casedb_schema(form)) except Exception: logger.exception("schema error") return HttpResponseBadRequest("schema error, see log for details") data.extend( sorted(item_lists_by_domain(domain), key=lambda x: x['name'].lower()) ) kw = {} if "pretty" in request.GET: kw["indent"] = 2 return HttpResponse(json.dumps(data, **kw))
def edit_form_actions(request, domain, app_id, form_unique_id): app = get_app(domain, app_id) form = app.get_form(form_unique_id) module = form.get_module() old_load_from_form = form.actions.load_from_form form.actions = FormActions.wrap(json.loads(request.POST['actions'])) add_properties_to_data_dictionary(domain, module.case_type, list(form.actions.update_case.update.keys())) if old_load_from_form: form.actions.load_from_form = old_load_from_form for condition in (form.actions.open_case.condition, form.actions.close_case.condition): if isinstance(condition.answer, six.string_types): soft_assert_type_text(condition.answer) condition.answer = condition.answer.strip('"\'') form.requires = request.POST.get('requires', form.requires) if actions_use_usercase(form.actions): if not is_usercase_in_use(domain): enable_usercase(domain) add_properties_to_data_dictionary(domain, USERCASE_TYPE, list(form.actions.usercase_update.update.keys())) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) response_json['usercasePropertiesMap'] = get_usercase_properties(app) return json_response(response_json)
def edit_form_actions(request, domain, app_id, form_unique_id): app = get_app(domain, app_id) form = app.get_form(form_unique_id) module = form.get_module() old_load_from_form = form.actions.load_from_form form.actions = FormActions.wrap(json.loads(request.POST['actions'])) add_properties_to_data_dictionary( domain, module.case_type, list(form.actions.update_case.update.keys())) if old_load_from_form: form.actions.load_from_form = old_load_from_form for condition in (form.actions.open_case.condition, form.actions.close_case.condition): if isinstance(condition.answer, six.string_types): soft_assert_type_text(condition.answer) condition.answer = condition.answer.strip('"\'') form.requires = request.POST.get('requires', form.requires) if actions_use_usercase(form.actions): if not is_usercase_in_use(domain): enable_usercase(domain) add_properties_to_data_dictionary( domain, USERCASE_TYPE, list(form.actions.usercase_update.update.keys())) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) response_json['usercasePropertiesMap'] = get_usercase_properties(app) return json_response(response_json)
def get_form_data_schema(request, domain, app_id, form_unique_id): """Get data schema :returns: A list of data source schema definitions. A data source schema definition is a dictionary. For details on the content of the dictionary, see https://github.com/dimagi/Vellum/blob/master/src/datasources.js """ data = [] app = get_app(domain, app_id) form = app.get_form(form_unique_id) try: data.append(get_session_schema(form)) if form.requires_case() or is_usercase_in_use(domain): data.append(get_casedb_schema(form)) except AppManagerException as e: notify_exception(request, message=str(e)) return HttpResponseBadRequest( str(e) or _("There is an error in the case management of your application. " "Please fix the error to see case properties in this tree")) except Exception as e: notify_exception(request, message=str(e)) return HttpResponseBadRequest("schema error, see log for details") data.extend(item_lists_by_domain(domain)) kw = {} if "pretty" in request.GET: kw["indent"] = 2 return HttpResponse(json.dumps(data, **kw))
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))
def get_usercase_properties(app): if is_usercase_in_use(app.domain): # TODO: add name here once it is fixed to concatenate first and last in form builder default_properties = {'first_name', 'last_name', 'phone_number', 'username'} case_properties = get_case_properties(app, [USERCASE_TYPE]) case_properties[USERCASE_TYPE] = list(set(case_properties[USERCASE_TYPE]) | default_properties) return case_properties return {USERCASE_TYPE: []}
def _setup_case_property_builder(app): defaults = ('name', 'date-opened', 'status', 'last_modified') if app.case_sharing: defaults += ('#owner_name',) per_type_defaults = None if is_usercase_in_use(app.domain): per_type_defaults = get_per_type_defaults(app.domain, [USERCASE_TYPE]) builder = ParentCasePropertyBuilder(app, defaults=defaults, per_type_defaults=per_type_defaults) return builder
def _setup_case_property_builder(app): defaults = ('name', 'date-opened', 'status') if app.case_sharing: defaults += ('#owner_name',) per_type_defaults = None if is_usercase_in_use(app.domain): per_type_defaults = get_per_type_defaults(app.domain, [USERCASE_TYPE]) builder = ParentCasePropertyBuilder(app, defaults=defaults, per_type_defaults=per_type_defaults) return builder
def filter_cases(request, domain, app_id, module_id, parent_id=None): app = Application.get(app_id) module = app.get_module(module_id) auth_cookie = request.COOKIES.get('sessionid') suite_gen = SuiteGenerator(app, is_usercase_in_use(domain)) xpath = suite_gen.get_filter_xpath(module) extra_instances = [{'id': inst.id, 'src': inst.src} for inst in suite_gen.get_instances_for_module(module, additional_xpaths=[xpath])] # touchforms doesn't like this to be escaped xpath = HTMLParser.HTMLParser().unescape(xpath) case_type = module.case_type if xpath: # if we need to do a custom filter, send it to touchforms for processing additional_filters = { "properties/case_type": case_type, "footprint": True } helper = SessionDataHelper(domain, request.couch_user) result = helper.filter_cases(xpath, additional_filters, DjangoAuth(auth_cookie), extra_instances=extra_instances) if result.get('status', None) == 'error': code = result.get('code', 500) message = result.get('message', _("Something went wrong filtering your cases.")) if code == 500: notify_exception(None, message=message) return json_response(message, status_code=code) case_ids = result.get("cases", []) else: # otherwise just use our built in api with the defaults case_ids = [res.id for res in get_filtered_cases( domain, status=CASE_STATUS_OPEN, case_type=case_type, user_id=request.couch_user._id, footprint=True, ids_only=True, )] cases = [CommCareCase.wrap(doc) for doc in iter_docs(CommCareCase.get_db(), case_ids)] if parent_id: cases = filter(lambda c: c.parent and c.parent.case_id == parent_id, cases) # refilter these because we might have accidentally included footprint cases # in the results from touchforms. this is a little hacky but the easiest # (quick) workaround. should be revisted when we optimize the case list. cases = filter(lambda c: c.type == case_type, cases) cases = [c.get_json(lite=True) for c in cases if c] return json_response(cases)
def edit_advanced_form_actions(request, domain, app_id, module_id, form_id): app = get_app(domain, app_id) form = app.get_module(module_id).get_form(form_id) json_loads = json.loads(request.POST.get('actions')) actions = AdvancedFormActions.wrap(json_loads) form.actions = actions if advanced_actions_use_usercase(form.actions) and not is_usercase_in_use(domain): enable_usercase(domain) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) return json_response(response_json)
def get_session_schema(form): """Get form session schema definition """ from corehq.apps.app_manager.suite_xml.sections.entries import EntriesHelper app = form.get_app() structure = {} datums = EntriesHelper(app).get_datums_meta_for_form_generic(form) datums = [ d for d in datums if not d.is_new_case_id and d.case_type and d.requires_selection ] if len(datums): session_var = datums[-1].datum.id structure["data"] = { "merge": True, "structure": { session_var: { "reference": { "hashtag": "#case", "source": "casedb", "subset": "case", "key": "@case_id", }, }, }, } if is_usercase_in_use( app.domain) and toggles.USER_PROPERTY_EASY_REFS.enabled( app.domain): structure["context"] = { "merge": True, "structure": { "userid": { "reference": { "hashtag": "#user", "source": "casedb", "subset": USERCASE_TYPE, "subset_key": "@case_type", "subset_filter": True, "key": "hq_user_id", }, }, }, } return { "id": "commcaresession", "uri": "jr://instance/session", "name": "Session", "path": "/session", "structure": structure, }
def get_per_type_defaults(domain, case_types=None): from corehq.apps.callcenter.utils import get_call_center_case_type_if_enabled per_type_defaults = {} if (not case_types and is_usercase_in_use(domain)) or USERCASE_TYPE in case_types: per_type_defaults = { USERCASE_TYPE: get_usercase_default_properties(domain) } callcenter_case_type = get_call_center_case_type_if_enabled(domain) if callcenter_case_type and (not case_types or callcenter_case_type in case_types): per_type_defaults[callcenter_case_type] = get_usercase_default_properties(domain) return per_type_defaults
def edit_advanced_form_actions(request, domain, app_id, module_id, form_id): app = get_app(domain, app_id) form = app.get_module(module_id).get_form(form_id) json_loads = json.loads(request.POST.get('actions')) actions = AdvancedFormActions.wrap(json_loads) form.actions = actions for action in actions.load_update_cases: add_properties_to_data_dictionary(domain, action.case_type, action.case_properties.keys()) if advanced_actions_use_usercase(form.actions) and not is_usercase_in_use(domain): enable_usercase(domain) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) return json_response(response_json)
def get_per_type_defaults(domain): """Get default properties for callcenter and usercases""" from corehq.apps.callcenter.utils import get_call_center_case_type_if_enabled per_type_defaults = {} if is_usercase_in_use(domain): per_type_defaults = { USERCASE_TYPE: _get_usercase_default_properties(domain) } callcenter_case_type = get_call_center_case_type_if_enabled(domain) if callcenter_case_type: per_type_defaults[callcenter_case_type] = _get_usercase_default_properties(domain) return per_type_defaults
def edit_form_actions(request, domain, app_id, module_id, form_id): app = get_app(domain, app_id) form = app.get_module(module_id).get_form(form_id) form.actions = FormActions.wrap(json.loads(request.POST['actions'])) for condition in (form.actions.open_case.condition, form.actions.close_case.condition): if isinstance(condition.answer, basestring): condition.answer = condition.answer.strip('"\'') form.requires = request.POST.get('requires', form.requires) if actions_use_usercase(form.actions) and not is_usercase_in_use(domain): enable_usercase(domain) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) response_json['usercasePropertiesMap'] = get_usercase_properties(app) return json_response(response_json)
def _get_module_details_context(app, module, case_property_builder, case_type_): subcase_types = list(app.get_subcase_types(module.case_type)) item = { 'label': gettext_lazy('Case List'), 'detail_label': gettext_lazy('Case Detail'), 'type': 'case', 'model': 'case', 'subcase_types': subcase_types, 'sort_elements': module.case_details.short.sort_elements, 'short': module.case_details.short, 'long': module.case_details.long, } case_properties = case_property_builder.get_properties(case_type_) if is_usercase_in_use(app.domain) and case_type_ != USERCASE_TYPE: usercase_properties = prefix_usercase_properties( case_property_builder.get_properties(USERCASE_TYPE)) case_properties |= usercase_properties item['properties'] = sorted(case_properties) item['fixture_select'] = module.fixture_select if isinstance(module, AdvancedModule): details = [item] if app.commtrack_enabled: details.append({ 'label': gettext_lazy('Product List'), 'detail_label': gettext_lazy('Product Detail'), 'type': 'product', 'model': 'product', 'properties': ['name'] + commtrack_ledger_sections(app.commtrack_requisition_mode), 'sort_elements': module.product_details.short.sort_elements, 'short': module.product_details.short, 'subcase_types': subcase_types, }) else: item['parent_select'] = module.parent_select details = [item] return details
def edit_advanced_form_actions(request, domain, app_id, form_unique_id): app = get_app(domain, app_id) form = app.get_form(form_unique_id) json_loads = json.loads(request.POST.get('actions')) actions = AdvancedFormActions.wrap(json_loads) if form.form_type == "shadow_form": form.extra_actions = actions else: form.actions = actions for action in actions.load_update_cases: add_properties_to_data_dictionary(domain, action.case_type, list(action.case_properties.keys())) if advanced_actions_use_usercase(actions) and not is_usercase_in_use(domain): enable_usercase(domain) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) return JsonResponse(response_json)
def _get_vellum_plugins(domain, form, module): """ Returns a list of enabled vellum plugins based on the domain's privileges. """ vellum_plugins = ["modeliteration", "itemset", "atwho"] if toggles.COMMTRACK.enabled(domain): vellum_plugins.append("commtrack") if toggles.VELLUM_SAVE_TO_CASE.enabled(domain): vellum_plugins.append("saveToCase") form_uses_case = ((module and module.case_type and form.requires_case()) or is_usercase_in_use(domain)) form_is_basic = form.doc_type == 'Form' if form_uses_case and form_is_basic: vellum_plugins.append("databrowser") return vellum_plugins
def edit_form_actions(request, domain, app_id, module_id, form_id): app = get_app(domain, app_id) form = app.get_module(module_id).get_form(form_id) old_load_from_form = form.actions.load_from_form form.actions = FormActions.wrap(json.loads(request.POST['actions'])) if old_load_from_form: form.actions.load_from_form = old_load_from_form for condition in (form.actions.open_case.condition, form.actions.close_case.condition): if isinstance(condition.answer, basestring): condition.answer = condition.answer.strip('"\'') form.requires = request.POST.get('requires', form.requires) if actions_use_usercase(form.actions) and not is_usercase_in_use(domain): enable_usercase(domain) response_json = {} app.save(response_json) response_json['propertiesMap'] = get_all_case_properties(app) response_json['usercasePropertiesMap'] = get_usercase_properties(app) return json_response(response_json)
def form_context(request, domain, app_id, module_id, form_id): app = Application.get(app_id) form_url = "%s%s" % (get_url_base(), reverse('download_xform', args=[domain, app_id, module_id, form_id])) case_id = request.GET.get('case_id') instance_id = request.GET.get('instance_id') try: form = app.get_module(module_id).get_form(form_id) except (FormNotFoundException, ModuleNotFoundException): raise Http404() form_name = form.name.values()[0] # make the name for the session we will use with the case and form session_name = u'{app} > {form}'.format( app=app.name, form=form_name, ) if case_id: session_name = u'{0} - {1}'.format(session_name, CommCareCase.get(case_id).name) root_context = { 'form_url': form_url, } if instance_id: try: root_context['instance_xml'] = XFormInstance.get_db().fetch_attachment( instance_id, ATTACHMENT_NAME ) except ResourceNotFound: raise Http404() session_extras = {'session_name': session_name, 'app_id': app._id} suite_gen = SuiteGenerator(app, is_usercase_in_use(domain)) session_extras.update(get_cloudcare_session_data(suite_gen, domain, form, request.couch_user)) delegation = request.GET.get('task-list') == 'true' offline = request.GET.get('offline') == 'true' session_helper = SessionDataHelper(domain, request.couch_user, case_id, delegation=delegation, offline=offline) return json_response(session_helper.get_full_context( root_context, session_extras ))
def get_form_data_schema(request, domain, form_unique_id): """Get data schema One of `app_id` or `form_unique_id` is required. `app_id` is ignored if `form_unique_id` is provided. :returns: A list of data source schema definitions. A data source schema definition is a dictionary. For details on the content of the dictionary, see https://github.com/dimagi/Vellum/blob/master/src/datasources.js """ data = [] try: form, app = Form.get_form(form_unique_id, and_app=True) except ResourceConflict: raise Http404() if app.domain != domain: raise Http404() try: data.append(get_session_schema(form)) if form.requires_case() or is_usercase_in_use(domain): data.append(get_casedb_schema(form)) except AppManagerException as e: notify_exception(request, message=str(e)) return HttpResponseBadRequest( str(e) or _("There is an error in the case management of your application. " "Please fix the error to see case properties in this tree") ) except Exception as e: notify_exception(request, message=six.text_type(e)) return HttpResponseBadRequest("schema error, see log for details") data.extend( sorted(item_lists_by_domain(domain), key=lambda x: x['name'].lower()) ) kw = {} if "pretty" in request.GET: kw["indent"] = 2 return HttpResponse(json.dumps(data, **kw))
def _get_vellum_plugins(domain, form, module): """ Returns a list of enabled vellum plugins based on the domain's privileges. """ vellum_plugins = ["modeliteration", "itemset", "atwho"] if (toggles.COMMTRACK.enabled(domain) or toggles.NON_COMMTRACK_LEDGERS.enabled(domain)): vellum_plugins.append("commtrack") if toggles.VELLUM_SAVE_TO_CASE.enabled(domain): vellum_plugins.append("saveToCase") form_uses_case = ( (module and module.case_type and form.requires_case()) or is_usercase_in_use(domain) ) form_is_basic = form.doc_type == 'Form' if form_uses_case and form_is_basic: vellum_plugins.append("databrowser") return vellum_plugins
def _get_module_details_context(app, module, case_property_builder, case_type_): subcase_types = list(app.get_subcase_types(module.case_type)) item = { 'label': gettext_lazy('Case List'), 'detail_label': gettext_lazy('Case Detail'), 'type': 'case', 'model': 'case', 'subcase_types': subcase_types, 'sort_elements': module.case_details.short.sort_elements, 'short': module.case_details.short, 'long': module.case_details.long, } case_properties = case_property_builder.get_properties(case_type_) if is_usercase_in_use(app.domain) and case_type_ != USERCASE_TYPE: usercase_properties = prefix_usercase_properties(case_property_builder.get_properties(USERCASE_TYPE)) case_properties |= usercase_properties item['properties'] = sorted(case_properties) item['fixture_select'] = module.fixture_select if isinstance(module, AdvancedModule): details = [item] if app.commtrack_enabled: details.append({ 'label': gettext_lazy('Product List'), 'detail_label': gettext_lazy('Product Detail'), 'type': 'product', 'model': 'product', 'properties': ['name'] + commtrack_ledger_sections(app.commtrack_requisition_mode), 'sort_elements': module.product_details.short.sort_elements, 'short': module.product_details.short, 'subcase_types': subcase_types, }) else: item['parent_select'] = module.parent_select details = [item] return details
def get_casedb_schema(form): """Get case database schema definition for vellum to display as an external data source. This lists all case types and their properties for the given app. """ app = form.get_app() subsets = [] if form.requires_case() and not form.get_module().search_config.data_registry: subsets.extend(_get_case_schema_subsets(app, form.get_module().case_type)) parent_select = getattr(form.get_module(), 'parent_select', None) if parent_select and parent_select.active and parent_select.relationship is None: # for child modules that use parent select where the parent is not a 'related' case # See toggles.NON_PARENT_MENU_SELECTION parent_module = app.get_module_by_unique_id(parent_select.module_id) source = clean_trans(parent_module.name, app.langs) subsets.extend(_get_case_schema_subsets(app, parent_module.case_type, source=source)) if is_usercase_in_use(app.domain): subsets.append({ "id": USERCASE_TYPE, "name": "user", "key": "@case_type", "structure": {p: {} for p in get_usercase_properties(app)[USERCASE_TYPE]}, }) return { "id": "casedb", "uri": "jr://instance/casedb", "name": "case", "path": "/casedb/case", "structure": {}, "subsets": subsets, }
def get_form_view_context_and_template(request, domain, form, langs, current_lang, messages=messages): xform_questions = [] xform = None form_errors = [] xform_validation_errored = False xform_validation_missing = False try: xform = form.wrapped_xform() except XFormException as e: form_errors.append("Error in form: %s" % e) except Exception as e: logging.exception(e) form_errors.append("Unexpected error in form: %s" % e) has_case_error = False if xform and xform.exists(): if xform.already_has_meta(): messages.warning( request, "This form has a meta block already! " "It may be replaced by CommCare HQ's standard meta block." ) try: xform_questions = xform.get_questions(langs, include_triggers=True) form.validate_form() except etree.XMLSyntaxError as e: form_errors.append("Syntax Error: %s" % e) except AppEditingError as e: form_errors.append("Error in application: %s" % e) except XFormValidationError: xform_validation_errored = True # showing these messages is handled by validate_form_for_build ajax except XFormValidationFailed: xform_validation_missing = True messages.warning(request, _("Unable to validate form due to server error.")) except XFormException as e: form_errors.append("Error in form: %s" % e) # any other kind of error should fail hard, # but for now there are too many for that to be practical except Exception as e: if settings.DEBUG: raise notify_exception(request, 'Unexpected Build Error') form_errors.append("Unexpected System Error: %s" % e) else: # remove upload questions (attachments) until MM Case Properties # are released to general public is_previewer = toggles.MM_CASE_PROPERTIES.enabled_for_request(request) xform_questions = [q for q in xform_questions if q["tag"] != "upload" or is_previewer] if not form_errors and not xform_validation_missing and not xform_validation_errored: try: form_action_errors = form.validate_for_build() if not form_action_errors: form.add_stuff_to_xform(xform) except CaseError as e: has_case_error = True messages.error(request, "Error in Case Management: %s" % e) except XFormException as e: messages.error(request, str(e)) except Exception as e: if settings.DEBUG: raise logging.exception(str(e)) messages.error(request, "Unexpected Error: %s" % e) try: languages = xform.get_languages() except Exception: languages = [] for err in form_errors: messages.error(request, err) module_case_types = [] app = form.get_app() all_modules = list(app.get_modules()) for module in all_modules: for case_type in module.get_case_types(): module_case_types.append({ 'id': module.unique_id, 'module_name': trans(module.name, langs), 'case_type': case_type, 'module_type': module.doc_type }) module = form.get_module() if not form.unique_id: form.get_unique_id() app.save() allow_usercase = domain_has_privilege(request.domain, privileges.USERCASE) valid_index_names = list(DEFAULT_CASE_INDEX_IDENTIFIERS.values()) if allow_usercase: valid_index_names.append(USERCASE_PREFIX[0:-1]) # strip trailing slash form_has_schedule = isinstance(form, AdvancedForm) and module.has_schedule try: case_properties_map = get_all_case_properties(app) usercase_properties_map = get_usercase_properties(app) except CaseError as e: case_properties_map = {} usercase_properties_map = {} if not has_case_error: messages.error(request, "Error in Case Management: %s" % e) case_config_options = { 'caseType': form.get_case_type(), 'moduleCaseTypes': module_case_types, 'propertiesMap': case_properties_map, 'propertyDescriptions': get_case_property_description_dict(domain), 'questions': xform_questions, 'reserved_words': load_case_reserved_words(), 'usercasePropertiesMap': usercase_properties_map, } context = { 'nav_form': form, 'xform_languages': languages, 'form_errors': form_errors, 'xform_validation_errored': xform_validation_errored, 'xform_validation_missing': xform_validation_missing, 'allow_form_copy': isinstance(form, (Form, AdvancedForm)), 'allow_form_filtering': not form_has_schedule, 'uses_form_workflow': form.post_form_workflow == WORKFLOW_FORM, 'allow_usercase': allow_usercase, 'is_usercase_in_use': is_usercase_in_use(request.domain), 'is_module_filter_enabled': app.enable_module_filtering, 'is_training_module': module.is_training_module, 'is_allowed_to_be_release_notes_form': form.is_allowed_to_be_release_notes_form, 'root_requires_same_case': module.root_requires_same_case(), 'is_case_list_form': form.is_case_list_form, 'edit_name_url': reverse('edit_form_attr', args=[app.domain, app.id, form.unique_id, 'name']), 'form_filter_patterns': { 'case_substring': CASE_XPATH_SUBSTRING_MATCHES, 'usercase_substring': USERCASE_XPATH_SUBSTRING_MATCHES, }, 'custom_instances': [ {'instanceId': instance.instance_id, 'instancePath': instance.instance_path} for instance in form.custom_instances ], 'custom_assertions': [ {'test': assertion.test, 'text': assertion.text.get(current_lang)} for assertion in form.custom_assertions ], 'form_icon': None, 'session_endpoints_enabled': toggles.SESSION_ENDPOINTS.enabled(domain), 'module_is_multi_select': module.is_multi_select(), 'module_loads_registry_case': module_loads_registry_case(module), } if toggles.CUSTOM_ICON_BADGES.enabled(domain): context['form_icon'] = form.custom_icon if form.custom_icon else CustomIcon() if toggles.COPY_FORM_TO_APP.enabled_for_request(request): context['apps_modules'] = get_apps_modules(domain, app.id, module.unique_id) if toggles.FORM_LINK_WORKFLOW.enabled(domain): context.update(_get_form_link_context(module, langs)) if isinstance(form, AdvancedForm): def commtrack_programs(): if app.commtrack_enabled: programs = Program.by_domain(app.domain) return [{'value': program.get_id, 'label': program.name} for program in programs] else: return [] all_programs = [{'value': '', 'label': _('All Programs')}] case_config_options.update({ 'commtrack_enabled': app.commtrack_enabled, 'commtrack_programs': all_programs + commtrack_programs(), 'module_id': module.unique_id, 'save_url': reverse("edit_advanced_form_actions", args=[app.domain, app.id, form.unique_id]), 'arbitrary_datums': form.arbitrary_datums, }) if form.form_type == "shadow_form": case_config_options.update({ 'actions': form.extra_actions, 'isShadowForm': True, }) else: case_config_options.update({ 'actions': form.actions, 'isShadowForm': False, }) if getattr(module, 'has_schedule', False): schedule_options = get_schedule_context(form) schedule_options.update({ 'phase': schedule_options['schedule_phase'], 'questions': xform_questions, 'save_url': reverse("edit_visit_schedule", args=[app.domain, app.id, form.unique_id]), 'schedule': form.schedule, }) context.update({ 'schedule_options': schedule_options, }) else: context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled_for_request(request), }) case_config_options.update({ 'actions': form.actions, 'allowUsercase': allow_usercase, 'save_url': reverse("edit_form_actions", args=[app.domain, app.id, form.unique_id]), 'valid_index_names': valid_index_names, }) context.update({'case_config_options': case_config_options}) return "app_manager/form_view.html", context
def get_usercase_properties(app): if is_usercase_in_use(app.domain): return get_case_properties(app, [USERCASE_TYPE]) return {USERCASE_TYPE: []}
def get_form_view_context_and_template(request, domain, form, langs, messages=messages): xform_questions = [] xform = None form_errors = [] xform_validation_errored = False xform_validation_missing = False try: xform = form.wrapped_xform() except XFormException as e: form_errors.append(u"Error in form: %s" % e) except Exception as e: logging.exception(e) form_errors.append(u"Unexpected error in form: %s" % e) if xform and xform.exists(): if xform.already_has_meta(): messages.warning( request, "This form has a meta block already! " "It may be replaced by CommCare HQ's standard meta block.") try: xform_questions = xform.get_questions(langs, include_triggers=True) form.validate_form() except etree.XMLSyntaxError as e: form_errors.append(u"Syntax Error: %s" % e) except AppEditingError as e: form_errors.append(u"Error in application: %s" % e) except XFormValidationError: xform_validation_errored = True # showing these messages is handled by validate_form_for_build ajax pass except XFormValidationFailed: xform_validation_missing = True messages.warning(request, _("Unable to validate form due to server error.")) except XFormException as e: form_errors.append(u"Error in form: %s" % e) # any other kind of error should fail hard, # but for now there are too many for that to be practical except Exception as e: if settings.DEBUG: raise notify_exception(request, 'Unexpected Build Error') form_errors.append(u"Unexpected System Error: %s" % e) else: # remove upload questions (attachemnts) until MM Case Properties # are released to general public is_previewer = toggles.MM_CASE_PROPERTIES.enabled( request.user.username) xform_questions = [ q for q in xform_questions if q["tag"] != "upload" or is_previewer ] if not form_errors and not xform_validation_missing and not xform_validation_errored: try: form_action_errors = form.validate_for_build() if not form_action_errors: form.add_stuff_to_xform(xform) except CaseError as e: messages.error(request, u"Error in Case Management: %s" % e) except XFormException as e: messages.error(request, unicode(e)) except Exception as e: if settings.DEBUG: raise logging.exception(unicode(e)) messages.error(request, u"Unexpected Error: %s" % e) try: languages = xform.get_languages() except Exception: languages = [] for err in form_errors: messages.error(request, err) module_case_types = [] app = form.get_app() all_modules = list(app.get_modules()) for module in all_modules: for case_type in module.get_case_types(): module_case_types.append({ 'id': module.unique_id, 'module_name': trans(module.name, langs), 'case_type': case_type, 'module_type': module.doc_type }) if not form.unique_id: form.get_unique_id() app.save() allow_usercase = domain_has_privilege(request.domain, privileges.USER_CASE) valid_index_names = DEFAULT_CASE_INDEX_IDENTIFIERS.values() if allow_usercase: valid_index_names.append(USERCASE_PREFIX[0:-1]) # strip trailing slash form_has_schedule = isinstance( form, AdvancedForm) and form.get_module().has_schedule case_config_options = { 'caseType': form.get_case_type(), 'moduleCaseTypes': module_case_types, 'propertiesMap': get_all_case_properties(app), 'questions': xform_questions, 'reserved_words': load_case_reserved_words(), } context = { 'nav_form': form, 'xform_languages': languages, "xform_questions": xform_questions, 'form_errors': form_errors, 'xform_validation_errored': xform_validation_errored, 'xform_validation_missing': xform_validation_missing, 'allow_cloudcare': isinstance(form, Form), 'allow_form_copy': isinstance(form, (Form, AdvancedForm)), 'allow_form_filtering': not isinstance(form, CareplanForm) and not form_has_schedule, 'allow_form_workflow': not isinstance(form, CareplanForm), 'uses_form_workflow': form.post_form_workflow == WORKFLOW_FORM, 'allow_usercase': allow_usercase, 'is_usercase_in_use': is_usercase_in_use(request.domain), 'is_module_filter_enabled': app.enable_module_filtering, 'is_case_list_form': form.is_case_list_form, 'edit_name_url': reverse('edit_form_attr', args=[app.domain, app.id, form.unique_id, 'name']), 'case_xpath_pattern_matches': CASE_XPATH_PATTERN_MATCHES, 'case_xpath_substring_matches': CASE_XPATH_SUBSTRING_MATCHES, 'user_case_xpath_pattern_matches': USER_CASE_XPATH_PATTERN_MATCHES, 'user_case_xpath_substring_matches': USER_CASE_XPATH_SUBSTRING_MATCHES, 'custom_instances': [{ 'instanceId': instance.instance_id, 'instancePath': instance.instance_path } for instance in form.custom_instances], 'can_preview_form': request.couch_user.has_permission(domain, 'edit_data') } if tours.NEW_APP.is_enabled( request.user) and not toggles.APP_MANAGER_V2.enabled( request.user.username): request.guided_tour = tours.NEW_APP.get_tour_data() if context['allow_form_workflow'] and toggles.FORM_LINK_WORKFLOW.enabled( domain): module = form.get_module() def qualified_form_name(form, auto_link): module_name = trans(form.get_module().name, langs) form_name = trans(form.name, langs) star = '* ' if auto_link else ' ' return u"{}{} -> {}".format(star, module_name, form_name) modules = filter(lambda m: m.case_type == module.case_type, all_modules) if getattr(module, 'root_module_id', None) and module.root_module not in modules: modules.append(module.root_module) auto_linkable_forms = list( itertools.chain.from_iterable( list(m.get_forms()) for m in modules)) def linkable_form(candidate_form): auto_link = candidate_form in auto_linkable_forms return { 'unique_id': candidate_form.unique_id, 'name': qualified_form_name(candidate_form, auto_link), 'auto_link': auto_link } context['linkable_forms'] = [ linkable_form(candidate_form) for candidate_module in all_modules for candidate_form in candidate_module.get_forms() ] if isinstance(form, CareplanForm): case_config_options.update({ 'save_url': reverse("edit_careplan_form_actions", args=[app.domain, app.id, module.id, form.id]), 'case_preload': [{ 'key': key, 'path': path } for key, path in form.case_preload.items()], 'customCaseUpdates': [{ 'key': key, 'path': path } for key, path in form.custom_case_updates.items()], 'fixedQuestions': form.get_fixed_questions(), 'mode': form.mode, }) elif isinstance(form, AdvancedForm): def commtrack_programs(): if app.commtrack_enabled: programs = Program.by_domain(app.domain) return [{ 'value': program.get_id, 'label': program.name } for program in programs] else: return [] all_programs = [{'value': '', 'label': _('All Programs')}] case_config_options.update({ 'save_url': reverse("edit_advanced_form_actions", args=[app.domain, app.id, module.id, form.id]), 'commtrack_enabled': app.commtrack_enabled, 'commtrack_programs': all_programs + commtrack_programs(), 'module_id': module.unique_id, 'propertyDescriptions': get_case_property_description_dict(domain), }) if form.form_type == "shadow_form": case_config_options.update({ 'actions': form.extra_actions, 'isShadowForm': True, }) else: case_config_options.update({ 'actions': form.actions, 'isShadowForm': False, }) if module.has_schedule: visit_scheduler_options = get_schedule_context(form) visit_scheduler_options.update({ 'questions': xform_questions, 'save_url': reverse("edit_visit_schedule", args=[app.domain, app.id, module.id, form.id]), 'schedule': form.schedule, 'phase': visit_scheduler_options['schedule_phase'], }) context.update( {'visit_scheduler_options': visit_scheduler_options}) else: case_config_options.update({ 'actions': form.actions, 'allowUsercase': allow_usercase, 'valid_index_names': valid_index_names, 'usercasePropertiesMap': get_usercase_properties(app), 'propertyDescriptions': get_case_property_description_dict(domain), 'save_url': reverse("edit_form_actions", args=[app.domain, app.id, module.id, form.id]), }) context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled_for_request(request), }) context.update({'case_config_options': case_config_options}) template = get_app_manager_template( request.user, "app_manager/v1/form_view.html", "app_manager/v2/form_view.html", ) return template, context
def domain_uses_usercase(): return is_usercase_in_use(self.app.domain)
def get_session_schema(form): """Get form session schema definition """ from corehq.apps.app_manager.suite_xml.sections.entries import EntriesHelper app = form.get_app() structure = {} datums = EntriesHelper(app).get_datums_meta_for_form_generic(form) datums = [ d for d in datums if d.requires_selection and d.case_type and not d.is_new_case_id ] def _get_structure(datum, data_registry, source=None): id_source = f":{slugify(source)}" if source else "" return { "reference": { "hashtag": f'#registry_case{id_source}' if data_registry else f"#case{id_source}", "source": "registry" if data_registry else "casedb", "subset": f"case{id_source}", "key": "@case_id", }, } unrelated_parents = set() for datum in datums: if not datum.module_id: continue module = app.get_module_by_unique_id(datum.module_id) parent_select_active = hasattr( module, 'parent_select') and module.parent_select.active if parent_select_active and module.parent_select.relationship is None: # for child modules that use parent select where the parent is not a 'related' case # See toggles.NON_PARENT_MENU_SELECTION unrelated_parents.add(module.parent_select.module_id) data_structure = {} for i, datum in enumerate(reversed(datums)): if isinstance(datum.datum, InstanceDatum): continue module_id = datum.module_id module = app.get_module_by_unique_id(module_id) if module_id else None data_registry = module.search_config.data_registry if module else None if i == 0: # always add the datum for this module data_structure[datum.datum.id] = _get_structure( datum, data_registry) else: if module and module_id in unrelated_parents: source = clean_trans( module.name, app.langs ) # ensure that this structure reference is unique data_structure[datum.datum.id] = _get_structure( datum, data_registry, source) if data_structure: structure["data"] = { "merge": True, "structure": data_structure, } if is_usercase_in_use(app.domain): structure["context"] = { "merge": True, "structure": { "userid": { "reference": { "hashtag": "#user", "source": "casedb", "subset": USERCASE_TYPE, "subset_key": "@case_type", "subset_filter": True, "key": "hq_user_id", }, }, }, } return { "id": "commcaresession", "uri": "jr://instance/session", "name": "Session", "path": "/session", "structure": structure, }
def _form_uses_case(module, form): return ((module and module.case_type and form.requires_case()) or is_usercase_in_use(domain))
def get_form_view_context_and_template(request, domain, form, langs, messages=messages): xform_questions = [] xform = None form_errors = [] xform_validation_errored = False xform_validation_missing = False try: xform = form.wrapped_xform() except XFormException as e: form_errors.append(u"Error in form: %s" % e) except Exception as e: logging.exception(e) form_errors.append(u"Unexpected error in form: %s" % e) if xform and xform.exists(): if xform.already_has_meta(): messages.warning( request, "This form has a meta block already! " "It may be replaced by CommCare HQ's standard meta block." ) try: xform_questions = xform.get_questions(langs, include_triggers=True) form.validate_form() except etree.XMLSyntaxError as e: form_errors.append(u"Syntax Error: %s" % e) except AppEditingError as e: form_errors.append(u"Error in application: %s" % e) except XFormValidationError: xform_validation_errored = True # showing these messages is handled by validate_form_for_build ajax pass except XFormValidationFailed: xform_validation_missing = True messages.warning(request, _("Unable to validate form due to server error.")) except XFormException as e: form_errors.append(u"Error in form: %s" % e) # any other kind of error should fail hard, # but for now there are too many for that to be practical except Exception as e: if settings.DEBUG: raise notify_exception(request, 'Unexpected Build Error') form_errors.append(u"Unexpected System Error: %s" % e) else: # remove upload questions (attachemnts) until MM Case Properties # are released to general public is_previewer = toggles.MM_CASE_PROPERTIES.enabled(request.user.username) xform_questions = [q for q in xform_questions if q["tag"] != "upload" or is_previewer] if not form_errors and not xform_validation_missing and not xform_validation_errored: try: form_action_errors = form.validate_for_build() if not form_action_errors: form.add_stuff_to_xform(xform) except CaseError as e: messages.error(request, u"Error in Case Management: %s" % e) except XFormException as e: messages.error(request, unicode(e)) except Exception as e: if settings.DEBUG: raise logging.exception(unicode(e)) messages.error(request, u"Unexpected Error: %s" % e) try: languages = xform.get_languages() except Exception: languages = [] for err in form_errors: messages.error(request, err) module_case_types = [] app = form.get_app() all_modules = list(app.get_modules()) for module in all_modules: for case_type in module.get_case_types(): module_case_types.append({ 'id': module.unique_id, 'module_name': trans(module.name, langs), 'case_type': case_type, 'module_type': module.doc_type }) if not form.unique_id: form.get_unique_id() app.save() form_has_schedule = isinstance(form, AdvancedForm) and form.get_module().has_schedule context = { 'nav_form': form, 'xform_languages': languages, "xform_questions": xform_questions, 'case_reserved_words_json': load_case_reserved_words(), 'module_case_types': module_case_types, 'form_errors': form_errors, 'xform_validation_errored': xform_validation_errored, 'xform_validation_missing': xform_validation_missing, 'allow_cloudcare': isinstance(form, Form), 'allow_form_copy': isinstance(form, (Form, AdvancedForm)), 'allow_form_filtering': not isinstance(form, CareplanForm) and not form_has_schedule, 'allow_form_workflow': not isinstance(form, CareplanForm), 'uses_form_workflow': form.post_form_workflow == WORKFLOW_FORM, 'allow_usercase': domain_has_privilege(request.domain, privileges.USER_CASE), 'is_usercase_in_use': is_usercase_in_use(request.domain), 'is_module_filter_enabled': app.enable_module_filtering, 'edit_name_url': reverse('edit_form_attr', args=[app.domain, app.id, form.unique_id, 'name']), 'case_xpath_pattern_matches': CASE_XPATH_PATTERN_MATCHES, 'case_xpath_substring_matches': CASE_XPATH_SUBSTRING_MATCHES, 'user_case_xpath_pattern_matches': USER_CASE_XPATH_PATTERN_MATCHES, 'user_case_xpath_substring_matches': USER_CASE_XPATH_SUBSTRING_MATCHES, 'custom_instances': [ {'instanceId': instance.instance_id, 'instancePath': instance.instance_path} for instance in form.custom_instances ], } if tours.NEW_APP.is_enabled(request.user): request.guided_tour = tours.NEW_APP.get_tour_data() if context['allow_form_workflow'] and toggles.FORM_LINK_WORKFLOW.enabled(domain): module = form.get_module() def qualified_form_name(form, auto_link): module_name = trans(form.get_module().name, langs) form_name = trans(form.name, langs) star = '* ' if auto_link else ' ' return u"{}{} -> {}".format(star, module_name, form_name) modules = filter(lambda m: m.case_type == module.case_type, all_modules) if getattr(module, 'root_module_id', None) and module.root_module not in modules: modules.append(module.root_module) auto_linkable_forms = list(itertools.chain.from_iterable(list(m.get_forms()) for m in modules)) def linkable_form(candidate_form): auto_link = candidate_form in auto_linkable_forms return { 'unique_id': candidate_form.unique_id, 'name': qualified_form_name(candidate_form, auto_link), 'auto_link': auto_link } context['linkable_forms'] = [ linkable_form(candidate_form) for candidate_module in all_modules for candidate_form in candidate_module.get_forms() ] if isinstance(form, CareplanForm): context.update({ 'mode': form.mode, 'fixed_questions': form.get_fixed_questions(), 'custom_case_properties': [ {'key': key, 'path': path} for key, path in form.custom_case_updates.items() ], 'case_preload': [ {'key': key, 'path': path} for key, path in form.case_preload.items() ], }) return "app_manager/v1/form_view_careplan.html", context elif isinstance(form, AdvancedForm): def commtrack_programs(): if app.commtrack_enabled: programs = Program.by_domain(app.domain) return [{'value': program.get_id, 'label': program.name} for program in programs] else: return [] all_programs = [{'value': '', 'label': _('All Programs')}] context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled(request.user.username), 'commtrack_programs': all_programs + commtrack_programs(), }) context.update(get_schedule_context(form)) return "app_manager/v1/form_view_advanced.html", context else: context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled(request.user.username), }) return "app_manager/v1/form_view.html", context
def get_casedb_schema(form): """Get case database schema definition for vellum to display as an external data source. This lists all case types and their properties for the given app. """ app = form.get_app() base_case_type = form.get_module().case_type if form.requires_case( ) else None case_types = app.get_case_types() | get_shared_case_types(app) per_type_defaults = get_per_type_defaults(app.domain, case_types) builder = ParentCasePropertyBuilder(app, ['case_name'], per_type_defaults, include_parent_properties=False) related = builder.get_parent_type_map(case_types) map = builder.get_case_property_map(case_types) descriptions_dict = get_case_property_description_dict(app.domain) if base_case_type: # Generate hierarchy of case types, represented as a list of lists of strings: # [[base_case_type], [parent_type1, parent_type2...], [grandparent_type1, grandparent_type2...]] # Vellum case management only supports three levels generation_names = ['case', 'parent', 'grandparent'] generations = [[] for g in generation_names] def _add_ancestors(ctype, generation): if generation < len(generation_names): generations[generation].append(ctype) for parent in related.get(ctype, {}).get('parent', []): _add_ancestors(parent, generation + 1) _add_ancestors(base_case_type, 0) # Remove any duplicate types or empty generations generations = [set(g) for g in generations if len(g)] else: generations = [] subsets = [{ "id": generation_names[i], "name": "{} ({})".format(generation_names[i], " or ".join(ctypes)) if i > 0 else base_case_type, "structure": { p: { "description": descriptions_dict.get(t, {}).get(p, '') } for t in ctypes for p in map[t] }, "related": { "parent": { "hashtag": "#case/" + generation_names[i + 1], "subset": generation_names[i + 1], "key": "@case_id", } } if i < len(generations) - 1 else None, } for i, ctypes in enumerate(generations)] if is_usercase_in_use(app.domain): subsets.append({ "id": USERCASE_TYPE, "name": "user", "key": "@case_type", "structure": {p: {} for p in get_usercase_properties(app)[USERCASE_TYPE]}, }) return { "id": "casedb", "uri": "jr://instance/casedb", "name": "case", "path": "/casedb/case", "structure": {}, "subsets": subsets, }
def get_form_view_context_and_template(request, domain, form, langs, messages=messages): xform_questions = [] xform = None form_errors = [] xform_validation_errored = False try: xform = form.wrapped_xform() except XFormException as e: form_errors.append(u"Error in form: %s" % e) except Exception as e: logging.exception(e) form_errors.append(u"Unexpected error in form: %s" % e) if xform and xform.exists(): if xform.already_has_meta(): messages.warning( request, "This form has a meta block already! " "It may be replaced by CommCare HQ's standard meta block." ) try: form.validate_form() xform_questions = xform.get_questions(langs, include_triggers=True, form=form) except etree.XMLSyntaxError as e: form_errors.append(u"Syntax Error: %s" % e) except AppEditingError as e: form_errors.append(u"Error in application: %s" % e) except XFormValidationError: xform_validation_errored = True # showing these messages is handled by validate_form_for_build ajax pass except XFormException as e: form_errors.append(u"Error in form: %s" % e) # any other kind of error should fail hard, # but for now there are too many for that to be practical except Exception as e: if settings.DEBUG: raise notify_exception(request, 'Unexpected Build Error') form_errors.append(u"Unexpected System Error: %s" % e) else: # remove upload questions (attachemnts) until MM Case Properties # are released to general public is_previewer = toggles.MM_CASE_PROPERTIES.enabled(request.user.username) xform_questions = [q for q in xform_questions if q["tag"] != "upload" or is_previewer] try: form_action_errors = form.validate_for_build() if not form_action_errors: form.add_stuff_to_xform(xform) except CaseError as e: messages.error(request, u"Error in Case Management: %s" % e) except XFormException as e: messages.error(request, unicode(e)) except Exception as e: if settings.DEBUG: raise logging.exception(unicode(e)) messages.error(request, u"Unexpected Error: %s" % e) try: languages = xform.get_languages() except Exception: languages = [] for err in form_errors: messages.error(request, err) module_case_types = [] app = form.get_app() all_modules = list(app.get_modules()) for module in all_modules: for case_type in module.get_case_types(): module_case_types.append({ 'id': module.unique_id, 'module_name': trans(module.name, langs), 'case_type': case_type, 'module_type': module.doc_type }) if not form.unique_id: form.get_unique_id() app.save() form_has_schedule = isinstance(form, AdvancedForm) and form.get_module().has_schedule module_filter_preview = feature_previews.MODULE_FILTER.enabled(request.domain) context = { 'nav_form': form, 'xform_languages': languages, "xform_questions": xform_questions, 'case_reserved_words_json': load_case_reserved_words(), 'module_case_types': module_case_types, 'form_errors': form_errors, 'xform_validation_errored': xform_validation_errored, 'allow_cloudcare': isinstance(form, Form), 'allow_form_copy': isinstance(form, (Form, AdvancedForm)), 'allow_form_filtering': (module_filter_preview or (not isinstance(form, CareplanForm) and not form_has_schedule)), 'allow_form_workflow': not isinstance(form, CareplanForm), 'allow_usercase': domain_has_privilege(request.domain, privileges.USER_CASE), 'is_usercase_in_use': is_usercase_in_use(request.domain), 'is_module_filter_enabled': (feature_previews.MODULE_FILTER.enabled(request.domain) and app.enable_module_filtering), 'edit_name_url': reverse('edit_form_attr', args=[app.domain, app.id, form.unique_id, 'name']), 'case_xpath_pattern_matches': CASE_XPATH_PATTERN_MATCHES, 'case_xpath_substring_matches': CASE_XPATH_SUBSTRING_MATCHES, 'user_case_xpath_pattern_matches': USER_CASE_XPATH_PATTERN_MATCHES, 'user_case_xpath_substring_matches': USER_CASE_XPATH_SUBSTRING_MATCHES, } if tours.NEW_APP.is_enabled(request.user): request.guided_tour = tours.NEW_APP.get_tour_data() if context['allow_form_workflow'] and toggles.FORM_LINK_WORKFLOW.enabled(domain): module = form.get_module() def qualified_form_name(form, auto_link): module_name = trans(form.get_module().name, langs) form_name = trans(form.name, langs) star = '* ' if auto_link else ' ' return u"{}{} -> {}".format(star, module_name, form_name) modules = filter(lambda m: m.case_type == module.case_type, all_modules) if getattr(module, 'root_module_id', None) and module.root_module not in modules: modules.append(module.root_module) auto_linkable_forms = list(itertools.chain.from_iterable(list(m.get_forms()) for m in modules)) def linkable_form(candidate_form): auto_link = candidate_form in auto_linkable_forms return { 'unique_id': candidate_form.unique_id, 'name': qualified_form_name(candidate_form, auto_link), 'auto_link': auto_link } context['linkable_forms'] = [ linkable_form(candidate_form) for candidate_module in all_modules for candidate_form in candidate_module.get_forms() ] if isinstance(form, CareplanForm): context.update({ 'mode': form.mode, 'fixed_questions': form.get_fixed_questions(), 'custom_case_properties': [ {'key': key, 'path': path} for key, path in form.custom_case_updates.items() ], 'case_preload': [ {'key': key, 'path': path} for key, path in form.case_preload.items() ], }) return "app_manager/form_view_careplan.html", context elif isinstance(form, AdvancedForm): def commtrack_programs(): if app.commtrack_enabled: programs = Program.by_domain(app.domain) return [{'value': program.get_id, 'label': program.name} for program in programs] else: return [] all_programs = [{'value': '', 'label': _('All Programs')}] context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled(request.user.username), 'commtrack_programs': all_programs + commtrack_programs(), }) context.update(get_schedule_context(form)) return "app_manager/form_view_advanced.html", context else: context.update({ 'show_custom_ref': toggles.APP_BUILDER_CUSTOM_PARENT_REF.enabled(request.user.username), }) return "app_manager/form_view.html", context