- BilletOrder entity: individual tickets with unique ETICKET-XXXX reference,
billetBuyer link, billet link, isScanned, scannedAt for entry control
- BilletOrderService: generates tickets after payment, creates A4 PDF with
BilletDesign colors if present (default otherwise), real QR code via
endroid/qr-code, event poster + org logo as base64, sends confirmation
email with all ticket PDFs attached
- PDF template (pdf/billet.html.twig): A4 layout matching preview design,
real QR code linking to /ticket/verify/{reference}
- Email template: order recap table, ticket references list, link to
/ma-commande/{reference}
- Public order page /ma-commande/{reference}: no auth required, shows
order details, ticket list with individual PDF download links
- Ticket verification page /ticket/verify/{reference}: shows valid/scanned
status with ticket and event details
- Download route /ma-commande/{ref}/billet/{ticketRef}: generates PDF on-the-fly
- Migration for billet_order table with unique reference index
- BilletOrderTest: 8 tests, 24 assertions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
2.8 KiB
Twig
55 lines
2.8 KiB
Twig
{% extends 'base.html.twig' %}
|
|
|
|
{% block title %}Verification billet - E-Ticket{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="page-container">
|
|
<div class="max-w-xl mx-auto">
|
|
<div class="card-brutal overflow-hidden">
|
|
<div class="section-header">
|
|
<h2 class="text-sm font-black uppercase tracking-widest text-white">Verification du billet</h2>
|
|
</div>
|
|
<div class="p-6 text-center">
|
|
{% if ticket.scanned %}
|
|
<div class="text-6xl mb-4 text-red-600">✗</div>
|
|
<h1 class="text-2xl font-black uppercase tracking-tighter mb-2">Billet deja scanne</h1>
|
|
<p class="text-sm font-bold text-gray-500 mb-4">Ce billet a ete scanne le {{ ticket.scannedAt|date('d/m/Y a H:i') }}</p>
|
|
{% else %}
|
|
<div class="text-6xl mb-4 text-green-600">✓</div>
|
|
<h1 class="text-2xl font-black uppercase tracking-tighter mb-2">Billet valide</h1>
|
|
{% endif %}
|
|
|
|
<div class="border-2 border-gray-900 p-4 bg-gray-50 text-left mt-6 space-y-2">
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Reference</span>
|
|
<span class="font-mono font-black">{{ ticket.reference }}</span>
|
|
</div>
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Billet</span>
|
|
<span class="font-black">{{ ticket.billetName }}</span>
|
|
</div>
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Evenement</span>
|
|
<span class="font-black">{{ order.event.title }}</span>
|
|
</div>
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Acheteur</span>
|
|
<span class="font-black">{{ order.firstName }} {{ order.lastName }}</span>
|
|
</div>
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Date</span>
|
|
<span class="font-black">{{ order.event.startAt|date('d/m/Y H:i') }}</span>
|
|
</div>
|
|
{% if ticket.billet.definedExit %}
|
|
<div class="flex justify-between text-sm">
|
|
<span class="font-bold text-gray-500">Sortie</span>
|
|
<span class="font-black text-red-600">Definitive</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|