- 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>
56 lines
3.1 KiB
Twig
56 lines
3.1 KiB
Twig
{% extends 'email/base.html.twig' %}
|
|
|
|
{% block title %}Vos billets - {{ order.event.title }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<h2>Vos billets sont prets !</h2>
|
|
<p>Bonjour {{ order.firstName }},</p>
|
|
<p>Merci pour votre commande <strong>{{ order.reference }}</strong> pour l'evenement <strong>{{ order.event.title }}</strong>.</p>
|
|
|
|
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
|
|
<thead>
|
|
<tr style="background: #111827; color: #fff;">
|
|
<th style="padding: 10px 12px; text-align: left; font-size: 11px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px;">Billet</th>
|
|
<th style="padding: 10px 12px; text-align: center; font-size: 11px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px;">Qt</th>
|
|
<th style="padding: 10px 12px; text-align: right; font-size: 11px; font-weight: 900; text-transform: uppercase; letter-spacing: 1px;">Total</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in order.items %}
|
|
<tr style="border-bottom: 1px solid #e5e7eb;">
|
|
<td style="padding: 10px 12px; font-weight: 700; font-size: 14px;">{{ item.billetName }}</td>
|
|
<td style="padding: 10px 12px; text-align: center; font-weight: 700;">{{ item.quantity }}</td>
|
|
<td style="padding: 10px 12px; text-align: right; font-weight: 900; color: #4f46e5;">{{ item.lineTotalHTDecimal|number_format(2, ',', ' ') }} €</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
<tfoot>
|
|
<tr style="border-top: 3px solid #111827;">
|
|
<td colspan="2" style="padding: 10px 12px; font-weight: 900; text-transform: uppercase; font-size: 13px;">Total</td>
|
|
<td style="padding: 10px 12px; text-align: right; font-weight: 900; font-size: 16px; color: #4f46e5;">{{ order.totalHTDecimal|number_format(2, ',', ' ') }} €</td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
|
|
{% if tickets|length > 0 %}
|
|
<p style="font-size: 13px; font-weight: 700; color: #6b7280;">Vos billets sont en piece jointe de cet email. Chaque billet contient un QR code unique a presenter a l'entree.</p>
|
|
|
|
<table style="width: 100%; border-collapse: collapse; margin: 16px 0;">
|
|
{% for ticket in tickets %}
|
|
<tr style="border-bottom: 1px solid #e5e7eb;">
|
|
<td style="padding: 6px 0; font-size: 12px; font-weight: 700;">{{ ticket.billetName }}</td>
|
|
<td style="padding: 6px 0; font-size: 11px; font-family: monospace; color: #6b7280;">{{ ticket.reference }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
{% endif %}
|
|
|
|
<p style="text-align: center; margin: 24px 0;">
|
|
<a href="{{ orderUrl }}" class="btn">Voir ma commande</a>
|
|
</p>
|
|
|
|
<p style="font-size: 12px; color: #9ca3af;">Evenement : {{ order.event.title }}<br>
|
|
Date : {{ order.event.startAt|date('d/m/Y') }} de {{ order.event.startAt|date('H:i') }} a {{ order.event.endAt|date('H:i') }}<br>
|
|
Lieu : {{ order.event.address }}, {{ order.event.zipcode }} {{ order.event.city }}</p>
|
|
{% endblock %}
|