feat(reservation/flow): Améliore le flux de réservation et ajoute des options.

Cette commit améliore le flux de réservation, ajoute une estimation des
frais de livraison et gère les options de produit et les paiements.
```
This commit is contained in:
Serreau Jovann
2026-02-05 08:18:29 +01:00
parent c837095cc3
commit 1896f83107
28 changed files with 1654 additions and 215 deletions

View File

@@ -189,54 +189,8 @@
</div>
{% set acompteOk = contratPaymentPay(contrat, 'accompte') %}
{% set cautionOk = contratPaymentPay(contrat, 'caution') %}
{% if solde > 0 %}
{% if acompteOk and cautionOk %}
<form data-turbo="false" action="{{ path('gestion_contrat_view', {'num': contrat.numReservation, 'act': 'soldePay'}) }}" method="GET" class="space-y-4">
{# On garde les paramètres de la route pour le formulaire en GET #}
<input type="hidden" name="num" value="{{ contrat.numReservation }}">
<input type="hidden" name="act" value="soldePay">
<div class="space-y-2">
<label for="amountToPay" class="text-[10px] font-black uppercase text-slate-400 ml-1">Montant à régler maintenant</label>
<div class="relative">
<input type="number"
name="amountToPay"
id="amountToPay"
step="0.01"
min="1"
max="{{ solde }}"
value="{{ solde }}"
class="w-full bg-white/5 border border-white/10 rounded-2xl px-6 py-4 text-2xl font-black italic text-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white/10 transition-all"
>
<span class="absolute right-6 top-1/2 -translate-y-1/2 text-xl font-black italic text-blue-400">€</span>
</div>
<p class="text-[9px] text-slate-500 italic ml-1 italic">Saisissez un montant (Max. {{ solde|number_format(2, ',', ' ') }}€)</p>
</div>
<button type="submit"
class="group flex items-center justify-center gap-3 w-full bg-blue-600 hover:bg-blue-500 text-white py-4 rounded-2xl font-black uppercase italic transition-all shadow-lg shadow-blue-900/20">
<span>Procéder au paiement</span>
<svg class="w-5 h-5 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M13 7l5 5m0 0l-5 5m5-5H6"/>
</svg>
</button>
</form>
{% else %}
<div class="bg-white/5 border border-white/10 rounded-2xl p-6">
<div class="flex items-start gap-3">
<svg class="w-5 h-5 text-amber-500 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
<p class="text-[10px] text-slate-400 font-bold uppercase italic leading-tight">
<span class="text-amber-500">Paiement du solde indisponible</span><br><br>
Vous devez d'abord :<br>
<span class="{{ acompteOk ? 'text-green-500' : 'text-slate-300' }}">1. Régler l'acompte ({{ acompteOk ? 'OK' : 'En attente' }})</span><br>
<span class="{{ cautionOk ? 'text-green-500' : 'text-slate-300' }}">2. Déposer la caution ({{ cautionOk ? 'OK' : 'En attente' }})</span>
</p>
</div>
</div>
{% endif %}
{% else %}
{% if solde <=0 %}
<div class="flex items-center gap-3 bg-green-500/20 text-green-400 p-6 rounded-2xl border border-green-500/30">
<svg class="w-8 h-8 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/>
@@ -330,54 +284,6 @@
</div>
{% endif %}
{# 3. CAUTION #}
{% if not contratPaymentPay(contrat, 'caution') %}
<div class="bg-white rounded-[2rem] border border-slate-100 shadow-xl shadow-slate-200/20 overflow-hidden">
<div class="bg-slate-800 p-6 text-white flex items-center gap-4">
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M12 9v2m0 4h.01"></path></svg></div>
<p class="text-sm font-black uppercase italic leading-none">Caution</p>
</div>
<div class="p-6 text-center">
<p class="text-3xl font-black text-slate-900 italic mb-4">{{ totalCaution|number_format(2, ',', ' ') }}€</p>
{% set canPayCaution = (date('now') >= contrat.dateAt.modify('-7 days')) %}
{% if canPayCaution and contratPaymentPay(contrat, 'accompte') %}
<a data-turbo="false" href="{{ path('gestion_contrat_view', {'num': contrat.numReservation,'act':'cautionPay'}) }}" class="block w-full bg-slate-900 text-white py-4 rounded-xl font-black uppercase text-xs hover:bg-blue-600 transition-all shadow-md">Déposer l'empreinte</a>
{% else %}
<div class="p-3 bg-slate-50 rounded-xl border border-slate-100">
<p class="text-[9px] text-slate-400 font-black uppercase tracking-tighter">Lien actif le {{ contrat.dateAt.modify('-7 days')|date('d/m/Y') }}</p>
<p class="text-[8px] text-slate-300 italic mt-1">(7j avant prestation)</p>
</div>
{% endif %}
</div>
</div>
{% else %}
<div class="bg-white rounded-[2rem] border border-green-100 shadow-xl shadow-green-100/20 overflow-hidden">
<div class="bg-green-500 p-6 text-white flex items-center gap-4">
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path></svg></div>
<p class="text-sm font-black uppercase italic leading-none">Caution Sécurisée</p>
</div>
<div class="p-5">
{% for payment in paymentCaution %}
<div class="bg-slate-50 p-4 rounded-2xl border border-slate-100">
<div class="flex justify-between items-center mb-2">
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Dépôt</p>
<p class="text-lg font-black text-slate-900 italic leading-none">{{ payment.amount|number_format(2, ',', ' ') }}€</p>
</div>
<div class="flex items-center gap-2">
<span class="text-[10px] font-black uppercase text-slate-700 italic">{{ payment.card.card.brand|default('Carte') }}</span>
<span class="text-[9px] text-slate-400 font-bold uppercase italic">**** {{ payment.card.card.last4|default('') }}</span>
{% if payment.card.card.funding == "debit" %}<span class="text-[7px] bg-slate-200 text-slate-500 px-1 rounded uppercase">Debit</span>{% endif %}
</div>
<div class="flex items-center gap-1 mt-2">
<span class="w-1.5 h-1.5 rounded-full bg-green-500"></span>
<p class="text-[8px] text-green-600 font-black uppercase tracking-tighter">Empreinte bancaire validée</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{# ... (Garder tout le code précédent inchangé jusqu'à la fin de la grille 3 colonnes) ... #}