Skip to content

Project

hypha.apply.projects.views.project

SendForApprovalView

Bases: View

form_class class-attribute instance-attribute

form_class = SetPendingForm

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/send_for_approval.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.object = get_object_or_404(Project, id=kwargs.get("pk"))
    # permission check
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.form_class(instance=self.object)
    project_settings = ProjectSettings.for_request(self.request)
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "project_settings": project_settings,
            "paf_approvals": PAFApprovals.objects.filter(project=self.object),
            "remaining_document_categories": DocumentCategory.objects.filter(
                ~Q(packet_files__project=self.object)
            ),
            "object": self.object,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(
        self.request.POST, user=self.request.user, instance=self.object
    )
    project_settings = ProjectSettings.for_request(self.request)
    if form.is_valid():
        project = self.object
        old_stage = project.status
        form.save()

        # remove PAF submission task for staff group
        remove_tasks_for_user(
            code=PROJECT_SUBMIT_PAF,
            user=self.object.lead,
            related_obj=self.object,
        )

        # remove PAF rejection task for staff if exists
        remove_tasks_for_user(
            code=PAF_REQUIRED_CHANGES,
            user=self.object.lead,
            related_obj=self.object,
        )

        paf_approvals = self.object.paf_approvals.filter(approved=False)

        if project_settings.paf_approval_sequential:
            if paf_approvals:
                user = paf_approvals.first().user
                if user:
                    # notify only if first user/approver is updated
                    messenger(
                        MESSAGES.SEND_FOR_APPROVAL,
                        request=self.request,
                        user=self.request.user,
                        source=self.object,
                    )
                    messenger(
                        MESSAGES.APPROVE_PAF,
                        request=self.request,
                        user=self.request.user,
                        source=self.object,
                        related=[paf_approvals.first()],
                    )
                    # add PAF waiting approval task for paf_approval user
                    add_task_to_user(
                        code=PAF_WAITING_APPROVAL,
                        user=user,
                        related_obj=self.object,
                    )
                else:
                    messenger(
                        MESSAGES.ASSIGN_PAF_APPROVER,
                        request=self.request,
                        user=self.request.user,
                        source=self.object,
                    )
                    # add PAF waiting assignee task for paf_approval reviewer_roles
                    add_task_to_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=paf_approvals.first().paf_reviewer_role.user_roles.all(),
                        related_obj=self.object,
                    )
        else:
            if paf_approvals.filter(user__isnull=False).exists():
                messenger(
                    MESSAGES.SEND_FOR_APPROVAL,
                    request=self.request,
                    user=self.request.user,
                    source=self.object,
                )
                messenger(
                    MESSAGES.APPROVE_PAF,
                    request=self.request,
                    user=self.request.user,
                    source=self.object,
                    related=paf_approvals.filter(user__isnull=False),
                )
                # add PAF waiting approval task for paf_approvals users
                for paf_approval in paf_approvals.filter(user__isnull=False):
                    add_task_to_user(
                        code=PAF_WAITING_APPROVAL,
                        user=paf_approval.user,
                        related_obj=self.object,
                    )
            if paf_approvals.filter(user__isnull=True).exists():
                messenger(
                    MESSAGES.ASSIGN_PAF_APPROVER,
                    request=self.request,
                    user=self.request.user,
                    source=self.object,
                )
                # add PAF waiting assignee task for paf_approvals reviewer_roles
                for paf_approval in paf_approvals.filter(user__isnull=True):
                    add_task_to_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                        related_obj=self.object,
                    )

        project.status = INTERNAL_APPROVAL
        project.save(update_fields=["status"])

        messenger(
            MESSAGES.PROJECT_TRANSITION,
            request=self.request,
            user=self.request.user,
            source=project,
            related=old_stage,
        )

        messages.success(
            self.request,
            _("PAF has been submitted for approval"),
            extra_tags=PROJECT_ACTION_MESSAGE_TAG,
        )
        return HttpResponseClientRefresh()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "project_settings": project_settings,
            "paf_approvals": PAFApprovals.objects.filter(project=self.object),
            "remaining_document_categories": DocumentCategory.objects.filter(
                ~Q(packet_files__project=self.object)
            ),
            "object": self.object,
        },
    )

UploadDocumentView

Bases: CreateView

form_class class-attribute instance-attribute

form_class = UploadDocumentForm

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/supporting_documents_upload.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    self.category = get_object_or_404(
        DocumentCategory, id=kwargs.get("category_pk")
    )
    # permission check
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    upload_document_form = self.form_class(
        instance=self.project, initial={"category": self.category}
    )
    return render(
        self.request,
        self.template_name,
        context={
            "form": upload_document_form,
            "value": _("Submit"),
            "category": self.category,
            "object": self.project,
        },
    )

post

post(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, request, *args, **kwargs):
    form = self.form_class(
        self.request.POST,
        request.FILES,
        instance=self.project,
        initial={"category": self.category},
    )
    if form.is_valid():
        form.instance.project = self.project
        form.save()
        messenger(
            MESSAGES.UPLOAD_DOCUMENT,
            request=self.request,
            user=self.request.user,
            source=self.project,
        )
        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {
                        "supportingDocumentUpload": None,
                        "showMessage": "Document has been uploaded",
                    }
                ),
            },
        )
    return render(
        self.request,
        self.template_name,
        context={"form": form, "value": _("Submit"), "object": self.project},
        status=400,
    )

RemoveDocumentView

Bases: View

model class-attribute instance-attribute

model = Project

delete

delete(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def delete(self, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    self.object = self.project.packet_files.get(pk=kwargs.get("document_pk"))
    self.object.delete()

    messages.success(
        self.request,
        _("Document has been removed"),
        extra_tags=PROJECT_ACTION_MESSAGE_TAG,
    )
    return HttpResponse(
        status=204,
        headers={
            "HX-Trigger": json.dumps(
                {
                    "supportingDocumentRemove": None,
                    "showMessage": "Document has been removed",
                }
            ),
        },
    )

RemoveContractDocumentView

Bases: View

model class-attribute instance-attribute

model = Project

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    if not request.user.is_applicant or request.user != self.project.user:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

delete

delete(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def delete(self, *args, **kwargs):
    self.object = self.project.contract_packet_files.get(
        pk=kwargs.get("document_pk")
    )
    self.object.delete()

    messages.success(
        self.request,
        _("Contracting document has been removed"),
        extra_tags=PROJECT_ACTION_MESSAGE_TAG,
    )

    return HttpResponse(
        status=204,
        headers={
            "HX-Trigger": json.dumps(
                {
                    "contractingDocumentRemove": None,
                    "showMessage": "Contracting Document has been removed",
                }
            ),
        },
    )

SelectDocumentView

Bases: DelegatedViewMixin, CreateView

form_class class-attribute instance-attribute

form_class = SelectDocumentForm

context_name class-attribute instance-attribute

context_name = 'select_document_form'

model class-attribute instance-attribute

model = PacketFile

should_show property

should_show

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_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

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return super().dispatch(request, *args, **kwargs)

form_invalid

form_invalid(form)
Source code in hypha/apply/projects/views/project.py
def form_invalid(self, form):
    for error in form.errors:
        messages.error(self.request, error)

    return redirect(self.project)

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/project.py
def form_valid(self, form):
    form.instance.project = self.project
    form.instance.name = form.instance.document.name

    response = super().form_valid(form)

    messenger(
        MESSAGES.UPLOAD_DOCUMENT,
        request=self.request,
        user=self.request.user,
        source=self.project,
    )

    return response

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/projects/views/project.py
def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs.pop("user")
    kwargs.pop("instance")
    kwargs["existing_files"] = get_files(self.get_parent_object())
    return kwargs

UpdateLeadView

Bases: DelegatedViewMixin, UpdateView

model class-attribute instance-attribute

model = Project

form_class class-attribute instance-attribute

form_class = UpdateProjectLeadForm

context_name class-attribute instance-attribute

context_name = '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/projects/views/project.py
def form_valid(self, form):
    # Fetch the old lead from the database
    old_lead = copy.copy(self.get_object().lead)
    tasks = get_project_lead_tasks(self.get_object().lead, self.get_object())

    response = super().form_valid(form)
    project = form.instance
    tasks.update(user=project.lead)

    messenger(
        MESSAGES.UPDATE_PROJECT_LEAD,
        request=self.request,
        user=self.request.user,
        source=project,
        related=old_lead or _("Unassigned"),
    )

    messages.success(
        self.request,
        _("Lead has been updated"),
        extra_tags=PROJECT_ACTION_MESSAGE_TAG,
    )
    return response

UpdateProjectTitleView

Bases: DelegatedViewMixin, UpdateView

model class-attribute instance-attribute

model = Project

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'title_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/projects/views/project.py
def form_valid(self, form):
    # Fetch the old lead from the database
    old_title = copy.copy(self.get_object().title)

    response = super().form_valid(form)
    project = form.instance

    messenger(
        MESSAGES.UPDATE_PROJECT_TITLE,
        request=self.request,
        user=self.request.user,
        source=project,
        related=old_title,
    )

    messages.success(
        self.request,
        _("Title has been updated"),
        extra_tags=PROJECT_ACTION_MESSAGE_TAG,
    )
    return response

ContractsMixin

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/project.py
def get_context_data(self, **kwargs):
    project = self.get_object()
    contracts = project.contracts.select_related(
        "approver",
    ).order_by("-created_at")

    latest_contract = contracts.first()
    contract_to_approve = None
    contract_to_sign = None
    if latest_contract:
        if not latest_contract.signed_by_applicant:
            contract_to_sign = latest_contract
        elif not latest_contract.approver:
            contract_to_approve = latest_contract

    context = super().get_context_data(**kwargs)
    context["contract_to_approve"] = contract_to_approve
    context["contract_to_sign"] = contract_to_sign
    context["contracts"] = contracts.approved()
    context["contract"] = latest_contract
    return context

ApproveContractView

Bases: View

form_class class-attribute instance-attribute

form_class = ApproveContractForm

model class-attribute instance-attribute

model = Contract

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/approve_contract.html'

get_object

get_object()
Source code in hypha/apply/projects/views/project.py
def get_object(self):
    latest_contract = self.project.contracts.order_by("-created_at").first()
    if latest_contract and not latest_contract.approver:
        return latest_contract

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, pk=self.kwargs["pk"])
    self.object = self.get_object()
    # permission
    return super().dispatch(request, *args, **kwargs)

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/projects/views/project.py
def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs["instance"] = self.object
    kwargs.pop("user")
    return kwargs

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.form_class(instance=self.object)
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Confirm"),
            "object": self.project,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(self.request.POST, instance=self.object)
    if form.is_valid():
        with transaction.atomic():
            form.instance.approver = self.request.user
            form.instance.approved_at = timezone.now()
            form.instance.project = self.project
            form.save()

            old_stage = self.project.status

            messenger(
                MESSAGES.APPROVE_CONTRACT,
                request=self.request,
                user=self.request.user,
                source=self.project,
                related=self.object,
            )
            # remove Project waiting contract review task for staff
            remove_tasks_for_user(
                code=PROJECT_WAITING_CONTRACT_REVIEW,
                user=self.project.lead,
                related_obj=self.project,
            )

            self.project.status = INVOICING_AND_REPORTING
            self.project.save(update_fields=["status"])

            messenger(
                MESSAGES.PROJECT_TRANSITION,
                request=self.request,
                user=self.request.user,
                source=self.project,
                related=old_stage,
            )
            # add Project waiting invoice task for applicant
            add_task_to_user(
                code=PROJECT_WAITING_INVOICE,
                user=self.project.user,
                related_obj=self.project,
            )

        messages.success(
            self.request,
            _(
                "Contractor documents have been approved."
                " You can receive invoices from vendor now."
            ),
            extra_tags=PROJECT_ACTION_MESSAGE_TAG,
        )
        return HttpResponseClientRefresh()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Confirm"),
            "object": self.project,
        },
    )

UploadContractView

Bases: View

model class-attribute instance-attribute

model = Project

form_class class-attribute instance-attribute

form_class = UploadContractForm

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/upload_contract.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    permission, _ = has_permission(
        "contract_upload", request.user, object=self.project
    )
    if permission:
        return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.get_form()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "user": self.request.user,
            "value": _("Upload") if self.request.user.is_applicant else _("Submit"),
            "object": self.project,
        },
    )

get_form_kwargs

get_form_kwargs()
Source code in hypha/apply/projects/views/project.py
def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs.pop("instance")
    kwargs.pop("user")
    return kwargs

get_form

get_form(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get_form(self, *args, **kwargs):
    form = self.form_class(*args, **kwargs)
    if self.request.user.is_applicant:
        form.fields.pop("signed_and_approved")
    return form

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.get_form(self.request.POST)

    if form.is_valid():
        if self.project.contracts.exists():
            form.instance = self.project.contracts.order_by("created_at").first()

        form.instance.project = self.project

        if self.request.user == self.project.user:
            form.instance.signed_by_applicant = True
            form.instance.uploaded_by_applicant_at = timezone.now()
            messages.success(
                self.request,
                _("Countersigned contract uploaded"),
                extra_tags=PROJECT_ACTION_MESSAGE_TAG,
            )
        elif self.request.user.is_contracting or self.request.user.is_apply_staff:
            form.instance.uploaded_by_contractor_at = timezone.now()
            messages.success(
                self.request,
                _("Signed contract uploaded"),
                extra_tags=PROJECT_ACTION_MESSAGE_TAG,
            )

        form.save()

        contract_signed_and_approved = form.cleaned_data.get("signed_and_approved")
        if contract_signed_and_approved:
            form.instance.approver = self.request.user
            form.instance.approved_at = timezone.now()
            form.instance.signed_and_approved = contract_signed_and_approved
            form.instance.signed_by_applicant = True
            form.instance.save(
                update_fields=[
                    "approver",
                    "approved_at",
                    "signed_and_approved",
                    "signed_by_applicant",
                ]
            )

            self.project.status = INVOICING_AND_REPORTING
            self.project.save(update_fields=["status"])
            old_stage = CONTRACTING

            messenger(
                MESSAGES.PROJECT_TRANSITION,
                request=self.request,
                user=self.request.user,
                source=self.project,
                related=old_stage,
            )
            # remove Project waiting contract task for contracting/staff group
            if settings.STAFF_UPLOAD_CONTRACT:
                remove_tasks_for_user(
                    code=PROJECT_WAITING_CONTRACT,
                    user=self.project.lead,
                    related_obj=self.project,
                )
            else:
                remove_tasks_for_user_group(
                    code=PROJECT_WAITING_CONTRACT,
                    user_group=Group.objects.filter(name=CONTRACTING_GROUP_NAME),
                    related_obj=self.project,
                )
            # add Project waiting invoice task for applicant
            add_task_to_user(
                code=PROJECT_WAITING_INVOICE,
                user=self.project.user,
                related_obj=self.project,
            )
        else:
            if self.request.user != self.project.user:
                messenger(
                    MESSAGES.UPLOAD_CONTRACT,
                    request=self.request,
                    user=self.request.user,
                    source=self.project,
                    related=form.instance,
                )
                # remove Project waiting contract task for contracting/staff group
                if settings.STAFF_UPLOAD_CONTRACT:
                    remove_tasks_for_user(
                        code=PROJECT_WAITING_CONTRACT,
                        user=self.project.lead,
                        related_obj=self.project,
                    )
                else:
                    remove_tasks_for_user_group(
                        code=PROJECT_WAITING_CONTRACT,
                        user_group=Group.objects.filter(
                            name=CONTRACTING_GROUP_NAME
                        ),
                        related_obj=self.project,
                    )
                # add Project waiting contract document task for applicant
                add_task_to_user(
                    code=PROJECT_WAITING_CONTRACT_DOCUMENT,
                    user=self.project.user,
                    related_obj=self.project,
                )
        return HttpResponseClientRefresh()

    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "user": self.request.user,
            "value": _("Upload") if self.request.user.is_applicant else _("Submit"),
            "object": self.project,
        },
    )

SkipPAFApprovalProcessView

Bases: UpdateView

model class-attribute instance-attribute

model = Project

form_class class-attribute instance-attribute

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.object = get_object_or_404(Project, id=kwargs.get("pk"))
    # permissions
    return super().dispatch(request, *args, **kwargs)

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/project.py
def form_valid(self, form):
    project = self.object
    old_stage = project.status
    project.is_locked = True
    project.status = CONTRACTING
    super().form_valid(form)

    # remove PAF submission task for staff group
    remove_tasks_for_user(
        code=PROJECT_SUBMIT_PAF,
        user=self.object.lead,
        related_obj=self.object,
    )

    # remove PAF rejection task for staff if exists
    remove_tasks_for_user(
        code=PAF_REQUIRED_CHANGES,
        user=self.object.lead,
        related_obj=self.object,
    )

    messenger(
        MESSAGES.PROJECT_TRANSITION,
        request=self.request,
        user=self.request.user,
        source=self.object,
        related=old_stage,
    )
    # add project waiting contract task to staff/contracting groups
    if settings.STAFF_UPLOAD_CONTRACT:
        add_task_to_user(
            code=PROJECT_WAITING_CONTRACT,
            user=self.object.lead,
            related_obj=self.object,
        )
    else:
        add_task_to_user_group(
            code=PROJECT_WAITING_CONTRACT,
            user_group=Group.objects.filter(name=CONTRACTING_GROUP_NAME),
            related_obj=self.object,
        )
    return HttpResponseClientRefresh()

SubmitContractDocumentsView

Bases: View

model class-attribute instance-attribute

model = Project

form_class class-attribute instance-attribute

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/submit_contracting_documents.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    if ContractDocumentCategory.objects.filter(
        ~Q(contract_packet_files__project=self.project) & Q(required=True)
    ).exists():
        raise PermissionDenied
    contract = self.project.contracts.order_by("-created_at").first()
    permission, _ = has_permission(
        "submit_contract_documents",
        request.user,
        object=self.project,
        raise_exception=True,
        contract=contract,
    )
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.form_class()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "object": self.project,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(self.request.POST, instance=self.project)
    if form.is_valid():
        form.save()

        self.project.submitted_contract_documents = True
        self.project.save(update_fields=["submitted_contract_documents"])

        messenger(
            MESSAGES.SUBMIT_CONTRACT_DOCUMENTS,
            request=self.request,
            user=self.request.user,
            source=self.project,
        )
        # remove project waiting contract documents task for applicant
        remove_tasks_for_user(
            code=PROJECT_WAITING_CONTRACT_DOCUMENT,
            user=self.project.user,
            related_obj=self.project,
        )
        # add project waiting contract review task for staff
        add_task_to_user(
            code=PROJECT_WAITING_CONTRACT_REVIEW,
            user=self.project.lead,
            related_obj=self.project,
        )

        messages.success(
            self.request,
            _("Contract documents submitted"),
            extra_tags=PROJECT_ACTION_MESSAGE_TAG,
        )
        return HttpResponseClientRefresh()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "object": self.project,
        },
    )

UploadContractDocumentView

Bases: View

form_class class-attribute instance-attribute

model class-attribute instance-attribute

model = Project

context_name class-attribute instance-attribute

context_name = 'contract_document_form'

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/contracting_documents_upload.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, id=kwargs.get("pk"))
    self.category = get_object_or_404(
        ContractDocumentCategory, id=kwargs.get("category_pk")
    )
    if request.user != self.project.user or not request.user.is_applicant:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    upload_contract_document_form = self.form_class(
        instance=self.project, initial={"category": self.category}
    )
    return render(
        self.request,
        self.template_name,
        context={
            "form": upload_contract_document_form,
            "value": _("Submit"),
            "category": self.category,
            "object": self.project,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(
        self.request.POST,
        self.request.FILES,
        instance=self.project,
        initial={"category": self.category},
    )
    if form.is_valid():
        form.instance.project = self.project
        form.save()

        return HttpResponse(
            status=204,
            headers={
                "HX-Trigger": json.dumps(
                    {
                        "contractingDocumentUpload": None,
                        "showMessage": "Contracting Document has been uploaded",
                    }
                ),
            },
        )
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "category": self.category,
            "object": self.project,
        },
    )

ChangePAFStatusView

Bases: View

form_class class-attribute instance-attribute

form_class = ChangePAFStatusForm

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/pafstatus_update.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.object = get_object_or_404(Project, pk=self.kwargs["pk"])
    permission, _ = has_permission(
        "paf_status_update",
        self.request.user,
        object=self.object,
        raise_exception=True,
        request=request,
    )
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.form_class(instance=self.object)
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Update Status"),
            "object": self.object,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(self.request.POST, instance=self.object)
    if form.is_valid():
        form.save()
        project_settings = ProjectSettings.for_request(self.request)
        paf_approval = self.request.user.paf_approvals.filter(
            project=self.object, approved=False
        ).first()
        if not paf_approval:
            # get paf project form for not-assigned case
            if project_settings.paf_approval_sequential:
                paf_approval = self.object.paf_approvals.filter(
                    approved=False
                ).first()
            else:
                for approval in self.object.paf_approvals.filter(approved=False):
                    if self.request.user.id in [
                        role_user.id
                        for role_user in get_users_for_groups(
                            list(approval.paf_reviewer_role.user_roles.all()),
                            exact_match=True,
                        )
                    ]:
                        paf_approval = approval
                        break
                else:
                    # should never be the case but still to avoid 500.
                    raise PermissionDenied("User don't have PAF approver roles")

        paf_status = form.cleaned_data.get("paf_status")
        comment = form.cleaned_data.get("comment", "")

        paf_status_update_message = _(
            "<p>{role} has updated PAF status to {paf_status}.</p>"
        ).format(
            role=paf_approval.paf_reviewer_role.label,
            paf_status=get_paf_status_display(paf_status).lower(),
        )
        Activity.objects.create(
            user=self.request.user,
            type=ACTION,
            source=self.object,
            timestamp=timezone.now(),
            message=paf_status_update_message,
            visibility=TEAM,
        )

        if paf_status == REQUEST_CHANGE:
            old_stage = self.object.status
            self.object.status = DRAFT
            self.object.save(update_fields=["status"])
            paf_approval.save()

            # remove PAF waiting assignee/approval task for paf approval user/reviewer roles.
            if project_settings.paf_approval_sequential:
                if paf_approval.user:
                    remove_tasks_for_user(
                        code=PAF_WAITING_APPROVAL,
                        user=paf_approval.user,
                        related_obj=self.object,
                    )
                else:
                    remove_tasks_for_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                        related_obj=self.object,
                    )
            else:
                for approval in self.object.paf_approvals.filter(approved=False):
                    if approval.user:
                        remove_tasks_for_user(
                            code=PAF_WAITING_APPROVAL,
                            user=approval.user,
                            related_obj=self.object,
                        )
                    else:
                        remove_tasks_for_user_group(
                            code=PAF_WAITING_ASSIGNEE,
                            user_group=approval.paf_reviewer_role.user_roles.all(),
                            related_obj=self.object,
                        )

            if not paf_approval.user:
                paf_approval.user = self.request.user
                paf_approval.save(update_fields=["user"])

            messenger(
                MESSAGES.REQUEST_PROJECT_CHANGE,
                request=self.request,
                user=self.request.user,
                source=self.object,
                comment=comment,
            )
            messenger(
                MESSAGES.PROJECT_TRANSITION,
                request=self.request,
                user=self.request.user,
                source=self.object,
                related=old_stage,
            )
            # add PAF required changes task to staff user group
            add_task_to_user(
                code=PAF_REQUIRED_CHANGES,
                user=self.object.lead,
                related_obj=self.object,
            )

            messages.success(
                self.request,
                _("PAF status has been updated"),
                extra_tags=PROJECT_ACTION_MESSAGE_TAG,
            )
        elif paf_status == APPROVE:
            # remove task for paf approval user/user_group related to this paf_approval of project
            if paf_approval.user:
                remove_tasks_for_user(
                    code=PAF_WAITING_APPROVAL,
                    user=paf_approval.user,
                    related_obj=self.object,
                )
            else:
                remove_tasks_for_user_group(
                    code=PAF_WAITING_ASSIGNEE,
                    user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                    related_obj=self.object,
                )
            paf_approval.approved = True
            paf_approval.approved_at = timezone.now()
            paf_approval.user = self.request.user
            paf_approval.save(update_fields=["approved", "approved_at", "user"])
            if project_settings.paf_approval_sequential:
                # notify next approver
                if self.object.paf_approvals.filter(approved=False).exists():
                    next_paf_approval = self.object.paf_approvals.filter(
                        approved=False
                    ).first()
                    if next_paf_approval.user:
                        messenger(
                            MESSAGES.APPROVE_PAF,
                            request=self.request,
                            user=self.request.user,
                            source=self.object,
                            related=[next_paf_approval],
                        )
                        # add PAF waiting approval task for next paf approval user
                        add_task_to_user(
                            code=PAF_WAITING_APPROVAL,
                            user=next_paf_approval.user,
                            related_obj=self.object,
                        )
                    else:
                        messenger(
                            MESSAGES.ASSIGN_PAF_APPROVER,
                            request=self.request,
                            user=self.request.user,
                            source=self.object,
                        )
                        # add PAF waiting assignee task for nex paf approval reviewer roles
                        add_task_to_user_group(
                            code=PAF_WAITING_ASSIGNEE,
                            user_group=next_paf_approval.paf_reviewer_role.user_roles.all(),
                            related_obj=self.object,
                        )
            messages.success(
                self.request,
                _("PAF has been approved"),
                extra_tags=PROJECT_ACTION_MESSAGE_TAG,
            )

        if form.cleaned_data["comment"]:
            comment = f"<p>\"{form.cleaned_data['comment']}.\"</p>"

            message = paf_status_update_message + comment

            Activity.objects.create(
                user=self.request.user,
                type=COMMENT,
                source=self.object,
                timestamp=timezone.now(),
                message=message,
                visibility=TEAM,
            )

        if self.object.is_approved_by_all_paf_reviewers:
            old_stage = self.object.status
            self.object.is_locked = True
            self.object.status = CONTRACTING
            self.object.save(update_fields=["is_locked", "status"])

            messenger(
                MESSAGES.PROJECT_TRANSITION,
                request=self.request,
                user=self.request.user,
                source=self.object,
                related=old_stage,
            )
            # add project waiting contract task to staff/contracting groups
            if settings.STAFF_UPLOAD_CONTRACT:
                add_task_to_user(
                    code=PROJECT_WAITING_CONTRACT,
                    user=self.object.lead,
                    related_obj=self.object,
                )
            else:
                add_task_to_user_group(
                    code=PROJECT_WAITING_CONTRACT,
                    user_group=Group.objects.filter(name=CONTRACTING_GROUP_NAME),
                    related_obj=self.object,
                )
        return HttpResponseClientRefresh()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Update Status"),
            "object": self.object,
        },
    )

ChangeProjectstatusView

Bases: DelegatedViewMixin, UpdateView

Project status can be updated manually only in 'IN PROGRESS, CLOSING and COMPLETE' state.

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'change_project_status'

model class-attribute instance-attribute

model = Project

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

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, pk=self.kwargs["pk"])
    permission, _ = has_permission(
        "project_status_update", request.user, self.project, raise_exception=True
    )
    return super().dispatch(request, *args, **kwargs)

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/project.py
def form_valid(self, form):
    old_stage = self.project.status

    response = super().form_valid(form)

    comment = form.cleaned_data.get("comment", "")

    if comment:
        Activity.objects.create(
            user=self.request.user,
            type=COMMENT,
            source=self.object,
            timestamp=timezone.now(),
            message=comment,
            visibility=ALL,
        )

    messenger(
        MESSAGES.PROJECT_TRANSITION,
        request=self.request,
        user=self.request.user,
        source=self.object,
        related=old_stage,
    )

    messages.success(
        self.request,
        _("Project status has been updated"),
        extra_tags=PROJECT_ACTION_MESSAGE_TAG,
    )
    return response

UpdateAssignApproversView

Bases: View

form_class class-attribute instance-attribute

form_class = AssignApproversForm

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/assign_pafapprovers.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, pk=self.kwargs["pk"])
    permission, _ = has_permission(
        "update_paf_assigned_approvers",
        request.user,
        self.project,
        raise_exception=True,
        request=request,
    )
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    from ..forms.project import get_latest_project_paf_approval_via_roles

    form = self.form_class(user=self.request.user, instance=self.project)
    paf_approval = get_latest_project_paf_approval_via_roles(
        project=self.project, roles=self.request.user.groups.all()
    )
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "pafapprover_exists": True if paf_approval.user else False,
            "object": self.project,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    from ..forms.project import get_latest_project_paf_approval_via_roles

    form = self.form_class(
        self.request.POST, user=self.request.user, instance=self.project
    )

    old_paf_approval = get_latest_project_paf_approval_via_roles(
        project=self.project, roles=self.request.user.groups.all()
    )

    if form.is_valid():
        form.save()

        # remove current task of user/user_group related to latest paf_approval of project
        if old_paf_approval.user:
            remove_tasks_for_user(
                code=PAF_WAITING_APPROVAL,
                user=old_paf_approval.user,
                related_obj=self.project,
            )
        else:
            remove_tasks_for_user_group(
                code=PAF_WAITING_ASSIGNEE,
                user_group=old_paf_approval.paf_reviewer_role.user_roles.all(),
                related_obj=self.project,
            )

        paf_approval = get_latest_project_paf_approval_via_roles(
            project=self.project, roles=self.request.user.groups.all()
        )

        if paf_approval.user:
            messenger(
                MESSAGES.APPROVE_PAF,
                request=self.request,
                user=self.request.user,
                source=self.project,
                related=[paf_approval],
            )
            # add PAF waiting approval task to updated paf_approval user
            add_task_to_user(
                code=PAF_WAITING_APPROVAL,
                user=paf_approval.user,
                related_obj=self.project,
            )
        else:
            messenger(
                MESSAGES.ASSIGN_PAF_APPROVER,
                request=self.request,
                user=self.request.user,
                source=self.project,
            )
            # add paf waiting for assignee task
            add_task_to_user_group(
                code=PAF_WAITING_ASSIGNEE,
                user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                related_obj=self.project,
            )

        return HttpResponseClientRefresh()

    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "pafapprover_exists": True if old_paf_approval.user else False,
            "object": self.project,
        },
    )

UpdatePAFApproversView

Bases: View

form_class class-attribute instance-attribute

form_class = ApproversForm

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/modals/update_pafapprovers.html'

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    self.project = get_object_or_404(Project, pk=self.kwargs["pk"])
    permission, _ = has_permission(
        "paf_approvers_update",
        request.user,
        self.project,
        raise_exception=True,
        request=request,
    )
    return super().dispatch(request, *args, **kwargs)

get

get(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, *args, **kwargs):
    form = self.form_class(instance=self.project)
    project_settings = ProjectSettings.for_request(self.request)
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "project_settings": project_settings,
            "object": self.project,
        },
    )

post

post(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def post(self, *args, **kwargs):
    form = self.form_class(self.request.POST, instance=self.project)

    project_settings = ProjectSettings.for_request(self.request)
    if form.is_valid():
        old_approvers = None
        if self.project.paf_approvals.exists():
            old_approvers = list(
                self.project.paf_approvals.filter(approved=False).values_list(
                    "user__id", flat=True
                )
            )
        # remove PAF waiting assignee/approval task for paf approval user/reviewer roles.
        if project_settings.paf_approval_sequential:
            paf_approval = self.project.paf_approvals.filter(approved=False).first()
            if paf_approval.user:
                remove_tasks_for_user(
                    code=PAF_WAITING_APPROVAL,
                    user=paf_approval.user,
                    related_obj=self.project,
                )
            else:
                remove_tasks_for_user_group(
                    code=PAF_WAITING_ASSIGNEE,
                    user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                    related_obj=self.project,
                )
        else:
            for approval in self.project.paf_approvals.filter(approved=False):
                if approval.user:
                    remove_tasks_for_user(
                        code=PAF_WAITING_APPROVAL,
                        user=approval.user,
                        related_obj=self.project,
                    )
                else:
                    remove_tasks_for_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=approval.paf_reviewer_role.user_roles.all(),
                        related_obj=self.project,
                    )

        form.save()

        paf_approvals = self.project.paf_approvals.filter(approved=False)

        if old_approvers and paf_approvals:
            # if approvers exists already
            if project_settings.paf_approval_sequential:
                user = paf_approvals.first().user
                if user and user.id != old_approvers[0]:
                    # notify only if first user/approver is updated
                    messenger(
                        MESSAGES.APPROVE_PAF,
                        request=self.request,
                        user=self.request.user,
                        source=self.project,
                        related=[paf_approvals.first()],
                    )
                    # add PAF waiting approval task to paf_approval user
                    add_task_to_user(
                        code=PAF_WAITING_APPROVAL,
                        user=user,
                        related_obj=self.project,
                    )
                elif not user:
                    messenger(
                        MESSAGES.ASSIGN_PAF_APPROVER,
                        request=self.request,
                        user=self.request.user,
                        source=self.project,
                    )
                    # add PAF waiting assignee to paf_approvals reviewer roles
                    add_task_to_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=paf_approvals.first().paf_reviewer_role.user_roles.all(),
                        related_obj=self.project,
                    )
            else:
                if paf_approvals.filter(user__isnull=False).exists():
                    messenger(
                        MESSAGES.APPROVE_PAF,
                        request=self.request,
                        user=self.request.user,
                        source=self.project,
                        related=paf_approvals.filter(user__isnull=False),
                    )
                    # add PAF waiting approval task for paf_approvals users
                    for paf_approval in paf_approvals.filter(user__isnull=False):
                        add_task_to_user(
                            code=PAF_WAITING_APPROVAL,
                            user=paf_approval.user,
                            related_obj=self.project,
                        )
                if paf_approvals.filter(user__isnull=True).exists():
                    messenger(
                        MESSAGES.ASSIGN_PAF_APPROVER,
                        request=self.request,
                        user=self.request.user,
                        source=self.project,
                    )
                    # add PAF waiting assignee task for paf_approvals reviewer_roles
                    for paf_approval in paf_approvals.filter(user__isnull=True):
                        add_task_to_user_group(
                            code=PAF_WAITING_ASSIGNEE,
                            user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                            related_obj=self.project,
                        )
        elif paf_approvals:
            # :todo: check if this is covering any case(might be a duplicate of SendForApprovalView)
            if paf_approvals.filter(user__isnull=False).exists():
                messenger(
                    MESSAGES.APPROVE_PAF,
                    request=self.request,
                    user=self.request.user,
                    source=self.project,
                    related=paf_approvals.filter(user__isnull=False),
                )
                # add PAF waiting approval task for paf_approvals users
                for paf_approval in paf_approvals.filter(user__isnull=False):
                    add_task_to_user(
                        code=PAF_WAITING_APPROVAL,
                        user=paf_approval.user,
                        related_obj=self.project,
                    )
            if paf_approvals.filter(user__isnull=True).exists():
                messenger(
                    MESSAGES.ASSIGN_PAF_APPROVER,
                    request=self.request,
                    user=self.request.user,
                    source=self.project,
                )
                # add PAF waiting assignee task for paf_approvals reviewer_roles
                for paf_approval in paf_approvals.filter(user__isnull=True):
                    add_task_to_user_group(
                        code=PAF_WAITING_ASSIGNEE,
                        user_group=paf_approval.paf_reviewer_role.user_roles.all(),
                        related_obj=self.project,
                    )

        messages.success(
            self.request,
            _("PAF approvers have been updated"),
            extra_tags=PROJECT_ACTION_MESSAGE_TAG,
        )
        return HttpResponseClientRefresh()
    return render(
        self.request,
        self.template_name,
        context={
            "form": form,
            "value": _("Submit"),
            "project_settings": project_settings,
            "object": self.project,
        },
    )

BaseProjectDetailView

Bases: ReportingMixin, DetailView

dispatch

dispatch(*args, **kwargs)
Source code in hypha/apply/projects/views/report.py
def dispatch(self, *args, **kwargs):
    project = self.get_object()
    if project.is_in_progress:
        if not hasattr(project, "report_config"):
            ReportConfig.objects.create(project=project)

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

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/project.py
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["statuses"] = get_project_status_choices()
    context["current_status_index"] = [
        status for status, _ in get_project_status_choices()
    ].index(self.object.status)
    context["supporting_documents_configured"] = (
        True if DocumentCategory.objects.count() else False
    )
    context["contracting_documents_configured"] = (
        True if ContractDocumentCategory.objects.count() else False
    )
    return context

AdminProjectDetailView

AdminProjectDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, ContractsMixin, BaseProjectDetailView

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

model = Project

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_admin_detail'

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(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def dispatch(self, *args, **kwargs):
    project = self.get_object()
    permission, _ = has_permission(
        "project_access", self.request.user, object=project, raise_exception=True
    )
    return super().dispatch(*args, **kwargs)

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/project.py
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["statuses"] = get_project_status_choices()
    context["current_status_index"] = [
        status for status, _ in get_project_status_choices()
    ].index(self.object.status)
    project_settings = ProjectSettings.for_request(self.request)
    context["project_settings"] = project_settings
    context["paf_approvals"] = PAFApprovals.objects.filter(project=self.object)

    if (
        self.object.is_in_progress
        and not self.object.report_config.disable_reporting
    ):
        # Current due report can be none for ONE_TIME,
        # In case of ONE_TIME, either reporting is already completed(last_report exists)
        # or there should be a current_due_report.
        if self.object.report_config.current_due_report():
            context["report_data"] = {
                "startDate": self.object.report_config.current_due_report().start_date,
                "projectEndDate": self.object.end_date,
            }
        else:
            context["report_data"] = {
                "startDate": self.object.report_config.last_report().start_date,
                "projectEndDate": self.object.end_date,
            }
    return context

ApplicantProjectDetailView

ApplicantProjectDetailView(*args, **kwargs)

Bases: ActivityContextMixin, DelegateableView, ContractsMixin, BaseProjectDetailView

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-'

form_views class-attribute instance-attribute

model class-attribute instance-attribute

model = Project

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_detail'

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/projects/views/project.py
def dispatch(self, request, *args, **kwargs):
    project = self.get_object()
    permission, _ = has_permission(
        "project_access", request.user, object=project, raise_exception=True
    )
    return super().dispatch(request, *args, **kwargs)

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/project.py
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["statuses"] = PROJECT_PUBLIC_STATUSES
    context["current_status_index"] = [
        status for status, _ in PROJECT_PUBLIC_STATUSES
    ].index(self.object.status)
    context["remaining_contract_document_categories"] = (
        ContractDocumentCategory.objects.filter(
            ~Q(contract_packet_files__project=self.object)
        )
    )
    return context

ProjectDetailView

Bases: ViewDispatcher

reviewer_view class-attribute instance-attribute

reviewer_view = None

partner_view class-attribute instance-attribute

partner_view = None

community_view class-attribute instance-attribute

community_view = None

admin_view class-attribute instance-attribute

finance_view class-attribute instance-attribute

finance_view = AdminProjectDetailView

contracting_view class-attribute instance-attribute

contracting_view = AdminProjectDetailView

applicant_view class-attribute instance-attribute

applicant_view = ApplicantProjectDetailView

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

ProjectPrivateMediaView

Bases: UserPassesTestMixin, PrivateMediaView

See also hypha/apply/funds/files.py

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/projects/views/project.py
def dispatch(self, *args, **kwargs):
    project_pk = self.kwargs["pk"]
    self.project = get_object_or_404(Project, pk=project_pk)
    return super().dispatch(*args, **kwargs)

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get_media(self, *args, **kwargs):
    if "file_pk" in kwargs:
        document = PacketFile.objects.get(pk=kwargs["file_pk"])
        if document.project != self.project:
            raise Http404
        return document.document
    else:
        field_id = kwargs["field_id"]
        file_name = kwargs["file_name"]
        path_to_file = generate_private_file_path(
            self.project.pk, field_id, file_name, path_start="project"
        )
        return self.storage.open(path_to_file)

test_func

test_func()
Source code in hypha/apply/projects/views/project.py
def test_func(self):
    if self.request.user.is_apply_staff:
        return True

    if self.request.user == self.project.user:
        return True

    if self.request.user.id in self.project.paf_approvals.filter(
        approved=False
    ).values_list("user__id", flat=True):
        return True

    return False

CategoryTemplatePrivateMediaView

Bases: 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/projects/views/project.py
def dispatch(self, *args, **kwargs):
    project_pk = self.kwargs["pk"]
    self.project = get_object_or_404(Project, pk=project_pk)
    self.category_type = kwargs["type"]
    permission, _ = has_permission(
        "project_access",
        self.request.user,
        object=self.project,
        raise_exception=True,
    )
    return super().dispatch(*args, **kwargs)

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get_media(self, *args, **kwargs):
    if self.category_type == "project_document":
        category = DocumentCategory.objects.get(pk=kwargs["category_pk"])
    elif self.category_type == "contract_document":
        category = ContractDocumentCategory.objects.get(pk=kwargs["category_pk"])
    else:
        raise Http404
    if not category.template:
        raise Http404
    return category.template

ContractPrivateMediaView

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/projects/views/project.py
def dispatch(self, *args, **kwargs):
    project_pk = self.kwargs["pk"]
    self.project = get_object_or_404(Project, pk=project_pk)
    return super().dispatch(*args, **kwargs)

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get_media(self, *args, **kwargs):
    document = Contract.objects.get(pk=kwargs["file_pk"])
    if document.project != self.project:
        raise Http404
    return document.file

test_func

test_func()
Source code in hypha/apply/projects/views/project.py
def test_func(self):
    if self.request.user.is_apply_staff or self.request.user.is_contracting:
        return True

    if self.request.user == self.project.user:
        return True

    return False

ContractDocumentPrivateMediaView

Bases: 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/projects/views/project.py
def dispatch(self, *args, **kwargs):
    project_pk = self.kwargs["pk"]
    self.project = get_object_or_404(Project, pk=project_pk)
    self.document = ContractPacketFile.objects.get(pk=kwargs["file_pk"])
    permission, _ = has_permission(
        "view_contract_documents",
        self.request.user,
        object=self.project,
        contract_category=self.document.category,
        raise_exception=True,
    )
    return super().dispatch(*args, **kwargs)

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get_media(self, *args, **kwargs):
    if self.document.project != self.project:
        raise Http404
    return self.document.document

ProjectDetailApprovalView

Bases: DetailView

model class-attribute instance-attribute

model = Project

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_approval_detail'

ProjectSOWView

Bases: DetailView

model class-attribute instance-attribute

model = Project

template_name_suffix class-attribute instance-attribute

template_name_suffix = '_sow_detail'

ProjectSOWDownloadView

Bases: SingleObjectMixin, View

model class-attribute instance-attribute

model = Project

get

get(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, request, *args, **kwargs):
    export_type = kwargs.get("export_type", "pdf")
    self.object = self.get_object()
    context = {}
    context["sow_data"] = self.get_sow_data_with_field(self.object)
    context["org_name"] = settings.ORG_LONG_NAME
    context["title"] = self.object.title
    context["project_link"] = self.request.build_absolute_uri(
        reverse("apply:projects:detail", kwargs={"pk": self.object.id})
    )
    template_path = "application_projects/sow_export.html"

    if export_type == "pdf":
        pdf_page_settings = PDFPageSettings.for_request(request)

        context["show_footer"] = True
        context["export_date"] = datetime.date.today().strftime("%b %d, %Y")
        context["export_user"] = request.user
        context["pagesize"] = pdf_page_settings.download_page_size

        return self.render_as_pdf(
            context=context,
            template=get_template(template_path),
            filename=self.get_slugified_file_name(export_type),
        )
    elif export_type == "docx":
        context["show_footer"] = False

        return self.render_as_docx(
            context=context,
            template=get_template(template_path),
            filename=self.get_slugified_file_name(export_type),
        )
    else:
        raise Http404(f"{export_type} type not supported at the moment")

render_as_pdf

render_as_pdf(context, template, filename)
Source code in hypha/apply/projects/views/project.py
def render_as_pdf(self, context, template, filename):
    html = template.render(context)
    response = HttpResponse(content_type="application/pdf")
    response["Content-Disposition"] = f"attachment; filename={filename}"

    pisa_status = pisa.CreatePDF(
        html, dest=response, encoding="utf-8", raise_exception=True
    )
    if pisa_status.err:
        # :todo: needs to handle it in a better way
        raise Http404("PDF type not supported at the moment")
    return response

render_as_docx

render_as_docx(context, template, filename)
Source code in hypha/apply/projects/views/project.py
def render_as_docx(self, context, template, filename):
    html = template.render(context)

    buf = io.BytesIO()
    document = Document()
    new_parser = HtmlToDocx()
    new_parser.add_html_to_document(html, document)
    document.save(buf)

    response = HttpResponse(buf.getvalue(), content_type="application/docx")
    response["Content-Disposition"] = f"attachment; filename={filename}"
    return response

get_slugified_file_name

get_slugified_file_name(export_type)
Source code in hypha/apply/projects/views/project.py
def get_slugified_file_name(self, export_type):
    return f"{datetime.date.today().strftime('%Y%m%d')}-{slugify(self.object.title)}.{export_type}"

get_sow_data_with_field

get_sow_data_with_field(project)
Source code in hypha/apply/projects/views/project.py
def get_sow_data_with_field(self, project):
    data_dict = {}
    if project.submission.page.specific.sow_forms.exists() and project.sow:
        form_data_dict = project.sow.form_data
        for field in project.sow.form_fields.raw_data:
            if field.get("type", None) in ["file", "multi_file"]:
                continue
            if field["id"] in form_data_dict.keys():
                if (
                    isinstance(field["value"], dict)
                    and "field_label" in field["value"]
                ):
                    data_dict[field["value"]["field_label"]] = form_data_dict[
                        field["id"]
                    ]

    return data_dict

ProjectDetailDownloadView

Bases: SingleObjectMixin, View

model class-attribute instance-attribute

model = Project

get

get(request, *args, **kwargs)
Source code in hypha/apply/projects/views/project.py
def get(self, request, *args, **kwargs):
    export_type = kwargs.get("export_type", None)
    self.object = self.get_object()
    context = self.get_paf_download_context()
    template_path = "application_projects/paf_export.html"

    if export_type == "pdf":
        pdf_page_settings = PDFPageSettings.for_request(request)

        context["show_footer"] = True
        context["export_date"] = datetime.date.today().strftime("%b %d, %Y")
        context["export_user"] = request.user
        context["pagesize"] = pdf_page_settings.download_page_size

        return self.render_as_pdf(
            context=context,
            template=get_template(template_path),
            filename=self.get_slugified_file_name(export_type),
        )
    elif export_type == "docx":
        context["show_footer"] = False

        return self.render_as_docx(
            context=context,
            template=get_template(template_path),
            filename=self.get_slugified_file_name(export_type),
        )
    else:
        raise Http404(f"{export_type} type not supported at the moment")

render_as_pdf

render_as_pdf(context, template, filename)
Source code in hypha/apply/projects/views/project.py
def render_as_pdf(self, context, template, filename):
    html = template.render(context)
    response = HttpResponse(content_type="application/pdf")
    response["Content-Disposition"] = f"attachment; filename={filename}"

    pisa_status = pisa.CreatePDF(
        html, dest=response, encoding="utf-8", raise_exception=True
    )
    if pisa_status.err:
        # :todo: needs to handle it in a better way
        raise Http404("PDF type not supported at the moment")
    return response

render_as_docx

render_as_docx(context, template, filename)
Source code in hypha/apply/projects/views/project.py
def render_as_docx(self, context, template, filename):
    html = template.render(context)

    buf = io.BytesIO()
    document = Document()
    new_parser = HtmlToDocx()
    new_parser.add_html_to_document(html, document)
    document.save(buf)

    response = HttpResponse(buf.getvalue(), content_type="application/docx")
    response["Content-Disposition"] = f"attachment; filename={filename}"
    return response

get_slugified_file_name

get_slugified_file_name(export_type)
Source code in hypha/apply/projects/views/project.py
def get_slugified_file_name(self, export_type):
    return f"{datetime.date.today().strftime('%Y%m%d')}-{slugify(self.object.title)}.{export_type}"

get_paf_download_context

get_paf_download_context()
Source code in hypha/apply/projects/views/project.py
def get_paf_download_context(self):
    context = {}
    context["id"] = self.object.id
    context["title"] = self.object.title
    context["project_link"] = self.request.build_absolute_uri(
        reverse("apply:projects:detail", kwargs={"pk": self.object.id})
    )
    context["contractor_name"] = self.object.user

    context["approvals"] = self.object.paf_approvals.all()
    context["paf_data"] = self.get_paf_data_with_field(self.object)
    context["sow_data"] = self.get_sow_data_with_field(self.object)
    context["submission"] = self.object.submission
    context["submission_link"] = self.request.build_absolute_uri(
        reverse(
            "apply:submissions:detail", kwargs={"pk": self.object.submission.id}
        )
    )
    context["supporting_documents"] = self.get_supporting_documents(self.object)
    context["org_name"] = settings.ORG_LONG_NAME
    return context

get_paf_data_with_field

get_paf_data_with_field(project)
Source code in hypha/apply/projects/views/project.py
def get_paf_data_with_field(self, project):
    data_dict = {}
    form_data_dict = project.form_data
    for field in project.form_fields.raw_data:
        if field.get("type", None) in ["file", "multi_file"]:
            continue
        if field["id"] in form_data_dict.keys():
            if isinstance(field["value"], dict) and "field_label" in field["value"]:
                data_dict[field["value"]["field_label"]] = form_data_dict[
                    field["id"]
                ]

    return data_dict

get_sow_data_with_field

get_sow_data_with_field(project)
Source code in hypha/apply/projects/views/project.py
def get_sow_data_with_field(self, project):
    data_dict = {}
    if project.submission.page.specific.sow_forms.exists() and project.sow:
        form_data_dict = project.sow.form_data
        for field in project.sow.form_fields.raw_data:
            if field.get("type", None) in ["file", "multi_file"]:
                continue
            if field["id"] in form_data_dict.keys():
                if (
                    isinstance(field["value"], dict)
                    and "field_label" in field["value"]
                ):
                    data_dict[field["value"]["field_label"]] = form_data_dict[
                        field["id"]
                    ]

    return data_dict

get_supporting_documents

get_supporting_documents(project)
Source code in hypha/apply/projects/views/project.py
def get_supporting_documents(self, project):
    documents_dict = {}
    for packet_file in project.packet_files.all():
        documents_dict[packet_file.title] = self.request.build_absolute_uri(
            reverse(
                "apply:projects:document",
                kwargs={"pk": project.id, "file_pk": packet_file.id},
            )
        )
    return documents_dict

ProjectFormEditView

Bases: BaseStreamForm, UpdateView

submission_form_class class-attribute instance-attribute

submission_form_class = PageStreamBaseForm

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

model class-attribute instance-attribute

model = Project

template_name class-attribute instance-attribute

template_name = 'application_projects/project_approval_form.html'

paf_form class-attribute instance-attribute

paf_form = None

sow_form class-attribute instance-attribute

sow_form = None

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

buttons

buttons()
Source code in hypha/apply/projects/views/project.py
def buttons(self):
    yield ("submit", "primary", _("Save"))

dispatch

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

    permission, msg = has_permission(
        "paf_edit", self.request.user, self.object, raise_exception=True
    )
    if not permission:
        messages.info(self.request, msg)
    return super().dispatch(request, *args, **kwargs)

approval_form

approval_form()
Source code in hypha/apply/projects/views/project.py
@cached_property
def approval_form(self):
    # fetching from the fund directly instead of going through round
    approval_form = (
        self.object.submission.page.specific.approval_forms.first()
    )  # picking up the first one

    return approval_form

approval_sow_form

approval_sow_form()
Source code in hypha/apply/projects/views/project.py
@cached_property
def approval_sow_form(self):
    # fetching from the fund directly instead of going through round
    approval_sow_form = (
        self.object.submission.page.specific.sow_forms.first()
    )  # picking up the first one

    return approval_sow_form

get_form_class

get_form_class(form_class, draft=False, form_data=None, user=None)
Source code in hypha/apply/projects/views/project.py
def get_form_class(self, form_class, draft=False, form_data=None, user=None):
    return type(
        "WagtailStreamForm",
        (form_class,),
        self.get_form_fields(draft, form_data, user),
    )

get_paf_form

get_paf_form(form_class=None)
Source code in hypha/apply/projects/views/project.py
def get_paf_form(self, form_class=None):
    if form_class is None:
        form_class = self.get_form_class(ProjectForm)
    return form_class(**self.get_paf_form_kwargs())

get_sow_form

get_sow_form(form_class=None)
Source code in hypha/apply/projects/views/project.py
def get_sow_form(self, form_class=None):
    if form_class is None:
        form_class = self.get_form_class(ProjectSOWForm)
    return form_class(**self.get_sow_form_kwargs())

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/project.py
def get_context_data(self, **kwargs):
    self.paf_form = self.get_paf_form()
    if self.approval_sow_form:
        self.sow_form = self.get_sow_form()

    submission_attachments = []
    for _field, files in self.object.submission.extract_files().items():
        if isinstance(files, list):
            submission_attachments.extend(files)
        else:
            submission_attachments.append(files)

    return {
        "title": self.object.title,
        "buttons": self.buttons(),
        "approval_form_exists": True if self.approval_form else False,
        "sow_form_exists": True if self.approval_sow_form else False,
        "paf_form": self.paf_form,
        "sow_form": self.sow_form,
        "object": self.object,
        "submissions_attachments": submission_attachments,
        **kwargs,
    }

get_paf_form_fields

get_paf_form_fields()
Source code in hypha/apply/projects/views/project.py
def get_paf_form_fields(self):
    return self.object.form_fields or self.approval_form.form.form_fields

get_sow_form_fields

get_sow_form_fields()
Source code in hypha/apply/projects/views/project.py
def get_sow_form_fields(self):
    if hasattr(self.object, "sow"):
        return (
            self.object.sow.form_fields or self.approval_sow_form.form.form_fields
        )
    return self.approval_sow_form.form.form_fields

get_defined_fields

get_defined_fields()
Source code in hypha/apply/projects/views/project.py
def get_defined_fields(self):
    approval_form = self.approval_form
    if approval_form and not self.paf_form:
        return self.get_paf_form_fields()
    if self.approval_sow_form and self.paf_form and not self.sow_form:
        return self.get_sow_form_fields()
    return self.object.get_defined_fields()

get_paf_form_kwargs

get_paf_form_kwargs()
Source code in hypha/apply/projects/views/project.py
def get_paf_form_kwargs(self):
    kwargs = super().get_form_kwargs()

    if self.approval_form:
        fields = self.approval_form.form.get_form_fields()
    else:
        fields = {}

    kwargs["extra_fields"] = fields
    initial = self.object.raw_data
    for field_id in self.object.file_field_ids:
        initial.pop(field_id + "-uploads", False)
        initial[field_id] = get_placeholder_file(self.object.raw_data.get(field_id))
    kwargs["initial"].update(initial)
    return kwargs

get_sow_form_kwargs

get_sow_form_kwargs()
Source code in hypha/apply/projects/views/project.py
def get_sow_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    if self.approval_sow_form:
        fields = self.approval_sow_form.form.get_form_fields()

        kwargs["extra_fields"] = fields
        try:
            sow_instance = self.object.sow
            initial = sow_instance.raw_data
            for field_id in sow_instance.file_field_ids:
                initial.pop(field_id + "-uploads", False)
                initial[field_id] = get_placeholder_file(
                    sow_instance.raw_data.get(field_id)
                )
            initial["project"] = self.object
            kwargs["initial"].update(initial)
        except ObjectDoesNotExist:
            kwargs["initial"].update({"project": self.object})
    return kwargs

post

post(request, *args, **kwargs)

Handle POST requests: instantiate a form instance with the passed POST variables and then check if it's valid.

Source code in hypha/apply/projects/views/project.py
def post(self, request, *args, **kwargs):
    """
    Handle POST requests: instantiate a form instance with the passed
    POST variables and then check if it's valid.
    """

    self.paf_form = self.get_paf_form()
    if self.approval_sow_form:
        self.sow_form = self.get_sow_form()
        if self.paf_form.is_valid() and self.sow_form.is_valid():
            # if both forms exists, both needs to be valid together
            try:
                paf_form_fields = self.get_paf_form_fields()
            except AttributeError:
                paf_form_fields = []
            try:
                sow_form_fields = self.get_sow_form_fields()
            except AttributeError:
                sow_form_fields = []

            self.paf_form.save(paf_form_fields=paf_form_fields)
            self.sow_form.save(sow_form_fields=sow_form_fields, project=self.object)
            self.paf_form.delete_temporary_files()
            self.sow_form.delete_temporary_files()
            # remove PAF addition task for staff group
            remove_tasks_for_user(
                code=PROJECT_WAITING_PAF,
                user=self.object.lead,
                related_obj=self.object,
            )
            # add PAF submission task for staff group
            add_task_to_user(
                code=PROJECT_SUBMIT_PAF,
                user=self.object.lead,
                related_obj=self.object,
            )
            return HttpResponseRedirect(self.get_success_url())
        else:
            if not self.paf_form.is_valid():
                return self.form_invalid(self.paf_form)
            return self.form_invalid(self.sow_form)
    else:
        if self.paf_form.is_valid():
            # paf can exist alone also, it needs to be valid
            try:
                paf_form_fields = self.get_paf_form_fields()
            except AttributeError:
                paf_form_fields = []
            self.paf_form.save(paf_form_fields=paf_form_fields)
            self.paf_form.delete_temporary_files()
            # remove PAF addition task for staff group
            remove_tasks_for_user(
                code=PROJECT_WAITING_PAF,
                user=self.object.lead,
                related_obj=self.object,
            )
            # add PAF submission task for staff group
            add_task_to_user(
                code=PROJECT_SUBMIT_PAF,
                user=self.object.lead,
                related_obj=self.object,
            )
            return HttpResponseRedirect(self.get_success_url())
        else:
            return self.form_invalid(self.paf_form)

ProjectListView

Bases: SingleTableMixin, FilterView

filterset_class class-attribute instance-attribute

filterset_class = ProjectListFilter

queryset class-attribute instance-attribute

queryset = for_table()

table_class class-attribute instance-attribute

table_class = ProjectsListTable

template_name class-attribute instance-attribute

template_name = 'application_projects/project_list.html'