Add public refund creation endpoint and PDF generation

Introduces RefundPublicView for public refund creation via email and invoice/order ID, returning refund info and a base64-encoded PDF slip. Adds RefundCreatePublicSerializer for validation and creation, implements PDF generation in Refund model, and provides a customer-facing HTML template for the return slip. Updates URLs to expose the new endpoint.
This commit is contained in:
2025-11-19 00:53:37 +01:00
parent b8a1a594b2
commit e86839f2da
5 changed files with 416 additions and 38 deletions

View File

@@ -505,6 +505,43 @@ class Refund(models.Model):
self.order.status = Order.Status.REFUNDED
self.order.save(update_fields=["status", "updated_at"])
def generate_refund_pdf_for_customer(self):
"""Vygeneruje PDF formulář k vrácení zboží pro zákazníka.
Šablona refund/customer_in_package_returning_form.html očekává:
- order: objekt objednávky
- items: seznam položek (dict) s klíči product_name, sku, quantity, variant, options, reason
- return_reason: textový důvod vrácení (kombinace reason_text / reason_choice)
Návratová hodnota: bytes (PDF obsah). Uložení necháváme na volající logice.
"""
order = self.order
# Připravíme položky pro šablonu (důvody per položku zatím None lze rozšířit)
prepared_items: list[dict] = []
for item in order.items.select_related('product'):
prepared_items.append({
"product_name": getattr(item.product, "name", "Item"),
"name": getattr(item.product, "name", "Item"), # fallbacky pro různé názvy v šabloně
"sku": getattr(item.product, "code", None),
"quantity": item.quantity,
"variant": None, # lze doplnit pokud existují varianty
"options": None, # lze doplnit pokud existují volby
"reason": None, # per-item reason (zatím nepodporováno)
})
return_reason = self.reason_text or self.get_reason_choice_display()
context = {
"order": order,
"items": prepared_items,
"return_reason": return_reason,
}
html_string = render_to_string("refund/customer_in_package_returning_form.html", context)
pdf_bytes = HTML(string=html_string).write_pdf()
return pdf_bytes
class Invoice(models.Model):
invoice_number = models.CharField(max_length=50, unique=True)