Ejemplo n.º 1
0
    def update_linked_model(self, in_data):
        model = in_data['model']
        type_ = model['type']
        detail = model['detail']
        detail_obj = wrap_detail(type_, detail) if detail else None

        master_link = get_domain_master_link(self.domain)
        error = ""
        try:
            update_model_type(master_link, type_, detail_obj)
            model_detail = detail_obj.to_json() if detail_obj else None
            master_link.update_last_pull(type_,
                                         self.request.couch_user._id,
                                         model_detail=model_detail)
        except (DomainLinkError, UnsupportedActionError) as e:
            error = str(e)

        track_workflow(self.request.couch_user.username,
                       "Linked domain: updated '{}' model".format(type_))

        timezone = get_timezone_for_request()
        return {
            'success': not error,
            'error': error,
            'last_update': server_to_user_time(master_link.last_pull, timezone)
        }
Ejemplo n.º 2
0
def case_upload_to_user_json(case_upload, request):
    domain = case_upload.domain
    tz = get_timezone_for_request(request)

    return CaseUploadJSON(
        domain=case_upload.domain,
        created_display=ServerTime(
            case_upload.created).user_time(tz).ui_string(),
        created=json_format_datetime(case_upload.created),
        upload_id=str(case_upload.upload_id),
        task_status=case_upload.get_task_status_json(),
        user_name=get_display_name_for_user_id(domain,
                                               case_upload.couch_user_id,
                                               default=''),
        case_type=case_upload.case_type,
        comment=case_upload.comment,
        upload_file_name=(case_upload.upload_file_meta.filename
                          if case_upload.upload_file_meta else None),
        upload_file_length=(case_upload.upload_file_meta.length
                            if case_upload.upload_file_meta else None),
        upload_file_download_allowed=user_may_view_file_upload(
            domain, request.couch_user, case_upload),
        upload_comment_edit_allowed=user_may_update_comment(
            request.couch_user, case_upload),
    )
Ejemplo n.º 3
0
    def page_context(self):
        """
        This view services both domains that are master domains and domains that are linked domains
        (and legacy domains that are both).
        """
        timezone = get_timezone_for_request()
        master_link = get_domain_master_link(self.domain)
        linked_domains = [self._link_context(link, timezone) for link in get_linked_domains(self.domain)]
        (master_apps, linked_apps) = self._get_apps()
        (master_reports, linked_reports) = self._get_reports()

        # Models belonging to this domain's master domain, for the purpose of pulling
        model_status = self._get_model_status(master_link, linked_apps, linked_reports)

        # Models belonging to this domain, for the purpose of pushing to linked domains
        master_model_status = self._get_master_model_status(master_apps, master_reports)

        return {
            'domain': self.domain,
            'timezone': timezone.localize(datetime.utcnow()).tzname(),
            'is_linked_domain': bool(master_link),
            'is_master_domain': bool(len(linked_domains)),
            'view_data': {
                'master_link': self._link_context(master_link, timezone) if master_link else None,
                'model_status': sorted(model_status, key=lambda m: m['name']),
                'master_model_status': sorted(master_model_status, key=lambda m: m['name']),
                'linked_domains': linked_domains,
                'models': [
                    {'slug': model[0], 'name': model[1]}
                    for model in LINKED_MODELS
                ]
            },
        }
Ejemplo n.º 4
0
 def get_formatted_response(self):
     timezone = get_timezone_for_request()
     if self.type == 'DateTime' and timezone \
             and isinstance(self.response, datetime.datetime):
         return (PhoneTime(self.response, timezone).user_time(timezone)
                 .ui_string())
     else:
         return self.response
Ejemplo n.º 5
0
 def get_formatted_response(self):
     timezone = get_timezone_for_request()
     if self.type == 'DateTime' and timezone \
             and isinstance(self.response, datetime.datetime):
         return (PhoneTime(self.response, timezone).user_time(timezone)
                 .ui_string())
     else:
         return self.response
Ejemplo n.º 6
0
def build_pullable_view_models_from_data_models(domain, upstream_link, apps, fixtures, reports, keywords):
    """
    Data models that originated in this domain's upstream domain that are available to pull
    :return: list of view models (dicts) used to render linked data models that can be pulled
    """
    linked_data_view_models = []

    if not upstream_link:
        return linked_data_view_models

    models_seen = set()
    timezone = get_timezone_for_request()
    history = get_actions_in_domain_link_history(upstream_link)
    for action in history:
        if action.row_number != 1:
            # first row is the most recent
            continue

        models_seen.add(action.model)
        last_update = server_to_user_time(action.date, timezone)

        if action.model == MODEL_APP:
            app = pop_app_for_action(action, apps)
            view_model = build_app_view_model(app, last_update=last_update)

        elif action.model == MODEL_FIXTURE:
            fixture = pop_fixture_for_action(action, fixtures, domain)
            view_model = build_fixture_view_model(fixture, last_update=last_update)

        elif action.model == MODEL_REPORT:
            report = pop_report_for_action(action, reports)
            view_model = build_report_view_model(report, last_update=last_update)

        elif action.model == MODEL_KEYWORD:
            keyword = pop_keyword_for_action(action, keywords)
            view_model = build_keyword_view_model(keyword, last_update=last_update)

        else:
            view_model = build_linked_data_view_model(
                model_type=action.model,
                name=LINKED_MODELS_MAP[action.model],
                detail=action.model_detail,
                last_update=last_update,
            )

        linked_data_view_models.append(view_model)

    # Add data models that have never been pulled into the downstream domain before
    # ignoring any models we have already added via domain history
    linked_data_view_models.extend(
        build_view_models_from_data_models(
            domain, apps, fixtures, reports, keywords, ignore_models=models_seen)
    )

    return linked_data_view_models
Ejemplo n.º 7
0
    def create_domain_link(self, in_data):
        domain_to_link = in_data['downstream_domain']
        try:
            domain_link = link_domains(self.request.couch_user, self.domain, domain_to_link)
        except (DomainDoesNotExist, DomainLinkAlreadyExists, DomainLinkNotAllowed, DomainLinkError) as e:
            return {'success': False, 'message': str(e)}

        track_workflow(self.request.couch_user.username, "Linked domain: domain link created")

        domain_link_view_model = build_domain_link_view_model(domain_link, get_timezone_for_request())
        return {'success': True, 'domain_link': domain_link_view_model}
Ejemplo n.º 8
0
    def _get_model_status(self, master_link, apps, reports):
        model_status = []
        if not master_link:
            return model_status

        models_seen = set()
        history = DomainLinkHistory.objects.filter(link=master_link).annotate(row_number=RawSQL(
            'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
            []
        ))
        linked_models = dict(LINKED_MODELS)
        timezone = get_timezone_for_request()
        for action in history:
            models_seen.add(action.model)
            if action.row_number != 1:
                # first row is the most recent
                continue
            name = linked_models[action.model]
            update = {
                'type': action.model,
                'name': name,
                'last_update': server_to_user_time(action.date, timezone),
                'detail': action.model_detail,
                'can_update': True
            }
            if action.model == 'app':
                app_name = ugettext('Unknown App')
                if action.model_detail:
                    detail = action.wrapped_detail
                    app = apps.pop(detail.app_id, None)
                    app_name = app.name if app else detail.app_id
                    if app:
                        update['detail'] = action.model_detail
                    else:
                        update['can_update'] = False
                else:
                    update['can_update'] = False
                update['name'] = '{} ({})'.format(name, app_name)
            model_status.append(update)
            if action.model == 'report':
                report_id = action.wrapped_detail.report_id
                try:
                    report = reports.get(report_id)
                    del reports[report_id]
                except KeyError:
                    report = ReportConfiguration.get(report_id)
                update['name'] = f'{name} ({report.title})'

        # Add in models and apps that have never been synced
        model_status.extend(self._get_master_model_status(apps, reports, ignore_models=models_seen))

        return model_status
Ejemplo n.º 9
0
def _get_cases_changed_context(domain, form, case_id=None):
    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,
                                  timezone=get_timezone_for_request()),
            "url":
            url,
            "valid_case":
            valid_case,
            "case_type":
            this_case.type if valid_case else None,
        })

    return {'cases': cases}
Ejemplo n.º 10
0
    def update_linked_model(self, in_data):
        model = in_data['model']
        type_ = model['type']
        detail = model['detail']
        detail_obj = wrap_detail(type_, detail) if detail else None

        master_link = get_domain_master_link(self.domain)
        update_model_type(master_link, type_, detail_obj)
        master_link.update_last_pull(type_, self.request.couch_user._id, model_details=detail_obj)

        track_workflow(self.request.couch_user.username, "Linked domain: updated '{}' model".format(type_))

        timezone = get_timezone_for_request()
        return {
            'success': True,
            'last_update': server_to_user_time(master_link.last_pull, timezone)
        }
Ejemplo n.º 11
0
    def update_linked_model(self, in_data):
        model = in_data['model']
        type_ = model['type']
        detail = model['detail']
        detail_obj = wrap_detail(type, detail) if detail else None

        master_link = get_domain_master_link(self.domain)
        update_model_type(master_link, type_, detail_obj)
        master_link.update_last_pull(type_, self.request.couch_user._id, model_details=detail_obj)

        track_workflow(self.request.couch_user.username, "Linked domain: updated '{}' model".format(type_))

        timezone = get_timezone_for_request()
        return {
            'success': True,
            'last_update': server_to_user_time(master_link.last_pull, timezone)
        }
Ejemplo n.º 12
0
def _get_form_metadata_context(domain, form, support_enabled=False):
    meta = _top_level_tags(form).get('meta', None) or {}
    meta['received_on'] = json_format_datetime(form.received_on)
    meta['server_modified_on'] = json_format_datetime(
        form.server_modified_on) if form.server_modified_on else ''
    if support_enabled:
        meta['last_sync_token'] = form.last_sync_token

    definition = get_default_definition(sorted_form_metadata_keys(list(meta)))
    form_meta_data = get_tables_as_columns(meta,
                                           definition,
                                           timezone=get_timezone_for_request())
    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)

    return {
        "form_meta_data": form_meta_data,
        "auth_context": auth_context,
        "auth_user_info": auth_user_info,
        "user_info": user_info,
    }
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
def case_upload_to_user_json(case_upload, request):
    domain = case_upload.domain
    tz = get_timezone_for_request(request)

    return CaseUploadJSON(
        domain=case_upload.domain,
        created=ServerTime(case_upload.created).user_time(tz).ui_string(),
        upload_id=str(case_upload.upload_id),
        task_status=case_upload.get_task_status_json(),
        user_name=get_display_name_for_user_id(
            domain, case_upload.couch_user_id, default=''),
        case_type=case_upload.case_type,
        comment=case_upload.comment,
        upload_file_name=(case_upload.upload_file_meta.filename
                          if case_upload.upload_file_meta else None),
        upload_file_length=(case_upload.upload_file_meta.length
                            if case_upload.upload_file_meta else None),
        upload_file_download_allowed=user_may_view_file_upload(
            domain, request.couch_user, case_upload),
        upload_comment_edit_allowed=user_may_update_comment(
            request.couch_user, case_upload),
    )
Ejemplo n.º 15
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))
Ejemplo n.º 16
0
    def page_context(self):
        """
        This view services both domains that are upstream, downstream, and legacy domains that are both
        """
        timezone = get_timezone_for_request()
        upstream_link = get_upstream_domain_link(self.domain)
        linked_domains = [build_domain_link_view_model(link, timezone) for link in get_linked_domains(self.domain)]
        upstream_apps, downstream_apps = get_upstream_and_downstream_apps(self.domain)
        upstream_fixtures, downstream_fixtures = get_upstream_and_downstream_fixtures(self.domain, upstream_link)
        upstream_reports, downstream_reports = get_upstream_and_downstream_reports(self.domain)
        upstream_keywords, downstream_keywords = get_upstream_and_downstream_keywords(self.domain)
        upstream_ucr_expressions, downstream_ucr_expressions = get_upstream_and_downstream_ucr_expressions(
            self.domain
        )

        is_superuser = self.request.couch_user.is_superuser
        timezone = get_timezone_for_request()
        view_models_to_pull = build_pullable_view_models_from_data_models(
            self.domain,
            upstream_link,
            downstream_apps,
            downstream_fixtures,
            downstream_reports,
            downstream_keywords,
            downstream_ucr_expressions,
            timezone,
            is_superuser=is_superuser
        )

        view_models_to_push = build_view_models_from_data_models(
            self.domain,
            upstream_apps,
            upstream_fixtures,
            upstream_reports,
            upstream_keywords,
            upstream_ucr_expressions,
            is_superuser=is_superuser
        )

        available_domains_to_link = get_available_domains_to_link(self.request.domain, self.request.couch_user)

        upstream_domain_urls = []
        for domain in get_available_upstream_domains(self.request.domain, self.request.couch_user):
            upstream_domain_urls.append({'name': domain, 'url': reverse('domain_links', args=[domain])})

        if upstream_link and upstream_link.is_remote:
            remote_linkable_ucr = get_remote_linkable_ucr(upstream_link)
        else:
            remote_linkable_ucr = None

        return {
            'domain': self.domain,
            'timezone': timezone.localize(datetime.utcnow()).tzname(),
            'view_data': {
                'is_superuser': is_superuser,
                'is_downstream_domain': bool(upstream_link),
                'upstream_domains': upstream_domain_urls,
                'available_domains': available_domains_to_link,
                'upstream_link': build_domain_link_view_model(upstream_link, timezone) if upstream_link else None,
                'view_models_to_pull': sorted(view_models_to_pull, key=lambda m: m['name']),
                'view_models_to_push': sorted(view_models_to_push, key=lambda m: m['name']),
                'linked_domains': sorted(linked_domains, key=lambda d: d['downstream_domain']),
                'linkable_ucr': remote_linkable_ucr,
                'has_full_access': can_domain_access_linked_domains(self.domain, include_lite_version=False),
            },
        }
Ejemplo n.º 17
0
    def page_context(self):
        timezone = get_timezone_for_request()

        def _link_context(link, timezone=timezone):
            return {
                'linked_domain': link.linked_domain,
                'master_domain': link.qualified_master,
                'remote_base_url': link.remote_base_url,
                'is_remote': link.is_remote,
                'last_update': server_to_user_time(link.last_pull, timezone) if link.last_pull else 'Never',
            }

        model_status = []
        linked_models = dict(LINKED_MODELS)
        master_link = get_domain_master_link(self.domain)
        if master_link:
            linked_apps = {
                app._id: app for app in get_brief_apps_in_domain(self.domain)
                if app.doc_type == 'LinkedApplication'
            }
            models_seen = set()
            history = DomainLinkHistory.objects.filter(link=master_link).annotate(row_number=RawSQL(
                'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
                []
            ))
            for action in history:
                models_seen.add(action.model)
                if action.row_number != 1:
                    # first row is the most recent
                    continue
                name = linked_models[action.model]
                update = {
                    'type': action.model,
                    'name': name,
                    'last_update': server_to_user_time(action.date, timezone),
                    'detail': action.model_detail,
                    'can_update': True
                }
                if action.model == 'app':
                    app_name = 'Unknown App'
                    if action.model_detail:
                        detail = action.wrapped_detail
                        app = linked_apps.pop(detail.app_id, None)
                        app_name = app.name if app else detail.app_id
                        if app:
                            update['detail'] = action.model_detail
                        else:
                            update['can_update'] = False
                    else:
                        update['can_update'] = False
                    update['name'] = '{} ({})'.format(name, app_name)
                model_status.append(update)

            # Add in models that have never been synced
            for model, name in LINKED_MODELS:
                if model not in models_seen and model != 'app':
                    model_status.append({
                        'type': model,
                        'name': name,
                        'last_update': ugettext('Never'),
                        'detail': None,
                        'can_update': True
                    })

            # Add in apps that have never been synced
            if linked_apps:
                for app in linked_apps.values():
                    update = {
                        'type': 'app',
                        'name': '{} ({})'.format(linked_models['app'], app.name),
                        'last_update': None,
                        'detail': AppLinkDetail(app_id=app._id).to_json(),
                        'can_update': True
                    }
                    model_status.append(update)

        return {
            'domain': self.domain,
            'timezone': timezone.localize(datetime.utcnow()).tzname(),
            'view_data': {
                'master_link': _link_context(master_link) if master_link else None,
                'model_status': sorted(model_status, key=lambda m: m['name']),
                'linked_domains': [
                    _link_context(link) for link in get_linked_domains(self.domain)
                ],
                'models': [
                    {'slug': model[0], 'name': model[1]}
                    for model in LINKED_MODELS
                ]
            },
        }
Ejemplo n.º 18
0
    def _get_model_status(self, master_link, apps, fixtures, reports,
                          keywords):
        model_status = []
        if not master_link:
            return model_status

        models_seen = set()
        history = DomainLinkHistory.objects.filter(
            link=master_link
        ).annotate(row_number=RawSQL(
            'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
            []))
        linked_models = dict(LINKED_MODELS)
        timezone = get_timezone_for_request()
        for action in history:
            models_seen.add(action.model)
            if action.row_number != 1:
                # first row is the most recent
                continue
            name = linked_models[action.model]
            update = {
                'type': action.model,
                'name': name,
                'last_update': server_to_user_time(action.date, timezone),
                'detail': action.model_detail,
                'can_update': True
            }
            if action.model == 'app':
                app_name = ugettext('Unknown App')
                if action.model_detail:
                    detail = action.wrapped_detail
                    app = apps.pop(detail.app_id, None)
                    app_name = app.name if app else detail.app_id
                    if app:
                        update['detail'] = action.model_detail
                    else:
                        update['can_update'] = False
                else:
                    update['can_update'] = False
                update['name'] = '{} ({})'.format(name, app_name)

            if action.model == 'fixture':
                tag_name = ugettext('Unknown Table')
                can_update = False
                if action.model_detail:
                    detail = action.wrapped_detail
                    tag = action.wrapped_detail.tag
                    try:
                        fixture = fixtures.get(tag)
                        del fixtures[tag]
                    except KeyError:
                        fixture = get_fixture_data_type_by_tag(
                            self.domain, tag)
                    tag_name = fixture.tag
                    can_update = fixture.is_global
                update['name'] = f'{name} ({tag_name})'
                update['can_update'] = can_update
            if action.model == 'report':
                report_id = action.wrapped_detail.report_id
                try:
                    report = reports.get(report_id)
                    del reports[report_id]
                except KeyError:
                    report = ReportConfiguration.get(report_id)
                update['name'] = f'{name} ({report.title})'
            if action.model == 'keyword':
                keyword_id = action.wrapped_detail.linked_keyword_id
                try:
                    keyword = keywords[keyword_id].keyword
                    del keywords[keyword_id]
                except KeyError:
                    try:
                        keyword = Keyword.objects.get(id=keyword_id).keyword
                    except Keyword.DoesNotExist:
                        keyword = ugettext_lazy("Deleted Keyword")
                        update['can_update'] = False
                update['name'] = f'{name} ({keyword})'

            model_status.append(update)

        # Add in models and apps that have never been synced
        model_status.extend(
            self._get_master_model_status(apps,
                                          fixtures,
                                          reports,
                                          keywords,
                                          ignore_models=models_seen))

        return model_status
Ejemplo n.º 19
0
    def page_context(self):
        timezone = get_timezone_for_request()

        def _link_context(link, timezone=timezone):
            return {
                'linked_domain':
                link.linked_domain,
                'master_domain':
                link.master_domain,
                'remote_base_url':
                link.remote_base_url,
                'remote_username':
                link.remote_username,
                'remote_api_key':
                link.remote_api_key,
                'is_remote':
                link.is_remote,
                'last_update':
                server_to_user_time(link.last_pull, timezone)
                if link.last_pull else 'Never',
            }

        model_status = []
        linked_models = dict(LINKED_MODELS)
        master_link = get_domain_master_link(self.domain)
        if master_link:
            linked_apps = {
                app._id: app
                for app in get_brief_apps_in_domain(self.domain)
                if app.doc_type == 'LinkedApplication'
            }
            models_seen = set()
            history = DomainLinkHistory.objects.filter(
                link=master_link
            ).annotate(row_number=RawSQL(
                'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
                []))
            for action in history:
                models_seen.add(action.model)
                if action.row_number != 1:
                    # first row is the most recent
                    continue
                name = linked_models[action.model]
                update = {
                    'type': action.model,
                    'name': name,
                    'last_update': server_to_user_time(action.date, timezone),
                    'detail': action.model_detail,
                    'can_update': True
                }
                if action.model == 'app':
                    app_name = 'Unknown App'
                    if action.model_detail:
                        detail = action.wrapped_detail
                        app = linked_apps.pop(detail.app_id, None)
                        app_name = app.name if app else detail.app_id
                        if app:
                            update['detail'] = action.model_detail
                        else:
                            update['can_update'] = False
                    else:
                        update['can_update'] = False
                    update['name'] = '{} ({})'.format(name, app_name)
                model_status.append(update)

            # Add in models that have never been synced
            for model, name in LINKED_MODELS:
                if model not in models_seen and model != 'app':
                    model_status.append({
                        'type': model,
                        'name': name,
                        'last_update': ugettext('Never'),
                        'detail': None,
                        'can_update': True
                    })

            # Add in apps that have never been synced
            if linked_apps:
                for app in linked_apps.values():
                    update = {
                        'type': 'app',
                        'name': '{} ({})'.format(linked_models['app'],
                                                 app.name),
                        'last_update': None,
                        'detail': AppLinkDetail(app_id=app._id).to_json(),
                        'can_update': True
                    }
                    model_status.append(update)

        return {
            'domain': self.domain,
            'timezone': timezone.localize(datetime.utcnow()).tzname(),
            'view_data': {
                'master_link':
                _link_context(master_link) if master_link else None,
                'model_status':
                sorted(model_status, key=lambda m: m['name']),
                'linked_domains': [
                    _link_context(link)
                    for link in get_linked_domains(self.domain)
                ],
                'models': [{
                    'slug': model[0],
                    'name': model[1]
                } for model in LINKED_MODELS]
            },
        }
Ejemplo n.º 20
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))