diff --git a/billing/templates/billing/emails/payment-notification.txt b/billing/templates/billing/emails/payment-notification.txt new file mode 100644 index 0000000..cd43a48 --- /dev/null +++ b/billing/templates/billing/emails/payment-notification.txt @@ -0,0 +1,14 @@ +Hello {{ username }}! + +An invoice is generated for your Hostea VM {{ payment.instance_name }}. + +- Configuration: {{payment.instance_configuration_id.name}} +- Invoice generated on: {{payment.date.month}}/{{payment.date.day}}/{{payment.date.year}} +- Total Amount: {{payment.total}} {{payment.currency|upper}} + +To pay, please click the link below: + +{{ link }} + +Cheers, +Hostea team diff --git a/billing/templates/billing/emails/payment-receipt.txt b/billing/templates/billing/emails/payment-receipt.txt new file mode 100644 index 0000000..5236f9e --- /dev/null +++ b/billing/templates/billing/emails/payment-receipt.txt @@ -0,0 +1,22 @@ +Hello {{ username }}! + + +This is a receipt for your latest Hostea payment. + +----------------------------------------------------- + +Hostea Receipt - {{payment.date.month}}/{{payment.date.day}}/{{payment.date.year}} + +- Instance Name: {{ payment.instance_name }} +- Configuration: {{payment.instance_configuration_id.name}} +- Total Amount: {{payment.total}} {{payment.currency|upper}} + + +To view the receipt online, please see the following link: + +{% url 'billing.invoice.details' payment_public_id=payment.public_ref %} + +We appreciate your business! + +Cheers, +Hostea team diff --git a/billing/tests.py b/billing/tests.py index ac6cca2..df0911c 100644 --- a/billing/tests.py +++ b/billing/tests.py @@ -16,6 +16,7 @@ import time from io import StringIO from django.contrib.auth import get_user_model +from django.core import mail from django.core.management import call_command from django.urls import reverse from django.test import TestCase, Client, override_settings @@ -89,6 +90,47 @@ class BillingTest(TestCase): reverse("infra.create", args=(payment.instance_name,)), ) + # create_instance_util creates an instance and pays for it. An email is + # sent when the invoice is generated and one after payment is made + # + # So we are first checking for the last email that was sent(receipt) + # and then the Gitea instance credentials notification followed by the + # invoice generation email. + receipt_mail = mail.outbox.pop() + self.assertEqual( + all( + [ + receipt_mail.to[0] == self.email, + "This is a receipt for your latest Hostea payment" + in receipt_mail.body, + ] + ), + True, + ) + + instance_notificaiton = mail.outbox.pop() + self.assertEqual( + all( + [ + instance_notificaiton.to[0] == self.email, + "Congratulations on your new Gitea instance!" + in instance_notificaiton.body, + ] + ), + True, + ) + + invoice_generated_mail = mail.outbox.pop() + self.assertEqual( + all( + [ + invoice_generated_mail.to[0] == self.email, + "An invoice is generated" in invoice_generated_mail.body, + ] + ), + True, + ) + ## payment failure page; no real functionality but user is redirected here # by stripe if payment is successful resp = c.get(reverse("billing.invoice.fail", args=(payment.public_ref,))) diff --git a/billing/views.py b/billing/views.py index d4ab2d3..1163518 100644 --- a/billing/views.py +++ b/billing/views.py @@ -16,13 +16,16 @@ from datetime import datetime, timedelta, timezone from django.shortcuts import get_object_or_404, redirect, render from django.template.response import TemplateResponse +from django.core.mail import send_mail from django.contrib.auth.decorators import login_required from django.http import HttpResponse +from django.template.loader import render_to_string from django.urls import reverse +from django.db.models import Q +from django.conf import settings from payments import get_payment_model, RedirectNeeded, PaymentStatus from dash.models import Instance -from django.db.models import Q from infrastructure.utils import create_vm_if_not_exists from dash.utils import footer_ctx @@ -88,7 +91,29 @@ def generate_invoice(request, instance_name: str): instance=instance, ) - return redirect(reverse("billing.invoice.details", args=(payment.public_ref,))) + invoice_link = reverse("billing.invoice.details", args=(payment.public_ref,)) + ctx = { + "username": request.user.username, + "link": invoice_link, + "payment": payment, + } + + body = render_to_string( + "billing/emails/payment-notification.txt", + context=ctx, + ) + + email = request.user.email + sender = settings.DEFAULT_FROM_EMAIL + + send_mail( + subject="[Hostea] An invoice is generated for your Hostea VM", + message=body, + from_email=f"No reply Hostea<{sender}>", # TODO read from settings.py + recipient_list=[email], + ) + + return redirect(invoice_link) @login_required @@ -118,6 +143,26 @@ def payment_success(request, payment_public_id): payment = get_object_or_404( get_payment_model(), public_ref=payment_public_id, paid_by=request.user ) + ctx = { + "username": request.user.username, + "payment": payment, + } + + body = render_to_string( + "billing/emails/payment-receipt.txt", + context=ctx, + ) + + email = request.user.email + sender = settings.DEFAULT_FROM_EMAIL + + send_mail( + subject="[Hostea] Payment receipt your Hostea VM", + message=body, + from_email=f"No reply Hostea<{sender}>", # TODO read from settings.py + recipient_list=[email], + ) + return redirect(reverse("infra.create", args=(payment.instance_name,)))