Example #1
0
def has_report_builder_access(request):
    builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER)
    legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER)
    beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
    has_add_on_priv = has_report_builder_add_on_privilege(request)

    return (builder_enabled and legacy_builder_priv) or beta_group_enabled or has_add_on_priv
Example #2
0
def delete_report(request, domain, report_id):
    if not (toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS)
            or toggle_enabled(request, toggles.REPORT_BUILDER)
            or toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
            or has_report_builder_add_on_privilege(request)):
        raise Http404()

    config = get_document_or_404(ReportConfiguration, domain, report_id)

    # Delete the data source too if it's not being used by any other reports.
    try:
        data_source, __ = get_datasource_config(config.config_id, domain)
    except DataSourceConfigurationNotFoundError:
        # It's possible the data source has already been deleted, but that's fine with us.
        pass
    else:
        if data_source.get_report_count() <= 1:
            # No other reports reference this data source.
            data_source.deactivate()

    config.delete()
    did_purge_something = purge_report_from_mobile_ucr(config)

    messages.success(request, _(u'Report "{}" deleted!').format(config.title))
    if did_purge_something:
        messages.warning(
            request,
            _(u"This report was used in one or more applications. "
              "It has been removed from there too."))
    redirect = request.GET.get("redirect", None)
    if not redirect:
        redirect = reverse('configurable_reports_home', args=[domain])
    return HttpResponseRedirect(redirect)
Example #3
0
def has_report_builder_access(request):
    builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER)
    legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER)
    beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
    has_add_on_priv = has_report_builder_add_on_privilege(request)

    return (builder_enabled and legacy_builder_priv) or beta_group_enabled or has_add_on_priv
Example #4
0
def delete_report(request, domain, report_id):
    if not (toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS)
            or toggle_enabled(request, toggles.REPORT_BUILDER)
            or toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
            or has_report_builder_add_on_privilege(request)):
        raise Http404()

    config = get_document_or_404(ReportConfiguration, domain, report_id)

    # Delete the data source too if it's not being used by any other reports.
    try:
        data_source, __ = get_datasource_config(config.config_id, domain)
    except DataSourceConfigurationNotFoundError:
        # It's possible the data source has already been deleted, but that's fine with us.
        pass
    else:
        if data_source.get_report_count() <= 1:
            # No other reports reference this data source.
            data_source.deactivate()

    config.delete()
    did_purge_something = purge_report_from_mobile_ucr(config)

    messages.success(request, _(u'Report "{}" deleted!').format(config.title))
    if did_purge_something:
        messages.warning(
            request,
            _(u"This report was used in one or more applications. "
              "It has been removed from there too.")
        )
    redirect = request.GET.get("redirect", None)
    if not redirect:
        redirect = reverse('configurable_reports_home', args=[domain])
    return HttpResponseRedirect(redirect)
Example #5
0
def can_edit_report(request, report):
    ucr_toggle = toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS)
    report_builder_toggle = toggle_enabled(request, toggles.REPORT_BUILDER)
    report_builder_beta_toggle = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
    add_on_priv = has_report_builder_add_on_privilege(request)
    created_by_builder = report.spec.report_meta.created_by_builder

    if created_by_builder:
        return report_builder_toggle or report_builder_beta_toggle or add_on_priv
    else:
        return ucr_toggle
Example #6
0
def can_edit_report(request, report):
    if not request.can_access_all_locations:
        return False

    ucr_toggle = toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS)
    report_builder_toggle = toggle_enabled(request, toggles.REPORT_BUILDER)
    report_builder_beta_toggle = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)
    add_on_priv = has_report_builder_add_on_privilege(request)
    created_by_builder = report.spec.report_meta.created_by_builder

    if created_by_builder:
        return report_builder_toggle or report_builder_beta_toggle or add_on_priv
    else:
        return ucr_toggle
Example #7
0
 def _handle_exception(self, response, exception):
     if self.existing_report and self.existing_report.report_meta.edited_manually:
         error_message_base = _(
             'It looks like this report was edited by hand and is no longer editable in report builder.'
         )
         if toggle_enabled(self.request, toggles.USER_CONFIGURABLE_REPORTS):
             error_message = '{} {}'.format(
                 error_message_base,
                 _('You can edit the report manually using the <a href="{}">advanced UI</a>.'
                   ).format(
                       reverse(EditConfigReportView.urlname,
                               args=[self.domain,
                                     self.existing_report._id])))
         else:
             error_message = '{} {}'.format(
                 error_message_base,
                 _('You can delete and recreate this report using the button below, or '
                   'report an issue if you believe you are seeing this page in error.'
                   ))
         response['error_message'] = error_message
         return response
     elif isinstance(exception, DataSourceConfigurationNotFoundError):
         response['details'] = None
         response['error_message'] = '{} {}'.format(
             str(exception), DATA_SOURCE_NOT_FOUND_ERROR_MESSAGE)
         return response
     else:
         raise
Example #8
0
 def _handle_exception(self, response, exception):
     if self.existing_report and self.existing_report.report_meta.edited_manually:
         error_message_base = _(
             'It looks like this report was edited by hand and is no longer editable in report builder.'
         )
         if toggle_enabled(self.request, toggles.USER_CONFIGURABLE_REPORTS):
             error_message = '{} {}'.format(error_message_base, _(
                 'You can edit the report manually using the <a href="{}">advanced UI</a>.'
             ).format(reverse(EditConfigReportView.urlname, args=[self.domain, self.existing_report._id])))
         else:
             error_message = '{} {}'.format(
                 error_message_base,
                 _('You can delete and recreate this report using the button below, or '
                   'report an issue if you believe you are seeing this page in error.')
             )
         response['error_message'] = error_message
         return response
     elif isinstance(exception, DataSourceConfigurationNotFoundError):
         response['details'] = None
         response['error_message'] = '{} {}'.format(
             str(exception),
             DATA_SOURCE_NOT_FOUND_ERROR_MESSAGE
         )
         return response
     else:
         raise
Example #9
0
def _can_edit_report(request, report):
    if not request.can_access_all_locations:
        return False

    if not request.couch_user.can_edit_reports():
        return False

    ucr_toggle = toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS)
    report_builder_toggle = toggle_enabled(request, toggles.REPORT_BUILDER)
    report_builder_beta_toggle = toggle_enabled(
        request, toggles.REPORT_BUILDER_BETA_GROUP)
    add_on_priv = has_report_builder_add_on_privilege(request)
    created_by_builder = report.report_meta.created_by_builder

    if created_by_builder:
        return report_builder_toggle or report_builder_beta_toggle or add_on_priv
    else:
        return ucr_toggle
Example #10
0
 def dispatch(self, request, *args, **kwargs):
     if has_report_builder_access(request):
         report_type = kwargs.get('report_type', None)
         if report_type != 'map' or toggle_enabled(request, REPORT_BUILDER_MAP_REPORTS):
             return super(ReportBuilderView, self).dispatch(request, *args, **kwargs)
         else:
             raise Http404
     else:
         raise Http404
Example #11
0
def allowed_report_builder_reports(request):
    """
    Return the number of report builder reports allowed
    """
    builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER)
    legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER)
    beta_group_enabled = toggle_enabled(request,
                                        toggles.REPORT_BUILDER_BETA_GROUP)

    if toggle_enabled(request, toggles.UNLIMITED_REPORT_BUILDER_REPORTS):
        return float("inf")
    if has_privilege(request, privileges.REPORT_BUILDER_30):
        return 30
    if has_privilege(request, privileges.REPORT_BUILDER_15):
        return 15
    if (has_privilege(request, privileges.REPORT_BUILDER_TRIAL)
            or has_privilege(request, privileges.REPORT_BUILDER_5)
            or beta_group_enabled
            or (builder_enabled and legacy_builder_priv)):
        return 5
        def get_remainder_column(question):
            col = ExportColumn(
                index=question,
                display='',
                show=True,
            ).to_config_format(selected=self.creating_new_export)

            if toggle_enabled(self.request, 'SPLIT_MULTISELECT_EXPORT'):
                update_multi_select_column(question, col)

            return col
Example #13
0
def allowed_report_builder_reports(request):
    """
    Return the number of report builder reports allowed
    """
    builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER)
    legacy_builder_priv = has_privilege(request, privileges.REPORT_BUILDER)
    beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)

    if toggle_enabled(request, toggles.UNLIMITED_REPORT_BUILDER_REPORTS):
        return float("inf")
    if has_privilege(request, privileges.REPORT_BUILDER_30):
        return 30
    if has_privilege(request, privileges.REPORT_BUILDER_15):
        return 15
    if (
        has_privilege(request, privileges.REPORT_BUILDER_TRIAL) or
        has_privilege(request, privileges.REPORT_BUILDER_5) or
        beta_group_enabled or
        (builder_enabled and legacy_builder_priv)
    ):
        return 5
Example #14
0
def render_form(form, domain, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.

    """
    case_id = options.get('case_id')
    side_pane = options.get('side_pane', False)
    user = options.get('user', None)
    request = options.get('request', None)
    support_enabled = toggle_enabled(request, toggles.SUPPORT)

    form_data, question_list_not_found = get_readable_data_for_submission(form)

    timezone = get_timezone_for_request()

    context = {
        "context_case_id": case_id,
        "instance": form,
        "is_archived": form.is_archived,
        "edit_info": _get_edit_info(form),
        "domain": domain,
        'question_list_not_found': question_list_not_found,
        "form_data": form_data,
        "side_pane": side_pane,
        "tz_abbrev": timezone.localize(datetime.utcnow()).tzname(),
    }

    context.update(_get_cases_changed_context(domain, form, case_id))
    context.update(_get_form_metadata_context(domain, form, timezone, support_enabled))
    context.update(_get_display_options(request, domain, user, form, support_enabled))
    context.update(_get_edit_info(form))
    instance_history = []
    if form.history:
        for operation in form.history:
            user_date = ServerTime(operation.date).user_time(timezone).done()
            instance_history.append({
                'readable_date': user_date.strftime("%Y-%m-%d %H:%M"),
                'readable_action': FORM_OPERATIONS.get(operation.operation, operation.operation),
                'user_info': get_doc_info_by_id(domain, operation.user),
            })
    context['instance_history'] = instance_history
    return render_to_string("reports/form/partials/single_form.html", context, request=request)
Example #15
0
    def page_context(self):
        try:
            report_form = self.report_form
        except Exception as e:
            if self.existing_report and self.existing_report.report_meta.edited_manually:
                error_message_base = _(
                    'It looks like this report was edited by hand and is no longer editable in report builder.'
                )
                if toggle_enabled(self.request, toggles.USER_CONFIGURABLE_REPORTS):
                    error_message = '{} {}'.format(error_message_base, _(
                        'You can edit the report manually using the <a href="{}">advanced UI</a>.'
                    ).format(reverse(EditConfigReportView.urlname, args=[self.domain, self.existing_report._id])))
                else:
                    error_message = '{} {}'.format(error_message_base, _(
                        'You can delete and recreate this report using the button below, or '
                        'report an issue if you believe you are seeing this page in error.'
                    ))
                self.template_name = 'userreports/report_error.html'
                return {
                    'report_id': self.existing_report.get_id,
                    'is_static': self.existing_report.is_static,
                    'error_message': error_message,
                    'details': unicode(e)
                }
            else:
                raise

        return {
            'report': {
                "title": self.page_name
            },
            'report_type': self.report_type,
            'form': report_form,
            'editing_existing_report': bool(self.existing_report),
            'property_options': [p._asdict() for p in report_form.data_source_properties.values()],
            'initial_filters': [f._asdict() for f in report_form.initial_filters],
            'initial_columns': [
                c._asdict() for c in getattr(report_form, 'initial_columns', [])
            ],
            'report_builder_events': self.request.session.pop(REPORT_BUILDER_EVENTS_KEY, [])
        }
Example #16
0
def render_form(form, domain, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.

    """
    case_id = options.get('case_id')
    side_pane = options.get('side_pane', False)
    user = options.get('user', None)
    request = options.get('request', None)
    support_enabled = toggle_enabled(request, toggles.SUPPORT)

    form_data, question_list_not_found = get_readable_data_for_submission(form)

    context = {
        "context_case_id": case_id,
        "instance": form,
        "is_archived": form.is_archived,
        "edit_info": _get_edit_info(form),
        "domain": domain,
        'question_list_not_found': question_list_not_found,
        "form_data": form_data,
        "form_table_options": {
            # todo: wells if display config has more than one column
            "put_loners_in_wells": False
        },
        "side_pane": side_pane,
    }

    context.update(_get_cases_changed_context(domain, form, case_id))
    context.update(_get_form_metadata_context(domain, form, support_enabled))
    context.update(
        _get_display_options(request, domain, user, form, support_enabled))
    context.update(_get_edit_info(form))
    return render_to_string("reports/form/partials/single_form.html",
                            context,
                            request=request)
Example #17
0
def render_form(form, domain, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.

    """

    timezone = get_timezone_for_request()
    case_id = options.get('case_id')
    side_pane = options.get('side_pane', False)
    user = options.get('user', None)
    request = options.get('request', None)
    support_enabled = toggle_enabled(request, toggles.SUPPORT)

    _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone)

    # Form Data tab
    form_data, question_list_not_found = get_readable_data_for_submission(form)

    # Case Changes tab
    case_blocks = extract_case_blocks(form)
    for i, block in enumerate(list(case_blocks)):
        if case_id and block.get(const.CASE_ATTR_ID) == case_id:
            case_blocks.pop(i)
            case_blocks.insert(0, block)

    cases = []
    for b in case_blocks:
        this_case_id = b.get(const.CASE_ATTR_ID)
        try:
            this_case = CaseAccessors(domain).get_case(this_case_id) if this_case_id else None
            valid_case = True
        except ResourceNotFound:
            this_case = None
            valid_case = False

        if this_case and this_case.case_id:
            url = reverse('case_details', args=[domain, this_case.case_id])
        else:
            url = "#"

        definition = get_default_definition(
            sorted_case_update_keys(b.keys()),
            assume_phonetimes=(not form.metadata or
                               (form.metadata.deviceID != CLOUDCARE_DEVICE_ID)),
        )
        cases.append({
            "is_current_case": case_id and this_case_id == case_id,
            "name": case_inline_display(this_case),
            "table": _get_tables_as_columns(b, definition),
            "url": url,
            "valid_case": valid_case
        })

    # Form Metadata tab
    meta = _top_level_tags(form).get('meta', None) or {}
    meta['received_on'] = json_format_datetime(form.received_on)
    if support_enabled:
        meta['last_sync_token'] = form.last_sync_token

    definition = get_default_definition(sorted_form_metadata_keys(meta.keys()))
    form_meta_data = _get_tables_as_columns(meta, definition)
    if getattr(form, 'auth_context', None):
        auth_context = AuthContext(form.auth_context)
        auth_context_user_id = auth_context.user_id
        auth_user_info = get_doc_info_by_id(domain, auth_context_user_id)
    else:
        auth_user_info = get_doc_info_by_id(domain, None)
        auth_context = AuthContext(
            user_id=None,
            authenticated=False,
            domain=domain,
        )
    meta_userID = meta.get('userID')
    meta_username = meta.get('username')
    if meta_userID == 'demo_user':
        user_info = DocInfo(
            domain=domain,
            display='demo_user',
        )
    elif meta_username == 'admin':
        user_info = DocInfo(
            domain=domain,
            display='admin',
        )
    else:
        user_info = get_doc_info_by_id(domain, meta_userID)

    user_can_edit = (
        request and user and request.domain
        and (user.can_edit_data() or user.is_commcare_user())
    )
    show_edit_options = (
        user_can_edit
        and can_edit_form_location(domain, user, form)
    )
    show_edit_submission = (
        user_can_edit
        and has_privilege(request, privileges.DATA_CLEANUP)
        and not form.is_deprecated
    )

    show_resave = (
        user_can_edit and support_enabled
    )

    def _get_edit_info(instance):
        info = {
            'was_edited': False,
            'is_edit': False,
        }
        if instance.is_deprecated:
            info.update({
                'was_edited': True,
                'latest_version': instance.orig_id,
            })
        if getattr(instance, 'edited_on', None) and getattr(instance, 'deprecated_form_id', None):
            info.update({
                'is_edit': True,
                'edited_on': instance.edited_on,
                'previous_version': instance.deprecated_form_id
            })
        return info

    return render_to_string("reports/form/partials/single_form.html", {
        "context_case_id": case_id,
        "instance": form,
        "is_archived": form.is_archived,
        "edit_info": _get_edit_info(form),
        "domain": domain,
        'question_list_not_found': question_list_not_found,
        "form_data": form_data,
        "cases": cases,
        "form_table_options": {
            # todo: wells if display config has more than one column
            "put_loners_in_wells": False
        },
        "form_meta_data": form_meta_data,
        "auth_context": auth_context,
        "auth_user_info": auth_user_info,
        "user_info": user_info,
        "side_pane": side_pane,
        "show_edit_options": show_edit_options,
        "show_edit_submission": show_edit_submission,
        "show_resave": show_resave,
    }, RequestContext(request))
Example #18
0
def get_app_view_context(request, app):

    is_cloudcare_allowed = has_privilege(request, privileges.CLOUDCARE)
    context = {}

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout(request.domain)[app.get_doc_type()])
    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get('disable_if_true')
            if disable_if_true and getattr(app, setting['id']):
                continue
            new_settings.append(setting)
        section['settings'] = new_settings

    if toggles.CUSTOM_PROPERTIES.enabled(
            request.domain) and 'custom_properties' in app.profile:
        custom_properties_array = map(
            lambda p: {
                'key': p[0],
                'value': p[1]
            },
            app.profile.get('custom_properties').items())
        context.update({'custom_properties': custom_properties_array})

    context.update({
        'settings_layout': settings_layout,
        'settings_values': get_settings_values(app),
        'is_cloudcare_allowed': is_cloudcare_allowed,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser:
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    (build_spec_setting, ) = filter(
        lambda x: x['type'] == 'hq' and x['id'] == 'build_spec', [
            setting for section in context['settings_layout']
            for setting in section['settings']
        ]) if context['settings_layout'] else (None, )
    if build_spec_setting:
        build_spec_setting['options_map'] = options_map
        build_spec_setting['default_app_version'] = app.application_version

    context.update({
        'bulk_ui_translation_upload': {
            'action':
            reverse('upload_bulk_ui_translations',
                    args=(app.domain, app.get_id)),
            'download_url':
            reverse('download_bulk_ui_translations',
                    args=(app.domain, app.get_id)),
            'adjective':
            _(u"U\u200BI translation"),
            'plural_noun':
            _(u"U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action':
            reverse('upload_bulk_app_translations',
                    args=(app.domain, app.get_id)),
            'download_url':
            reverse('download_bulk_app_translations',
                    args=(app.domain, app.get_id)),
            'adjective':
            _("app translation"),
            'plural_noun':
            _("app translations"),
        },
    })
    context.update({
        'bulk_ui_translation_form':
        get_bulk_upload_form(context,
                             context_key="bulk_ui_translation_upload"),
        'bulk_app_translation_form':
        get_bulk_upload_form(context,
                             context_key="bulk_app_translation_upload")
    })
    context['is_app_view'] = True
    try:
        context['fetchLimit'] = int(
            request.GET.get('limit', DEFAULT_FETCH_LIMIT))
    except ValueError:
        context['fetchLimit'] = DEFAULT_FETCH_LIMIT

    if app.get_doc_type() == 'LinkedApplication':
        context['master_version'] = get_app(None, app.master,
                                            latest=True).version
    return context
Example #19
0
def render_form(form, domain, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.
    
    """
    # don't actually use the passed in timezone since we assume form submissions already come
    # in in local time.
    # todo: we should revisit this when we properly handle timezones in form processing.
    timezone = pytz.utc
    case_id = options.get('case_id')
    side_pane = options.get('side_pane', False)
    user = options.get('user', None)

    _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone)

    # Form Data tab
    form_data, question_list_not_found = get_readable_data_for_submission(form)

    # Case Changes tab
    case_blocks = extract_case_blocks(form)
    for i, block in enumerate(list(case_blocks)):
        if case_id and block.get(const.CASE_ATTR_ID) == case_id:
            case_blocks.pop(i)
            case_blocks.insert(0, block)

    cases = []
    for b in case_blocks:
        this_case_id = b.get(const.CASE_ATTR_ID)
        try:
            this_case = CommCareCase.get(this_case_id) if this_case_id else None
            valid_case = True
        except ResourceNotFound:
            this_case = None
            valid_case = False

        if this_case and this_case._id:
            url = reverse('case_details', args=[domain, this_case._id])
        else:
            url = "#"

        definition = get_definition(sorted_case_update_keys(b.keys()))
        cases.append({
            "is_current_case": case_id and this_case_id == case_id,
            "name": case_inline_display(this_case),
            "table": _get_tables_as_columns(b, definition),
            "url": url,
            "valid_case": valid_case
        })

    # Form Metadata tab
    meta = form.top_level_tags().get('meta', None) or {}
    definition = get_definition(sorted_form_metadata_keys(meta.keys()))
    form_meta_data = _get_tables_as_columns(meta, definition)
    if 'auth_context' in form:
        auth_context = AuthContext(form.auth_context)
        auth_context_user_id = auth_context.user_id
        auth_user_info = get_doc_info_by_id(domain, auth_context_user_id)
    else:
        auth_user_info = get_doc_info_by_id(domain, None)
        auth_context = AuthContext(
            user_id=None,
            authenticated=False,
            domain=domain,
        )
    meta_userID = meta.get('userID')
    meta_username = meta.get('username')
    if meta_userID == 'demo_user':
        user_info = DocInfo(
            domain=domain,
            display='demo_user',
        )
    elif meta_username == 'admin':
        user_info = DocInfo(
            domain=domain,
            display='admin',
        )
    else:
        user_info = get_doc_info_by_id(domain, meta_userID)

    request = options.get('request', None)
    user_can_edit = (
        request and user and request.domain
        and (user.can_edit_data() or user.is_commcare_user())
    )
    show_edit_submission = (
        user_can_edit
        and has_privilege(request, privileges.CLOUDCARE)
        and toggle_enabled(request, toggles.EDIT_SUBMISSIONS)
    )
    # stuffing this in the same flag as case rebuild
    show_resave = (
        user_can_edit and toggle_enabled(request, toggles.CASE_REBUILD)
    )
    return render_to_string("reports/form/partials/single_form.html", {
        "context_case_id": case_id,
        "instance": form,
        "is_archived": form.doc_type == "XFormArchived",
        "domain": domain,
        'question_list_not_found': question_list_not_found,
        "form_data": form_data,
        "cases": cases,
        "form_table_options": {
            # todo: wells if display config has more than one column
            "put_loners_in_wells": False
        },
        "form_meta_data": form_meta_data,
        "auth_context": auth_context,
        "auth_user_info": auth_user_info,
        "user_info": user_info,
        "side_pane": side_pane,
        "user": user,
        "show_edit_submission": show_edit_submission,
        "show_resave": show_resave,
    })
    def update_table_conf_with_questions(self, table_conf):
        column_conf = table_conf[0].get("column_configuration", [])

        current_questions = set(self.custom_export.question_order)
        remaining_questions = current_questions.copy()

        def is_special_type(q):
            return any([q.startswith('form.#'), q.startswith('form.@'), q.startswith('form.case.'),
                        q.startswith('form.meta.'), q.startswith('form.subcase_')])

        def generate_additional_columns(requires_case):
            ret = []
            case_name_col = CustomColumn(slug='case_name', index=FORM_CASE_ID_PATH, display='info.case_name',
                                         transform=CASENAME_TRANSFORM, show=True, selected=True)
            if not requires_case:
                case_name_col.show, case_name_col.selected, case_name_col.tag = False, False, 'deleted'
            matches = filter(case_name_col.match, column_conf)
            if matches:
                # hack/annoying - also might have to re-add the case id column which can get
                # overwritten by case name if only that is set.
                case_id_cols = filter(lambda col: col['index'] == FORM_CASE_ID_PATH, column_conf)
                if len(case_id_cols) <= 1:
                    ret.append(ExportColumn(
                        index=FORM_CASE_ID_PATH,
                        display='info.case_id',
                        show=True,
                    ).to_config_format(selected=False))

                for match in matches:
                    case_name_col.format_for_javascript(match)

            elif filter(lambda col: col["index"] == case_name_col.index, column_conf):
                ret.append(case_name_col.default_column())
            return ret

        question_schema = self.custom_export.question_schema.question_schema

        def update_multi_select_column(question, col):
            if question in question_schema and not question_schema[question].repeat_context:
                if self.creating_new_export:
                    col["options"] = question_schema[question].options
                    col["allOptions"] = question_schema[question].options
                    col["doc_type"] = SplitColumn.__name__
                else:
                    current_options = set(col.get("options", []))
                    col["allOptions"] = list(set(question_schema[question].options) | current_options)

        for col in column_conf:
            question = col["index"]
            if question in remaining_questions:
                remaining_questions.discard(question)
                col["show"] = True
            if question.startswith("form.") and not is_special_type(question) and question not in current_questions:
                col["tag"] = "deleted"
                col["show"] = False
            if question in self.questions_to_show:
                col["show"] = True
            if self.creating_new_export and (question in self.default_questions or question in current_questions):
                col["selected"] = True

            if toggle_enabled(self.request, 'SPLIT_MULTISELECT_EXPORT'):
                update_multi_select_column(question, col)

        requires_case = self.custom_export.uses_cases()

        case_cols = filter(lambda col: col["index"] == FORM_CASE_ID_PATH, column_conf)
        if not requires_case:
            for col in case_cols:
                if col['index'] == FORM_CASE_ID_PATH:
                    col['tag'], col['show'], col['selected'] = 'deleted', False, False
                    col['allOptions'] = []
        elif not case_cols:
            column_conf.append({
                'index': FORM_CASE_ID_PATH,
                'show': True,
                'is_sensitive': False,
                'selected': True,
                'transform': None,
                'tag': None,
                'display': '',
                'doc_type': None,
                'allOptions': None,
                'options': []
            })

        # This adds [info] location.#text to the standard list of columns to export, even if no forms have been
        # submitted with location data yet.
        if (self.custom_export.app
                and not self.custom_export.app.is_remote_app()
                and self.custom_export.app.auto_gps_capture):
            loc_present = False
            for col in column_conf:
                if col['index'] == 'form.meta.location.#text':
                    loc_present = True
            if not loc_present:
                column_conf.append({
                    'index': 'form.meta.location.#text',
                    'show': True,
                    'is_sensitive': False,
                    'selected': False,
                    'transform': None,
                    'tag': None,
                    'display': '',
                    'doc_type': None,
                    'allOptions': None,
                    'options': []
                })

        column_conf.extend(generate_additional_columns(requires_case))

        def get_remainder_column(question):
            col = ExportColumn(
                index=question,
                display='',
                show=True,
            ).to_config_format(selected=self.creating_new_export)

            if toggle_enabled(self.request, 'SPLIT_MULTISELECT_EXPORT'):
                update_multi_select_column(question, col)

            return col

        column_conf.extend([
            get_remainder_column(q)
            for q in remaining_questions
        ])

        # show all questions in repeat groups by default
        for conf in table_conf:
            if conf["index"].startswith('#.form.'):
                for col in conf.get("column_configuration", []):
                    col["show"] = True


        table_conf[0]["column_configuration"] = column_conf
        return table_conf
Example #21
0
 def toggles_enabled(report_class, request):
     if not getattr(report_class, 'toggles', ()):
         return True
     return all(toggle_enabled(request, toggle) for toggle in report_class.toggles)
Example #22
0
 def toggles_enabled(report_class, request):
     if not getattr(report_class, 'toggles', ()):
         return True
     return all(toggle_enabled(request, toggle) for toggle in report_class.toggles)
Example #23
0
def get_app_view_context(request, app):
    """
    This provides the context to render commcare settings on Edit Application Settings page

    This is where additional app or domain specific context can be added to any individual
    commcare-setting defined in commcare-app-settings.yaml or commcare-profile-settings.yaml
    """
    context = {
        'legacy_select2': True,
    }

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout(app.get_doc_type()))
    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get('disable_if_true')
            if disable_if_true and getattr(app, setting['id']):
                continue
            new_settings.append(setting)
        section['settings'] = new_settings

    app_view_options = {
        'permissions': {
            'cloudcare': has_privilege(request, privileges.CLOUDCARE),
        },
        'sections': settings_layout,
        'urls': {
            'save': reverse("edit_commcare_settings",
                            args=(app.domain, app.id)),
        },
        'user': {
            'is_previewer': request.couch_user.is_previewer(),
        },
        'values': get_settings_values(app),
        'warning': _("This is not an allowed value for this field"),
    }
    if (app.get_doc_type() == 'Application'
            and toggles.CUSTOM_PROPERTIES.enabled(request.domain)
            and 'custom_properties' in getattr(app, 'profile', {})):
        custom_properties_array = [{
            'key': p[0],
            'value': p[1]
        } for p in app.profile.get('custom_properties').items()]
        app_view_options.update({'customProperties': custom_properties_array})
    context.update({
        'app_view_options': app_view_options,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser and not toggles.IS_CONTRACTOR.enabled(
            request.user.username):
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    def _get_setting(setting_type, setting_id):
        # get setting dict from settings_layout
        if not settings_layout:
            return None
        matched = [
            x for x in [
                setting for section in settings_layout
                for setting in section['settings']
            ] if x['type'] == setting_type and x['id'] == setting_id
        ]
        if matched:
            return matched[0]
        else:
            return None

    build_spec_setting = _get_setting('hq', 'build_spec')
    if build_spec_setting:
        build_spec_setting['options_map'] = options_map
        build_spec_setting['default_app_version'] = app.application_version

    practice_user_setting = _get_setting('hq', 'practice_mobile_worker_id')
    if practice_user_setting and has_privilege(
            request, privileges.PRACTICE_MOBILE_WORKERS):
        try:
            practice_users = get_practice_mode_mobile_workers(request.domain)
        except ESError:
            notify_exception(request,
                             'Error getting practice mode mobile workers')
            practice_users = []
        practice_user_setting['values'] = [''] + [
            u['_id'] for u in practice_users
        ]
        practice_user_setting['value_names'] = [_('Not set')] + [
            u['username'] for u in practice_users
        ]

    context.update({
        'bulk_ui_translation_upload': {
            'action':
            reverse('upload_bulk_ui_translations',
                    args=(app.domain, app.get_id)),
            'download_url':
            reverse('download_bulk_ui_translations',
                    args=(app.domain, app.get_id)),
            'adjective':
            _("U\u200BI translation"),
            'plural_noun':
            _("U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action':
            reverse('upload_bulk_app_translations',
                    args=(app.domain, app.get_id)),
            'download_url':
            reverse('download_bulk_app_translations',
                    args=(app.domain, app.get_id)),
            'adjective':
            _("app translation"),
            'plural_noun':
            _("app translations"),
            'can_validate_app_translations':
            toggles.VALIDATE_APP_TRANSLATIONS.enabled_for_request(request)
        },
        'bulk_app_multimedia_upload': {
            'action':
            reverse(
                'upload_bulk_app_translations',  # TODO
                args=(app.domain, app.get_id)),
            'download_url':
            reverse('download_bulk_multimedia_translations',
                    args=(app.domain, app.get_id)),
            'adjective':
            _("multimedia"),
            'plural_noun':
            _("multimedia references"),
        },
    })
    context.update({
        'bulk_ui_translation_form':
        get_bulk_upload_form(
            context,
            context_key="bulk_ui_translation_upload",
        ),
        'bulk_app_translation_form':
        get_bulk_upload_form(
            context,
            context_key="bulk_app_translation_upload",
            form_class=AppTranslationsBulkUploadForm,
            app=app,
        ),
        'bulk_multimedia_translation_form':
        get_bulk_upload_form(
            context,
            context_key="bulk_app_multimedia_upload",
            form_class=MultimediaTranslationsBulkUploadForm,
        ),
    })
    context.update({
        'smart_lang_display_enabled':
        getattr(app, 'smart_lang_display', False)
    })
    # Not used in APP_MANAGER_V2
    context['is_app_view'] = True

    if app.get_doc_type() == 'LinkedApplication':
        context['upstream_url'] = _get_upstream_url(app, request.couch_user)
        try:
            context['master_version'] = app.get_master_version()
        except RemoteRequestError:
            pass
    return context
Example #24
0
def get_app_view_context(request, app):

    is_cloudcare_allowed = has_privilege(request, privileges.CLOUDCARE)
    context = {}

    settings_layout = copy.deepcopy(get_commcare_settings_layout(request.domain)[app.get_doc_type()])
    for section in settings_layout:
        new_settings = []
        for setting in section["settings"]:
            toggle_name = setting.get("toggle")
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get("privilege")
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get("disable_if_true")
            if disable_if_true and getattr(app, setting["id"]):
                continue
            new_settings.append(setting)
        section["settings"] = new_settings

    if toggles.CUSTOM_PROPERTIES.enabled(request.domain) and "custom_properties" in app.profile:
        custom_properties_array = map(
            lambda p: {"key": p[0], "value": p[1]}, app.profile.get("custom_properties").items()
        )
        context.update({"custom_properties": custom_properties_array})

    context.update(
        {
            "settings_layout": settings_layout,
            "settings_values": get_settings_values(app),
            "is_cloudcare_allowed": is_cloudcare_allowed,
        }
    )

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser:
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    (build_spec_setting,) = filter(
        lambda x: x["type"] == "hq" and x["id"] == "build_spec",
        [setting for section in context["settings_layout"] for setting in section["settings"]],
    )
    build_spec_setting["options_map"] = options_map
    build_spec_setting["default_app_version"] = app.application_version

    context.update(
        {
            "bulk_ui_translation_upload": {
                "action": reverse("upload_bulk_ui_translations", args=(app.domain, app.get_id)),
                "download_url": reverse("download_bulk_ui_translations", args=(app.domain, app.get_id)),
                "adjective": _(u"U\u200BI translation"),
                "plural_noun": _(u"U\u200BI translations"),
            },
            "bulk_app_translation_upload": {
                "action": reverse("upload_bulk_app_translations", args=(app.domain, app.get_id)),
                "download_url": reverse("download_bulk_app_translations", args=(app.domain, app.get_id)),
                "adjective": _("app translation"),
                "plural_noun": _("app translations"),
            },
        }
    )
    context.update(
        {
            "bulk_ui_translation_form": get_bulk_upload_form(context, context_key="bulk_ui_translation_upload"),
            "bulk_app_translation_form": get_bulk_upload_form(context, context_key="bulk_app_translation_upload"),
        }
    )
    context["is_app_view"] = True
    try:
        context["fetchLimit"] = int(request.GET.get("limit", DEFAULT_FETCH_LIMIT))
    except ValueError:
        context["fetchLimit"] = DEFAULT_FETCH_LIMIT

    return context
Example #25
0
def render_form(form, domain, options):
    """
    Uses options since Django 1.3 doesn't seem to support templatetag kwargs.
    Change to kwargs when we're on a version of Django that does.

    """

    timezone = get_timezone_for_request()
    case_id = options.get('case_id')
    side_pane = options.get('side_pane', False)
    user = options.get('user', None)
    request = options.get('request', None)
    support_enabled = toggle_enabled(request, toggles.SUPPORT)

    _get_tables_as_columns = partial(get_tables_as_columns, timezone=timezone)

    # Form Data tab
    form_data, question_list_not_found = get_readable_data_for_submission(form)

    # Case Changes tab
    case_blocks = extract_case_blocks(form)
    for i, block in enumerate(list(case_blocks)):
        if case_id and block.get(const.CASE_ATTR_ID) == case_id:
            case_blocks.pop(i)
            case_blocks.insert(0, block)

    cases = []
    for b in case_blocks:
        this_case_id = b.get(const.CASE_ATTR_ID)
        try:
            this_case = CaseAccessors(domain).get_case(
                this_case_id) if this_case_id else None
            valid_case = True
        except ResourceNotFound:
            this_case = None
            valid_case = False

        if this_case and this_case.case_id:
            url = reverse('case_details', args=[domain, this_case.case_id])
        else:
            url = "#"

        definition = get_default_definition(
            sorted_case_update_keys(b.keys()),
            assume_phonetimes=(
                not form.metadata
                or (form.metadata.deviceID != CLOUDCARE_DEVICE_ID)),
        )
        cases.append({
            "is_current_case": case_id and this_case_id == case_id,
            "name": case_inline_display(this_case),
            "table": _get_tables_as_columns(b, definition),
            "url": url,
            "valid_case": valid_case
        })

    # Form Metadata tab
    meta = _top_level_tags(form).get('meta', None) or {}
    meta['received_on'] = json_format_datetime(form.received_on)
    if support_enabled:
        meta['last_sync_token'] = form.last_sync_token

    definition = get_default_definition(sorted_form_metadata_keys(meta.keys()))
    form_meta_data = _get_tables_as_columns(meta, definition)
    if getattr(form, 'auth_context', None):
        auth_context = AuthContext(form.auth_context)
        auth_context_user_id = auth_context.user_id
        auth_user_info = get_doc_info_by_id(domain, auth_context_user_id)
    else:
        auth_user_info = get_doc_info_by_id(domain, None)
        auth_context = AuthContext(
            user_id=None,
            authenticated=False,
            domain=domain,
        )
    meta_userID = meta.get('userID')
    meta_username = meta.get('username')
    if meta_userID == 'demo_user':
        user_info = DocInfo(
            domain=domain,
            display='demo_user',
        )
    elif meta_username == 'admin':
        user_info = DocInfo(
            domain=domain,
            display='admin',
        )
    else:
        user_info = get_doc_info_by_id(domain, meta_userID)

    user_can_edit = (request and user and request.domain
                     and (user.can_edit_data() or user.is_commcare_user()))
    show_edit_options = (user_can_edit
                         and can_edit_form_location(domain, user, form))
    show_edit_submission = (user_can_edit
                            and has_privilege(request, privileges.DATA_CLEANUP)
                            and not form.is_deprecated)

    show_resave = (user_can_edit and support_enabled)

    def _get_edit_info(instance):
        info = {
            'was_edited': False,
            'is_edit': False,
        }
        if instance.is_deprecated:
            info.update({
                'was_edited': True,
                'latest_version': instance.orig_id,
            })
        if getattr(instance, 'edited_on', None) and getattr(
                instance, 'deprecated_form_id', None):
            info.update({
                'is_edit': True,
                'edited_on': instance.edited_on,
                'previous_version': instance.deprecated_form_id
            })
        return info

    return render_to_string(
        "reports/form/partials/single_form.html",
        {
            "context_case_id": case_id,
            "instance": form,
            "is_archived": form.is_archived,
            "edit_info": _get_edit_info(form),
            "domain": domain,
            'question_list_not_found': question_list_not_found,
            "form_data": form_data,
            "cases": cases,
            "form_table_options": {
                # todo: wells if display config has more than one column
                "put_loners_in_wells": False
            },
            "form_meta_data": form_meta_data,
            "auth_context": auth_context,
            "auth_user_info": auth_user_info,
            "user_info": user_info,
            "side_pane": side_pane,
            "show_edit_options": show_edit_options,
            "show_edit_submission": show_edit_submission,
            "show_resave": show_resave,
        },
        RequestContext(request))
Example #26
0
def get_app_view_context(request, app):
    """
    This provides the context to render commcare settings on Edit Application Settings page

    This is where additional app or domain specific context can be added to any individual
    commcare-setting defined in commcare-app-settings.yaml or commcare-profile-settings.yaml
    """
    context = {}

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout(app)
    )

    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get('disable_if_true')
            if disable_if_true and getattr(app, setting['id']):
                continue
            if is_linked_app(app):
                if setting['id'] in app.SUPPORTED_SETTINGS:
                    if setting['id'] not in app.linked_app_attrs:
                        setting['is_inherited'] = True
            new_settings.append(setting)
        section['settings'] = new_settings

    app_view_options = {
        'permissions': {
            'cloudcare': has_privilege(request, privileges.CLOUDCARE),
            'case_sharing_groups': has_privilege(request,
                                                 privileges.CASE_SHARING_GROUPS),
        },
        'sections': settings_layout,
        'urls': {
            'save': reverse("edit_commcare_settings", args=(app.domain, app.id)),
        },
        'user': {
            'is_previewer': request.couch_user.is_previewer(),
        },
        'values': get_settings_values(app),
        'warning': _("This is not an allowed value for this field"),
    }
    if (app.get_doc_type() == 'Application'
            and toggles.CUSTOM_PROPERTIES.enabled(request.domain)
            and 'custom_properties' in getattr(app, 'profile', {})):
        custom_properties_array = [{'key': p[0], 'value': p[1]} for p in app.profile.get('custom_properties').items()]
        app_view_options.update({'customProperties': custom_properties_array})
    context.update({
        'app_view_options': app_view_options,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser and not toggles.IS_CONTRACTOR.enabled(request.user.username):
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    def _get_setting(setting_type, setting_id):
        # get setting dict from settings_layout
        if not settings_layout:
            return None
        matched = [x for x in [
                setting for section in settings_layout
                for setting in section['settings']
            ] if x['type'] == setting_type and x['id'] == setting_id]
        if matched:
            return matched[0]
        else:
            return None

    build_spec_setting = _get_setting('hq', 'build_spec')
    if build_spec_setting:
        build_spec_setting['options_map'] = options_map
        build_spec_setting['default_app_version'] = app.application_version

    practice_user_setting = _get_setting('hq', 'practice_mobile_worker_id')
    if practice_user_setting and has_privilege(request, privileges.PRACTICE_MOBILE_WORKERS):
        try:
            practice_users = get_practice_mode_mobile_workers(request.domain)
        except ESError:
            notify_exception(request, 'Error getting practice mode mobile workers')
            practice_users = []
        practice_user_setting['values'] = [''] + [u['_id'] for u in practice_users]
        practice_user_setting['value_names'] = [_('Not set')] + [u['username'] for u in practice_users]

    context.update({
        'bulk_ui_translation_upload': {
            'action': reverse('upload_bulk_ui_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_ui_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("U\u200BI translation"),
            'plural_noun': _("U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action': reverse('upload_bulk_app_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_app_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("app translation"),
            'plural_noun': _("app translations"),
            'can_select_language': toggles.BULK_UPDATE_MULTIMEDIA_PATHS.enabled_for_request(request),
            'can_validate_app_translations': toggles.VALIDATE_APP_TRANSLATIONS.enabled_for_request(request),
        },
    })
    context.update({
        'bulk_ui_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_ui_translation_upload",
        ),
        'bulk_app_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_app_translation_upload",
            form_class=AppTranslationsBulkUploadForm,
        ),
    })
    context.update({
        'smart_lang_display_enabled': getattr(app, 'smart_lang_display', False)
    })

    context.update({
        'is_linked_app': is_linked_app(app),
        'is_remote_app': is_remote_app(app),
    })
    if is_linked_app(app):
        try:
            master_versions_by_id = app.get_latest_master_releases_versions()
            master_briefs = [brief for brief in app.get_master_app_briefs() if brief.id in master_versions_by_id]
        except RemoteRequestError:
            messages.error(request, "Unable to reach remote master server. Please try again later.")
            master_versions_by_id = {}
            master_briefs = []
        upstream_brief = {}
        for b in master_briefs:
            if b.id == app.upstream_app_id:
                upstream_brief = b
        context.update({
            'master_briefs': master_briefs,
            'master_versions_by_id': master_versions_by_id,
            'multiple_masters': app.enable_multi_master and len(master_briefs) > 1,
            'upstream_version': app.upstream_version,
            'upstream_brief': upstream_brief,
            'upstream_url': _get_upstream_url(app, request.couch_user),
            'upstream_url_template': _get_upstream_url(app, request.couch_user, master_app_id='---'),
        })
    return context
Example #27
0
def has_report_builder_access(request):
    builder_enabled = toggle_enabled(request, toggles.REPORT_BUILDER)
    builder_privileges = has_privilege(request, privileges.REPORT_BUILDER)
    beta_group_enabled = toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP)

    return (builder_enabled and builder_privileges) or beta_group_enabled
Example #28
0
def get_app_view_context(request, app):
    """
    This provides the context to render commcare settings on Edit Application Settings page

    This is where additional app or domain specific context can be added to any individual
    commcare-setting defined in commcare-app-settings.yaml or commcare-profile-settings.yaml
    """
    context = {}

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout(app.get_doc_type())
    )
    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get('disable_if_true')
            if disable_if_true and getattr(app, setting['id']):
                continue
            if app.get_doc_type() == 'LinkedApplication':
                if setting['id'] in app.SUPPORTED_SETTINGS:
                    if setting['id'] not in app.linked_app_attrs:
                        setting['is_inherited'] = True
            new_settings.append(setting)
        section['settings'] = new_settings

    app_view_options = {
        'permissions': {
            'cloudcare': has_privilege(request, privileges.CLOUDCARE),
        },
        'sections': settings_layout,
        'urls': {
            'save': reverse("edit_commcare_settings", args=(app.domain, app.id)),
        },
        'user': {
            'is_previewer': request.couch_user.is_previewer(),
        },
        'values': get_settings_values(app),
        'warning': _("This is not an allowed value for this field"),
    }
    if (app.get_doc_type() == 'Application'
            and toggles.CUSTOM_PROPERTIES.enabled(request.domain)
            and 'custom_properties' in getattr(app, 'profile', {})):
        custom_properties_array = [{'key': p[0], 'value': p[1]} for p in app.profile.get('custom_properties').items()]
        app_view_options.update({'customProperties': custom_properties_array})
    context.update({
        'app_view_options': app_view_options,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser and not toggles.IS_CONTRACTOR.enabled(request.user.username):
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    def _get_setting(setting_type, setting_id):
        # get setting dict from settings_layout
        if not settings_layout:
            return None
        matched = [x for x in [
                setting for section in settings_layout
                for setting in section['settings']
            ] if x['type'] == setting_type and x['id'] == setting_id]
        if matched:
            return matched[0]
        else:
            return None

    build_spec_setting = _get_setting('hq', 'build_spec')
    if build_spec_setting:
        build_spec_setting['options_map'] = options_map
        build_spec_setting['default_app_version'] = app.application_version

    practice_user_setting = _get_setting('hq', 'practice_mobile_worker_id')
    if practice_user_setting and has_privilege(request, privileges.PRACTICE_MOBILE_WORKERS):
        try:
            practice_users = get_practice_mode_mobile_workers(request.domain)
        except ESError:
            notify_exception(request, 'Error getting practice mode mobile workers')
            practice_users = []
        practice_user_setting['values'] = [''] + [u['_id'] for u in practice_users]
        practice_user_setting['value_names'] = [_('Not set')] + [u['username'] for u in practice_users]

    context.update({
        'bulk_ui_translation_upload': {
            'action': reverse('upload_bulk_ui_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_ui_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("U\u200BI translation"),
            'plural_noun': _("U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action': reverse('upload_bulk_app_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_app_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("app translation"),
            'plural_noun': _("app translations"),
            'can_select_language': toggles.BULK_UPDATE_MULTIMEDIA_PATHS.enabled_for_request(request),
            'can_validate_app_translations': toggles.VALIDATE_APP_TRANSLATIONS.enabled_for_request(request),
        },
    })
    context.update({
        'bulk_ui_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_ui_translation_upload",
        ),
        'bulk_app_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_app_translation_upload",
            form_class=AppTranslationsBulkUploadForm,
        ),
    })
    context.update({
        'smart_lang_display_enabled': getattr(app, 'smart_lang_display', False)
    })
    # Not used in APP_MANAGER_V2
    context['is_app_view'] = True

    if app.get_doc_type() == 'LinkedApplication':
        context['upstream_url'] = _get_upstream_url(app, request.couch_user)
        try:
            context['master_version'] = app.get_master_version()
        except RemoteRequestError:
            pass
    return context
Example #29
0
def get_app_view_context(request, app):
    """
    This provides the context to render commcare settings on Edit Application Settings page

    This is where additional app or domain specific context can be added to any individual
    commcare-setting defined in commcare-app-settings.yaml or commcare-profile-settings.yaml
    """
    context = {}

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout(request.user)[app.get_doc_type()]
    )
    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            disable_if_true = setting.get('disable_if_true')
            if disable_if_true and getattr(app, setting['id']):
                continue
            new_settings.append(setting)
        section['settings'] = new_settings

    app_view_options = {
        'permissions': {
            'cloudcare': has_privilege(request, privileges.CLOUDCARE),
        },
        'sections': settings_layout,
        'urls': {
            'save': reverse("edit_commcare_settings", args=(app.domain, app.id)),
        },
        'user': {
            'is_previewer': request.couch_user.is_previewer(),
        },
        'values': get_settings_values(app),
        'warning': _("This is not an allowed value for this field"),
    }
    if toggles.CUSTOM_PROPERTIES.enabled(request.domain) and 'custom_properties' in getattr(app, 'profile', {}):
        custom_properties_array = map(lambda p: {'key': p[0], 'value': p[1]},
                                      app.profile.get('custom_properties').items())
        app_view_options.update({'customProperties': custom_properties_array})
    context.update({
        'app_view_options': app_view_options,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser:
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    def _get_setting(setting_type, setting_id):
        # get setting dict from settings_layout
        if not settings_layout:
            return None
        matched = filter(
            lambda x: x['type'] == setting_type and x['id'] == setting_id,
            [
                setting for section in settings_layout
                for setting in section['settings']
            ]
        )
        if matched:
            return matched[0]
        else:
            return None

    build_spec_setting = _get_setting('hq', 'build_spec')
    if build_spec_setting:
        build_spec_setting['options_map'] = options_map
        build_spec_setting['default_app_version'] = app.application_version

    practice_user_setting = _get_setting('hq', 'practice_mobile_worker_id')
    if practice_user_setting and has_privilege(request, privileges.PRACTICE_MOBILE_WORKERS):
        try:
            practice_users = get_practice_mode_mobile_workers(request.domain)
        except ESError:
            notify_exception(request, 'Error getting practice mode mobile workers')
            practice_users = []
        practice_user_setting['values'] = [''] + [u['_id'] for u in practice_users]
        practice_user_setting['value_names'] = [_('Not set')] + [u['username'] for u in practice_users]

    context.update({
        'bulk_ui_translation_upload': {
            'action': reverse('upload_bulk_ui_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_ui_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _(u"U\u200BI translation"),
            'plural_noun': _(u"U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action': reverse('upload_bulk_app_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_app_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("app translation"),
            'plural_noun': _("app translations"),
        },
    })
    context.update({
        'bulk_ui_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_ui_translation_upload"
        ),
        'bulk_app_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_app_translation_upload"
        )
    })
    # Not used in APP_MANAGER_V2
    context['is_app_view'] = True
    try:
        context['fetchLimit'] = int(request.GET.get('limit', DEFAULT_FETCH_LIMIT))
    except ValueError:
        context['fetchLimit'] = DEFAULT_FETCH_LIMIT

    if app.get_doc_type() == 'LinkedApplication':
        context['master_version'] = get_app(None, app.master, latest=True).version
    return context
Example #30
0
def get_app_view_context(request, app):

    is_cloudcare_allowed = has_privilege(request, privileges.CLOUDCARE)
    context = {}

    settings_layout = copy.deepcopy(
        get_commcare_settings_layout()[app.get_doc_type()])
    for section in settings_layout:
        new_settings = []
        for setting in section['settings']:
            toggle_name = setting.get('toggle')
            if toggle_name and not toggle_enabled(request, toggle_name):
                continue
            privilege_name = setting.get('privilege')
            if privilege_name and not has_privilege(request, privilege_name):
                continue
            new_settings.append(setting)
        section['settings'] = new_settings

    if toggles.CUSTOM_PROPERTIES.enabled(request.domain) and 'custom_properties' in app.profile:
        custom_properties_array = map(lambda p: {'key': p[0], 'value': p[1]},
                                      app.profile.get('custom_properties').items())
        context.update({'custom_properties': custom_properties_array})

    context.update({
        'settings_layout': settings_layout,
        'settings_values': get_settings_values(app),
        'is_cloudcare_allowed': is_cloudcare_allowed,
    })

    build_config = CommCareBuildConfig.fetch()
    options = build_config.get_menu()
    if not request.user.is_superuser:
        options = [option for option in options if not option.superuser_only]
    options_map = defaultdict(lambda: {"values": [], "value_names": []})
    for option in options:
        builds = options_map[option.build.major_release()]
        builds["values"].append(option.build.to_string())
        builds["value_names"].append(option.get_label())
        if "default" not in builds:
            app_ver = MAJOR_RELEASE_TO_VERSION[option.build.major_release()]
            builds["default"] = build_config.get_default(app_ver).to_string()

    (build_spec_setting,) = filter(
        lambda x: x['type'] == 'hq' and x['id'] == 'build_spec',
        [setting for section in context['settings_layout']
            for setting in section['settings']]
    )
    build_spec_setting['options_map'] = options_map
    build_spec_setting['default_app_version'] = app.application_version

    context.update({
        'bulk_ui_translation_upload': {
            'action': reverse('upload_bulk_ui_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_ui_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _(u"U\u200BI translation"),
            'plural_noun': _(u"U\u200BI translations"),
        },
        'bulk_app_translation_upload': {
            'action': reverse('upload_bulk_app_translations',
                              args=(app.domain, app.get_id)),
            'download_url': reverse('download_bulk_app_translations',
                                    args=(app.domain, app.get_id)),
            'adjective': _("app translation"),
            'plural_noun': _("app translations"),
        },
    })
    context.update({
        'bulk_ui_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_ui_translation_upload"
        ),
        'bulk_app_translation_form': get_bulk_upload_form(
            context,
            context_key="bulk_app_translation_upload"
        )
    })
    context['is_app_view'] = True
    return context