Skip to content

Views

hypha.apply.determinations.views

BatchDeterminationCreateView

Bases: BaseStreamForm, CreateView

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

submission_form_class class-attribute instance-attribute

submission_form_class = BatchDeterminationForm

template_name class-attribute instance-attribute

template_name = 'determinations/batch_determination_form.html'

from_db classmethod

from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def from_db(cls, db, field_names, values):
    instance = super().from_db(db, field_names, values)
    if "form_data" in field_names:
        instance.form_data = cls.deserialize_form_data(
            instance, instance.form_data, instance.form_fields
        )
    return instance

deserialize_form_data classmethod

deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
    data = form_data.copy()
    # PERFORMANCE NOTE:
    # Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
    # including any sub queries that they do
    for _i, field_data in enumerate(form_fields.raw_data):
        block = form_fields.stream_block.child_blocks[field_data["type"]]
        field_id = field_data.get("id")
        try:
            value = data[field_id]
        except KeyError:
            pass
        else:
            data[field_id] = block.decode(value)
    return data

get_form_fields

get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_fields(self, draft=False, form_data=None, user=None):
    if form_data is None:
        form_data = {}

    form_fields = OrderedDict()
    field_blocks = self.get_defined_fields()
    group_counter = 1
    is_in_group = False

    # If true option 1 is selected
    grouped_fields_visible = False
    for struct_child in field_blocks:
        block = struct_child.block
        struct_value = struct_child.value
        if isinstance(block, FormFieldBlock):
            field_from_block = block.get_field(struct_value)
            disabled_help_text = _(
                "You are logged in so this information is fetched from your user account."
            )
            if isinstance(block, FullNameBlock) and user and user.is_authenticated:
                if user.full_name:
                    field_from_block.disabled = True
                    field_from_block.initial = user.full_name
                    field_from_block.help_text = disabled_help_text
                else:
                    field_from_block.help_text = _(
                        "You are logged in but your user account does not have a "
                        "full name. We'll update your user account with the name you provide here."
                    )
            if isinstance(block, EmailBlock) and user and user.is_authenticated:
                field_from_block.disabled = True
                field_from_block.initial = user.email
                field_from_block.help_text = disabled_help_text
            if draft and not issubclass(
                block.__class__, ApplicationMustIncludeFieldBlock
            ):
                field_from_block.required = False
            field_from_block.help_link = struct_value.get("help_link")
            field_from_block.group_number = group_counter if is_in_group else 1
            if isinstance(block, GroupToggleBlock) and not is_in_group:
                field_from_block.group_number = 1
                field_from_block.grouper_for = group_counter + 1
                group_counter += 1
                is_in_group = True
                grouped_fields_visible = (
                    form_data.get(struct_child.id) == field_from_block.choices[0][0]
                )
            if isinstance(block, TextFieldBlock):
                field_from_block.word_limit = struct_value.get("word_limit")
            if isinstance(block, MultiInputCharFieldBlock):
                number_of_inputs = struct_value.get("number_of_inputs")
                for index in range(number_of_inputs):
                    form_fields[struct_child.id + "_" + str(index)] = (
                        field_from_block
                    )
                    field_from_block.multi_input_id = struct_child.id
                    field_from_block.add_button_text = struct_value.get(
                        "add_button_text"
                    )
                    if (
                        index == number_of_inputs - 1
                    ):  # Add button after last input field
                        field_from_block.multi_input_add_button = True
                        # Index for field until which fields will be visible to applicant.
                        # Initially only the first field with id UUID_0 will be visible.
                        field_from_block.visibility_index = 0
                        field_from_block.max_index = index
                    if index != 0:
                        field_from_block.multi_input_field = True
                        field_from_block.required = False
                        field_from_block.initial = None
                    field_from_block = copy.copy(field_from_block)
            else:
                if is_in_group and not isinstance(block, GroupToggleBlock):
                    field_from_block.required_when_visible = (
                        field_from_block.required
                    )
                    field_from_block.required = (
                        field_from_block.required & grouped_fields_visible
                    )
                    field_from_block.visible = grouped_fields_visible
                form_fields[struct_child.id] = field_from_block
        elif isinstance(block, GroupToggleEndBlock):
            # Group toggle end block is used only to group fields and not used in actual form.
            # Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
            is_in_group = False
        else:
            field_wrapper = BlockFieldWrapper(struct_child)
            field_wrapper.group_number = group_counter if is_in_group else 1
            form_fields[struct_child.id] = field_wrapper

    return form_fields

dispatch

dispatch(*args, **kwargs)
Source code in hypha/apply/determinations/views.py
def dispatch(self, *args, **kwargs):
    self._submissions = None
    if not self.get_action() or not self.get_submissions():
        messages.warning(
            self.request, "Improperly configured request, please try again."
        )
        return HttpResponseRedirect(self.get_success_url())

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

get_action

get_action()
Source code in hypha/apply/determinations/views.py
def get_action(self):
    return self.request.GET.get("action", "")

get_submissions

get_submissions()
Source code in hypha/apply/determinations/views.py
def get_submissions(self):
    if not self._submissions:
        try:
            submission_ids = self.request.GET.get("submissions").split(",")
        except AttributeError:
            return None
        try:
            ids = [int(pk) for pk in submission_ids]
        except ValueError:
            return None
        self._submissions = ApplicationSubmission.objects.filter(id__in=ids)
    return self._submissions

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/determinations/views.py
def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs["user"] = self.request.user
    kwargs["submissions"] = self.get_submissions()
    kwargs["action"] = self.get_action()
    kwargs["site"] = Site.find_for_request(self.request)
    kwargs.pop("instance")
    return kwargs

check_all_submissions_are_of_same_type

check_all_submissions_are_of_same_type(submissions)

Checks if all the submission as the new determination form attached to it.

Or all should be using the old determination forms.

We can not create batch determination with submissions using two different type of forms.

Source code in hypha/apply/determinations/views.py
def check_all_submissions_are_of_same_type(self, submissions):
    """
    Checks if all the submission as the new determination form attached to it.

    Or all should be using the old determination forms.

    We can not create batch determination with submissions using two different
    type of forms.
    """
    return (
        len(
            {
                submission.is_determination_form_attached
                for submission in submissions
            }
        )
        == 1
    )

get_form_class

get_form_class()
Source code in hypha/apply/determinations/views.py
def get_form_class(self):
    submissions = self.get_submissions()
    if not self.check_all_submissions_are_of_same_type(submissions):
        raise ValueError(
            "All selected submissions excpects determination forms attached"
            " - please contact admin"
        )
    if not submissions[0].is_determination_form_attached:
        # If all the submission has same type of forms but they are not the
        # new streamfield forms then use the old determination forms.
        return get_form_for_stages(submissions)
    form_fields = self.get_form_fields()
    field_blocks = self.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, DeterminationBlock):
            # Outcome is already set in case of batch determinations so we do
            # not need to render this field.
            form_fields.pop(field_block.id)
    return type("WagtailStreamForm", (self.submission_form_class,), form_fields)

get_defined_fields

get_defined_fields()
Source code in hypha/apply/determinations/views.py
def get_defined_fields(self):
    return get_fields_for_stages(self.get_submissions())

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/determinations/views.py
def get_context_data(self, **kwargs):
    outcome = TRANSITION_DETERMINATION[self.get_action()]
    submission = self.get_submissions()[0]
    transition = transition_from_outcome(outcome, submission)
    action_name = submission.workflow[transition].display_name
    return super().get_context_data(
        action_name=action_name,
        submissions=self.get_submissions(),
        **kwargs,
    )

form_valid

form_valid(form)
Source code in hypha/apply/determinations/views.py
def form_valid(self, form):
    submissions = self.get_submissions()
    response = super().form_valid(form)
    determinations = {
        determination.submission.id: determination
        for determination in form.instances
    }
    messenger(
        MESSAGES.BATCH_DETERMINATION_OUTCOME,
        request=self.request,
        user=self.request.user,
        sources=submissions.filter(id__in=list(determinations)),
        related=determinations,
    )

    for submission in submissions:
        try:
            determination = determinations[submission.id]
        except KeyError:
            messages.warning(
                self.request,
                'Unable to determine submission "{title}" as already determined'.format(
                    title=submission.title_text_display
                ),
            )
        else:
            if submission.is_determination_form_attached:
                determination.form_fields = self.get_defined_fields()
                determination.message = form.cleaned_data[
                    determination.message_field.id
                ]
                determination.save()
            transition = transition_from_outcome(
                form.cleaned_data.get("outcome"), submission
            )

            if determination.outcome == NEEDS_MORE_INFO:
                # We keep a record of the message sent to the user in the comment
                Activity.comments.create(
                    message=determination.stripped_message,
                    timestamp=timezone.now(),
                    user=self.request.user,
                    source=submission,
                    related_object=determination,
                )

            submission.perform_transition(
                transition, self.request.user, request=self.request, notify=False
            )
    return response

should_redirect classmethod

should_redirect(request, submissions, actions)
Source code in hypha/apply/determinations/views.py
@classmethod
def should_redirect(cls, request, submissions, actions):
    excluded = []
    for submission in submissions:
        if has_final_determination(submission):
            excluded.append(submission)

    non_determine_states = set(actions) - set(DETERMINATION_OUTCOMES.keys())
    if not any(non_determine_states):
        if excluded:
            messages.warning(
                request,
                _(
                    "A determination already exists for the following submissions and they have been excluded: {submissions}"
                ).format(
                    submissions=", ".join(
                        [submission.title_text_display for submission in excluded]
                    ),
                ),
            )

        submissions = submissions.exclude(
            id__in=[submission.id for submission in excluded]
        )
        action = outcome_from_actions(actions)
        return HttpResponseRedirect(
            reverse_lazy("apply:submissions:determinations:batch")
            + "?action="
            + action
            + "&submissions="
            + ",".join([str(submission.id) for submission in submissions])
            + "&next="
            + parse.quote_plus(request.get_full_path()),
        )
    elif set(actions) != non_determine_states:
        raise ValueError("Inconsistent states provided - please talk to an admin")

get_success_url

get_success_url()
Source code in hypha/apply/determinations/views.py
def get_success_url(self):
    try:
        return self.request.GET["next"]
    except KeyError:
        return reverse_lazy("apply:submissions:list")

DeterminationCreateOrUpdateView

Bases: BaseStreamForm, CreateOrUpdateView

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

submission_form_class class-attribute instance-attribute

submission_form_class = DeterminationModelForm

model class-attribute instance-attribute

model = Determination

template_name class-attribute instance-attribute

template_name = 'determinations/determination_form.html'

get

get(request, *args, **kwargs)
Source code in hypha/apply/utils/views.py
def get(self, request, *args, **kwargs):
    try:
        self.object = self.get_object()
    except self.model.DoesNotExist:
        self.object = None

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

post

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

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

from_db classmethod

from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def from_db(cls, db, field_names, values):
    instance = super().from_db(db, field_names, values)
    if "form_data" in field_names:
        instance.form_data = cls.deserialize_form_data(
            instance, instance.form_data, instance.form_fields
        )
    return instance

deserialize_form_data classmethod

deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
    data = form_data.copy()
    # PERFORMANCE NOTE:
    # Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
    # including any sub queries that they do
    for _i, field_data in enumerate(form_fields.raw_data):
        block = form_fields.stream_block.child_blocks[field_data["type"]]
        field_id = field_data.get("id")
        try:
            value = data[field_id]
        except KeyError:
            pass
        else:
            data[field_id] = block.decode(value)
    return data

get_form_fields

get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_fields(self, draft=False, form_data=None, user=None):
    if form_data is None:
        form_data = {}

    form_fields = OrderedDict()
    field_blocks = self.get_defined_fields()
    group_counter = 1
    is_in_group = False

    # If true option 1 is selected
    grouped_fields_visible = False
    for struct_child in field_blocks:
        block = struct_child.block
        struct_value = struct_child.value
        if isinstance(block, FormFieldBlock):
            field_from_block = block.get_field(struct_value)
            disabled_help_text = _(
                "You are logged in so this information is fetched from your user account."
            )
            if isinstance(block, FullNameBlock) and user and user.is_authenticated:
                if user.full_name:
                    field_from_block.disabled = True
                    field_from_block.initial = user.full_name
                    field_from_block.help_text = disabled_help_text
                else:
                    field_from_block.help_text = _(
                        "You are logged in but your user account does not have a "
                        "full name. We'll update your user account with the name you provide here."
                    )
            if isinstance(block, EmailBlock) and user and user.is_authenticated:
                field_from_block.disabled = True
                field_from_block.initial = user.email
                field_from_block.help_text = disabled_help_text
            if draft and not issubclass(
                block.__class__, ApplicationMustIncludeFieldBlock
            ):
                field_from_block.required = False
            field_from_block.help_link = struct_value.get("help_link")
            field_from_block.group_number = group_counter if is_in_group else 1
            if isinstance(block, GroupToggleBlock) and not is_in_group:
                field_from_block.group_number = 1
                field_from_block.grouper_for = group_counter + 1
                group_counter += 1
                is_in_group = True
                grouped_fields_visible = (
                    form_data.get(struct_child.id) == field_from_block.choices[0][0]
                )
            if isinstance(block, TextFieldBlock):
                field_from_block.word_limit = struct_value.get("word_limit")
            if isinstance(block, MultiInputCharFieldBlock):
                number_of_inputs = struct_value.get("number_of_inputs")
                for index in range(number_of_inputs):
                    form_fields[struct_child.id + "_" + str(index)] = (
                        field_from_block
                    )
                    field_from_block.multi_input_id = struct_child.id
                    field_from_block.add_button_text = struct_value.get(
                        "add_button_text"
                    )
                    if (
                        index == number_of_inputs - 1
                    ):  # Add button after last input field
                        field_from_block.multi_input_add_button = True
                        # Index for field until which fields will be visible to applicant.
                        # Initially only the first field with id UUID_0 will be visible.
                        field_from_block.visibility_index = 0
                        field_from_block.max_index = index
                    if index != 0:
                        field_from_block.multi_input_field = True
                        field_from_block.required = False
                        field_from_block.initial = None
                    field_from_block = copy.copy(field_from_block)
            else:
                if is_in_group and not isinstance(block, GroupToggleBlock):
                    field_from_block.required_when_visible = (
                        field_from_block.required
                    )
                    field_from_block.required = (
                        field_from_block.required & grouped_fields_visible
                    )
                    field_from_block.visible = grouped_fields_visible
                form_fields[struct_child.id] = field_from_block
        elif isinstance(block, GroupToggleEndBlock):
            # Group toggle end block is used only to group fields and not used in actual form.
            # Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
            is_in_group = False
        else:
            field_wrapper = BlockFieldWrapper(struct_child)
            field_wrapper.group_number = group_counter if is_in_group else 1
            form_fields[struct_child.id] = field_wrapper

    return form_fields

get_object

get_object(queryset=None)
Source code in hypha/apply/determinations/views.py
def get_object(self, queryset=None):
    return self.model.objects.get(submission=self.submission, is_draft=True)

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/determinations/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )

    if not can_create_determination(request.user, self.submission):
        return self.back_to_submission(
            _("You do not have permission to create that determination.")
        )

    if has_final_determination(self.submission):
        return self.back_to_submission(
            _("A final determination has already been submitted.")
        )

    try:
        self.determination = self.get_object()
    except Determination.DoesNotExist:
        pass
    else:
        if not can_edit_determination(
            request.user, self.determination, self.submission
        ):
            return self.back_to_detail(
                _(
                    "There is a draft determination you do not have permission to edit."
                )
            )

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

back_to_submission

back_to_submission(message)
Source code in hypha/apply/determinations/views.py
def back_to_submission(self, message):
    messages.warning(self.request, message)
    return HttpResponseRedirect(self.submission.get_absolute_url())

back_to_detail

back_to_detail(message)
Source code in hypha/apply/determinations/views.py
def back_to_detail(self, message):
    messages.warning(self.request, message)
    return HttpResponseRedirect(self.determination.get_absolute_url())

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/determinations/views.py
def get_context_data(self, **kwargs):
    site = Site.find_for_request(self.request)
    determination_messages = DeterminationMessageSettings.for_site(site)

    # Pass blocks ids to identify block types(determination & message) in determination message template js.
    field_blocks_ids = {}
    if self.submission.is_determination_form_attached:
        for field_block in self.get_defined_fields():
            if isinstance(field_block.block, DeterminationBlock) or isinstance(
                field_block.block, DeterminationMessageBlock
            ):
                field_blocks_ids[field_block.block_type] = field_block.id

    return super().get_context_data(
        submission=self.submission,
        message_templates=determination_messages.get_for_stage(
            self.submission.stage.name
        ),
        field_blocks_ids=field_blocks_ids,
        **kwargs,
    )

get_defined_fields

get_defined_fields()
Source code in hypha/apply/determinations/views.py
def get_defined_fields(self):
    return get_fields_for_stage(self.submission)

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/determinations/views.py
def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs["user"] = self.request.user
    kwargs["submission"] = self.submission
    kwargs["action"] = self.request.GET.get("action")
    kwargs["site"] = Site.find_for_request(self.request)
    return kwargs

get_form_class

get_form_class()
Source code in hypha/apply/determinations/views.py
def get_form_class(self):
    action = self.request.GET.get("action")
    if not self.submission.is_determination_form_attached:
        # If new determination forms are not attached use the old ones.
        return get_form_for_stage(self.submission)
    form_fields = self.get_form_fields()
    field_blocks = self.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, DeterminationBlock):
            outcome_choices = outcome_choices_for_phase(
                self.submission, self.request.user
            )
            # Outcome field choices need to be set according to the phase.
            form_fields[field_block.id].choices = outcome_choices
            if action:
                # Set initial outcome based on action.
                form_fields[field_block.id].initial = TRANSITION_DETERMINATION[
                    action
                ]
    form_fields = self.add_proposal_form_field(form_fields, action)
    return type("WagtailStreamForm", (self.submission_form_class,), form_fields)

add_proposal_form_field

add_proposal_form_field(fields, action)
Source code in hypha/apply/determinations/views.py
def add_proposal_form_field(self, fields, action):
    stages_num = len(self.submission.workflow.stages)
    if stages_num > 1 and self.submission.stage == Concept:
        second_stage_forms = self.submission.get_from_parent("forms").filter(
            stage=2
        )
        if second_stage_forms.count() > 1:
            proposal_form_choices = [
                (index, form.form.name)
                for index, form in enumerate(second_stage_forms)
            ]
            proposal_form_choices.insert(
                0, ("", _("-- No proposal form selected -- "))
            )
            proposal_form_help_text = _(
                "Select the proposal form only for determination approval"
            )
            if action == "invited_to_proposal":
                proposal_form_help_text = _(
                    "Select the proposal form to use for proposal stage."
                )
            fields["proposal_form"] = forms.ChoiceField(
                label=_("Proposal Form"),
                choices=proposal_form_choices,
                help_text=proposal_form_help_text,
                required=True if action == "invited_to_proposal" else False,
            )
            fields.move_to_end("proposal_form", last=False)
    return fields

get_success_url

get_success_url()
Source code in hypha/apply/determinations/views.py
def get_success_url(self):
    return self.submission.get_absolute_url()

form_valid

form_valid(form)
Source code in hypha/apply/determinations/views.py
def form_valid(self, form):
    if self.submission.is_determination_form_attached:
        form.instance.form_fields = self.get_defined_fields()

    super().form_valid(form)
    if self.object.is_draft:
        add_task_to_user(
            code=DETERMINATION_DRAFT,
            user=self.object.author,
            related_obj=self.object,
        )
        return HttpResponseRedirect(self.submission.get_absolute_url())

    with transaction.atomic():
        messenger(
            MESSAGES.DETERMINATION_OUTCOME,
            request=self.request,
            user=self.object.author,
            submission=self.object.submission,
            related=self.object,
        )
        proposal_form = form.cleaned_data.get("proposal_form")
        transition = transition_from_outcome(
            int(self.object.outcome), self.submission
        )

        if self.object.outcome == NEEDS_MORE_INFO:
            # We keep a record of the message sent to the user in the comment
            Activity.comments.create(
                message=self.object.stripped_message,
                timestamp=timezone.now(),
                user=self.request.user,
                source=self.submission,
                related_object=self.object,
            )
        self.submission.perform_transition(
            transition,
            self.request.user,
            request=self.request,
            notify=False,
            proposal_form=proposal_form,
        )

        if self.submission.accepted_for_funding and settings.PROJECTS_AUTO_CREATE:
            Project.create_from_submission(self.submission)

    # remove current users's task for determination
    remove_tasks_for_user(
        code=DETERMINATION_DRAFT, user=self.object.author, related_obj=self.object
    )

    # remove all current determination tasks for the submission
    remove_tasks_of_related_obj_for_specific_code(
        code=DETERMINATION_DRAFT, related_obj=self.object
    )

    # remove all review draft tasks for the submission's draft reviews
    for review in Review.objects.filter(
        submission=self.object.submission, is_draft=True
    ):
        remove_tasks_of_related_obj_for_specific_code(
            code=REVIEW_DRAFT, related_obj=review
        )

    messenger(
        MESSAGES.DETERMINATION_OUTCOME,
        request=self.request,
        user=self.object.author,
        source=self.object.submission,
        related=self.object,
    )

    return HttpResponseRedirect(self.submission.get_absolute_url())

should_redirect classmethod

should_redirect(request, submission, action)
Source code in hypha/apply/determinations/views.py
@classmethod
def should_redirect(cls, request, submission, action):
    if has_final_determination(submission):
        determination = submission.determinations.final().first()
        if determination.outcome == TRANSITION_DETERMINATION[action]:
            # We want to progress as normal so don't redirect through form
            return False
        else:
            if request:
                # Add a helpful message to prompt them to select the correct option
                messages.warning(
                    request,
                    _(
                        'A determination of "{current}" exists but you tried to progress as "{target}"'
                    ).format(
                        current=determination.get_outcome_display(),
                        target=action,
                    ),
                )

    if action in DETERMINATION_OUTCOMES:
        return HttpResponseRedirect(
            reverse_lazy(
                "apply:submissions:determinations:form", args=(submission.id,)
            )
            + "?action="
            + action
        )

AdminDeterminationDetailView

Bases: DetailView

model class-attribute instance-attribute

model = Determination

get_object

get_object(queryset=None)
Source code in hypha/apply/determinations/views.py
def get_object(self, queryset=None):
    return get_object_or_404(
        self.model, submission=self.submission, id=self.kwargs["pk"]
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/determinations/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )
    determination = self.get_object()

    if (
        can_edit_determination(request.user, determination, self.submission)
        and determination.is_draft
    ):
        return HttpResponseRedirect(
            reverse_lazy(
                "apply:submissions:determinations:form", args=(self.submission.id,)
            )
        )

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

ReviewerDeterminationDetailView

Bases: DetailView

model class-attribute instance-attribute

model = Determination

get_object

get_object(queryset=None)
Source code in hypha/apply/determinations/views.py
def get_object(self, queryset=None):
    return get_object_or_404(
        self.model, submission=self.submission, id=self.kwargs["pk"]
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/determinations/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )
    determination = self.get_object()

    if not determination.submitted:
        return HttpResponseRedirect(
            reverse_lazy("apply:submissions:detail", args=(self.submission.id,))
        )

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

PartnerDeterminationDetailView

Bases: DetailView

model class-attribute instance-attribute

model = Determination

get_queryset

get_queryset()
Source code in hypha/apply/determinations/views.py
def get_queryset(self):
    return super().get_queryset().filter(submission=self.submission)

dispatch

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

    if self.submission.user == request.user:
        return ApplicantDeterminationDetailView.as_view()(request, *args, **kwargs)

    # Only allow partners in the submission they are added as partners
    partner_has_access = self.submission.partners.filter(
        pk=request.user.pk
    ).exists()
    if not partner_has_access:
        raise PermissionDenied

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

CommunityDeterminationDetailView

Bases: DetailView

model class-attribute instance-attribute

model = Determination

get_queryset

get_queryset()
Source code in hypha/apply/determinations/views.py
def get_queryset(self):
    return super().get_queryset().filter(submission=self.submission)

dispatch

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

    if self.submission.user == request.user:
        return ApplicantDeterminationDetailView.as_view()(request, *args, **kwargs)

    # Only allow community reviewers in submission with a community review state.
    if not self.submission.community_review:
        raise PermissionDenied

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

ApplicantDeterminationDetailView

Bases: DetailView

model class-attribute instance-attribute

model = Determination

get_object

get_object(queryset=None)
Source code in hypha/apply/determinations/views.py
def get_object(self, queryset=None):
    return get_object_or_404(
        self.model, submission=self.submission, id=self.kwargs["pk"]
    )

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/determinations/views.py
def dispatch(self, request, *args, **kwargs):
    self.submission = get_object_or_404(
        ApplicationSubmission, id=self.kwargs["submission_pk"]
    )
    determination = self.get_object()

    if request.user != self.submission.user:
        raise PermissionDenied

    if determination.is_draft:
        return HttpResponseRedirect(
            reverse_lazy(
                "apply:submissions:determinations:detail",
                args=(self.submission.id,),
            )
        )

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

DeterminationDetailView

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()

DeterminationEditView

Bases: BaseStreamForm, UpdateView

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

submission_form_class class-attribute instance-attribute

submission_form_class = DeterminationModelForm

model class-attribute instance-attribute

model = Determination

template_name class-attribute instance-attribute

template_name = 'determinations/determination_form.html'

raise_exception class-attribute instance-attribute

raise_exception = True

from_db classmethod

from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def from_db(cls, db, field_names, values):
    instance = super().from_db(db, field_names, values)
    if "form_data" in field_names:
        instance.form_data = cls.deserialize_form_data(
            instance, instance.form_data, instance.form_fields
        )
    return instance

deserialize_form_data classmethod

deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
    data = form_data.copy()
    # PERFORMANCE NOTE:
    # Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
    # including any sub queries that they do
    for _i, field_data in enumerate(form_fields.raw_data):
        block = form_fields.stream_block.child_blocks[field_data["type"]]
        field_id = field_data.get("id")
        try:
            value = data[field_id]
        except KeyError:
            pass
        else:
            data[field_id] = block.decode(value)
    return data

get_form_fields

get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_fields(self, draft=False, form_data=None, user=None):
    if form_data is None:
        form_data = {}

    form_fields = OrderedDict()
    field_blocks = self.get_defined_fields()
    group_counter = 1
    is_in_group = False

    # If true option 1 is selected
    grouped_fields_visible = False
    for struct_child in field_blocks:
        block = struct_child.block
        struct_value = struct_child.value
        if isinstance(block, FormFieldBlock):
            field_from_block = block.get_field(struct_value)
            disabled_help_text = _(
                "You are logged in so this information is fetched from your user account."
            )
            if isinstance(block, FullNameBlock) and user and user.is_authenticated:
                if user.full_name:
                    field_from_block.disabled = True
                    field_from_block.initial = user.full_name
                    field_from_block.help_text = disabled_help_text
                else:
                    field_from_block.help_text = _(
                        "You are logged in but your user account does not have a "
                        "full name. We'll update your user account with the name you provide here."
                    )
            if isinstance(block, EmailBlock) and user and user.is_authenticated:
                field_from_block.disabled = True
                field_from_block.initial = user.email
                field_from_block.help_text = disabled_help_text
            if draft and not issubclass(
                block.__class__, ApplicationMustIncludeFieldBlock
            ):
                field_from_block.required = False
            field_from_block.help_link = struct_value.get("help_link")
            field_from_block.group_number = group_counter if is_in_group else 1
            if isinstance(block, GroupToggleBlock) and not is_in_group:
                field_from_block.group_number = 1
                field_from_block.grouper_for = group_counter + 1
                group_counter += 1
                is_in_group = True
                grouped_fields_visible = (
                    form_data.get(struct_child.id) == field_from_block.choices[0][0]
                )
            if isinstance(block, TextFieldBlock):
                field_from_block.word_limit = struct_value.get("word_limit")
            if isinstance(block, MultiInputCharFieldBlock):
                number_of_inputs = struct_value.get("number_of_inputs")
                for index in range(number_of_inputs):
                    form_fields[struct_child.id + "_" + str(index)] = (
                        field_from_block
                    )
                    field_from_block.multi_input_id = struct_child.id
                    field_from_block.add_button_text = struct_value.get(
                        "add_button_text"
                    )
                    if (
                        index == number_of_inputs - 1
                    ):  # Add button after last input field
                        field_from_block.multi_input_add_button = True
                        # Index for field until which fields will be visible to applicant.
                        # Initially only the first field with id UUID_0 will be visible.
                        field_from_block.visibility_index = 0
                        field_from_block.max_index = index
                    if index != 0:
                        field_from_block.multi_input_field = True
                        field_from_block.required = False
                        field_from_block.initial = None
                    field_from_block = copy.copy(field_from_block)
            else:
                if is_in_group and not isinstance(block, GroupToggleBlock):
                    field_from_block.required_when_visible = (
                        field_from_block.required
                    )
                    field_from_block.required = (
                        field_from_block.required & grouped_fields_visible
                    )
                    field_from_block.visible = grouped_fields_visible
                form_fields[struct_child.id] = field_from_block
        elif isinstance(block, GroupToggleEndBlock):
            # Group toggle end block is used only to group fields and not used in actual form.
            # Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
            is_in_group = False
        else:
            field_wrapper = BlockFieldWrapper(struct_child)
            field_wrapper.group_number = group_counter if is_in_group else 1
            form_fields[struct_child.id] = field_wrapper

    return form_fields

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/determinations/views.py
def get_context_data(self, **kwargs):
    site = Site.find_for_request(self.request)
    determination_messages = DeterminationMessageSettings.for_site(site)

    determination = self.get_object()
    return super().get_context_data(
        submission=determination.submission,
        message_templates=determination_messages.get_for_stage(
            determination.submission.stage.name
        ),
        **kwargs,
    )

get_defined_fields

get_defined_fields()
Source code in hypha/apply/determinations/views.py
def get_defined_fields(self):
    determination = self.get_object()
    return determination.form_fields or get_fields_for_stage(
        determination.submission
    )

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/determinations/views.py
def get_form_kwargs(self):
    determiantion = self.get_object()
    kwargs = super().get_form_kwargs()
    kwargs["user"] = self.request.user
    kwargs["submission"] = determiantion.submission
    kwargs["edit"] = True
    kwargs["action"] = self.request.GET.get("action")
    kwargs["site"] = Site.find_for_request(self.request)
    if self.object:
        kwargs["initial"] = self.object.form_data
    return kwargs

get_form_class

get_form_class()
Source code in hypha/apply/determinations/views.py
def get_form_class(self):
    determination = self.get_object()
    if not determination.use_new_determination_form:
        return get_form_for_stage(determination.submission)
    form_fields = self.get_form_fields()
    field_blocks = self.get_defined_fields()
    for field_block in field_blocks:
        if isinstance(field_block.block, DeterminationBlock):
            # Outcome can not be edited after being set once, so we do not
            # need to render this field.
            form_fields.pop(field_block.id)
    return type("WagtailStreamForm", (self.submission_form_class,), form_fields)

form_valid

form_valid(form)
Source code in hypha/apply/determinations/views.py
def form_valid(self, form):
    super().form_valid(form)
    determination = self.get_object()
    messenger(
        MESSAGES.DETERMINATION_OUTCOME,
        request=self.request,
        user=self.object.author,
        source=self.object.submission,
        related=self.object,
    )

    return HttpResponseRedirect(determination.submission.get_absolute_url())

get_form_for_stages

get_form_for_stages(submissions)
Source code in hypha/apply/determinations/views.py
def get_form_for_stages(submissions):
    forms = [get_form_for_stage(submission, batch=True) for submission in submissions]
    if len(set(forms)) != 1:
        raise ValueError("Submissions expect different forms - please contact admin")

    return forms[0]

get_form_for_stage

get_form_for_stage(submission, batch=False, edit=False)
Source code in hypha/apply/determinations/views.py
def get_form_for_stage(submission, batch=False, edit=False):
    if batch:
        forms = [BatchConceptDeterminationForm, BatchProposalDeterminationForm]
    else:
        forms = [ConceptDeterminationForm, ProposalDeterminationForm]
    index = submission.workflow.stages.index(submission.stage)
    return forms[index]

get_fields_for_stages

get_fields_for_stages(submissions)
Source code in hypha/apply/determinations/views.py
def get_fields_for_stages(submissions):
    forms_fields = [get_fields_for_stage(submission) for submission in submissions]
    if not all(i == forms_fields[0] for i in forms_fields):
        raise ValueError("Submissions expect different forms - please contact admin")
    return forms_fields[0]

get_fields_for_stage

get_fields_for_stage(submission)
Source code in hypha/apply/determinations/views.py
def get_fields_for_stage(submission):
    forms = submission.get_from_parent("determination_forms").all()
    index = submission.workflow.stages.index(submission.stage)
    try:
        return forms[index].form.form_fields
    except IndexError:
        return forms[0].form.form_fields

outcome_choices_for_phase

outcome_choices_for_phase(submission, user)

Outcome choices correspond to Phase transitions. We need to filter out non-matching choices. i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.

Source code in hypha/apply/determinations/views.py
def outcome_choices_for_phase(submission, user):
    """
    Outcome choices correspond to Phase transitions.
    We need to filter out non-matching choices.
    i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.
    """
    available_choices = [("", _("-- No determination selected -- "))]
    choices = dict(DETERMINATION_CHOICES)
    for transition_name in determination_actions(user, submission):
        try:
            determination_type = TRANSITION_DETERMINATION[transition_name]
        except KeyError:
            pass
        else:
            available_choices.append((determination_type, choices[determination_type]))
    return available_choices