Skip to content

Payment

hypha.apply.projects.views.payment

InvoiceAccessMixin

Bases: UserPassesTestMixin

model class-attribute instance-attribute

model = Invoice

get_object

get_object()
Source code in hypha/apply/projects/views/payment.py
def get_object(self):
    project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return get_object_or_404(project.invoices.all(), pk=self.kwargs["invoice_pk"])

test_func

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

    if self.request.user.is_finance:
        return True

    if self.request.user == self.get_object().project.user:
        return True

    return False

ChangeInvoiceStatusView

Bases: DelegatedViewMixin, InvoiceAccessMixin, UpdateView

form_class class-attribute instance-attribute

context_name class-attribute instance-attribute

context_name = 'change_invoice_status'

model class-attribute instance-attribute

model = Invoice

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

test_func

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

    if self.request.user.is_finance:
        return True

    if self.request.user == self.get_object().project.user:
        return True

    return False

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_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/payment.py
def form_valid(self, form):
    invoice = get_object_or_404(
        Invoice, pk=self.kwargs["invoice_pk"]
    )  # to get the old status
    old_status = invoice.status
    response = super().form_valid(form)
    if form.cleaned_data["comment"]:
        invoice_status_change = _(
            "<p>Invoice status updated to: {status}.</p>"
        ).format(status=self.object.get_status_display())
        comment = f"<p>{self.object.comment}.</p>"

        message = invoice_status_change + comment

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

    if (
        self.request.user.is_apply_staff and self.object.status == APPROVED_BY_STAFF
    ) or (
        settings.INVOICE_EXTENDED_WORKFLOW
        and self.request.user.is_finance_level_1
        and self.object.status == APPROVED_BY_FINANCE
    ):
        messenger(
            MESSAGES.APPROVE_INVOICE,
            request=self.request,
            user=self.request.user,
            source=self.object.project,
            related=self.object,
        )

    messenger(
        MESSAGES.UPDATE_INVOICE_STATUS,
        request=self.request,
        user=self.request.user,
        source=self.object.project,
        related=self.object,
    )

    handle_tasks_on_invoice_update(old_status=old_status, invoice=self.object)

    return response

DeleteInvoiceView

Bases: DeleteView

model class-attribute instance-attribute

model = Invoice

get_object

get_object()
Source code in hypha/apply/projects/views/payment.py
def get_object(self):
    project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return get_object_or_404(project.invoices.all(), pk=self.kwargs["invoice_pk"])

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/payment.py
def dispatch(self, request, *args, **kwargs):
    self.object = self.get_object()
    if not self.object.can_user_delete(request.user):
        raise PermissionDenied

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

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/payment.py
@transaction.atomic()
def form_valid(self, form):
    # remove all tasks related to this invoice irrespective of code and users/user_group
    remove_tasks_of_related_obj(related_obj=self.object)

    response = super().form_valid(form)

    messenger(
        MESSAGES.DELETE_INVOICE,
        request=self.request,
        user=self.request.user,
        source=self.object.project,
        related=self.object.project,
    )

    return response

get_success_url

get_success_url()
Source code in hypha/apply/projects/views/payment.py
def get_success_url(self):
    return self.object.project.get_absolute_url()

InvoiceAdminView

InvoiceAdminView(*args, **kwargs)

Bases: InvoiceAccessMixin, DelegateableView, DetailView

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

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

model class-attribute instance-attribute

model = Invoice

form_views class-attribute instance-attribute

form_views = [ChangeInvoiceStatusView]

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)

get_object

get_object()
Source code in hypha/apply/projects/views/payment.py
def get_object(self):
    project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return get_object_or_404(project.invoices.all(), pk=self.kwargs["invoice_pk"])

test_func

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

    if self.request.user.is_finance:
        return True

    if self.request.user == self.get_object().project.user:
        return True

    return False

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/payment.py
def get_context_data(self, **kwargs):
    invoice = self.get_object()
    project = invoice.project
    deliverables = project.deliverables.all()
    invoice_activities = Activity.actions.filter(
        related_content_type__model="invoice", related_object_id=invoice.id
    ).visible_to(self.request.user)
    return super().get_context_data(
        **kwargs,
        deliverables=deliverables,
        latest_activity=invoice_activities.first(),
        activities=invoice_activities[1:],
    )

InvoiceApplicantView

InvoiceApplicantView(*args, **kwargs)

Bases: InvoiceAccessMixin, DelegateableView, DetailView

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

form_prefix class-attribute instance-attribute

form_prefix = 'form-submitted-'

model class-attribute instance-attribute

model = Invoice

form_views class-attribute instance-attribute

form_views = []

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)

get_object

get_object()
Source code in hypha/apply/projects/views/payment.py
def get_object(self):
    project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return get_object_or_404(project.invoices.all(), pk=self.kwargs["invoice_pk"])

test_func

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

    if self.request.user.is_finance:
        return True

    if self.request.user == self.get_object().project.user:
        return True

    return False

get_context_data

get_context_data(**kwargs)
Source code in hypha/apply/projects/views/payment.py
def get_context_data(self, **kwargs):
    invoice = self.get_object()
    invoice_activities = Activity.actions.filter(
        related_content_type__model="invoice", related_object_id=invoice.id
    ).visible_to(self.request.user)
    return super().get_context_data(
        **kwargs,
        latest_activity=invoice_activities.first(),
        activities=invoice_activities[1:],
    )

InvoiceView

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

contracting_view class-attribute instance-attribute

contracting_view = None

admin_view class-attribute instance-attribute

admin_view = InvoiceAdminView

finance_view class-attribute instance-attribute

finance_view = InvoiceAdminView

applicant_view class-attribute instance-attribute

applicant_view = InvoiceApplicantView

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 self.finance_check(request):
        view = self.finance_view
    elif 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()

CreateInvoiceView

Bases: CreateView

model class-attribute instance-attribute

model = Invoice

form_class class-attribute instance-attribute

form_class = CreateInvoiceForm

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/payment.py
def dispatch(self, request, *args, **kwargs):
    self.project = Project.objects.get(pk=kwargs["pk"])
    if not request.user.is_apply_staff and not self.project.user == request.user:
        return redirect(self.project)
    return super().dispatch(request, *args, **kwargs)

buttons

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

get_context_data

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

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/payment.py
def form_valid(self, form):
    form.instance.project = self.project
    form.instance.by = self.request.user

    response = super().form_valid(form)

    if form.cleaned_data["message_for_pm"]:
        invoice_status_change = _("<p>Invoice added.</p>")

        message_for_pm = f'<p>{form.cleaned_data["message_for_pm"]}</p>'

        message = invoice_status_change + message_for_pm

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

    messenger(
        MESSAGES.CREATE_INVOICE,
        request=self.request,
        user=self.request.user,
        source=self.project,
        related=self.object,
    )

    if len(self.project.invoices.all()) == 1:
        # remove Project waiting invoices task for applicant on first invoice
        remove_tasks_for_user(
            code=PROJECT_WAITING_INVOICE,
            user=self.project.user,
            related_obj=self.project,
        )

    # add Invoice waiting approval task for Staff group
    add_task_to_user_group(
        code=INVOICE_WAITING_APPROVAL,
        user_group=Group.objects.filter(name=STAFF_GROUP_NAME),
        related_obj=self.object,
    )

    messages.success(
        self.request, _("Invoice added"), extra_tags=PROJECT_ACTION_MESSAGE_TAG
    )

    # Required for django-file-form: delete temporary files for the new files
    # that are uploaded.
    form.delete_temporary_files()
    return response

EditInvoiceView

Bases: InvoiceAccessMixin, UpdateView

model class-attribute instance-attribute

model = Invoice

form_class class-attribute instance-attribute

form_class = EditInvoiceForm

get_object

get_object()
Source code in hypha/apply/projects/views/payment.py
def get_object(self):
    project = get_object_or_404(Project, pk=self.kwargs["pk"])
    return get_object_or_404(project.invoices.all(), pk=self.kwargs["invoice_pk"])

test_func

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

    if self.request.user.is_finance:
        return True

    if self.request.user == self.get_object().project.user:
        return True

    return False

dispatch

dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/payment.py
def dispatch(self, request, *args, **kwargs):
    invoice = self.get_object()
    if not invoice.can_user_edit(request.user):
        return redirect(invoice)
    return super().dispatch(request, *args, **kwargs)

buttons

buttons()
Source code in hypha/apply/projects/views/payment.py
def buttons(self):
    yield ("submit", "primary", _("Save"))
    if self.object.can_user_delete(self.request.user):
        yield ("delete", "warning", _("Delete"))

get_initial

get_initial()
Source code in hypha/apply/projects/views/payment.py
def get_initial(self):
    initial = super().get_initial()
    initial["supporting_documents"] = [
        document.document for document in self.object.supporting_documents.all()
    ]
    return initial

get_context_data

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

post

post(request, *args, **kwargs)
Source code in hypha/apply/projects/views/payment.py
def post(self, request, *args, **kwargs):
    self.object = self.get_object()
    form = self.get_form()
    if "delete" in form.data:
        return redirect(
            "apply:projects:invoice-delete",
            pk=self.object.project.id,
            invoice_pk=self.object.id,
        )
    if form.is_valid():
        return self.form_valid(form)
    else:
        return self.form_invalid(form)

form_valid

form_valid(form)
Source code in hypha/apply/projects/views/payment.py
def form_valid(self, form):
    old_status = self.object.status
    response = super().form_valid(form)

    if form.cleaned_data:
        if self.object.status in INVOICE_TRANISTION_TO_RESUBMITTED:
            self.object.transition_invoice_to_resubmitted()
            self.object.save()

        if form.cleaned_data["message_for_pm"]:
            invoice_status_change = _(
                "<p>Invoice status updated to: {status}.</p>"
            ).format(status=self.object.get_status_display())
            message_for_pm = f'<p>{form.cleaned_data["message_for_pm"]}</p>'
            message = invoice_status_change + message_for_pm

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

    messenger(
        MESSAGES.UPDATE_INVOICE_STATUS,
        request=self.request,
        user=self.request.user,
        source=self.object.project,
        related=self.object,
    )

    if self.request.user.is_applicant and old_status == CHANGES_REQUESTED_BY_STAFF:
        # remove invoice required changes task for applicant
        remove_tasks_for_user(
            code=INVOICE_REQUIRED_CHANGES,
            user=self.object.project.user,
            related_obj=self.object,
        )

        # add invoice waiting approval task for staff group
        add_task_to_user_group(
            code=INVOICE_WAITING_APPROVAL,
            user_group=Group.objects.filter(name=STAFF_GROUP_NAME),
            related_obj=self.object,
        )

    if (
        self.request.user.is_apply_staff
        and old_status == CHANGES_REQUESTED_BY_FINANCE
    ):
        # remove invoice required changes task for staff group
        remove_tasks_for_user_group(
            code=INVOICE_REQUIRED_CHANGES,
            user_group=Group.objects.filter(name=STAFF_GROUP_NAME),
            related_obj=self.object,
        )
        # add invoice waiting approval task for staff group
        add_task_to_user_group(
            code=INVOICE_WAITING_APPROVAL,
            user_group=Group.objects.filter(name=STAFF_GROUP_NAME),
            related_obj=self.object,
        )

    # Required for django-file-form: delete temporary files for the new files
    # that are uploaded.
    form.delete_temporary_files()
    return response

InvoicePrivateMedia

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/payment.py
def dispatch(self, *args, **kwargs):
    invoice_pk = self.kwargs["invoice_pk"]
    project_pk = self.kwargs["pk"]
    self.project = get_object_or_404(Project, pk=project_pk)
    self.invoice = get_object_or_404(self.project.invoices.all(), pk=invoice_pk)

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

get_media

get_media(*args, **kwargs)
Source code in hypha/apply/projects/views/payment.py
def get_media(self, *args, **kwargs):
    file_pk = kwargs.get("file_pk")
    if not file_pk:
        return self.invoice.document

    document = get_object_or_404(self.invoice.supporting_documents, pk=file_pk)
    return document.document

test_func

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

    if self.request.user.is_finance:
        return True

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

    return False

InvoiceListView

Bases: SingleTableMixin, FilterView

filterset_class class-attribute instance-attribute

filterset_class = InvoiceListFilter

model class-attribute instance-attribute

model = Invoice

table_class class-attribute instance-attribute

table_class = InvoiceListTable

template_name class-attribute instance-attribute

template_name = 'application_projects/invoice_list.html'