add webhooks for refused signature contrat
This commit is contained in:
@@ -128,6 +128,7 @@ class ReserverController extends AbstractController
|
|||||||
$runningTotalHT += $formulaBasePrice;
|
$runningTotalHT += $formulaBasePrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$products = [];
|
||||||
if (!empty($ids)) {
|
if (!empty($ids)) {
|
||||||
$products = $productRepository->findBy(['id' => $ids]);
|
$products = $productRepository->findBy(['id' => $ids]);
|
||||||
$processedProductIds = [];
|
$processedProductIds = [];
|
||||||
@@ -196,7 +197,7 @@ class ReserverController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$promoData = $session->getPromotion();
|
$promoData = $session->getPromotion();
|
||||||
if ($promoData && $runningTotalHT > 0) {
|
if ($promoData && $runningTotalHT > 0 && $this->isDiscountAllowed($products)) {
|
||||||
$discount = $runningTotalHT * ($promoData['percentage'] / 100);
|
$discount = $runningTotalHT * ($promoData['percentage'] / 100);
|
||||||
$promoLine = new DevisLine();
|
$promoLine = new DevisLine();
|
||||||
$promoLine->setProduct("Promotion : " . $promoData['name'] . " (-" . $promoData['percentage'] . "%)");
|
$promoLine->setProduct("Promotion : " . $promoData['name'] . " (-" . $promoData['percentage'] . "%)");
|
||||||
@@ -1451,7 +1452,8 @@ class ReserverController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$discountAmount = 0;
|
$discountAmount = 0;
|
||||||
if ($promotion) {
|
// Application de la remise seulement si autorisée (pas uniquement des produits 2-7 Ans)
|
||||||
|
if ($promotion && $this->isDiscountAllowed($products)) {
|
||||||
$discountAmount = $totalHT * ($promotion->getPercentage() / 100);
|
$discountAmount = $totalHT * ($promotion->getPercentage() / 100);
|
||||||
$totalHT -= $discountAmount;
|
$totalHT -= $discountAmount;
|
||||||
}
|
}
|
||||||
@@ -1473,4 +1475,30 @@ class ReserverController extends AbstractController
|
|||||||
'tvaEnabled' => $tvaEnabled
|
'tvaEnabled' => $tvaEnabled
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si la remise doit être appliquée.
|
||||||
|
* Si le panier ne contient QUE des produits de la catégorie '2-7 Ans', la remise est refusée.
|
||||||
|
* S'il y a un mélange ou d'autres produits, elle est acceptée.
|
||||||
|
*/
|
||||||
|
private function isDiscountAllowed(array $products): bool
|
||||||
|
{
|
||||||
|
if (empty($products)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasOnlyExcluded = true;
|
||||||
|
foreach ($products as $product) {
|
||||||
|
$cat = $product->getCategory();
|
||||||
|
// Handle both object (Category entity) and string cases for robustness
|
||||||
|
$catName = is_object($cat) && method_exists($cat, 'getName') ? $cat->getName() : (string)$cat;
|
||||||
|
|
||||||
|
if ($catName !== '2-7 Ans') {
|
||||||
|
$hasOnlyExcluded = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$hasOnlyExcluded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,21 @@
|
|||||||
Générer la Facture
|
Générer la Facture
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{# --- BOUTON RENVOYER LIEN SIGNATURE (Caché si signé ou refusé) --- #}
|
||||||
|
{# Note: contrat.signed semble être utilisé dans le snippet original, mais list.twig utilise isSigned. Je vérifie les deux ou je suppose isSigned correct si c'est l'entité. #}
|
||||||
|
{# Dans le doute, j'utilise la logique cohérente avec le statut #}
|
||||||
|
{% if not contrat.signed and not contrat.refused %}
|
||||||
|
<a data-turbo="false" href="{{ path('app_crm_contrats', {idSend: contrat.id}) }}"
|
||||||
|
onclick="return confirm('Renvoyer les documents à {{ contrat.customer.email }} ?')"
|
||||||
|
class="flex items-center gap-2 px-6 py-2.5 bg-indigo-600 hover:bg-indigo-500 border border-indigo-500 rounded-xl text-white text-[10px] font-black uppercase italic transition-all shadow-lg shadow-indigo-500/20 group">
|
||||||
|
<svg class="w-4 h-4 group-hover:rotate-12 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
|
||||||
|
</svg>
|
||||||
|
Renvoyer le lien
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if contrat.signed %}
|
{% if contrat.signed %}
|
||||||
<a href="{{ vich_uploader_asset(contrat,'devisSignFile') }}" download
|
<a href="{{ vich_uploader_asset(contrat,'devisSignFile') }}" download
|
||||||
class="flex items-center gap-2 px-6 py-2.5 bg-emerald-500/10 hover:bg-emerald-500/20 border border-emerald-500/20 backdrop-blur-md rounded-xl text-emerald-400 text-[10px] font-black uppercase italic transition-all group">
|
class="flex items-center gap-2 px-6 py-2.5 bg-emerald-500/10 hover:bg-emerald-500/20 border border-emerald-500/20 backdrop-blur-md rounded-xl text-emerald-400 text-[10px] font-black uppercase italic transition-all group">
|
||||||
@@ -49,11 +64,33 @@
|
|||||||
|
|
||||||
<div class="space-y-8 pb-20">
|
<div class="space-y-8 pb-20">
|
||||||
|
|
||||||
|
{# --- BANNIÈRE DE REFUS (Prioritaire) --- #}
|
||||||
|
{% if contrat.refused %}
|
||||||
|
<div class="bg-red-600/20 border-b border-red-500/30 px-8 py-4 rounded-[1.5rem] flex items-center justify-between gap-3 backdrop-blur-md animate-in fade-in slide-in-from-top-4 duration-500">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<div class="p-3 bg-red-500 rounded-2xl shadow-lg shadow-red-500/20">
|
||||||
|
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-sm font-black text-red-400 uppercase tracking-widest leading-none">CONTRAT REFUSÉ PAR LE CLIENT</h3>
|
||||||
|
<p class="text-sm text-red-100/80 mt-1 font-medium italic">
|
||||||
|
Motif du refus : "{{ contrat.refusedRaison|default('Aucune raison spécifiée') }}"
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-2 bg-red-500 text-white rounded-xl text-[10px] font-black uppercase shadow-lg shadow-red-500/20">
|
||||||
|
Action Requise
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# --- 1. BANDEAU DE STATUT RAPIDE --- #}
|
{# --- 1. BANDEAU DE STATUT RAPIDE --- #}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<div class="p-4 rounded-[1.5rem] bg-white/5 border border-white/10 backdrop-blur-md flex items-center justify-between">
|
<div class="p-4 rounded-[1.5rem] bg-white/5 border border-white/10 backdrop-blur-md flex items-center justify-between">
|
||||||
<span class="text-[10px] font-black uppercase text-slate-300 tracking-widest">État Juridique</span>
|
<span class="text-[10px] font-black uppercase text-slate-300 tracking-widest">État Juridique</span>
|
||||||
{% if contrat.signed %}
|
{% if contrat.refused %}
|
||||||
|
<span class="px-3 py-1 bg-red-500/10 text-red-400 text-[9px] font-black rounded-lg border border-red-500/20">REFUSÉ</span>
|
||||||
|
{% elseif contrat.signed %}
|
||||||
<span class="px-3 py-1 bg-emerald-500/10 text-emerald-400 text-[9px] font-black rounded-lg border border-emerald-500/20">SIGNÉ</span>
|
<span class="px-3 py-1 bg-emerald-500/10 text-emerald-400 text-[9px] font-black rounded-lg border border-emerald-500/20">SIGNÉ</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="px-3 py-1 bg-amber-500/10 text-amber-400 text-[9px] font-black rounded-lg border border-amber-500/20 animate-pulse">EN ATTENTE</span>
|
<span class="px-3 py-1 bg-amber-500/10 text-amber-400 text-[9px] font-black rounded-lg border border-amber-500/20 animate-pulse">EN ATTENTE</span>
|
||||||
@@ -89,7 +126,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# --- 2. INFOS CLIENT & ÉVÉNEMENT --- #}
|
{# --- 2. INFOS CLIENT & ÉVÉNEMENT --- #}
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<div class="absolute -inset-0.5 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-[2.5rem] blur opacity-50"></div>
|
<div class="absolute -inset-0.5 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-[2.5rem] blur opacity-50"></div>
|
||||||
<div class="relative h-full p-8 bg-slate-900/40 border border-white/10 backdrop-blur-xl rounded-[2.5rem]">
|
<div class="relative h-full p-8 bg-slate-900/40 border border-white/10 backdrop-blur-xl rounded-[2.5rem]">
|
||||||
@@ -98,7 +135,7 @@
|
|||||||
<svg class="w-7 h-7 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
|
<svg class="w-7 h-7 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-xl font-black text-white italic tracking-tighter uppercase">{{ contrat.customer.surname }} {{ contrat.customer.name }}</h2>
|
<h2 class="text-xl font-black text-white italic tracking-tighter uppercase {{ contrat.refused ? 'line-through decoration-red-500/50' : '' }}">{{ contrat.customer.surname }} {{ contrat.customer.name }}</h2>
|
||||||
<p class="text-slate-500 font-bold text-[10px] uppercase tracking-widest">Locataire</p>
|
<p class="text-slate-500 font-bold text-[10px] uppercase tracking-widest">Locataire</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,7 +168,7 @@
|
|||||||
|
|
||||||
{# --- 3. SECTION LOGISTIQUE & ÉTAT DES LIEUX --- #}
|
{# --- 3. SECTION LOGISTIQUE & ÉTAT DES LIEUX --- #}
|
||||||
{% if contrat.etatLieux %}
|
{% if contrat.etatLieux %}
|
||||||
<div class="space-y-4">
|
<div class="space-y-4 {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Logistique & État des lieux</h3>
|
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Logistique & État des lieux</h3>
|
||||||
|
|
||||||
{% if contrat.etatLieux.status == 'edl_return_refused' %}
|
{% if contrat.etatLieux.status == 'edl_return_refused' %}
|
||||||
@@ -225,7 +262,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# --- 4. ÉTAT DES PAIEMENTS --- #}
|
{# --- 4. ÉTAT DES PAIEMENTS --- #}
|
||||||
<div class="p-8 bg-white/[0.02] border border-white/10 rounded-[2.5rem] backdrop-blur-md">
|
<div class="p-8 bg-white/[0.02] border border-white/10 rounded-[2.5rem] backdrop-blur-md {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<div class="flex flex-col md:flex-row gap-8 justify-around items-start">
|
<div class="flex flex-col md:flex-row gap-8 justify-around items-start">
|
||||||
{# ACOMPTE #}
|
{# ACOMPTE #}
|
||||||
<div class="flex flex-col items-center gap-4 text-center w-full">
|
<div class="flex flex-col items-center gap-4 text-center w-full">
|
||||||
@@ -305,7 +342,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# --- 5. PRODUITS ET OPTIONS --- #}
|
{# --- 5. PRODUITS ET OPTIONS --- #}
|
||||||
<div class="grid grid-cols-1 xl:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 xl:grid-cols-2 gap-8 {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Équipements loués</h3>
|
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Équipements loués</h3>
|
||||||
<div class="bg-white/[0.02] border border-white/10 rounded-[2rem] divide-y divide-white/5 overflow-hidden">
|
<div class="bg-white/[0.02] border border-white/10 rounded-[2rem] divide-y divide-white/5 overflow-hidden">
|
||||||
@@ -340,7 +377,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# --- 6. HISTORIQUE FINANCIER --- #}
|
{# --- 6. HISTORIQUE FINANCIER --- #}
|
||||||
<div class="space-y-4">
|
<div class="space-y-4 {{ contrat.refused ? 'opacity-75 grayscale' : '' }}">
|
||||||
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Historique des transactions</h3>
|
<h3 class="px-2 text-sm font-black text-slate-400 uppercase tracking-[0.3em]">Historique des transactions</h3>
|
||||||
<div class="bg-white/[0.02] border border-white/10 rounded-[2.5rem] overflow-hidden">
|
<div class="bg-white/[0.02] border border-white/10 rounded-[2.5rem] overflow-hidden">
|
||||||
<table class="w-full text-left">
|
<table class="w-full text-left">
|
||||||
|
|||||||
Reference in New Issue
Block a user