475 lines
39 KiB
Twig
475 lines
39 KiB
Twig
{% extends 'revervation/base.twig' %}
|
|
|
|
{% block title %}Récapitulatif de réservation #{{ contrat.numReservation }}{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="min-h-screen bg-slate-50 py-12 px-4">
|
|
<div class="max-w-7xl mx-auto">
|
|
|
|
{# HEADER : NAVIGATION, TITRE, DATES & LIEU #}
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
|
|
<div class="md:col-span-2 flex items-center gap-6">
|
|
<a href="{{ path('gestion_contrat') }}" class="w-12 h-12 bg-white rounded-2xl border border-slate-100 flex items-center justify-center text-slate-400 hover:text-blue-600 transition-all shadow-sm">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
|
|
</a>
|
|
<div class="flex flex-col md:flex-row md:items-center gap-4 md:gap-8">
|
|
<div>
|
|
<h1 class="text-3xl font-black italic uppercase text-slate-900 leading-none">Détails <span class="text-blue-600">Réservation</span></h1>
|
|
<p class="text-slate-400 text-[10px] font-black uppercase tracking-[0.2em] mt-2">Référence : #{{ contrat.numReservation }}</p>
|
|
</div>
|
|
|
|
<div class="flex items-center bg-white px-6 py-3 rounded-2xl border border-slate-100 shadow-sm gap-6">
|
|
<div class="text-center">
|
|
<p class="text-[8px] font-black uppercase text-slate-400 tracking-widest mb-1">Du</p>
|
|
<p class="text-sm font-black text-slate-900 uppercase italic">{{ contrat.dateAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
<div class="flex flex-col items-center">
|
|
<div class="h-px w-8 bg-blue-200 mb-1"></div>
|
|
<span class="text-[9px] font-black text-blue-600 uppercase">{{ days }} J</span>
|
|
</div>
|
|
<div class="text-center">
|
|
<p class="text-[8px] font-black uppercase text-slate-400 tracking-widest mb-1">Au</p>
|
|
<p class="text-sm font-black text-slate-900 uppercase italic">{{ contrat.endAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-blue-600 rounded-[2rem] p-5 text-white flex items-center gap-4 shadow-lg shadow-blue-200">
|
|
<div class="w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center shrink-0">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/></svg>
|
|
</div>
|
|
<div class="overflow-hidden">
|
|
<p class="text-[9px] font-black uppercase tracking-widest opacity-80 mb-1">Lieu de l'événement</p>
|
|
<p class="font-bold uppercase italic text-[11px] truncate leading-tight">
|
|
{{ contrat.addressEvent }} {% if contrat.address2Event %}- {{ contrat.address2Event }}{% endif %}
|
|
</p>
|
|
<p class="font-black uppercase italic text-sm truncate">{{ contrat.townEvent }} ({{ contrat.zipCodeEvent }})</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# SECTION IDENTITÉ #}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
|
|
<div class="bg-white rounded-[2.5rem] p-8 border border-slate-100 shadow-sm">
|
|
<p class="text-[10px] font-black text-blue-600 uppercase tracking-widest mb-4">Le Prestataire</p>
|
|
<p class="text-xl font-black text-slate-900 uppercase italic">SEGARD LILIAN - <span class="text-blue-600">LUDIKEVENT</span></p>
|
|
<div class="mt-4 space-y-1 text-sm text-slate-500 font-medium italic">
|
|
<p>6, rue du Château, 02800 DANIZY</p>
|
|
<p>SIRET : 930 488 408 00012</p>
|
|
<p class="text-blue-600 font-black not-italic mt-2">06 14 17 24 47</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-[2.5rem] p-8 border border-slate-100 shadow-sm">
|
|
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest mb-4">Le Client / Loueur</p>
|
|
<p class="text-xl font-black text-slate-900 uppercase italic">{{ contrat.customer.name }} {{ contrat.customer.surname }}</p>
|
|
<div class="mt-4 space-y-2">
|
|
<div class="flex items-center gap-2">
|
|
<svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
|
<p class="text-sm text-slate-900 font-bold underline decoration-blue-200 underline-offset-4">{{ contrat.customer.email }}</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/></svg>
|
|
<p class="text-sm text-slate-900 font-bold underline decoration-blue-200 underline-offset-4">{{ contrat.customer.phone }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-8 items-start mb-12">
|
|
{# COLONNE GAUCHE : PRESTATIONS ET DOCS #}
|
|
<div class="lg:col-span-3 space-y-6">
|
|
<div class="bg-white rounded-[2.5rem] border border-slate-100 shadow-xl shadow-slate-200/40 overflow-hidden">
|
|
<div class="p-8 border-b border-slate-50 flex justify-between items-center bg-slate-50/30">
|
|
<h2 class="text-xs font-black uppercase tracking-widest text-slate-900">Détail des prestations & Options</h2>
|
|
<span class="bg-blue-600 text-white text-[10px] font-black px-4 py-1.5 rounded-full uppercase">{{ days }} Jours</span>
|
|
</div>
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left">
|
|
<tbody class="divide-y divide-slate-50">
|
|
{% for line in contrat.contratsLines %}
|
|
{% if tvaEnabled %}
|
|
{% set priceLine = (line.price1DayHt*1.20) + ((line.priceSupDayHt*1.20) * (days - 1)) %}
|
|
{% else %}
|
|
{% set priceLine = line.price1DayHt + (line.priceSupDayHt * (days - 1)) %}
|
|
{% endif %}
|
|
<tr class="hover:bg-slate-50/30 transition-colors">
|
|
<td class="px-8 py-6">
|
|
<p class="font-black text-slate-900 uppercase text-sm leading-tight">{{ line.name }}</p>
|
|
{% if tvaEnabled %}
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix 1 Jour : {{ (line.price1DayHt*1.20)|number_format(0, ',', ' ') }}€ TTC</p>
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix Jour suplémentaire : {{ (line.priceSupDayHt*1.20)|number_format(0, ',', ' ') }}€ TTC</p>
|
|
{% else %}
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix 1 Jour : {{ line.price1DayHt|number_format(0, ',', ' ') }}€ HT</p>
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Prix Jour suplémentaire : {{ line.priceSupDayHt|number_format(0, ',', ' ') }}€ HT</p>
|
|
{% endif %}
|
|
|
|
<p class="text-[10px] text-slate-400 font-bold italic mt-1 uppercase">Caution : {{ line.caution|number_format(0, ',', ' ') }}€</p>
|
|
</td>
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ priceLine|number_format(2, ',', ' ') }}€</td>
|
|
|
|
</tr>
|
|
{% endfor %}
|
|
{% for line in contrat.contratsOptions %}
|
|
<tr class="bg-slate-50/20">
|
|
<td class="px-8 py-6">
|
|
<p class="font-bold text-blue-600 uppercase text-xs italic tracking-widest mb-1">Option</p>
|
|
<p class="font-black text-slate-900 uppercase text-sm leading-tight">{{ line.name }}</p>
|
|
</td>
|
|
{% if tvaEnabled %}
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ (line.price*1.20)|number_format(2, ',', ' ') }}€</td>
|
|
{% else %}
|
|
<td class="px-8 py-6 text-right font-black text-slate-900 italic text-lg">{{ line.price|number_format(2, ',', ' ') }}€</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{# DOCUMENTS PDF #}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{% set contractPath = contrat.signed ? 'devisSignFile' : 'devisFile' %}
|
|
<a download href="{{ vich_uploader_asset(contrat, contractPath) }}" class="group flex items-center justify-between p-3 pr-8 bg-white border border-slate-100 rounded-3xl shadow-sm hover:border-blue-200 transition-all">
|
|
<div class="w-14 h-14 bg-blue-50 rounded-2xl flex items-center justify-center text-blue-600 shrink-0 group-hover:bg-blue-600 group-hover:text-white transition-all">
|
|
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
|
|
</div>
|
|
<span class="text-xs font-black uppercase tracking-widest text-slate-600 italic">Contrat (PDF)</span>
|
|
</a>
|
|
{% if contrat.signed %}
|
|
<a download href="{{ vich_uploader_asset(contrat, 'devisAuditFile') }}" class="group flex items-center justify-between p-3 pr-8 bg-white border border-slate-100 rounded-3xl shadow-sm hover:border-blue-200 transition-all">
|
|
<div class="w-14 h-14 bg-blue-50 rounded-2xl flex items-center justify-center text-blue-600 shrink-0 group-hover:bg-blue-600 group-hover:text-white transition-all">
|
|
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
|
|
<span class="text-xs font-black uppercase tracking-widest text-slate-600 italic">Certificat</span>
|
|
</a>
|
|
{% endif %}
|
|
{% if solde <=0 %}
|
|
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{# --- COLONNE DROITE : FINANCES --- #}
|
|
<div class="lg:col-span-2 space-y-4">
|
|
{# TOTAL HT - Version compacte #}
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Hors Taxes (HT)</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ totalHT|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
{% if tvaEnabled %}
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Total TVA</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ (totalTTC-totalHT)|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
<div class="bg-white rounded-[1.5rem] p-6 border border-slate-100 shadow-sm flex justify-between items-center">
|
|
<div>
|
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Total Prestations</p>
|
|
<p class="text-xs font-bold text-slate-400 italic">Total TTC</p>
|
|
</div>
|
|
<p class="text-3xl font-black text-slate-900 italic tracking-tighter">{{ totalTTC|number_format(2, ',', ' ') }}€</p>
|
|
</div>
|
|
{% endif %}
|
|
{# SOLDE FINAL - Bloc Principal avec saisie du montant #}
|
|
<div class="bg-slate-900 rounded-[2rem] p-8 text-white shadow-xl shadow-slate-200 relative overflow-hidden">
|
|
<div class="absolute top-0 right-0 -mt-4 -mr-4 w-24 h-24 bg-blue-600/10 rounded-full blur-2xl"></div>
|
|
|
|
<div class="relative">
|
|
<p class="text-xs font-black text-blue-400 uppercase tracking-widest mb-2">Solde restant à régler</p>
|
|
<div class="flex items-baseline gap-2 mb-8">
|
|
<p class="text-5xl font-black italic tracking-tighter">{{ solde|number_format(2, ',', ' ') }}€</p>
|
|
</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 %}
|
|
<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"/>
|
|
</svg>
|
|
<div>
|
|
<p class="text-sm font-black uppercase italic">Dossier Soldé</p>
|
|
<p class="text-[9px] opacity-70 font-bold uppercase tracking-widest">Aucun montant restant</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<p class="text-[9px] text-slate-500 font-bold uppercase italic mt-6 text-center tracking-widest opacity-60">
|
|
Paiement sécurisé via Stripe
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# --- SECTION ACTIONS : 3 COLONNES --- #}
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
|
|
{# 1. SIGNATURE #}
|
|
{% if contrat.signed %}
|
|
<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="M5 13l4 4L19 7"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Contrat Signé</p>
|
|
</div>
|
|
<div class="p-6 text-center">
|
|
<p class="text-[10px] text-slate-400 font-black uppercase mb-1 tracking-widest">Numéro de signature</p>
|
|
<p class="text-[10px] font-mono font-bold text-slate-800 break-all bg-slate-50 p-3 rounded-xl border border-slate-100">{{ signedNumber }}</p>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-white rounded-[2rem] border border-red-100 shadow-xl shadow-red-100/20 overflow-hidden">
|
|
<div class="bg-red-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="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Signature</p>
|
|
</div>
|
|
<div class="p-6">
|
|
<a href="{{ signUrl }}" class="flex flex-col items-center justify-center p-5 bg-slate-900 text-white rounded-2xl hover:bg-blue-600 transition-all group shadow-lg">
|
|
<span class="font-black uppercase italic text-sm">Signer le contrat</span>
|
|
<span class="text-[9px] text-blue-300 font-black uppercase mt-1 tracking-widest">Étape 1 : Obligatoire</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# 2. ACOMPTE #}
|
|
{% if not contratPaymentPay(contrat, 'accompte') %}
|
|
<div class="bg-white rounded-[2rem] border border-red-100 shadow-xl shadow-red-100/20 overflow-hidden">
|
|
<div class="bg-red-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="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Acompte (25%)</p>
|
|
</div>
|
|
<div class="p-6 text-center">
|
|
<p class="text-3xl font-black text-slate-900 italic mb-4">{{ arrhes|number_format(2, ',', ' ') }}€</p>
|
|
{% if contrat.signed %}
|
|
<a data-turbo="false" href="{{ path('gestion_contrat_view', {'num': contrat.numReservation,'act':'accomptePay'}) }}" 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">Régler l'acompte</a>
|
|
{% else %}
|
|
<div class="p-3 bg-amber-50 rounded-xl border border-amber-100">
|
|
<span class="text-[9px] text-amber-600 font-black uppercase tracking-tighter">Attente de signature du contrat</span>
|
|
</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="M5 13l4 4L19 7"></path></svg></div>
|
|
<p class="text-sm font-black uppercase italic leading-none">Acompte Réglé</p>
|
|
</div>
|
|
<div class="p-5">
|
|
{% for payment in paymentList %}
|
|
<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">Moyen utilisé</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.method_label|default('Carte Bancaire') }}</span>
|
|
{% if payment.card.type == "card" %}
|
|
<span class="text-[9px] text-slate-400 font-bold uppercase italic">({{ payment.card.card.brand|default('') }} **** {{ payment.card.card.last4|default('') }})</span>
|
|
{% endif %}
|
|
</div>
|
|
<p class="text-[8px] text-slate-400 font-medium italic mt-2 uppercase tracking-tighter">Validé le {{ payment.validateAt|date('d/m/Y') }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</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) ... #}
|
|
|
|
{# --- SECTION HISTORIQUE COMPLET DES TRANSACTIONS --- #}
|
|
<div class="mt-12">
|
|
<div class="flex items-center gap-4 mb-6">
|
|
<div class="h-px flex-1 bg-slate-200"></div>
|
|
<h2 class="text-[10px] font-black uppercase tracking-[0.3em] text-slate-400">Historique des transactions</h2>
|
|
<div class="h-px flex-1 bg-slate-200"></div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-[2.5rem] border border-slate-100 shadow-sm overflow-hidden">
|
|
<table class="w-full text-left">
|
|
<thead>
|
|
<tr class="bg-slate-50/50 border-b border-slate-100">
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Date & Heure</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Type / Objet</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest">Méthode</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-right">Montant</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-right">Confirmation de paiement</th>
|
|
<th class="px-8 py-4 text-[9px] font-black uppercase text-slate-400 tracking-widest text-center">Statut</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50">
|
|
{# Fusion de toutes les listes de paiement pour l'affichage global #}
|
|
{% set allPayments = paymentList|merge(paymentCaution)|merge(paymentCtaList|default([])) %}
|
|
|
|
{% if allPayments is not empty %}
|
|
{% for pay in allPayments|sort((a, b) => b.validateAt <=> a.validateAt) %}
|
|
<tr class="hover:bg-slate-50/30 transition-colors">
|
|
<td class="px-8 py-5">
|
|
<p class="text-xs font-bold text-slate-900">{{ pay.validateAt|date('d/m/Y') }}</p>
|
|
<p class="text-[10px] text-slate-400 italic">{{ pay.validateAt|date('H:i') }}</p>
|
|
</td>
|
|
<td class="px-8 py-5">
|
|
{% if pay in paymentCaution %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-slate-100 text-slate-600 tracking-tighter">Caution (Empreinte)</span>
|
|
{% elseif pay in paymentList %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-blue-50 text-blue-600 tracking-tighter">Acompte</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-[8px] font-black uppercase bg-indigo-50 text-indigo-600 tracking-tighter">Paiement complémentaire</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="px-8 py-5">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-6 h-4 bg-slate-100 rounded flex items-center justify-center text-[7px] font-bold text-slate-500 uppercase">
|
|
{{ pay.card.card.brand|default('CB') }}
|
|
</div>
|
|
<p class="text-[10px] font-bold text-slate-700 italic">**** {{ pay.card.card.last4|default('----') }}</p>
|
|
</div>
|
|
</td>
|
|
<td class="px-8 py-5 text-right font-black text-slate-900 italic text-sm">
|
|
{{ pay.amount|number_format(2, ',', ' ') }}€
|
|
</td>
|
|
<td class="px-8 py-5 text-right">
|
|
<div class="flex justify-end">
|
|
<a target="_blank" href="{{ path('gestion_contrat_view', {num: contrat.numReservation, idPaymentPdf: pay.id}) }}"
|
|
class="group relative flex items-center justify-center w-10 h-10 bg-blue-50 hover:bg-blue-600 text-blue-600 hover:text-white rounded-full transition-all duration-300 shadow-sm"
|
|
title="Télécharger le reçu">
|
|
|
|
{# Icône de téléchargement épurée #}
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 stroke-[2.5] transition-transform group-hover:scale-110" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
|
|
</svg>
|
|
|
|
{# Tooltip (optionnel) #}
|
|
<span class="absolute -top-8 scale-0 group-hover:scale-100 transition-all bg-slate-800 text-white text-[10px] px-2 py-1 rounded font-bold uppercase tracking-tighter">
|
|
PDF
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</td>
|
|
<td class="px-8 py-5 text-center">
|
|
<div class="inline-flex items-center gap-1.5 text-green-600">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path></svg>
|
|
<span class="text-[9px] font-black uppercase">Validé</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="5" class="px-8 py-10 text-center">
|
|
<p class="text-xs font-bold text-slate-400 italic uppercase tracking-widest">Aucune transaction enregistrée pour le moment</p>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|