예제 #1
0
def manual_payment(request, invoice_id):
    ''' Allows staff to make manual payments or refunds on an invoice.'''

    FORM_PREFIX = "manual_payment"

    if not request.user.is_staff:
        raise Http404()

    invoice_id = int(invoice_id)
    inv = get_object_or_404(commerce.Invoice, pk=invoice_id)
    current_invoice = InvoiceController(inv)

    form = forms.ManualPaymentForm(
        request.POST or None,
        prefix=FORM_PREFIX,
    )

    if request.POST and form.is_valid():
        form.instance.invoice = inv
        form.save()
        current_invoice.update_status()
        form = forms.ManualPaymentForm(prefix=FORM_PREFIX)

    data = {
        "invoice": inv,
        "form": form,
    }

    return render(request, "registrasion/manual_payment.html", data)
예제 #2
0
def manual_payment(request, invoice_id):
    ''' Allows staff to make manual payments or refunds on an invoice.'''

    FORM_PREFIX = "manual_payment"

    if not request.user.is_staff:
        raise Http404()

    invoice_id = int(invoice_id)
    inv = get_object_or_404(commerce.Invoice, pk=invoice_id)
    current_invoice = InvoiceController(inv)

    form = forms.ManualPaymentForm(
        request.POST or None,
        prefix=FORM_PREFIX,
    )

    if request.POST and form.is_valid():
        form.instance.invoice = inv
        form.save()
        current_invoice.update_status()
        form = forms.ManualPaymentForm(prefix=FORM_PREFIX)

    data = {
        "invoice": inv,
        "form": form,
    }

    return render(request, "registrasion/manual_payment.html", data)
예제 #3
0
def checkout(request):
    ''' Runs the checkout process for the current cart.

    If the query string contains ``fix_errors=true``, Registrasion will attempt
    to fix errors preventing the system from checking out, including by
    cancelling expired discounts and vouchers, and removing any unavailable
    products.

    Returns:
        render or redirect:
            If the invoice is generated successfully, or there's already a
            valid invoice for the current cart, redirect to ``invoice``.
            If there are errors when generating the invoice, render
            ``registrasion/checkout_errors.html`` with the following data::

                {
                    "error_list", [str, ...]  # The errors to display.
                }

    '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return _checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
예제 #4
0
def demopay(request, invoice_id, access_code):
    ''' Marks the invoice with the given invoice id as paid.
    '''
    invoice_id = int(invoice_id)
    inv = get_object_or_404(rego.Invoice.objects, pk=invoice_id)

    invoice = InvoiceController(inv)

    if not invoice.can_view(user=request.user, access_code=access_code):
        raise Http404()

    to_invoice = redirect("invoice", invoice.invoice.id, access_code)

    try:
        invoice.validate_allowed_to_pay(
        )  # Verify that we're allowed to do this.
    except ValidationError as ve:
        messages.error(request, ve.message)
        return to_invoice

    # Create the payment object
    models.DemoPayment.objects.create(
        invoice=invoice.invoice,
        reference="Demo payment by user: "******"This invoice was successfully paid.")

    return to_invoice
예제 #5
0
def refund(request, invoice_id):
    ''' Allows staff to refund payments against an invoice and request a
    credit note.'''

    if not request.user.is_staff:
        raise Http404()

    invoice_id = int(invoice_id)
    inv = get_object_or_404(commerce.Invoice, pk=invoice_id)
    current_invoice = InvoiceController(inv)

    try:
        current_invoice.refund()
        messages.success(request, "This invoice has been refunded.")
    except ValidationError as ve:
        messages.error(request, ve)

    return redirect("invoice", invoice_id)
예제 #6
0
def refund(request, invoice_id):
    ''' Allows staff to refund payments against an invoice and request a
    credit note.'''

    if not request.user.is_staff:
        raise Http404()

    invoice_id = int(invoice_id)
    inv = get_object_or_404(commerce.Invoice, pk=invoice_id)
    current_invoice = InvoiceController(inv)

    try:
        current_invoice.refund()
        messages.success(request, "This invoice has been refunded.")
    except ValidationError as ve:
        messages.error(request, ve)

    return redirect("invoice", invoice_id)
예제 #7
0
def demopay(request, invoice_id, access_code):
    ''' Marks the invoice with the given invoice id as paid.
    '''
    invoice_id = int(invoice_id)
    inv = get_object_or_404(rego.Invoice.objects,pk=invoice_id)

    invoice = InvoiceController(inv)

    if not invoice.can_view(user=request.user, access_code=access_code):
        raise Http404()

    to_invoice = redirect("invoice", invoice.invoice.id, access_code)

    try:
        invoice.validate_allowed_to_pay()  # Verify that we're allowed to do this.
    except ValidationError as ve:
        messages.error(request, ve.message)
        return to_invoice

    # Create the payment object
    models.DemoPayment.objects.create(
        invoice=invoice.invoice,
        reference="Demo payment by user: "******"This invoice was successfully paid.")

    return to_invoice
예제 #8
0
def invoice(request, invoice_id, access_code=None):
    ''' Displays an invoice for a given invoice id.
    This view is not authenticated, but it will only allow access to either:
    the user the invoice belongs to; staff; or a request made with the correct
    access code.
    '''

    invoice_id = int(invoice_id)
    inv = commerce.Invoice.objects.get(pk=invoice_id)

    current_invoice = InvoiceController(inv)

    if not current_invoice.can_view(
            user=request.user,
            access_code=access_code,
            ):
        raise Http404()

    data = {
        "invoice": current_invoice.invoice,
    }

    return render(request, "registrasion/invoice.html", data)
예제 #9
0
def invoice(request, invoice_id, access_code=None):
    ''' Displays an invoice for a given invoice id.
    This view is not authenticated, but it will only allow access to either:
    the user the invoice belongs to; staff; or a request made with the correct
    access code.
    '''

    invoice_id = int(invoice_id)
    inv = commerce.Invoice.objects.get(pk=invoice_id)

    current_invoice = InvoiceController(inv)

    if not current_invoice.can_view(
            user=request.user,
            access_code=access_code,
    ):
        raise Http404()

    data = {
        "invoice": current_invoice.invoice,
    }

    return render(request, "registrasion/invoice.html", data)
예제 #10
0
    def cancellation_fee(self, percentage):
        ''' Generates an invoice with a cancellation fee, and applies
        credit to the invoice.

        percentage (Decimal): The percentage of the credit note to turn into
        a cancellation fee. Must be 0 <= percentage <= 100.
        '''

        # Circular Import
        from registrasion.controllers.invoice import InvoiceController

        assert(percentage >= 0 and percentage <= 100)

        cancellation_fee = self.credit_note.value * percentage / 100
        due = datetime.timedelta(days=1)
        item = [("Cancellation fee", cancellation_fee)]
        invoice = InvoiceController.manual_invoice(
            self.credit_note.invoice.user, due, item
        )

        if not invoice.is_paid:
            self.apply_to_invoice(invoice)

        return InvoiceController(invoice)
예제 #11
0
def checkout(request):
    ''' Runs checkout for the current cart of items, ideally generating an
    invoice. '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
예제 #12
0
def checkout(request):
    ''' Runs checkout for the current cart of items, ideally generating an
    invoice. '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
예제 #13
0
def checkout(request, user_id=None):
    ''' Runs the checkout process for the current cart.

    If the query string contains ``fix_errors=true``, Registrasion will attempt
    to fix errors preventing the system from checking out, including by
    cancelling expired discounts and vouchers, and removing any unavailable
    products.

    Arguments:
        user_id (castable to int):
            If the requesting user is staff, then the user ID can be used to
            run checkout for another user.
    Returns:
        render or redirect:
            If the invoice is generated successfully, or there's already a
            valid invoice for the current cart, redirect to ``invoice``.
            If there are errors when generating the invoice, render
            ``registrasion/checkout_errors.html`` with the following data::

                {
                    "error_list", [str, ...]  # The errors to display.
                }

    '''

    if user_id is not None:
        if request.user.is_staff:
            user = User.objects.get(id=int(user_id))
        else:
            raise Http404()
    else:
        user = request.user

    current_cart = CartController.for_user(user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return _checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
예제 #14
0
def invoice(request, invoice_id, access_code=None):
    ''' Displays an invoice.

    This view is not authenticated, but it will only allow access to either:
    the user the invoice belongs to; staff; or a request made with the correct
    access code.

    Arguments:

        invoice_id (castable to int): The invoice_id for the invoice you want
            to view.

        access_code (Optional[str]): The access code for the user who owns
            this invoice.

    Returns:
        render:
            Renders ``registrasion/invoice.html``, with the following
            data::

                {
                    "invoice": models.commerce.Invoice(),
                }

    Raises:
        Http404: if the current user cannot view this invoice and the correct
            access_code is not provided.

    '''

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    if not current_invoice.can_view(
            user=request.user,
            access_code=access_code,
            ):
        raise Http404()

    data = {
        "invoice": current_invoice.invoice,
    }

    return render(request, "registrasion/invoice.html", data)
예제 #15
0
def tuokcehc_finalise(request, invoice_id, access_code):
    ''' View that takes an actual django form and uses it to finalise a payment. '''

    inv = InvoiceController.for_id_or_404(str(invoice_id))
    to_invoice = get_to_invoice(inv, access_code)

    form = forms.TuokcehcForm(request.POST)

    if request.POST and form.is_valid():
        try:
            inv.validate_allowed_to_pay()  # Verify that we're allowed to do this.
            process_card(request, form, inv)
        except StripeError as e:
            body = e.json_body
            err  = body.get('error', {})
            message = err.get('message')
            messages.error(request, "There was an issue processing your card: " + message)

        return to_invoice
예제 #16
0
def manual_payment(request, invoice_id):
    ''' Allows staff to make manual payments or refunds on an invoice.

    This form requires a login, and the logged in user needs to be staff.

    Arguments:
        invoice_id (castable to int): The invoice ID to be paid

    Returns:
        render:
            Renders ``registrasion/manual_payment.html`` with the following
            data::

                {
                    "invoice": models.commerce.Invoice(),
                    "form": form,   # A form that saves a ``ManualPayment``
                                    # object.
                }

    '''

    FORM_PREFIX = "manual_payment"

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    form = forms.ManualPaymentForm(
        request.POST or None,
        prefix=FORM_PREFIX,
    )

    if request.POST and form.is_valid():
        form.instance.invoice = current_invoice.invoice
        form.instance.entered_by = request.user
        form.save()
        current_invoice.update_status()
        form = forms.ManualPaymentForm(prefix=FORM_PREFIX)

    data = {
        "invoice": current_invoice.invoice,
        "form": form,
    }

    return render(request, "registrasion/manual_payment.html", data)
예제 #17
0
def manual_payment(request, invoice_id):
    ''' Allows staff to make manual payments or refunds on an invoice.

    This form requires a login, and the logged in user needs to be staff.

    Arguments:
        invoice_id (castable to int): The invoice ID to be paid

    Returns:
        render:
            Renders ``registrasion/manual_payment.html`` with the following
            data::

                {
                    "invoice": models.commerce.Invoice(),
                    "form": form,   # A form that saves a ``ManualPayment``
                                    # object.
                }

    '''

    FORM_PREFIX = "manual_payment"

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    form = forms.ManualPaymentForm(
        request.POST or None,
        prefix=FORM_PREFIX,
    )

    if request.POST and form.is_valid():
        form.instance.invoice = current_invoice.invoice
        form.instance.entered_by = request.user
        form.save()
        current_invoice.update_status()
        form = forms.ManualPaymentForm(prefix=FORM_PREFIX)

    data = {
        "invoice": current_invoice.invoice,
        "form": form,
    }

    return render(request, "registrasion/manual_payment.html", data)
예제 #18
0
def invoice(request, invoice_id, access_code=None):
    ''' Displays an invoice.

    This view is not authenticated, but it will only allow access to either:
    the user the invoice belongs to; staff; or a request made with the correct
    access code.

    Arguments:

        invoice_id (castable to int): The invoice_id for the invoice you want
            to view.

        access_code (Optional[str]): The access code for the user who owns
            this invoice.

    Returns:
        render:
            Renders ``registrasion/invoice.html``, with the following
            data::

                {
                    "invoice": models.commerce.Invoice(),
                }

    Raises:
        Http404: if the current user cannot view this invoice and the correct
            access_code is not provided.

    '''

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    if not current_invoice.can_view(
            user=request.user,
            access_code=access_code,
            ):
        raise Http404()

    data = {
        "invoice": current_invoice.invoice,
    }

    return render(request, "registrasion/invoice.html", data)
예제 #19
0
def card(request, invoice_id, access_code=None):
    ''' View that shows and processes a Stripe CreditCardForm to pay the given
    invoice. Redirects back to the invoice once the invoice is fully paid.

    Arguments:
        invoice_id (castable to str): The invoice id for the invoice to pay.
        access_code (str): The optional access code for the invoice (for
            unauthenticated payment)

    '''

    form = forms.CreditCardForm(request.POST or None)

    inv = InvoiceController.for_id_or_404(str(invoice_id))

    if not inv.can_view(user=request.user, access_code=access_code):
        raise Http404()

    to_invoice = get_to_invoice(inv, access_code)

    if inv.invoice.balance_due() <= 0:
        return to_invoice

    if request.POST and form.is_valid():
        try:
            inv.validate_allowed_to_pay()  # Verify that we're allowed to do this.
            process_card(request, form, inv)
            return to_invoice
        except StripeError as e:
            form.add_error(None, ValidationError(e))
        except ValidationError as ve:
            form.add_error(None, ve)

    data = {
        "invoice": inv.invoice,
        "form": form,
    }

    return render(
        request, "registrasion/stripe/credit_card_payment.html", data
    )
예제 #20
0
def refund(request, invoice_id):
    ''' Marks an invoice as refunded and requests a credit note for the
    full amount paid against the invoice.

    This view requires a login, and the logged in user must be staff.

    Arguments:
        invoice_id (castable to int): The ID of the invoice to refund.

    Returns:
        redirect:
            Redirects to ``invoice``.

    '''

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    try:
        current_invoice.refund()
        messages.success(request, "This invoice has been refunded.")
    except ValidationError as ve:
        messages.error(request, ve)

    return redirect("invoice", invoice_id)
예제 #21
0
def tuokcehc_entry_point(request, invoice_id, access_code):
    ''' View that takes a POST token from tuokcehc.js and uses it to load a form
    that may charge a card. '''

    inv = InvoiceController.for_id_or_404(str(invoice_id))
    to_invoice = get_to_invoice(inv, access_code)

    if not inv.can_view(user=request.user, access_code=access_code):
        raise Http404()

    if request.POST and "stripe_token" not in request.POST:
        return to_invoice

    form = forms.TuokcehcForm(request.POST)

    data = {
        "form": form,
        "access_code": access_code,
        "invoice": inv.invoice,
    }

    return render(
        request, "registrasion/stripe/tuokcehc.html", data
    )
예제 #22
0
def refund(request, invoice_id):
    ''' Marks an invoice as refunded and requests a credit note for the
    full amount paid against the invoice.

    This view requires a login, and the logged in user must be staff.

    Arguments:
        invoice_id (castable to int): The ID of the invoice to refund.

    Returns:
        redirect:
            Redirects to ``invoice``.

    '''

    current_invoice = InvoiceController.for_id_or_404(invoice_id)

    try:
        current_invoice.refund()
        messages.success(request, "This invoice has been refunded.")
    except ValidationError as ve:
        messages.error(request, ve)

    return redirect("invoice", invoice_id)
예제 #23
0
    def apply_to_invoice(self, invoice):
        ''' Applies the total value of this credit note to the specified
        invoice. If this credit note overpays the invoice, a new credit note
        containing the residual value will be created.

        Raises ValidationError if the given invoice is not allowed to be
        paid.
        '''

        # Circular Import
        from registrasion.controllers.invoice import InvoiceController
        inv = InvoiceController(invoice)
        inv.validate_allowed_to_pay()

        # Apply payment to invoice
        commerce.CreditNoteApplication.objects.create(
            parent=self.credit_note,
            invoice=invoice,
            amount=self.credit_note.value,
            reference="Applied credit note #%d" % self.credit_note.id,
        )

        inv.update_status()