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