Files
e-ticket/templates/email/order_confirmation.html.twig
Serreau Jovann 52cb19df8b Add BilletOrder entity, PDF generation, email with QR codes, public order page
- 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>
2026-03-21 14:04:45 +01:00

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, ',', ' ') }} &euro;</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, ',', ' ') }} &euro;</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 %}