Skip to content

Views

hypha.apply.funds.views

User module-attribute

User = get_user_model()

SubmissionStatsMixin

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    submissions = ApplicationSubmission.objects.exclude_draft()
    # Getting values is an expensive operation. If there's no valid filters
    # then `count_values` & `total_value` will be encapsulating all submissions
    # and should be used rather than recaluclating these values.
    if not (filter := kwargs.get("filter")) or not is_filter_empty(filter):
        submission_count = kwargs.get("count_values")
        submission_sum = kwargs.get("total_value")
    else:
        submission_count = submissions.count()
        submission_value = submissions.current().value()
        submission_sum = format_submission_sum_value(submission_value)

    submission_undetermined_count = submissions.undetermined().count()
    review_my_count = submissions.reviewed_by(self.request.user).count()

    submission_accepted = submissions.current_accepted()
    submission_accepted_value = submission_accepted.value()
    submission_accepted_sum = format_submission_sum_value(submission_accepted_value)
    submission_accepted_count = submission_accepted.count()

    reviews = Review.objects.submitted()
    review_count = reviews.count()
    review_my_score = reviews.by_user(self.request.user).score()

    return super().get_context_data(
        submission_undetermined_count=submission_undetermined_count,
        review_my_count=review_my_count,
        submission_sum=submission_sum,
        submission_count=submission_count,
        submission_accepted_count=submission_accepted_count,
        submission_accepted_sum=submission_accepted_sum,
        review_count=review_count,
        review_my_score=review_my_score,
        **kwargs,
    )

BaseAdminSubmissionsTable

Bases: SingleTableMixin, FilterView

table_class class-attribute instance-attribute

table_class = AdminSubmissionsTable

filterset_class class-attribute instance-attribute

filterset_class = SubmissionFilterAndSearch

filter_action class-attribute instance-attribute

filter_action = ''

search_action class-attribute instance-attribute

search_action = ''

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

get_table_kwargs

get_table_kwargs(**kwargs)
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self, **kwargs):
    return {**self.excluded, **kwargs}

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    new_kwargs = super().get_filterset_kwargs(filterset_class)
    new_kwargs.update(self.excluded)
    new_kwargs.update(kwargs)
    return new_kwargs

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    submissions = self.filterset_class._meta.model.objects.current().for_table(
        self.request.user
    )

    if not can_access_drafts(self.request.user):
        submissions = submissions.exclude_draft()

    return submissions

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    search_term = self.request.GET.get("query")

    return super().get_context_data(
        search_term=search_term,
        search_action=self.search_action,
        filter_action=self.filter_action,
        can_export=can_export_submissions(self.request.user),
        **kwargs,
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    disp = super().dispatch(request, *args, **kwargs)
    if "export" in request.GET and can_export_submissions(request.user):
        csv_data = export_submissions_to_csv(self.object_list)
        response = HttpResponse(csv_data.readlines(), content_type="text/csv")
        response["Content-Disposition"] = "attachment; filename=submissions.csv"
        return response
    return disp

BatchUpdateLeadView

Bases: DelegatedViewMixin, FormView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'batch_lead_form'

setup

setup(request, *args, **kwargs)

Initialize attributes shared by all view methods.

Source code in hypha/apply/utils/views.py
def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

get_object

get_object()
Source code in hypha/apply/utils/views.py
def get_object(self):
    # Make sure the form instance, bound at the parent class level,  is the same as the
    # value we work with on the class.
    # If we don't have self.object, bind the parent instance to it. This value will then
    # be used by the form. Any further calls to get_object will get a new instance of the object
    if not hasattr(self, "object"):
        parent_object = self.get_parent_object()
        if isinstance(parent_object, self.model):
            return parent_object

    return super().get_object()

get_template_names

get_template_names()
Source code in hypha/apply/utils/views.py
def get_template_names(self):
    return self.kwargs["template_names"]

get_form_name

get_form_name()
Source code in hypha/apply/utils/views.py
def get_form_name(self):
    return self.context_name

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()
    form_kwargs["user"] = self.request.user
    form_kwargs.update(**self.get_parent_kwargs())
    return form_kwargs

get_parent_kwargs

get_parent_kwargs()
Source code in hypha/apply/utils/views.py
def get_parent_kwargs(self):
    try:
        return self.parent.get_form_kwargs()
    except AttributeError:
        return self.kwargs["parent"].get_form_kwargs()

get_parent_object

get_parent_object()
Source code in hypha/apply/utils/views.py
def get_parent_object(self):
    return self.get_parent_kwargs()["instance"]

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/utils/views.py
def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    form.name = self.get_form_name()
    return form

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/utils/views.py
def get_context_data(self, **kwargs):
    # Use the previous context but override the validated form
    form = kwargs.pop("form")
    kwargs.update(self.kwargs["context"])
    kwargs.update(**{self.context_name: form})
    return super().get_context_data(**kwargs)

is_model_form classmethod

is_model_form()
Source code in hypha/apply/utils/views.py
@classmethod
def is_model_form(cls):
    return issubclass(cls.form_class, ModelForm)

contribute_form

contribute_form(parent)
Source code in hypha/apply/utils/views.py
def contribute_form(self, parent):
    self.parent = parent

    # We do not want to bind any forms generated this way
    # pretend we are doing a get request to avoid passing data to forms
    old_method = None
    if self.request.method in ("POST", "PUT"):
        old_method = self.request.method
        self.request.method = "GET"

    form = self.get_form()

    if old_method:
        self.request.method = old_method
    return self.context_name, form

get_success_url

get_success_url()
Source code in hypha/apply/utils/views.py
def get_success_url(self):
    query = self.request.GET.urlencode()
    if query:
        query = "?" + query
    return self.request.path + query

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    new_lead = form.cleaned_data["lead"]
    submissions = form.cleaned_data["submissions"]
    services.bulk_update_lead(
        submissions=submissions,
        user=self.request.user,
        lead=new_lead,
        request=self.request,
    )
    return super().form_valid(form)

form_invalid

form_invalid(form)
Source code in hypha/apply/funds/views.py
def form_invalid(self, form):
    messages.error(
        self.request,
        mark_safe(_("Sorry something went wrong") + form.errors.as_ul()),
    )
    return super().form_invalid(form)

BatchUpdateReviewersView

Bases: DelegatedViewMixin, FormView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'batch_reviewer_form'

setup

setup(request, *args, **kwargs)

Initialize attributes shared by all view methods.

Source code in hypha/apply/utils/views.py
def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

get_object

get_object()
Source code in hypha/apply/utils/views.py
def get_object(self):
    # Make sure the form instance, bound at the parent class level,  is the same as the
    # value we work with on the class.
    # If we don't have self.object, bind the parent instance to it. This value will then
    # be used by the form. Any further calls to get_object will get a new instance of the object
    if not hasattr(self, "object"):
        parent_object = self.get_parent_object()
        if isinstance(parent_object, self.model):
            return parent_object

    return super().get_object()

get_template_names

get_template_names()
Source code in hypha/apply/utils/views.py
def get_template_names(self):
    return self.kwargs["template_names"]

get_form_name

get_form_name()
Source code in hypha/apply/utils/views.py
def get_form_name(self):
    return self.context_name

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()
    form_kwargs["user"] = self.request.user
    form_kwargs.update(**self.get_parent_kwargs())
    return form_kwargs

get_parent_kwargs

get_parent_kwargs()
Source code in hypha/apply/utils/views.py
def get_parent_kwargs(self):
    try:
        return self.parent.get_form_kwargs()
    except AttributeError:
        return self.kwargs["parent"].get_form_kwargs()

get_parent_object

get_parent_object()
Source code in hypha/apply/utils/views.py
def get_parent_object(self):
    return self.get_parent_kwargs()["instance"]

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/utils/views.py
def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    form.name = self.get_form_name()
    return form

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/utils/views.py
def get_context_data(self, **kwargs):
    # Use the previous context but override the validated form
    form = kwargs.pop("form")
    kwargs.update(self.kwargs["context"])
    kwargs.update(**{self.context_name: form})
    return super().get_context_data(**kwargs)

is_model_form classmethod

is_model_form()
Source code in hypha/apply/utils/views.py
@classmethod
def is_model_form(cls):
    return issubclass(cls.form_class, ModelForm)

contribute_form

contribute_form(parent)
Source code in hypha/apply/utils/views.py
def contribute_form(self, parent):
    self.parent = parent

    # We do not want to bind any forms generated this way
    # pretend we are doing a get request to avoid passing data to forms
    old_method = None
    if self.request.method in ("POST", "PUT"):
        old_method = self.request.method
        self.request.method = "GET"

    form = self.get_form()

    if old_method:
        self.request.method = old_method
    return self.context_name, form

get_success_url

get_success_url()
Source code in hypha/apply/utils/views.py
def get_success_url(self):
    query = self.request.GET.urlencode()
    if query:
        query = "?" + query
    return self.request.path + query

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    submissions = form.cleaned_data["submissions"]
    external_reviewers = form.cleaned_data["external_reviewers"]
    assigned_roles = {
        role: form.cleaned_data[field] for field, role in form.role_fields.items()
    }
    services.bulk_update_reviewers(
        submissions=submissions,
        external_reviewers=external_reviewers,
        assigned_roles=assigned_roles,
        user=self.request.user,
        request=self.request,
    )

    return super().form_valid(form)

form_invalid

form_invalid(form)
Source code in hypha/apply/funds/views.py
def form_invalid(self, form):
    messages.error(
        self.request,
        mark_safe(_("Sorry something went wrong") + form.errors.as_ul()),
    )
    return super().form_invalid(form)

BatchDeleteSubmissionView

Bases: DelegatedViewMixin, FormView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'batch_delete_submission_form'

setup

setup(request, *args, **kwargs)

Initialize attributes shared by all view methods.

Source code in hypha/apply/utils/views.py
def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

get_object

get_object()
Source code in hypha/apply/utils/views.py
def get_object(self):
    # Make sure the form instance, bound at the parent class level,  is the same as the
    # value we work with on the class.
    # If we don't have self.object, bind the parent instance to it. This value will then
    # be used by the form. Any further calls to get_object will get a new instance of the object
    if not hasattr(self, "object"):
        parent_object = self.get_parent_object()
        if isinstance(parent_object, self.model):
            return parent_object

    return super().get_object()

get_template_names

get_template_names()
Source code in hypha/apply/utils/views.py
def get_template_names(self):
    return self.kwargs["template_names"]

get_form_name

get_form_name()
Source code in hypha/apply/utils/views.py
def get_form_name(self):
    return self.context_name

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()
    form_kwargs["user"] = self.request.user
    form_kwargs.update(**self.get_parent_kwargs())
    return form_kwargs

get_parent_kwargs

get_parent_kwargs()
Source code in hypha/apply/utils/views.py
def get_parent_kwargs(self):
    try:
        return self.parent.get_form_kwargs()
    except AttributeError:
        return self.kwargs["parent"].get_form_kwargs()

get_parent_object

get_parent_object()
Source code in hypha/apply/utils/views.py
def get_parent_object(self):
    return self.get_parent_kwargs()["instance"]

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/utils/views.py
def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    form.name = self.get_form_name()
    return form

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/utils/views.py
def get_context_data(self, **kwargs):
    # Use the previous context but override the validated form
    form = kwargs.pop("form")
    kwargs.update(self.kwargs["context"])
    kwargs.update(**{self.context_name: form})
    return super().get_context_data(**kwargs)

is_model_form classmethod

is_model_form()
Source code in hypha/apply/utils/views.py
@classmethod
def is_model_form(cls):
    return issubclass(cls.form_class, ModelForm)

contribute_form

contribute_form(parent)
Source code in hypha/apply/utils/views.py
def contribute_form(self, parent):
    self.parent = parent

    # We do not want to bind any forms generated this way
    # pretend we are doing a get request to avoid passing data to forms
    old_method = None
    if self.request.method in ("POST", "PUT"):
        old_method = self.request.method
        self.request.method = "GET"

    form = self.get_form()

    if old_method:
        self.request.method = old_method
    return self.context_name, form

get_success_url

get_success_url()
Source code in hypha/apply/utils/views.py
def get_success_url(self):
    query = self.request.GET.urlencode()
    if query:
        query = "?" + query
    return self.request.path + query

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    submissions = form.cleaned_data["submissions"]
    services.bulk_delete_submissions(
        submissions=submissions,
        user=self.request.user,
        request=self.request,
    )
    return super().form_valid(form)

form_invalid

form_invalid(form)
Source code in hypha/apply/funds/views.py
def form_invalid(self, form):
    messages.error(
        self.request,
        mark_safe(_("Sorry something went wrong") + form.errors.as_ul()),
    )
    return super().form_invalid(form)

BatchArchiveSubmissionView

Bases: DelegatedViewMixin, FormView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'batch_archive_submission_form'

setup

setup(request, *args, **kwargs)

Initialize attributes shared by all view methods.

Source code in hypha/apply/utils/views.py
def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

get_object

get_object()
Source code in hypha/apply/utils/views.py
def get_object(self):
    # Make sure the form instance, bound at the parent class level,  is the same as the
    # value we work with on the class.
    # If we don't have self.object, bind the parent instance to it. This value will then
    # be used by the form. Any further calls to get_object will get a new instance of the object
    if not hasattr(self, "object"):
        parent_object = self.get_parent_object()
        if isinstance(parent_object, self.model):
            return parent_object

    return super().get_object()

get_template_names

get_template_names()
Source code in hypha/apply/utils/views.py
def get_template_names(self):
    return self.kwargs["template_names"]

get_form_name

get_form_name()
Source code in hypha/apply/utils/views.py
def get_form_name(self):
    return self.context_name

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()
    form_kwargs["user"] = self.request.user
    form_kwargs.update(**self.get_parent_kwargs())
    return form_kwargs

get_parent_kwargs

get_parent_kwargs()
Source code in hypha/apply/utils/views.py
def get_parent_kwargs(self):
    try:
        return self.parent.get_form_kwargs()
    except AttributeError:
        return self.kwargs["parent"].get_form_kwargs()

get_parent_object

get_parent_object()
Source code in hypha/apply/utils/views.py
def get_parent_object(self):
    return self.get_parent_kwargs()["instance"]

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/utils/views.py
def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    form.name = self.get_form_name()
    return form

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/utils/views.py
def get_context_data(self, **kwargs):
    # Use the previous context but override the validated form
    form = kwargs.pop("form")
    kwargs.update(self.kwargs["context"])
    kwargs.update(**{self.context_name: form})
    return super().get_context_data(**kwargs)

is_model_form classmethod

is_model_form()
Source code in hypha/apply/utils/views.py
@classmethod
def is_model_form(cls):
    return issubclass(cls.form_class, ModelForm)

contribute_form

contribute_form(parent)
Source code in hypha/apply/utils/views.py
def contribute_form(self, parent):
    self.parent = parent

    # We do not want to bind any forms generated this way
    # pretend we are doing a get request to avoid passing data to forms
    old_method = None
    if self.request.method in ("POST", "PUT"):
        old_method = self.request.method
        self.request.method = "GET"

    form = self.get_form()

    if old_method:
        self.request.method = old_method
    return self.context_name, form

get_success_url

get_success_url()
Source code in hypha/apply/utils/views.py
def get_success_url(self):
    query = self.request.GET.urlencode()
    if query:
        query = "?" + query
    return self.request.path + query

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    # If a user without archive edit access is somehow able to access batch archive submissions
    # (ie. they were looking at the submission list when permissions changed) "refresh" the page
    if not can_alter_archived_submissions(self.request.user):
        return HttpResponseRedirect(self.request.path)
    submissions = form.cleaned_data["submissions"]
    services.bulk_archive_submissions(
        submissions=submissions,
        user=self.request.user,
        request=self.request,
    )
    return super().form_valid(form)

form_invalid

form_invalid(form)
Source code in hypha/apply/funds/views.py
def form_invalid(self, form):
    messages.error(
        self.request,
        mark_safe(_("Sorry something went wrong") + form.errors.as_ul()),
    )
    return super().form_invalid(form)

BatchProgressSubmissionView

Bases: DelegatedViewMixin, FormView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'batch_progress_form'

setup

setup(request, *args, **kwargs)

Initialize attributes shared by all view methods.

Source code in hypha/apply/utils/views.py
def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

get_object

get_object()
Source code in hypha/apply/utils/views.py
def get_object(self):
    # Make sure the form instance, bound at the parent class level,  is the same as the
    # value we work with on the class.
    # If we don't have self.object, bind the parent instance to it. This value will then
    # be used by the form. Any further calls to get_object will get a new instance of the object
    if not hasattr(self, "object"):
        parent_object = self.get_parent_object()
        if isinstance(parent_object, self.model):
            return parent_object

    return super().get_object()

get_template_names

get_template_names()
Source code in hypha/apply/utils/views.py
def get_template_names(self):
    return self.kwargs["template_names"]

get_form_name

get_form_name()
Source code in hypha/apply/utils/views.py
def get_form_name(self):
    return self.context_name

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    form_kwargs = super().get_form_kwargs()
    form_kwargs["user"] = self.request.user
    form_kwargs.update(**self.get_parent_kwargs())
    return form_kwargs

get_parent_kwargs

get_parent_kwargs()
Source code in hypha/apply/utils/views.py
def get_parent_kwargs(self):
    try:
        return self.parent.get_form_kwargs()
    except AttributeError:
        return self.kwargs["parent"].get_form_kwargs()

get_parent_object

get_parent_object()
Source code in hypha/apply/utils/views.py
def get_parent_object(self):
    return self.get_parent_kwargs()["instance"]

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/utils/views.py
def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    form.name = self.get_form_name()
    return form

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/utils/views.py
def get_context_data(self, **kwargs):
    # Use the previous context but override the validated form
    form = kwargs.pop("form")
    kwargs.update(self.kwargs["context"])
    kwargs.update(**{self.context_name: form})
    return super().get_context_data(**kwargs)

is_model_form classmethod

is_model_form()
Source code in hypha/apply/utils/views.py
@classmethod
def is_model_form(cls):
    return issubclass(cls.form_class, ModelForm)

contribute_form

contribute_form(parent)
Source code in hypha/apply/utils/views.py
def contribute_form(self, parent):
    self.parent = parent

    # We do not want to bind any forms generated this way
    # pretend we are doing a get request to avoid passing data to forms
    old_method = None
    if self.request.method in ("POST", "PUT"):
        old_method = self.request.method
        self.request.method = "GET"

    form = self.get_form()

    if old_method:
        self.request.method = old_method
    return self.context_name, form

get_success_url

get_success_url()
Source code in hypha/apply/utils/views.py
def get_success_url(self):
    query = self.request.GET.urlencode()
    if query:
        query = "?" + query
    return self.request.path + query

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    submissions = form.cleaned_data["submissions"]
    transitions = form.cleaned_data.get("action")

    try:
        redirect = BatchDeterminationCreateView.should_redirect(
            self.request, submissions, transitions
        )
    except ValueError as e:
        messages.warning(self.request, "Could not determine: " + str(e))
        return self.form_invalid(form)
    else:
        if redirect:
            return redirect

    failed = []
    phase_changes = {}
    for submission in submissions:
        valid_actions = {
            action
            for action, _ in submission.get_actions_for_user(self.request.user)
        }
        old_phase = submission.phase
        try:
            transition = (valid_actions & set(transitions)).pop()
            submission.perform_transition(
                transition,
                self.request.user,
                request=self.request,
                notify=False,
            )
        except (PermissionDenied, KeyError):
            failed.append(submission)
        else:
            phase_changes[submission.id] = old_phase

    if failed:
        messages.warning(
            self.request,
            _("Failed to update: ")
            + ", ".join(str(submission) for submission in failed),
        )

    succeeded_submissions = submissions.exclude(
        id__in=[submission.id for submission in failed]
    )
    messenger(
        MESSAGES.BATCH_TRANSITION,
        user=self.request.user,
        request=self.request,
        sources=succeeded_submissions,
        related=phase_changes,
    )

    ready_for_review = [phase for phase in transitions if phase in review_statuses]
    if ready_for_review:
        messenger(
            MESSAGES.BATCH_READY_FOR_REVIEW,
            user=self.request.user,
            request=self.request,
            sources=succeeded_submissions.filter(status__in=ready_for_review),
        )

    return super().form_valid(form)

BaseReviewerSubmissionsTable

Bases: BaseAdminSubmissionsTable

filter_action class-attribute instance-attribute

filter_action = ''

search_action class-attribute instance-attribute

search_action = ''

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

table_class class-attribute instance-attribute

filterset_class class-attribute instance-attribute

get_table_kwargs

get_table_kwargs(**kwargs)
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self, **kwargs):
    return {**self.excluded, **kwargs}

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    new_kwargs = super().get_filterset_kwargs(filterset_class)
    new_kwargs.update(self.excluded)
    new_kwargs.update(kwargs)
    return new_kwargs

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    search_term = self.request.GET.get("query")

    return super().get_context_data(
        search_term=search_term,
        search_action=self.search_action,
        filter_action=self.filter_action,
        can_export=can_export_submissions(self.request.user),
        **kwargs,
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    disp = super().dispatch(request, *args, **kwargs)
    if "export" in request.GET and can_export_submissions(request.user):
        csv_data = export_submissions_to_csv(self.object_list)
        response = HttpResponse(csv_data.readlines(), content_type="text/csv")
        response["Content-Disposition"] = "attachment; filename=submissions.csv"
        return response
    return disp

get_queryset

get_queryset()

If use_settings variable is set for ReviewerSettings use settings parameters to filter submissions or return only reviewed_by as it was by default.

Source code in hypha/apply/funds/views.py
def get_queryset(self):
    """
    If use_settings variable is set for ReviewerSettings use settings
    parameters to filter submissions or return only reviewed_by as it
    was by default.
    """
    reviewer_settings = ReviewerSettings.for_request(self.request)
    if reviewer_settings.use_settings:
        return (
            super()
            .get_queryset()
            .for_reviewer_settings(self.request.user, reviewer_settings)
            .order_by("-submit_time")
        )
    return super().get_queryset().reviewed_by(self.request.user)

SubmissionAdminListView

SubmissionAdminListView(*args, **kwargs)

Bases: BaseAdminSubmissionsTable, DelegateableListView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

table_class class-attribute instance-attribute

table_class = AdminSubmissionsTable

filterset_class class-attribute instance-attribute

filterset_class = SubmissionFilterAndSearch

filter_action class-attribute instance-attribute

filter_action = ''

search_action class-attribute instance-attribute

search_action = ''

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

template_name class-attribute instance-attribute

template_name = 'funds/submissions.html'

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
    }

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object_list = self.get_queryset()
    return super().post(request, *args, **kwargs)

get_table_kwargs

get_table_kwargs(**kwargs)
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self, **kwargs):
    return {**self.excluded, **kwargs}

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    disp = super().dispatch(request, *args, **kwargs)
    if "export" in request.GET and can_export_submissions(request.user):
        csv_data = export_submissions_to_csv(self.object_list)
        response = HttpResponse(csv_data.readlines(), content_type="text/csv")
        response["Content-Disposition"] = "attachment; filename=submissions.csv"
        return response
    return disp

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    new_kwargs = super().get_filterset_kwargs(filterset_class)
    archived_kwargs = {"archived": self.request.GET.get("archived", 0)}
    new_kwargs.update(archived_kwargs)
    new_kwargs.update(kwargs)
    return new_kwargs

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    if self.request.GET.get("archived"):
        # if archived is in param, let archived filter handle the queryset as per its value.
        submissions = (
            self.filterset_class._meta.model.objects.include_archive().for_table(
                self.request.user
            )
        )
    else:
        submissions = self.filterset_class._meta.model.objects.current().for_table(
            self.request.user
        )

    if not can_access_drafts(self.request.user):
        submissions = submissions.exclude_draft()

    return submissions

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    show_archive = can_view_archived_submissions(self.request.user)
    can_archive = can_bulk_archive_submissions(self.request.user)

    return super().get_context_data(
        show_archive=show_archive,
        can_bulk_archive=can_archive,
        **kwargs,
    )

GroupingApplicationsListView

Bases: TemplateView

Template view for grouped submissions

template_name class-attribute instance-attribute

template_name = 'funds/grouped_application_list.html'

SubmissionReviewerListView

Bases: BaseReviewerSubmissionsTable

table_class class-attribute instance-attribute

filterset_class class-attribute instance-attribute

filter_action class-attribute instance-attribute

filter_action = ''

search_action class-attribute instance-attribute

search_action = ''

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

template_name class-attribute instance-attribute

template_name = 'funds/submissions.html'

get_table_kwargs

get_table_kwargs(**kwargs)
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self, **kwargs):
    return {**self.excluded, **kwargs}

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    new_kwargs = super().get_filterset_kwargs(filterset_class)
    new_kwargs.update(self.excluded)
    new_kwargs.update(kwargs)
    return new_kwargs

get_queryset

get_queryset()

If use_settings variable is set for ReviewerSettings use settings parameters to filter submissions or return only reviewed_by as it was by default.

Source code in hypha/apply/funds/views.py
def get_queryset(self):
    """
    If use_settings variable is set for ReviewerSettings use settings
    parameters to filter submissions or return only reviewed_by as it
    was by default.
    """
    reviewer_settings = ReviewerSettings.for_request(self.request)
    if reviewer_settings.use_settings:
        return (
            super()
            .get_queryset()
            .for_reviewer_settings(self.request.user, reviewer_settings)
            .order_by("-submit_time")
        )
    return super().get_queryset().reviewed_by(self.request.user)

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    search_term = self.request.GET.get("query")

    return super().get_context_data(
        search_term=search_term,
        search_action=self.search_action,
        filter_action=self.filter_action,
        can_export=can_export_submissions(self.request.user),
        **kwargs,
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    disp = super().dispatch(request, *args, **kwargs)
    if "export" in request.GET and can_export_submissions(request.user):
        csv_data = export_submissions_to_csv(self.object_list)
        response = HttpResponse(csv_data.readlines(), content_type="text/csv")
        response["Content-Disposition"] = "attachment; filename=submissions.csv"
        return response
    return disp

SubmissionListView

Bases: ViewDispatcher

partner_view class-attribute instance-attribute

partner_view = None

community_view class-attribute instance-attribute

community_view = None

applicant_view class-attribute instance-attribute

applicant_view = None

finance_view class-attribute instance-attribute

finance_view = None

contracting_view class-attribute instance-attribute

contracting_view = None

admin_view class-attribute instance-attribute

reviewer_view class-attribute instance-attribute

admin_check

admin_check(request)
Source code in hypha/apply/utils/views.py
def admin_check(self, request):
    return request.user.is_apply_staff

reviewer_check

reviewer_check(request)
Source code in hypha/apply/utils/views.py
def reviewer_check(self, request):
    return request.user.is_reviewer

partner_check

partner_check(request)
Source code in hypha/apply/utils/views.py
def partner_check(self, request):
    return request.user.is_partner

community_check

community_check(request)
Source code in hypha/apply/utils/views.py
def community_check(self, request):
    return request.user.is_community_reviewer

finance_check

finance_check(request)
Source code in hypha/apply/utils/views.py
def finance_check(self, request):
    return request.user.is_finance

contracting_check

contracting_check(request)
Source code in hypha/apply/utils/views.py
def contracting_check(self, request):
    return request.user.is_contracting

applicant_check

applicant_check(request)
Source code in hypha/apply/utils/views.py
def applicant_check(self, request):
    return request.user.is_applicant

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def dispatch(self, request, *args, **kwargs):
    view = None

    if self.admin_check(request):
        view = self.admin_view
    elif self.reviewer_check(request):
        view = self.reviewer_view
    elif self.partner_check(request):
        view = self.partner_view
    elif self.community_check(request):
        view = self.community_view
    elif settings.PROJECTS_ENABLED and self.finance_check(request):
        view = self.finance_view
    elif settings.PROJECTS_ENABLED and self.contracting_check(request):
        view = self.contracting_view
    elif self.applicant_check(request):
        view = self.applicant_view

    if view:
        return view.as_view()(request, *args, **kwargs)
    return HttpResponseForbidden()

SubmissionsByStatus

SubmissionsByStatus(*args, **kwargs)

Bases: BaseAdminSubmissionsTable, DelegateableListView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

table_class class-attribute instance-attribute

table_class = AdminSubmissionsTable

filterset_class class-attribute instance-attribute

filterset_class = SubmissionFilterAndSearch

filter_action class-attribute instance-attribute

filter_action = ''

search_action class-attribute instance-attribute

search_action = ''

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

template_name class-attribute instance-attribute

template_name = 'funds/submissions_by_status.html'

status_mapping class-attribute instance-attribute

status_mapping = PHASES_MAPPING

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
    }

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object_list = self.get_queryset()
    return super().post(request, *args, **kwargs)

get_table_kwargs

get_table_kwargs(**kwargs)
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self, **kwargs):
    return {**self.excluded, **kwargs}

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.status = kwargs.get("status")
    try:
        status_data = self.status_mapping[self.status]
    except KeyError:
        raise Http404(_("No statuses match the requested value")) from None
    self.status_name = status_data["name"]
    self.statuses = status_data["statuses"]
    return super().dispatch(request, *args, **kwargs)

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    return super().get_filterset_kwargs(
        filterset_class, limit_statuses=self.statuses, **kwargs
    )

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    return super().get_queryset().filter(status__in=self.statuses)

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(
        status=self.status_name,
        statuses=self.statuses,
        **kwargs,
    )

ProgressSubmissionView

Bases: View

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(ProgressSubmissionView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    project_creation_form = ProgressSubmissionForm(
        instance=self.submission, user=self.request.user
    )
    return render(
        self.request,
        "funds/includes/progress_form.html",
        context={
            "form": project_creation_form,
            "value": _("Progress"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = ProgressSubmissionForm(
        self.request.POST, instance=self.submission, user=self.request.user
    )
    if form.is_valid():
        action = form.cleaned_data.get("action")
        redirect = DeterminationCreateOrUpdateView.should_redirect(
            self.request, self.submission, action
        )
        message_storage = messages.get_messages(self.request)
        if redirect:
            return HttpResponseClientRedirect(redirect.url, content=message_storage)

        self.submission.perform_transition(
            action, self.request.user, request=self.request
        )
        form.save()
        return HttpResponseClientRefresh()
    return render(
        self.request,
        "funds/includes/progress_form.html",
        context={"form": form, "value": _("Progress"), "object": self.submission},
        status=400,
    )

CreateProjectView

Bases: View

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(CreateProjectView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    project_creation_form = ProjectCreateForm(instance=self.submission)
    return render(
        self.request,
        "funds/includes/create_project_form.html",
        context={
            "form": project_creation_form,
            "value": _("Confirm"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = ProjectCreateForm(self.request.POST, instance=self.submission)
    if form.is_valid():
        project = form.save()
        # Record activity
        messenger(
            MESSAGES.CREATED_PROJECT,
            request=self.request,
            user=self.request.user,
            source=project,
            related=project.submission,
        )
        # add task for staff to add PAF to the project
        add_task_to_user(
            code=PROJECT_WAITING_PAF,
            user=project.lead,
            related_obj=project,
        )
        return HttpResponseClientRedirect(project.get_absolute_url())
    return render(
        self.request,
        "funds/includes/create_project_form.html",
        context={"form": form, "value": _("Confirm"), "object": self.object},
        status=400,
    )

UpdateLeadView

Bases: View

model class-attribute instance-attribute

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'lead_form'

template class-attribute instance-attribute

template = 'funds/modals/update_lead_form.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.object = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit", request.user, object=self.object, raise_exception=False
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.object.get_absolute_url())
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    lead_form = UpdateSubmissionLeadForm(instance=self.object)
    return render(
        self.request,
        self.template,
        context={
            "form": lead_form,
            "value": _("Submit"),
            "object": self.object,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = UpdateSubmissionLeadForm(self.request.POST, instance=self.object)
    old_lead = copy(self.object.lead)
    if form.is_valid():
        form.save()
        messenger(
            MESSAGES.UPDATE_LEAD,
            request=self.request,
            user=self.request.user,
            source=form.instance,
            related=old_lead,
        )
        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {"leadUpdated": None, "showMessage": "Submission Lead updated."}
                ),
            },
        )
    return render(
        self.request,
        self.template,
        context={"form": form, "value": _("Update"), "object": self.object},
        status=400,
    )

UpdateReviewersView

Bases: View

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(UpdateReviewersView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    reviewer_form = UpdateReviewersForm(
        user=self.request.user, instance=self.submission
    )
    return render(
        self.request,
        "funds/includes/update_reviewer_form.html",
        context={
            "form": reviewer_form,
            "value": _("Update"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = UpdateReviewersForm(
        self.request.POST, user=self.request.user, instance=self.submission
    )
    old_reviewers = {copy(reviewer) for reviewer in form.instance.assigned.all()}
    if form.is_valid():
        form.save()
        new_reviewers = set(form.instance.assigned.all())
        added = new_reviewers - old_reviewers
        removed = old_reviewers - new_reviewers
        messenger(
            MESSAGES.REVIEWERS_UPDATED,
            request=self.request,
            user=self.request.user,
            source=self.submission,
            added=added,
            removed=removed,
        )
        # Update submission status if needed.
        services.set_status_after_reviewers_assigned(
            submission=form.instance,
            updated_by=self.request.user,
            request=self.request,
        )
        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {"reviewerUpdated": None, "showMessage": "Reviewers updated."}
                ),
            },
        )

    return render(
        self.request,
        "funds/includes/update_reviewer_form.html",
        context={"form": form, "value": _("Update"), "object": self.submission},
    )

UpdatePartnersView

Bases: View

model class-attribute instance-attribute

form_class class-attribute instance-attribute

form_class = UpdatePartnersForm

context_name class-attribute instance-attribute

context_name = 'partner_form'

template class-attribute instance-attribute

template = 'funds/modals/update_partner_form.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(UpdatePartnersView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    partner_form = UpdatePartnersForm(
        user=self.request.user, instance=self.submission
    )
    return render(
        self.request,
        self.template,
        context={
            "form": partner_form,
            "value": _("Update"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = UpdatePartnersForm(
        self.request.POST, user=self.request.user, instance=self.submission
    )
    old_partners = set(self.submission.partners.all())
    if form.is_valid():
        form.save()
        new_partners = set(form.instance.partners.all())

        added = new_partners - old_partners
        removed = old_partners - new_partners
        messenger(
            MESSAGES.PARTNERS_UPDATED,
            request=self.request,
            user=self.request.user,
            source=self.submission,
            added=added,
            removed=removed,
        )

        messenger(
            MESSAGES.PARTNERS_UPDATED_PARTNER,
            request=self.request,
            user=self.request.user,
            source=self.submission,
            added=added,
            removed=removed,
        )

        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {
                        "partnerUpdated": None,
                        "showMessage": "Partners updated successfully.",
                    }
                ),
            },
        )

    return render(
        self.request,
        self.template,
        context={"form": form, "value": _("Update"), "object": self.submission},
        status=400,
    )

UpdateMetaTermsView

Bases: View

template class-attribute instance-attribute

template = 'funds/includes/update_meta_terms_form.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(UpdateMetaTermsView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    metaterms_form = UpdateMetaTermsForm(
        user=self.request.user, instance=self.submission
    )
    return render(
        self.request,
        self.template,
        context={
            "form": metaterms_form,
            "value": _("Update"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = UpdateMetaTermsForm(
        self.request.POST, instance=self.submission, user=self.request.user
    )
    if form.is_valid():
        form.save()

        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {
                        "metaTermsUpdated": None,
                        "showMessage": "Meta terms updated successfully.",
                    }
                ),
            },
        )
    return render(
        self.request,
        self.template,
        context={"form": form, "value": _("Update"), "object": self.submission},
        status=400,
    )

TranslateSubmissionView

Bases: View

template class-attribute instance-attribute

template = 'funds/includes/translate_application_form.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(
        ApplicationSubmission, id=kwargs.get("pk")
    )
    if not request.user.is_org_faculty:
        messages.warning(
            self.request,
            "User attempted to translate submission but is not org faculty",
        )
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(TranslateSubmissionView, self).dispatch(
        request, *args, **kwargs
    )

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    raise Http404

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    raise Http404

ReminderCreateView

Bases: View

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(ApplicationSubmission, id=kwargs.get("pk"))
    permission, reason = has_permission(
        "submission_edit",
        request.user,
        object=self.submission,
        raise_exception=False,
    )
    if not permission:
        messages.warning(self.request, reason)
        return HttpResponseRedirect(self.submission.get_absolute_url())
    return super(ReminderCreateView, self).dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, *args, **kwargs):
    reminder_form = CreateReminderForm(instance=self.submission)
    return render(
        self.request,
        "funds/includes/create_reminder_form.html",
        context={
            "form": reminder_form,
            "value": _("Create Reminder"),
            "object": self.submission,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, *args, **kwargs):
    form = CreateReminderForm(
        self.request.POST, instance=self.submission, user=self.request.user
    )
    if form.is_valid():
        reminder = form.save()
        messenger(
            MESSAGES.CREATE_REMINDER,
            request=self.request,
            user=self.request.user,
            source=self.submission,
            related=reminder,
        )
        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps({"remindersUpdated": None}),
            },
        )
    return render(
        self.request,
        "funds/includes/create_reminder_form.html",
        context={"form": form, "value": _("Create"), "object": self.submission},
        status=400,
    )

ReminderDeleteView

Bases: DeleteView

model class-attribute instance-attribute

model = Reminder

get_success_url

get_success_url()
Source code in hypha/apply/funds/views.py
def get_success_url(self):
    submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )
    return reverse_lazy("funds:submissions:detail", args=(submission.id,))

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    reminder = self.get_object()
    messenger(
        MESSAGES.DELETE_REMINDER,
        user=self.request.user,
        request=self.request,
        source=reminder.submission,
        related=reminder,
    )
    return super().form_valid(form)

AdminSubmissionDetailView

AdminSubmissionDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, DetailView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_admin_detail'

model class-attribute instance-attribute

form_views class-attribute instance-attribute

form_views = [CommentFormView]

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
        "instance": self.object,
    }

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()

    kwargs["object"] = self.object

    return super().post(request, *args, **kwargs)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    if submission.status == DRAFT_STATE and not submission.can_view_draft(
        request.user
    ):
        raise Http404
    permission, _ = has_permission(
        "submission_view", request.user, object=submission, raise_exception=True
    )
    redirect = SubmissionSealedView.should_redirect(request, submission)
    return redirect or super().dispatch(request, *args, **kwargs)

get

get(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
    self.object = self.get_object()

    extra_context = {}

    # Check for language params - if they exist and are valid then update the context
    if lang_params := get_translation_params(request=request):
        from_lang, to_lang = lang_params
        try:
            self.object.form_data = translate_application_form_data(
                self.object, from_lang, to_lang
            )
            extra_context.update(
                {
                    "from_lang_name": get_lang_name(from_lang),
                    "to_lang_name": get_lang_name(to_lang),
                }
            )
        except ValueError:
            # Language package isn't valid or installed, redirect to the submission w/o params
            return redirect(self.object.get_absolute_url())

    context = self.get_context_data(object=self.object, **extra_context)
    return self.render_to_response(context)

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    other_submissions = (
        self.model.objects.filter(user=self.object.user)
        .current()
        .exclude(id=self.object.id)
        .order_by("-submit_time")
    )
    if self.object.next:
        other_submissions = other_submissions.exclude(id=self.object.next.id)

    return super().get_context_data(
        other_submissions=other_submissions,
        archive_access_groups=get_archive_view_groups(),
        can_archive=can_alter_archived_submissions(self.request.user),
        **kwargs,
    )

ReviewerSubmissionDetailView

ReviewerSubmissionDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, DetailView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_reviewer_detail'

model class-attribute instance-attribute

form_views class-attribute instance-attribute

form_views = [CommentFormView]

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
        "instance": self.object,
    }

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/activity/views.py
def get_context_data(self, **kwargs):
    extra = {
        # Do not prefetch on the related_object__author as the models
        # are not homogeneous and this will fail
        "comments": services.get_related_comments_for_user(
            self.object, self.request.user
        ),
        "comments_count": services.get_comment_count(
            self.object, self.request.user
        ),
    }
    return super().get_context_data(**extra, **kwargs)

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()

    kwargs["object"] = self.object

    return super().post(request, *args, **kwargs)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    # If the requesting user submitted the application, return the Applicant view.
    # Reviewers may sometimes be applicants as well.
    if submission.user == request.user:
        return ApplicantSubmissionDetailView.as_view()(request, *args, **kwargs)
    if submission.status == DRAFT_STATE:
        raise Http404

    permission, _ = has_permission(
        "submission_view", request.user, object=submission, raise_exception=True
    )

    reviewer_settings = ReviewerSettings.for_request(request)
    if reviewer_settings.use_settings:
        queryset = ApplicationSubmission.objects.for_reviewer_settings(
            request.user, reviewer_settings
        )
        # Reviewer can't view submission which is not listed in ReviewerSubmissionsTable
        if not queryset.filter(id=submission.id).exists():
            raise PermissionDenied

    return super().dispatch(request, *args, **kwargs)

PartnerSubmissionDetailView

PartnerSubmissionDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, DetailView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

model class-attribute instance-attribute

form_views class-attribute instance-attribute

form_views = [CommentFormView]

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
        "instance": self.object,
    }

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/activity/views.py
def get_context_data(self, **kwargs):
    extra = {
        # Do not prefetch on the related_object__author as the models
        # are not homogeneous and this will fail
        "comments": services.get_related_comments_for_user(
            self.object, self.request.user
        ),
        "comments_count": services.get_comment_count(
            self.object, self.request.user
        ),
    }
    return super().get_context_data(**extra, **kwargs)

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()

    kwargs["object"] = self.object

    return super().post(request, *args, **kwargs)

get_object

get_object()
Source code in hypha/apply/funds/views.py
def get_object(self):
    return super().get_object().from_draft()

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    permission, _ = has_permission(
        "submission_view", request.user, object=submission, raise_exception=True
    )
    # If the requesting user submitted the application, return the Applicant view.
    # Partners may sometimes be applicants as well.
    if submission.user == request.user:
        return ApplicantSubmissionDetailView.as_view()(request, *args, **kwargs)
    # Only allow partners in the submission they are added as partners
    partner_has_access = submission.partners.filter(pk=request.user.pk).exists()
    if not partner_has_access:
        raise PermissionDenied
    if submission.status == DRAFT_STATE:
        raise Http404
    return super().dispatch(request, *args, **kwargs)

CommunitySubmissionDetailView

CommunitySubmissionDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, DetailView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_community_detail'

model class-attribute instance-attribute

form_views class-attribute instance-attribute

form_views = [CommentFormView]

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
        "instance": self.object,
    }

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/activity/views.py
def get_context_data(self, **kwargs):
    extra = {
        # Do not prefetch on the related_object__author as the models
        # are not homogeneous and this will fail
        "comments": services.get_related_comments_for_user(
            self.object, self.request.user
        ),
        "comments_count": services.get_comment_count(
            self.object, self.request.user
        ),
    }
    return super().get_context_data(**extra, **kwargs)

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()

    kwargs["object"] = self.object

    return super().post(request, *args, **kwargs)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    permission, _ = has_permission(
        "submission_view", request.user, object=submission, raise_exception=True
    )
    # If the requesting user submitted the application, return the Applicant view.
    # Reviewers may sometimes be applicants as well.
    if submission.user == request.user:
        return ApplicantSubmissionDetailView.as_view()(request, *args, **kwargs)
    # Only allow community reviewers in submission with a community review state.
    if not submission.community_review:
        raise PermissionDenied
    if submission.status == DRAFT_STATE:
        raise Http404
    return super().dispatch(request, *args, **kwargs)

ApplicantSubmissionDetailView

ApplicantSubmissionDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, DetailView

Source code in hypha/apply/utils/views.py
def __init__(self, *args, **kwargs):
    self._form_views = {
        self.form_prefix + form_view.context_name: form_view
        for form_view in self.form_views
    }

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

model class-attribute instance-attribute

form_views class-attribute instance-attribute

form_views = [CommentFormView]

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/utils/views.py
def get_form_kwargs(self):
    return {
        "user": self.request.user,
        "instance": self.object,
    }

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/activity/views.py
def get_context_data(self, **kwargs):
    extra = {
        # Do not prefetch on the related_object__author as the models
        # are not homogeneous and this will fail
        "comments": services.get_related_comments_for_user(
            self.object, self.request.user
        ),
        "comments_count": services.get_comment_count(
            self.object, self.request.user
        ),
    }
    return super().get_context_data(**extra, **kwargs)

post

post(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()

    kwargs["object"] = self.object

    return super().post(request, *args, **kwargs)

get_object

get_object()
Source code in hypha/apply/funds/views.py
def get_object(self):
    return super().get_object().from_draft()

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    permission, _ = has_permission(
        "submission_view", request.user, object=submission, raise_exception=True
    )
    # This view is only for applicants.
    if submission.user != request.user:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

SubmissionDetailView

Bases: ViewDispatcher

finance_view class-attribute instance-attribute

finance_view = None

contracting_view class-attribute instance-attribute

contracting_view = None

admin_view class-attribute instance-attribute

reviewer_view class-attribute instance-attribute

partner_view class-attribute instance-attribute

community_view class-attribute instance-attribute

applicant_view class-attribute instance-attribute

admin_check

admin_check(request)
Source code in hypha/apply/utils/views.py
def admin_check(self, request):
    return request.user.is_apply_staff

reviewer_check

reviewer_check(request)
Source code in hypha/apply/utils/views.py
def reviewer_check(self, request):
    return request.user.is_reviewer

partner_check

partner_check(request)
Source code in hypha/apply/utils/views.py
def partner_check(self, request):
    return request.user.is_partner

community_check

community_check(request)
Source code in hypha/apply/utils/views.py
def community_check(self, request):
    return request.user.is_community_reviewer

finance_check

finance_check(request)
Source code in hypha/apply/utils/views.py
def finance_check(self, request):
    return request.user.is_finance

contracting_check

contracting_check(request)
Source code in hypha/apply/utils/views.py
def contracting_check(self, request):
    return request.user.is_contracting

applicant_check

applicant_check(request)
Source code in hypha/apply/utils/views.py
def applicant_check(self, request):
    return request.user.is_applicant

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def dispatch(self, request, *args, **kwargs):
    view = None

    if self.admin_check(request):
        view = self.admin_view
    elif self.reviewer_check(request):
        view = self.reviewer_view
    elif self.partner_check(request):
        view = self.partner_view
    elif self.community_check(request):
        view = self.community_view
    elif settings.PROJECTS_ENABLED and self.finance_check(request):
        view = self.finance_view
    elif settings.PROJECTS_ENABLED and self.contracting_check(request):
        view = self.contracting_view
    elif self.applicant_check(request):
        view = self.applicant_view

    if view:
        return view.as_view()(request, *args, **kwargs)
    return HttpResponseForbidden()

SubmissionSealedView

Bases: DetailView

template_name class-attribute instance-attribute

template_name = 'funds/submission_sealed.html'

model class-attribute instance-attribute

get

get(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, request, *args, **kwargs):
    submission = self.get_object()
    if not self.round_is_sealed(submission):
        return self.redirect_detail(submission)
    return super().get(request, *args, **kwargs)

post

post(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def post(self, request, *args, **kwargs):
    submission = self.get_object()
    if self.can_view_sealed(request.user):
        self.peeked(submission)
    return self.redirect_detail(submission)

redirect_detail

redirect_detail(submission)
Source code in hypha/apply/funds/views.py
def redirect_detail(self, submission):
    return HttpResponseRedirect(
        reverse_lazy("funds:submissions:detail", args=(submission.id,))
    )

peeked

peeked(submission)
Source code in hypha/apply/funds/views.py
def peeked(self, submission):
    messenger(
        MESSAGES.OPENED_SEALED,
        request=self.request,
        user=self.request.user,
        source=submission,
    )
    self.request.session.setdefault("peeked", {})[str(submission.id)] = True
    # Dictionary updates do not trigger session saves. Force update
    self.request.session.modified = True

can_view_sealed

can_view_sealed(user)
Source code in hypha/apply/funds/views.py
def can_view_sealed(self, user):
    return user.is_superuser

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(
        can_view_sealed=self.can_view_sealed(self.request.user),
        **kwargs,
    )

round_is_sealed classmethod

round_is_sealed(submission)
Source code in hypha/apply/funds/views.py
@classmethod
def round_is_sealed(cls, submission):
    try:
        return submission.round.specific.is_sealed
    except AttributeError:
        # Its a lab - cant be sealed
        return False

has_peeked classmethod

has_peeked(request, submission)
Source code in hypha/apply/funds/views.py
@classmethod
def has_peeked(cls, request, submission):
    return str(submission.id) in request.session.get("peeked", {})

should_redirect classmethod

should_redirect(request, submission)
Source code in hypha/apply/funds/views.py
@classmethod
def should_redirect(cls, request, submission):
    if cls.round_is_sealed(submission) and not cls.has_peeked(request, submission):
        return HttpResponseRedirect(
            reverse_lazy("funds:submissions:sealed", args=(submission.id,))
        )

BaseSubmissionEditView

Bases: UpdateView

Converts the data held on the submission into an editable format and knows how to save that back to the object. Shortcuts the normal update view save approach

model class-attribute instance-attribute

render_preview

render_preview(request, form)

Gets a rendered preview of a form

Creates a new revision on the ApplicationSubmission, removes the forms temporary files

Parameters:

  • request (HttpRequest) –

    Request used to trigger the preview to be used in the render

  • form (BaseModelForm) –

    Form to be rendered

Returns:

  • HttpResponse –

    An HttpResponse containing a preview of the given form

Source code in hypha/apply/funds/views.py
def render_preview(self, request: HttpRequest, form: BaseModelForm) -> HttpResponse:
    """Gets a rendered preview of a form

    Creates a new revision on the `ApplicationSubmission`, removes the
    forms temporary files

    Args:
        request:
            Request used to trigger the preview to be used in the render
        form:
            Form to be rendered

    Returns:
        An `HttpResponse` containing a preview of the given form
    """

    self.object.create_revision(draft=True, by=request.user)
    messages.success(self.request, _("Draft saved"))

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()

    context = self.get_context_data()
    return render(request, "funds/application_preview.html", context)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    permission, _ = has_permission(
        "submission_edit",
        request.user,
        object=self.get_object(),
        raise_exception=True,
    )
    if not self.get_object().phase.permissions.can_edit(request.user):
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

buttons

buttons()

The buttons to be presented to the in the EditView

Returns:

  • str –

    A generator returning a tuple strings in the format of:

  • str –

    (

Source code in hypha/apply/funds/views.py
def buttons(
    self,
) -> Generator[Tuple[str, str, str], Tuple[str, str, str], Tuple[str, str, str]]:
    """The buttons to be presented to the in the EditView

    Returns:
        A generator returning a tuple strings in the format of:
        (<button type>, <button styling>, <button label>)
    """
    if settings.SUBMISSION_PREVIEW_REQUIRED:
        yield ("preview", "primary", _("Preview and submit"))
        yield ("save", "white", _("Save draft"))
    else:
        yield ("submit", "primary", _("Submit"))
        yield ("save", "white", _("Save draft"))
        yield ("preview", "white", _("Preview"))

get_object_fund_current_round

get_object_fund_current_round()
Source code in hypha/apply/funds/views.py
def get_object_fund_current_round(self):
    assigned_fund = self.object.round.get_parent().specific
    if assigned_fund.open_round:
        return assigned_fund.open_round
    return False

get_on_submit_transition

get_on_submit_transition(user)

Gets the transition that should be triggered when a form is submitted.

Checks all available status transitions for the current user and returns the first one that has trigger_on_submit=True in its custom settings.

Returns:

  • dict –

    The transition configuration dictionary with trigger_on_submit=True, or None if no matching transition is found.

Source code in hypha/apply/funds/views.py
def get_on_submit_transition(self, user):
    """Gets the transition that should be triggered when a form is submitted.

    Checks all available status transitions for the current user and returns the first
    one that has trigger_on_submit=True in its custom settings.

    Returns:
        dict: The transition configuration dictionary with trigger_on_submit=True,
            or None if no matching transition is found.
    """
    return next(
        (
            t
            for t in self.object.get_available_user_status_transitions(user)
            if t.custom.get("trigger_on_submit", False)
        ),
        None,
    )

form_valid

form_valid(form)

Handle the form returned from a SubmissionEditView.

Determine whether to return a form preview, draft the new edits, or submit and transition the ApplicationSubmission object

Parameters:

  • form (BaseModelForm) –

    The valid form

Returns:

  • HttpResponse –

    An HttpResponse depending on the actions taken in the edit view

Source code in hypha/apply/funds/views.py
def form_valid(self, form: BaseModelForm) -> HttpResponse:
    """Handle the form returned from a `SubmissionEditView`.

    Determine whether to return a form preview, draft the new edits,
    or submit and transition the `ApplicationSubmission` object

    Args:
        form: The valid form

    Returns:
        An `HttpResponse` depending on the actions taken in the edit view
    """

    self.object.form_data = form.cleaned_data

    is_draft = self.object.status == DRAFT_STATE

    # Handle a preview or a save (aka a draft)
    if "preview" in self.request.POST:
        return self.render_preview(self.request, form)

    if "save" in self.request.POST:
        return self.save_draft_and_refresh_page(form=form)

    # Handle an application being submitted from a DRAFT_STATE. This includes updating submit_time
    if is_draft and "submit" in self.request.POST:
        self.object.submit_time = timezone.now()
        if self.object.round:
            current_round = self.get_object_fund_current_round()
            if current_round:
                self.object.round = current_round
        self.object.save(update_fields=["submit_time", "round"])

    revision = self.object.create_revision(by=self.request.user)
    submitting_proposal = self.object.phase.name in STAGE_CHANGE_ACTIONS

    if submitting_proposal:
        messenger(
            MESSAGES.PROPOSAL_SUBMITTED,
            request=self.request,
            user=self.request.user,
            source=self.object,
        )
    elif revision and not self.object.status == DRAFT_STATE:
        messenger(
            MESSAGES.APPLICANT_EDIT,
            request=self.request,
            user=self.request.user,
            source=self.object,
            related=revision,
        )

    if "submit" in self.request.POST:
        if transition := self.get_on_submit_transition(self.request.user):
            notify = (
                not (revision or submitting_proposal)
                or self.object.status == DRAFT_STATE,
            )
            self.object.perform_transition(
                transition.target,
                self.request.user,
                request=self.request,
                notify=notify,  # Use the other notification
            )

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()
    return HttpResponseRedirect(self.get_success_url())

get_form_kwargs

get_form_kwargs()

Returns the keyword arguments for instantiating the form.

This method is called by the form mixin during form instantiation. It returns a dictionary of keyword arguments that will be passed to the form's constructor.

Returns:

  • dict –

    A dictionary of keyword arguments for the form constructor.

Source code in hypha/apply/funds/views.py
def get_form_kwargs(self):
    """
    Returns the keyword arguments for instantiating the form.

    This method is called by the form mixin during form instantiation.
    It returns a dictionary of keyword arguments that will be passed to
    the form's constructor.

    Returns:
        dict: A dictionary of keyword arguments for the form constructor.
    """
    kwargs = super().get_form_kwargs()
    instance = kwargs.pop("instance").from_draft()
    initial = instance.raw_data
    for field_id in instance.file_field_ids:
        initial.pop(field_id + "-uploads", False)
        initial[field_id] = self.get_placeholder_file(
            instance.raw_data.get(field_id)
        )
    kwargs["initial"] = initial
    return kwargs

get_placeholder_file

get_placeholder_file(initial_file)
Source code in hypha/apply/funds/views.py
def get_placeholder_file(self, initial_file):
    if not isinstance(initial_file, list):
        return PlaceholderUploadedFile(
            initial_file.filename, size=initial_file.size, file_id=initial_file.name
        )
    return [
        PlaceholderUploadedFile(f.filename, size=f.size, file_id=f.name)
        for f in initial_file
    ]

save_draft_and_refresh_page

save_draft_and_refresh_page(form)
Source code in hypha/apply/funds/views.py
def save_draft_and_refresh_page(self, form) -> HttpResponseRedirect:
    self.object.create_revision(draft=True, by=self.request.user)
    form.delete_temporary_files()
    messages.success(self.request, _("Draft saved"))
    return HttpResponseRedirect(
        reverse_lazy("funds:submissions:edit", args=(self.object.id,))
    )

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(buttons=self.buttons(), **kwargs)

get_form_class

get_form_class()

Returns the form class for the view.

This method is called by the view during form instantiation. It returns the form class that will be used to render the form.

When trying to save as draft, this method will return a version of form class that doesn't validate required fields while saving.

The method also disables any group toggle fields in the form, as they are not supported on edit forms.

Returns:

  • class –

    The form class for the view.

Source code in hypha/apply/funds/views.py
def get_form_class(self):
    """
    Returns the form class for the view.

    This method is called by the view during form instantiation. It returns
    the form class that will be used to render the form.

    When trying to save as draft, this method will return a version of form
    class that doesn't validate required fields while saving.

    The method also disables any group toggle fields in the form, as they
    are not supported on edit forms.

    Returns:
        class: The form class for the view.
    """
    is_draft = True if "save" in self.request.POST else False
    form_fields = self.object.get_form_fields(
        draft=is_draft, form_data=self.object.raw_data, user=self.request.user
    )
    field_blocks = self.object.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, GroupToggleBlock):
            # Disable group toggle field as it is not supported on edit forms.
            form_fields[field_block.id].disabled = True
    return type(
        "WagtailStreamForm", (self.object.submission_form_class,), form_fields
    )

AdminSubmissionEditView

Bases: BaseSubmissionEditView

model class-attribute instance-attribute

render_preview

render_preview(request, form)

Gets a rendered preview of a form

Creates a new revision on the ApplicationSubmission, removes the forms temporary files

Parameters:

  • request (HttpRequest) –

    Request used to trigger the preview to be used in the render

  • form (BaseModelForm) –

    Form to be rendered

Returns:

  • HttpResponse –

    An HttpResponse containing a preview of the given form

Source code in hypha/apply/funds/views.py
def render_preview(self, request: HttpRequest, form: BaseModelForm) -> HttpResponse:
    """Gets a rendered preview of a form

    Creates a new revision on the `ApplicationSubmission`, removes the
    forms temporary files

    Args:
        request:
            Request used to trigger the preview to be used in the render
        form:
            Form to be rendered

    Returns:
        An `HttpResponse` containing a preview of the given form
    """

    self.object.create_revision(draft=True, by=request.user)
    messages.success(self.request, _("Draft saved"))

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()

    context = self.get_context_data()
    return render(request, "funds/application_preview.html", context)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    permission, _ = has_permission(
        "submission_edit",
        request.user,
        object=self.get_object(),
        raise_exception=True,
    )
    if not self.get_object().phase.permissions.can_edit(request.user):
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

get_object_fund_current_round

get_object_fund_current_round()
Source code in hypha/apply/funds/views.py
def get_object_fund_current_round(self):
    assigned_fund = self.object.round.get_parent().specific
    if assigned_fund.open_round:
        return assigned_fund.open_round
    return False

get_on_submit_transition

get_on_submit_transition(user)

Gets the transition that should be triggered when a form is submitted.

Checks all available status transitions for the current user and returns the first one that has trigger_on_submit=True in its custom settings.

Returns:

  • dict –

    The transition configuration dictionary with trigger_on_submit=True, or None if no matching transition is found.

Source code in hypha/apply/funds/views.py
def get_on_submit_transition(self, user):
    """Gets the transition that should be triggered when a form is submitted.

    Checks all available status transitions for the current user and returns the first
    one that has trigger_on_submit=True in its custom settings.

    Returns:
        dict: The transition configuration dictionary with trigger_on_submit=True,
            or None if no matching transition is found.
    """
    return next(
        (
            t
            for t in self.object.get_available_user_status_transitions(user)
            if t.custom.get("trigger_on_submit", False)
        ),
        None,
    )

form_valid

form_valid(form)

Handle the form returned from a SubmissionEditView.

Determine whether to return a form preview, draft the new edits, or submit and transition the ApplicationSubmission object

Parameters:

  • form (BaseModelForm) –

    The valid form

Returns:

  • HttpResponse –

    An HttpResponse depending on the actions taken in the edit view

Source code in hypha/apply/funds/views.py
def form_valid(self, form: BaseModelForm) -> HttpResponse:
    """Handle the form returned from a `SubmissionEditView`.

    Determine whether to return a form preview, draft the new edits,
    or submit and transition the `ApplicationSubmission` object

    Args:
        form: The valid form

    Returns:
        An `HttpResponse` depending on the actions taken in the edit view
    """

    self.object.form_data = form.cleaned_data

    is_draft = self.object.status == DRAFT_STATE

    # Handle a preview or a save (aka a draft)
    if "preview" in self.request.POST:
        return self.render_preview(self.request, form)

    if "save" in self.request.POST:
        return self.save_draft_and_refresh_page(form=form)

    # Handle an application being submitted from a DRAFT_STATE. This includes updating submit_time
    if is_draft and "submit" in self.request.POST:
        self.object.submit_time = timezone.now()
        if self.object.round:
            current_round = self.get_object_fund_current_round()
            if current_round:
                self.object.round = current_round
        self.object.save(update_fields=["submit_time", "round"])

    revision = self.object.create_revision(by=self.request.user)
    submitting_proposal = self.object.phase.name in STAGE_CHANGE_ACTIONS

    if submitting_proposal:
        messenger(
            MESSAGES.PROPOSAL_SUBMITTED,
            request=self.request,
            user=self.request.user,
            source=self.object,
        )
    elif revision and not self.object.status == DRAFT_STATE:
        messenger(
            MESSAGES.APPLICANT_EDIT,
            request=self.request,
            user=self.request.user,
            source=self.object,
            related=revision,
        )

    if "submit" in self.request.POST:
        if transition := self.get_on_submit_transition(self.request.user):
            notify = (
                not (revision or submitting_proposal)
                or self.object.status == DRAFT_STATE,
            )
            self.object.perform_transition(
                transition.target,
                self.request.user,
                request=self.request,
                notify=notify,  # Use the other notification
            )

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()
    return HttpResponseRedirect(self.get_success_url())

get_form_kwargs

get_form_kwargs()

Returns the keyword arguments for instantiating the form.

This method is called by the form mixin during form instantiation. It returns a dictionary of keyword arguments that will be passed to the form's constructor.

Returns:

  • dict –

    A dictionary of keyword arguments for the form constructor.

Source code in hypha/apply/funds/views.py
def get_form_kwargs(self):
    """
    Returns the keyword arguments for instantiating the form.

    This method is called by the form mixin during form instantiation.
    It returns a dictionary of keyword arguments that will be passed to
    the form's constructor.

    Returns:
        dict: A dictionary of keyword arguments for the form constructor.
    """
    kwargs = super().get_form_kwargs()
    instance = kwargs.pop("instance").from_draft()
    initial = instance.raw_data
    for field_id in instance.file_field_ids:
        initial.pop(field_id + "-uploads", False)
        initial[field_id] = self.get_placeholder_file(
            instance.raw_data.get(field_id)
        )
    kwargs["initial"] = initial
    return kwargs

get_placeholder_file

get_placeholder_file(initial_file)
Source code in hypha/apply/funds/views.py
def get_placeholder_file(self, initial_file):
    if not isinstance(initial_file, list):
        return PlaceholderUploadedFile(
            initial_file.filename, size=initial_file.size, file_id=initial_file.name
        )
    return [
        PlaceholderUploadedFile(f.filename, size=f.size, file_id=f.name)
        for f in initial_file
    ]

save_draft_and_refresh_page

save_draft_and_refresh_page(form)
Source code in hypha/apply/funds/views.py
def save_draft_and_refresh_page(self, form) -> HttpResponseRedirect:
    self.object.create_revision(draft=True, by=self.request.user)
    form.delete_temporary_files()
    messages.success(self.request, _("Draft saved"))
    return HttpResponseRedirect(
        reverse_lazy("funds:submissions:edit", args=(self.object.id,))
    )

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(buttons=self.buttons(), **kwargs)

get_form_class

get_form_class()

Returns the form class for the view.

This method is called by the view during form instantiation. It returns the form class that will be used to render the form.

When trying to save as draft, this method will return a version of form class that doesn't validate required fields while saving.

The method also disables any group toggle fields in the form, as they are not supported on edit forms.

Returns:

  • class –

    The form class for the view.

Source code in hypha/apply/funds/views.py
def get_form_class(self):
    """
    Returns the form class for the view.

    This method is called by the view during form instantiation. It returns
    the form class that will be used to render the form.

    When trying to save as draft, this method will return a version of form
    class that doesn't validate required fields while saving.

    The method also disables any group toggle fields in the form, as they
    are not supported on edit forms.

    Returns:
        class: The form class for the view.
    """
    is_draft = True if "save" in self.request.POST else False
    form_fields = self.object.get_form_fields(
        draft=is_draft, form_data=self.object.raw_data, user=self.request.user
    )
    field_blocks = self.object.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, GroupToggleBlock):
            # Disable group toggle field as it is not supported on edit forms.
            form_fields[field_block.id].disabled = True
    return type(
        "WagtailStreamForm", (self.object.submission_form_class,), form_fields
    )

buttons

buttons()

The buttons to be presented in the AdminSubmissionEditView

Admins shouldn't be required to preview, but should have the option.

Returns:

  • str –

    A generator returning a tuple strings in the format of:

  • str –

    (

Source code in hypha/apply/funds/views.py
def buttons(
    self,
) -> Generator[Tuple[str, str, str], Tuple[str, str, str], Tuple[str, str, str]]:
    """The buttons to be presented in the `AdminSubmissionEditView`

    Admins shouldn't be required to preview, but should have the option.

    Returns:
        A generator returning a tuple strings in the format of:
        (<button type>, <button styling>, <button label>)
    """
    yield ("submit", "primary", _("Submit"))
    yield ("save", "white", _("Save draft"))
    yield ("preview", "white", _("Preview"))

ApplicantSubmissionEditView

Bases: BaseSubmissionEditView

model class-attribute instance-attribute

render_preview

render_preview(request, form)

Gets a rendered preview of a form

Creates a new revision on the ApplicationSubmission, removes the forms temporary files

Parameters:

  • request (HttpRequest) –

    Request used to trigger the preview to be used in the render

  • form (BaseModelForm) –

    Form to be rendered

Returns:

  • HttpResponse –

    An HttpResponse containing a preview of the given form

Source code in hypha/apply/funds/views.py
def render_preview(self, request: HttpRequest, form: BaseModelForm) -> HttpResponse:
    """Gets a rendered preview of a form

    Creates a new revision on the `ApplicationSubmission`, removes the
    forms temporary files

    Args:
        request:
            Request used to trigger the preview to be used in the render
        form:
            Form to be rendered

    Returns:
        An `HttpResponse` containing a preview of the given form
    """

    self.object.create_revision(draft=True, by=request.user)
    messages.success(self.request, _("Draft saved"))

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()

    context = self.get_context_data()
    return render(request, "funds/application_preview.html", context)

buttons

buttons()

The buttons to be presented to the in the EditView

Returns:

  • str –

    A generator returning a tuple strings in the format of:

  • str –

    (

Source code in hypha/apply/funds/views.py
def buttons(
    self,
) -> Generator[Tuple[str, str, str], Tuple[str, str, str], Tuple[str, str, str]]:
    """The buttons to be presented to the in the EditView

    Returns:
        A generator returning a tuple strings in the format of:
        (<button type>, <button styling>, <button label>)
    """
    if settings.SUBMISSION_PREVIEW_REQUIRED:
        yield ("preview", "primary", _("Preview and submit"))
        yield ("save", "white", _("Save draft"))
    else:
        yield ("submit", "primary", _("Submit"))
        yield ("save", "white", _("Save draft"))
        yield ("preview", "white", _("Preview"))

get_object_fund_current_round

get_object_fund_current_round()
Source code in hypha/apply/funds/views.py
def get_object_fund_current_round(self):
    assigned_fund = self.object.round.get_parent().specific
    if assigned_fund.open_round:
        return assigned_fund.open_round
    return False

get_on_submit_transition

get_on_submit_transition(user)

Gets the transition that should be triggered when a form is submitted.

Checks all available status transitions for the current user and returns the first one that has trigger_on_submit=True in its custom settings.

Returns:

  • dict –

    The transition configuration dictionary with trigger_on_submit=True, or None if no matching transition is found.

Source code in hypha/apply/funds/views.py
def get_on_submit_transition(self, user):
    """Gets the transition that should be triggered when a form is submitted.

    Checks all available status transitions for the current user and returns the first
    one that has trigger_on_submit=True in its custom settings.

    Returns:
        dict: The transition configuration dictionary with trigger_on_submit=True,
            or None if no matching transition is found.
    """
    return next(
        (
            t
            for t in self.object.get_available_user_status_transitions(user)
            if t.custom.get("trigger_on_submit", False)
        ),
        None,
    )

form_valid

form_valid(form)

Handle the form returned from a SubmissionEditView.

Determine whether to return a form preview, draft the new edits, or submit and transition the ApplicationSubmission object

Parameters:

  • form (BaseModelForm) –

    The valid form

Returns:

  • HttpResponse –

    An HttpResponse depending on the actions taken in the edit view

Source code in hypha/apply/funds/views.py
def form_valid(self, form: BaseModelForm) -> HttpResponse:
    """Handle the form returned from a `SubmissionEditView`.

    Determine whether to return a form preview, draft the new edits,
    or submit and transition the `ApplicationSubmission` object

    Args:
        form: The valid form

    Returns:
        An `HttpResponse` depending on the actions taken in the edit view
    """

    self.object.form_data = form.cleaned_data

    is_draft = self.object.status == DRAFT_STATE

    # Handle a preview or a save (aka a draft)
    if "preview" in self.request.POST:
        return self.render_preview(self.request, form)

    if "save" in self.request.POST:
        return self.save_draft_and_refresh_page(form=form)

    # Handle an application being submitted from a DRAFT_STATE. This includes updating submit_time
    if is_draft and "submit" in self.request.POST:
        self.object.submit_time = timezone.now()
        if self.object.round:
            current_round = self.get_object_fund_current_round()
            if current_round:
                self.object.round = current_round
        self.object.save(update_fields=["submit_time", "round"])

    revision = self.object.create_revision(by=self.request.user)
    submitting_proposal = self.object.phase.name in STAGE_CHANGE_ACTIONS

    if submitting_proposal:
        messenger(
            MESSAGES.PROPOSAL_SUBMITTED,
            request=self.request,
            user=self.request.user,
            source=self.object,
        )
    elif revision and not self.object.status == DRAFT_STATE:
        messenger(
            MESSAGES.APPLICANT_EDIT,
            request=self.request,
            user=self.request.user,
            source=self.object,
            related=revision,
        )

    if "submit" in self.request.POST:
        if transition := self.get_on_submit_transition(self.request.user):
            notify = (
                not (revision or submitting_proposal)
                or self.object.status == DRAFT_STATE,
            )
            self.object.perform_transition(
                transition.target,
                self.request.user,
                request=self.request,
                notify=notify,  # Use the other notification
            )

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()
    return HttpResponseRedirect(self.get_success_url())

get_form_kwargs

get_form_kwargs()

Returns the keyword arguments for instantiating the form.

This method is called by the form mixin during form instantiation. It returns a dictionary of keyword arguments that will be passed to the form's constructor.

Returns:

  • dict –

    A dictionary of keyword arguments for the form constructor.

Source code in hypha/apply/funds/views.py
def get_form_kwargs(self):
    """
    Returns the keyword arguments for instantiating the form.

    This method is called by the form mixin during form instantiation.
    It returns a dictionary of keyword arguments that will be passed to
    the form's constructor.

    Returns:
        dict: A dictionary of keyword arguments for the form constructor.
    """
    kwargs = super().get_form_kwargs()
    instance = kwargs.pop("instance").from_draft()
    initial = instance.raw_data
    for field_id in instance.file_field_ids:
        initial.pop(field_id + "-uploads", False)
        initial[field_id] = self.get_placeholder_file(
            instance.raw_data.get(field_id)
        )
    kwargs["initial"] = initial
    return kwargs

get_placeholder_file

get_placeholder_file(initial_file)
Source code in hypha/apply/funds/views.py
def get_placeholder_file(self, initial_file):
    if not isinstance(initial_file, list):
        return PlaceholderUploadedFile(
            initial_file.filename, size=initial_file.size, file_id=initial_file.name
        )
    return [
        PlaceholderUploadedFile(f.filename, size=f.size, file_id=f.name)
        for f in initial_file
    ]

save_draft_and_refresh_page

save_draft_and_refresh_page(form)
Source code in hypha/apply/funds/views.py
def save_draft_and_refresh_page(self, form) -> HttpResponseRedirect:
    self.object.create_revision(draft=True, by=self.request.user)
    form.delete_temporary_files()
    messages.success(self.request, _("Draft saved"))
    return HttpResponseRedirect(
        reverse_lazy("funds:submissions:edit", args=(self.object.id,))
    )

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(buttons=self.buttons(), **kwargs)

get_form_class

get_form_class()

Returns the form class for the view.

This method is called by the view during form instantiation. It returns the form class that will be used to render the form.

When trying to save as draft, this method will return a version of form class that doesn't validate required fields while saving.

The method also disables any group toggle fields in the form, as they are not supported on edit forms.

Returns:

  • class –

    The form class for the view.

Source code in hypha/apply/funds/views.py
def get_form_class(self):
    """
    Returns the form class for the view.

    This method is called by the view during form instantiation. It returns
    the form class that will be used to render the form.

    When trying to save as draft, this method will return a version of form
    class that doesn't validate required fields while saving.

    The method also disables any group toggle fields in the form, as they
    are not supported on edit forms.

    Returns:
        class: The form class for the view.
    """
    is_draft = True if "save" in self.request.POST else False
    form_fields = self.object.get_form_fields(
        draft=is_draft, form_data=self.object.raw_data, user=self.request.user
    )
    field_blocks = self.object.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, GroupToggleBlock):
            # Disable group toggle field as it is not supported on edit forms.
            form_fields[field_block.id].disabled = True
    return type(
        "WagtailStreamForm", (self.object.submission_form_class,), form_fields
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    if request.user != submission.user:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

PartnerSubmissionEditView

Bases: ApplicantSubmissionEditView

model class-attribute instance-attribute

render_preview

render_preview(request, form)

Gets a rendered preview of a form

Creates a new revision on the ApplicationSubmission, removes the forms temporary files

Parameters:

  • request (HttpRequest) –

    Request used to trigger the preview to be used in the render

  • form (BaseModelForm) –

    Form to be rendered

Returns:

  • HttpResponse –

    An HttpResponse containing a preview of the given form

Source code in hypha/apply/funds/views.py
def render_preview(self, request: HttpRequest, form: BaseModelForm) -> HttpResponse:
    """Gets a rendered preview of a form

    Creates a new revision on the `ApplicationSubmission`, removes the
    forms temporary files

    Args:
        request:
            Request used to trigger the preview to be used in the render
        form:
            Form to be rendered

    Returns:
        An `HttpResponse` containing a preview of the given form
    """

    self.object.create_revision(draft=True, by=request.user)
    messages.success(self.request, _("Draft saved"))

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()

    context = self.get_context_data()
    return render(request, "funds/application_preview.html", context)

buttons

buttons()

The buttons to be presented to the in the EditView

Returns:

  • str –

    A generator returning a tuple strings in the format of:

  • str –

    (

Source code in hypha/apply/funds/views.py
def buttons(
    self,
) -> Generator[Tuple[str, str, str], Tuple[str, str, str], Tuple[str, str, str]]:
    """The buttons to be presented to the in the EditView

    Returns:
        A generator returning a tuple strings in the format of:
        (<button type>, <button styling>, <button label>)
    """
    if settings.SUBMISSION_PREVIEW_REQUIRED:
        yield ("preview", "primary", _("Preview and submit"))
        yield ("save", "white", _("Save draft"))
    else:
        yield ("submit", "primary", _("Submit"))
        yield ("save", "white", _("Save draft"))
        yield ("preview", "white", _("Preview"))

get_object_fund_current_round

get_object_fund_current_round()
Source code in hypha/apply/funds/views.py
def get_object_fund_current_round(self):
    assigned_fund = self.object.round.get_parent().specific
    if assigned_fund.open_round:
        return assigned_fund.open_round
    return False

get_on_submit_transition

get_on_submit_transition(user)

Gets the transition that should be triggered when a form is submitted.

Checks all available status transitions for the current user and returns the first one that has trigger_on_submit=True in its custom settings.

Returns:

  • dict –

    The transition configuration dictionary with trigger_on_submit=True, or None if no matching transition is found.

Source code in hypha/apply/funds/views.py
def get_on_submit_transition(self, user):
    """Gets the transition that should be triggered when a form is submitted.

    Checks all available status transitions for the current user and returns the first
    one that has trigger_on_submit=True in its custom settings.

    Returns:
        dict: The transition configuration dictionary with trigger_on_submit=True,
            or None if no matching transition is found.
    """
    return next(
        (
            t
            for t in self.object.get_available_user_status_transitions(user)
            if t.custom.get("trigger_on_submit", False)
        ),
        None,
    )

form_valid

form_valid(form)

Handle the form returned from a SubmissionEditView.

Determine whether to return a form preview, draft the new edits, or submit and transition the ApplicationSubmission object

Parameters:

  • form (BaseModelForm) –

    The valid form

Returns:

  • HttpResponse –

    An HttpResponse depending on the actions taken in the edit view

Source code in hypha/apply/funds/views.py
def form_valid(self, form: BaseModelForm) -> HttpResponse:
    """Handle the form returned from a `SubmissionEditView`.

    Determine whether to return a form preview, draft the new edits,
    or submit and transition the `ApplicationSubmission` object

    Args:
        form: The valid form

    Returns:
        An `HttpResponse` depending on the actions taken in the edit view
    """

    self.object.form_data = form.cleaned_data

    is_draft = self.object.status == DRAFT_STATE

    # Handle a preview or a save (aka a draft)
    if "preview" in self.request.POST:
        return self.render_preview(self.request, form)

    if "save" in self.request.POST:
        return self.save_draft_and_refresh_page(form=form)

    # Handle an application being submitted from a DRAFT_STATE. This includes updating submit_time
    if is_draft and "submit" in self.request.POST:
        self.object.submit_time = timezone.now()
        if self.object.round:
            current_round = self.get_object_fund_current_round()
            if current_round:
                self.object.round = current_round
        self.object.save(update_fields=["submit_time", "round"])

    revision = self.object.create_revision(by=self.request.user)
    submitting_proposal = self.object.phase.name in STAGE_CHANGE_ACTIONS

    if submitting_proposal:
        messenger(
            MESSAGES.PROPOSAL_SUBMITTED,
            request=self.request,
            user=self.request.user,
            source=self.object,
        )
    elif revision and not self.object.status == DRAFT_STATE:
        messenger(
            MESSAGES.APPLICANT_EDIT,
            request=self.request,
            user=self.request.user,
            source=self.object,
            related=revision,
        )

    if "submit" in self.request.POST:
        if transition := self.get_on_submit_transition(self.request.user):
            notify = (
                not (revision or submitting_proposal)
                or self.object.status == DRAFT_STATE,
            )
            self.object.perform_transition(
                transition.target,
                self.request.user,
                request=self.request,
                notify=notify,  # Use the other notification
            )

    # Required for django-file-form: delete temporary files for the new files
    # uploaded while edit.
    form.delete_temporary_files()
    return HttpResponseRedirect(self.get_success_url())

get_form_kwargs

get_form_kwargs()

Returns the keyword arguments for instantiating the form.

This method is called by the form mixin during form instantiation. It returns a dictionary of keyword arguments that will be passed to the form's constructor.

Returns:

  • dict –

    A dictionary of keyword arguments for the form constructor.

Source code in hypha/apply/funds/views.py
def get_form_kwargs(self):
    """
    Returns the keyword arguments for instantiating the form.

    This method is called by the form mixin during form instantiation.
    It returns a dictionary of keyword arguments that will be passed to
    the form's constructor.

    Returns:
        dict: A dictionary of keyword arguments for the form constructor.
    """
    kwargs = super().get_form_kwargs()
    instance = kwargs.pop("instance").from_draft()
    initial = instance.raw_data
    for field_id in instance.file_field_ids:
        initial.pop(field_id + "-uploads", False)
        initial[field_id] = self.get_placeholder_file(
            instance.raw_data.get(field_id)
        )
    kwargs["initial"] = initial
    return kwargs

get_placeholder_file

get_placeholder_file(initial_file)
Source code in hypha/apply/funds/views.py
def get_placeholder_file(self, initial_file):
    if not isinstance(initial_file, list):
        return PlaceholderUploadedFile(
            initial_file.filename, size=initial_file.size, file_id=initial_file.name
        )
    return [
        PlaceholderUploadedFile(f.filename, size=f.size, file_id=f.name)
        for f in initial_file
    ]

save_draft_and_refresh_page

save_draft_and_refresh_page(form)
Source code in hypha/apply/funds/views.py
def save_draft_and_refresh_page(self, form) -> HttpResponseRedirect:
    self.object.create_revision(draft=True, by=self.request.user)
    form.delete_temporary_files()
    messages.success(self.request, _("Draft saved"))
    return HttpResponseRedirect(
        reverse_lazy("funds:submissions:edit", args=(self.object.id,))
    )

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(buttons=self.buttons(), **kwargs)

get_form_class

get_form_class()

Returns the form class for the view.

This method is called by the view during form instantiation. It returns the form class that will be used to render the form.

When trying to save as draft, this method will return a version of form class that doesn't validate required fields while saving.

The method also disables any group toggle fields in the form, as they are not supported on edit forms.

Returns:

  • class –

    The form class for the view.

Source code in hypha/apply/funds/views.py
def get_form_class(self):
    """
    Returns the form class for the view.

    This method is called by the view during form instantiation. It returns
    the form class that will be used to render the form.

    When trying to save as draft, this method will return a version of form
    class that doesn't validate required fields while saving.

    The method also disables any group toggle fields in the form, as they
    are not supported on edit forms.

    Returns:
        class: The form class for the view.
    """
    is_draft = True if "save" in self.request.POST else False
    form_fields = self.object.get_form_fields(
        draft=is_draft, form_data=self.object.raw_data, user=self.request.user
    )
    field_blocks = self.object.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, GroupToggleBlock):
            # Disable group toggle field as it is not supported on edit forms.
            form_fields[field_block.id].disabled = True
    return type(
        "WagtailStreamForm", (self.object.submission_form_class,), form_fields
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, request, *args, **kwargs):
    submission = self.get_object()
    # If the requesting user submitted the application, return the Applicant view.
    # Partners may somtimes be applicants as well.
    partner_has_access = submission.partners.filter(pk=request.user.pk).exists()
    if not partner_has_access and submission.user != request.user:
        raise PermissionDenied
    return super(ApplicantSubmissionEditView, self).dispatch(
        request, *args, **kwargs
    )

SubmissionEditView

Bases: ViewDispatcher

community_view class-attribute instance-attribute

community_view = None

finance_view class-attribute instance-attribute

finance_view = None

contracting_view class-attribute instance-attribute

contracting_view = None

admin_view class-attribute instance-attribute

applicant_view class-attribute instance-attribute

applicant_view = ApplicantSubmissionEditView

reviewer_view class-attribute instance-attribute

partner_view class-attribute instance-attribute

admin_check

admin_check(request)
Source code in hypha/apply/utils/views.py
def admin_check(self, request):
    return request.user.is_apply_staff

reviewer_check

reviewer_check(request)
Source code in hypha/apply/utils/views.py
def reviewer_check(self, request):
    return request.user.is_reviewer

partner_check

partner_check(request)
Source code in hypha/apply/utils/views.py
def partner_check(self, request):
    return request.user.is_partner

community_check

community_check(request)
Source code in hypha/apply/utils/views.py
def community_check(self, request):
    return request.user.is_community_reviewer

finance_check

finance_check(request)
Source code in hypha/apply/utils/views.py
def finance_check(self, request):
    return request.user.is_finance

contracting_check

contracting_check(request)
Source code in hypha/apply/utils/views.py
def contracting_check(self, request):
    return request.user.is_contracting

applicant_check

applicant_check(request)
Source code in hypha/apply/utils/views.py
def applicant_check(self, request):
    return request.user.is_applicant

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def dispatch(self, request, *args, **kwargs):
    view = None

    if self.admin_check(request):
        view = self.admin_view
    elif self.reviewer_check(request):
        view = self.reviewer_view
    elif self.partner_check(request):
        view = self.partner_view
    elif self.community_check(request):
        view = self.community_view
    elif settings.PROJECTS_ENABLED and self.finance_check(request):
        view = self.finance_view
    elif settings.PROJECTS_ENABLED and self.contracting_check(request):
        view = self.contracting_view
    elif self.applicant_check(request):
        view = self.applicant_view

    if view:
        return view.as_view()(request, *args, **kwargs)
    return HttpResponseForbidden()

RevisionListView

Bases: ListView

model class-attribute instance-attribute

get_queryset

get_queryset()

Get a queryset of all valid ApplicationRevisions that can be compared for the current submission

This excludes draft & preview revisions unless draft(s) are the only existing revisions, in which the last draft will be returned in a QuerySet

Returns:

Source code in hypha/apply/funds/views.py
def get_queryset(self):
    """Get a queryset of all valid `ApplicationRevision`s that can be
    compared for the current submission

    This excludes draft & preview revisions unless draft(s) are the only
    existing revisions, in which the last draft will be returned in a QuerySet

    Returns:
        An [`ApplicationRevision`][hypha.apply.funds.models.ApplicationRevision] QuerySet
    """
    self.submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )
    revisions = self.model.objects.filter(submission=self.submission).exclude(
        draft__isnull=False, live__isnull=True
    )

    filtered_revisions = revisions.filter(is_draft=False)

    # An edge case for when an instance has `SUBMISSIONS_DRAFT_ACCESS_STAFF=True`
    # and a staff member tries to view the revisions of the draft.
    if len(filtered_revisions) < 1:
        self.queryset = self.model.objects.filter(id=revisions.last().id)
    else:
        self.queryset = filtered_revisions

    return super().get_queryset()

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    return super().get_context_data(
        submission=self.submission,
        **kwargs,
    )

RevisionCompareView

Bases: DetailView

model class-attribute instance-attribute

template_name class-attribute instance-attribute

template_name = 'funds/revisions_compare.html'

pk_url_kwarg class-attribute instance-attribute

pk_url_kwarg = 'submission_pk'

compare_revisions

compare_revisions(from_data, to_data)
Source code in hypha/apply/funds/views.py
def compare_revisions(self, from_data, to_data):
    self.object.form_data = from_data.form_data
    from_rendered_text_fields = self.object.render_text_blocks_answers()
    from_required = self.render_required()

    self.object.form_data = to_data.form_data
    to_rendered_text_fields = self.object.render_text_blocks_answers()
    to_required = self.render_required()

    required_fields = [
        compare(*fields) for fields in zip(from_required, to_required, strict=False)
    ]

    stream_fields = [
        compare(*fields)
        for fields in zip(
            from_rendered_text_fields, to_rendered_text_fields, strict=False
        )
    ]

    return (required_fields, stream_fields)

render_required

render_required()
Source code in hypha/apply/funds/views.py
def render_required(self):
    return [
        getattr(self.object, "get_{}_display".format(field))()
        for field in self.object.named_blocks
    ]

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    from_revision = self.object.revisions.get(id=self.kwargs["from"])
    to_revision = self.object.revisions.get(id=self.kwargs["to"])
    required_fields, stream_fields = self.compare_revisions(
        from_revision, to_revision
    )
    timestamps = (from_revision.timestamp, to_revision.timestamp)
    return super().get_context_data(
        timestamps=timestamps,
        required_fields=required_fields,
        stream_fields=stream_fields,
        **kwargs,
    )

RoundListView

Bases: SingleTableMixin, FilterView

template_name class-attribute instance-attribute

template_name = 'funds/rounds.html'

table_class class-attribute instance-attribute

table_class = RoundsTable

filterset_class class-attribute instance-attribute

filterset_class = RoundsFilter

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    return RoundsAndLabs.objects.with_progress()

SubmissionDeleteView

Bases: LoginRequiredMixin, UserPassesTestMixin, DeleteView

View for deleting submissions with confirmation modal.

After successful deletion: - Redirects applicants to their dashboard - Redirects staff to the submissions list - Creates delete notification unless author deleting own draft

model class-attribute instance-attribute

test_func

test_func()
Source code in hypha/apply/funds/views.py
def test_func(self):
    return has_object_permission(
        "delete_submission", self.request.user, obj=self.get_object()
    )

get_success_url

get_success_url()
Source code in hypha/apply/funds/views.py
def get_success_url(self):
    if self.request.user.is_applicant:
        return reverse_lazy("dashboard:dashboard")
    return reverse_lazy("funds:submissions:list")

form_valid

form_valid(form)
Source code in hypha/apply/funds/views.py
def form_valid(self, form):
    submission = self.get_object()

    # Notify unless author delete own draft.
    if submission.status != DRAFT_STATE and submission.user != self.request.user:
        messenger(
            MESSAGES.DELETE_SUBMISSION,
            user=self.request.user,
            request=self.request,
            source=submission,
        )

    # Delete NEW_SUBMISSION event for this particular submission, if any.
    # Otherwise, the submission deletion will fail.
    Event.objects.filter(
        type=MESSAGES.NEW_SUBMISSION, object_id=submission.id
    ).delete()

    # delete submission and redirect to success url
    return super().form_valid(form)

SubmissionPrivateMediaView

Bases: UserPassesTestMixin, PrivateMediaView

storage class-attribute instance-attribute

storage = PrivateStorage()

raise_exception class-attribute instance-attribute

raise_exception = True

get

get(*args, **kwargs)
Source code in hypha/apply/utils/storage.py
def get(self, *args, **kwargs):
    file_to_serve = self.get_media(*args, **kwargs)
    return FileResponse(file_to_serve)

dispatch

dispatch(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def dispatch(self, *args, **kwargs):
    submission_pk = self.kwargs["pk"]
    self.submission = get_object_or_404(ApplicationSubmission, pk=submission_pk)
    return super().dispatch(*args, **kwargs)

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/funds/views.py
def get_media(self, *args, **kwargs):
    field_id = kwargs["field_id"]
    file_name = kwargs["file_name"]
    path_to_file = generate_private_file_path(
        self.submission.pk, field_id, file_name
    )
    return self.storage.open(path_to_file)

test_func

test_func()
Source code in hypha/apply/funds/views.py
def test_func(self):
    permission, _ = has_permission(
        "submission_view", self.request.user, self.submission
    )
    return permission

SubmissionDetailSimplifiedView

Bases: DetailView

model class-attribute instance-attribute

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_simplified_detail'

get_object

get_object(queryset=None)
Source code in hypha/apply/funds/views.py
def get_object(self, queryset=None):
    obj = super().get_object(queryset)

    if not hasattr(obj, "project"):
        raise Http404

    return obj

SubmissionDetailPDFView

Bases: SingleObjectMixin, View

model class-attribute instance-attribute

get_object

get_object(queryset=None)
Source code in hypha/apply/funds/views.py
def get_object(self, queryset=None):
    obj = super().get_object(queryset)

    if not hasattr(obj, "project"):
        raise Http404

    return obj

get

get(request, *args, **kwargs)
Source code in hypha/apply/funds/views.py
def get(self, request, *args, **kwargs):
    self.object = self.get_object()
    pdf_page_settings = PDFPageSettings.for_request(request)
    content = draw_submission_content(self.object.output_text_answers())
    pdf = make_pdf(
        title=self.object.title,
        sections=[
            {
                "content": content,
                "title": "Submission",
                "meta": [
                    self.object.stage,
                    self.object.page,
                    self.object.round,
                    f"Lead: { self.object.lead }",
                ],
            },
        ],
        pagesize=pdf_page_settings.download_page_size,
    )
    return FileResponse(
        pdf,
        as_attachment=True,
        filename=self.object.title + ".pdf",
    )

SubmissionResultView

Bases: SubmissionStatsMixin, FilterView

template_name class-attribute instance-attribute

template_name = 'funds/submissions_result.html'

filterset_class class-attribute instance-attribute

filterset_class = SubmissionFilterAndSearch

filter_action class-attribute instance-attribute

filter_action = ''

excluded_fields class-attribute instance-attribute

excluded_fields = SUBMISSIONS_TABLE_EXCLUDED_FIELDS

excluded property

excluded

get_filterset_kwargs

get_filterset_kwargs(filterset_class, **kwargs)
Source code in hypha/apply/funds/views.py
def get_filterset_kwargs(self, filterset_class, **kwargs):
    new_kwargs = super().get_filterset_kwargs(filterset_class)
    new_kwargs.update(self.excluded)
    new_kwargs.update(kwargs)
    return new_kwargs

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    return (
        self.filterset_class._meta.model.objects.current()
        .exclude_draft()
        .defer(
            "search_data",
            "drupal_id",
            "submit_time",
            "workflow_name",
            "search_document",
            "live_revision_id",
            "draft_revision_id",
            "summary",
        )
    )

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    search_term = self.request.GET.get("query")

    if self.object_list:
        submission_values = self.object_list.value()
        count_values = submission_values.get("value__count")
        total_value = format_submission_sum_value(submission_values)
        if value := submission_values.get("value__avg"):
            average_value = round(value)
        else:
            average_value = 0
    else:
        count_values = 0
        total_value = 0
        average_value = 0

    return super().get_context_data(
        search_term=search_term,
        filter_action=self.filter_action,
        count_values=count_values,
        total_value=total_value,
        average_value=average_value,
        **kwargs,
    )

ReviewerLeaderboard

Bases: SingleTableMixin, FilterView

filterset_class class-attribute instance-attribute

filterset_class = ReviewerLeaderboardFilter

filter_action class-attribute instance-attribute

filter_action = ''

table_class class-attribute instance-attribute

table_pagination class-attribute instance-attribute

table_pagination = False

template_name class-attribute instance-attribute

template_name = 'funds/reviewer_leaderboard.html'

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    search_term = self.request.GET.get("query")

    return super().get_context_data(
        search_term=search_term,
        filter_action=self.filter_action,
        **kwargs,
    )

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    # Only list reviewers.
    return self.filterset_class._meta.model.objects.reviewers()

get_table_data

get_table_data()
Source code in hypha/apply/funds/views.py
def get_table_data(self):
    ninety_days_ago = timezone.now() - timedelta(days=90)
    this_year = timezone.now().year
    last_year = timezone.now().year - 1
    return (
        super()
        .get_table_data()
        .annotate(
            total=Count("assignedreviewers__review"),
            ninety_days=Count(
                "assignedreviewers__review",
                filter=Q(
                    assignedreviewers__review__created_at__date__gte=ninety_days_ago
                ),
            ),
            this_year=Count(
                "assignedreviewers__review",
                filter=Q(assignedreviewers__review__created_at__year=this_year),
            ),
            last_year=Count(
                "assignedreviewers__review",
                filter=Q(assignedreviewers__review__created_at__year=last_year),
            ),
        )
    )

ReviewerLeaderboardDetail

Bases: SingleTableMixin, ListView

model class-attribute instance-attribute

model = Review

table_class class-attribute instance-attribute

paginator_class class-attribute instance-attribute

paginator_class = LazyPaginator

table_pagination class-attribute instance-attribute

table_pagination = {'per_page': 25}

template_name class-attribute instance-attribute

template_name = 'funds/reviewer_leaderboard_detail.html'

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/funds/views.py
def get_context_data(self, **kwargs):
    obj = User.objects.get(pk=self.kwargs.get("pk"))
    return super().get_context_data(object=obj, **kwargs)

get_table_data

get_table_data()
Source code in hypha/apply/funds/views.py
def get_table_data(self):
    return (
        super()
        .get_table_data()
        .filter(author__reviewer_id=self.kwargs.get("pk"))
        .select_related("submission")
    )

RoleColumn

Bases: Column

render

render(value, record)
Source code in hypha/apply/funds/views.py
def render(self, value, record):
    return AssignedReviewers.objects.filter(
        reviewer=record,
        role=self.verbose_name,
        submission__status__in=active_statuses,
    ).count()

StaffAssignments

Bases: SingleTableMixin, ListView

model class-attribute instance-attribute

model = User

table_class class-attribute instance-attribute

table_class = StaffAssignmentsTable

table_pagination class-attribute instance-attribute

table_pagination = False

template_name class-attribute instance-attribute

template_name = 'funds/staff_assignments.html'

get_queryset

get_queryset()
Source code in hypha/apply/funds/views.py
def get_queryset(self):
    # Only list staff.
    return self.model.objects.staff()

get_table_data

get_table_data()
Source code in hypha/apply/funds/views.py
def get_table_data(self):
    table_data = super().get_table_data()
    reviewer_roles = ReviewerRole.objects.all().order_by("order")
    for data in table_data:
        for i, _role in enumerate(reviewer_roles):
            # Only setting column name with dummy value 0.
            # Actual value will be set in RoleColumn render method.
            setattr(data, f"role{i}", 0)
    return table_data

get_table_kwargs

get_table_kwargs()
Source code in hypha/apply/funds/views.py
def get_table_kwargs(self):
    reviewer_roles = ReviewerRole.objects.all().order_by("order")
    extra_columns = []
    for i, role in enumerate(reviewer_roles):
        extra_columns.append((f"role{i}", RoleColumn(verbose_name=role)))
    return {
        "extra_columns": extra_columns,
    }

submission_success

submission_success(request, pk)
Source code in hypha/apply/funds/views.py
def submission_success(request, pk):
    submission = get_object_or_404(ApplicationSubmission, pk=pk)
    return render(
        request,
        "funds/submission-success.html",
        {
            "form_submission": submission,
        },
    )

htmx_archive_unarchive_submission

htmx_archive_unarchive_submission(request, pk)
Source code in hypha/apply/funds/views.py
@login_required
@user_passes_test(is_apply_staff)
@require_http_methods(["GET", "POST"])
def htmx_archive_unarchive_submission(request, pk):
    submission = get_object_or_404(ApplicationSubmission, id=pk)
    permission, reason = has_permission(
        "archive_alter", request.user, object=submission, raise_exception=False
    )
    if not permission:
        return HttpResponse(reason)

    if submission.is_archive:
        template = "funds/includes/modal_unarchive_submission_confirm.html"
    else:
        template = "funds/includes/modal_archive_submission_confirm.html"

    if request.method == "POST":
        if submission.is_archive:
            submission.is_archive = False
            submission.save()
            messenger(
                MESSAGES.UNARCHIVE_SUBMISSION,
                request=request,
                user=request.user,
                source=submission,
            )
        else:
            submission.is_archive = True
            submission.save()
            messenger(
                MESSAGES.ARCHIVE_SUBMISSION,
                request=request,
                user=request.user,
                source=submission,
            )

        return redirect(submission.get_absolute_url())

    return render(
        request,
        template,
        context={"submission": submission},
    )

reminder_list

reminder_list(request, pk)
Source code in hypha/apply/funds/views.py
@login_required
@user_passes_test(is_apply_staff)
@require_http_methods(["GET"])
def reminder_list(request, pk):
    submission = get_object_or_404(ApplicationSubmission, id=pk)
    reminders = Reminder.objects.filter(submission=submission)
    return render(
        request,
        "funds/includes/reminders_block.html",
        context={"reminders": reminders, "object": submission},
    )