feat: Implement PDF receipt generation and email sending for purchases

This commit is contained in:
Daniel (elordenador)
2026-03-23 08:19:14 +00:00
parent 260d8cf290
commit 328fe9f985
3 changed files with 73 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
from fpdf import FPDF
import string, random
class Recibo(FPDF):
def header(self):
self.set_font('Arial', 'B', 15)
self.cell(0, 10, 'RECIBO DE PAGO', ln=True, align='C')
self.ln(10)
def footer(self):
self.set_y(-15)
self.set_font('Arial', 'I', 8)
self.cell(0, 10, f'Pagina {self.page_no()}', align='C')
def generar_recibo(cliente: str, total: float, objetos: list, metodo_pago: str):
pdf = Recibo()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(0, 10, f"Cliente: {cliente}", ln=True)
pdf.cell(0, 10, f"")
DATA = []
DATA.append(
("Cant.", "Nombre", "Precio Unit.", "Subtotal")
)
pdf.cell(0, 10, "DETALLE DEL COBRO", ln=True, align='C')
pdf.ln(5)
with pdf.table() as table:
for data_row in DATA:
row = table.row()
for datum in data_row:
row.cell(datum)
pdf.ln(5)
pdf.set_font("Arial", "B", 12)
pdf.cell(0, 10, f'TOTAL A PAGAR: {total}', align="R")
return pdf.output(dest="S")
+23
View File
@@ -1,9 +1,11 @@
from celery import shared_task from celery import shared_task
from django.conf import settings from django.conf import settings
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.core.mail import EmailMessage
from .utilities import send_email, send_hemail from .utilities import send_email, send_hemail
from .vars import login_message, verify_message from .vars import login_message, verify_message
import random, string import random, string
from . import pdf
from .models import User, VerificationCode from .models import User, VerificationCode
@shared_task @shared_task
@@ -51,3 +53,24 @@ def enviar_correo_recuperacion(email: str):
) )
send_hemail(email, "Reset de Contraseña", html_content, "Estas reseteando la contraseña...") send_hemail(email, "Reset de Contraseña", html_content, "Estas reseteando la contraseña...")
# Purchased items should be a list of dictionary, the dictionary must follow this tags: amount, product name, price (each)
@shared_task
def process_purchase(user_id: int, purchased_items: list, payment_method: str):
user = User.objects.get(id=user_id)
total = 0
for i in purchased_items:
total += i["price"]*i["amount"]
pdf_data = pdf.generar_recibo(user.get_full_name(), total, purchased_items, payment_method)
email = EmailMessage(
subject="Tu recibo de compra",
body = "Hola, adjunto encontrarás el recibo de tu reciente transacción",
from_email = settings.DEFAULT_FROM_EMAIL,
to = [user.email]
)
email.attach("recibo.pdf", pdf_data, "application/pdf")
email.send()
+11
View File
@@ -328,6 +328,7 @@ def create_order_from_cart(request, payment_method, payment_reference="", shippi
order_total = Decimal("0.00") order_total = Decimal("0.00")
items_with_totals = [] items_with_totals = []
purchased_items = []
for item in cart_items: for item in cart_items:
product = item.product product = item.product
@@ -338,6 +339,13 @@ def create_order_from_cart(request, payment_method, payment_reference="", shippi
) )
order_total += line_total_with_vat order_total += line_total_with_vat
items_with_totals.append((item, unit_price_with_vat, line_total_with_vat)) items_with_totals.append((item, unit_price_with_vat, line_total_with_vat))
purchased_items.append(
{
"amount": item.quantity,
"product_name": product.name,
"price": float(unit_price_with_vat),
}
)
with transaction.atomic(): with transaction.atomic():
order = Order.objects.create( order = Order.objects.create(
@@ -364,6 +372,9 @@ def create_order_from_cart(request, payment_method, payment_reference="", shippi
cart.items.all().delete() cart.items.all().delete()
if request.user.is_authenticated and purchased_items:
tasks.process_purchase.delay(request.user.id, purchased_items, payment_method)
return order return order