fix: paiement manuel partiel - un avis peut avoir plusieurs paiements
- Ne passe en 'accepted' que quand totalPaid >= totalTtc - Facture generee uniquement quand totalement paye - Message flash avec reste a payer si paiement partiel - Modal affiche "Deja paye / Reste" si paiements existants - Bouton visible sur avis send + tout state non cancel/accepted Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -308,27 +308,49 @@ class AdvertController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creer l'AdvertPayment
|
// Creer l'AdvertPayment
|
||||||
$payment = new \App\Entity\AdvertPayment($advert, \App\Entity\AdvertPayment::TYPE_SUCCESS, number_format((float) $amount, 2, '.', ''));
|
$amountFormatted = number_format((float) $amount, 2, '.', '');
|
||||||
|
$payment = new \App\Entity\AdvertPayment($advert, \App\Entity\AdvertPayment::TYPE_SUCCESS, $amountFormatted);
|
||||||
$payment->setMethod($method);
|
$payment->setMethod($method);
|
||||||
$this->em->persist($payment);
|
$this->em->persist($payment);
|
||||||
|
|
||||||
// Mettre a jour l'etat de l'avis
|
|
||||||
$advert->setState(Advert::STATE_ACCEPTED);
|
|
||||||
|
|
||||||
// Tracker l'evenement
|
// Tracker l'evenement
|
||||||
$this->em->persist(new \App\Entity\AdvertEvent($advert, \App\Entity\AdvertEvent::TYPE_PAY, 'Paiement manuel : '.$methodLabel.' - '.$amount.' EUR'));
|
$this->em->persist(new \App\Entity\AdvertEvent($advert, \App\Entity\AdvertEvent::TYPE_PAY, 'Paiement manuel : '.$methodLabel.' - '.$amount.' EUR'));
|
||||||
|
|
||||||
|
// Calculer le total des paiements reussis
|
||||||
|
$totalPaid = 0.0;
|
||||||
|
foreach ($advert->getPayments() as $p) {
|
||||||
|
if (\App\Entity\AdvertPayment::TYPE_SUCCESS === $p->getType()) {
|
||||||
|
$totalPaid += (float) $p->getAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$totalPaid += (float) $amountFormatted;
|
||||||
|
|
||||||
|
$advertTotal = (float) $advert->getTotalTtc();
|
||||||
|
$isFullyPaid = $totalPaid >= ($advertTotal - 0.01);
|
||||||
|
|
||||||
|
if ($isFullyPaid) {
|
||||||
|
$advert->setState(Advert::STATE_ACCEPTED);
|
||||||
|
}
|
||||||
|
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
|
||||||
// Generer la facture
|
// Generer la facture uniquement si totalement paye
|
||||||
try {
|
if ($isFullyPaid) {
|
||||||
$factureService->createPaidFactureFromAdvert($advert, number_format((float) $amount, 2, '.', ''), $methodLabel);
|
try {
|
||||||
} catch (\Throwable $e) {
|
$factureService->createPaidFactureFromAdvert($advert, number_format($advertTotal, 2, '.', ''), $methodLabel);
|
||||||
$this->addFlash('warning', 'Paiement enregistre mais erreur generation facture : '.$e->getMessage());
|
} catch (\Throwable $e) {
|
||||||
|
$this->addFlash('warning', 'Paiement enregistre mais erreur generation facture : '.$e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->meilisearch->indexAdvert($advert);
|
$this->meilisearch->indexAdvert($advert);
|
||||||
|
|
||||||
$this->addFlash('success', 'Paiement de '.$amount.' EUR enregistre ('.$methodLabel.') pour l\'avis '.$advert->getOrderNumber()->getNumOrder().'.');
|
$remaining = $advertTotal - $totalPaid;
|
||||||
|
if ($isFullyPaid) {
|
||||||
|
$this->addFlash('success', 'Paiement complet de '.$amount.' EUR enregistre ('.$methodLabel.'). Avis '.$advert->getOrderNumber()->getNumOrder().' marque paye.');
|
||||||
|
} else {
|
||||||
|
$this->addFlash('success', 'Paiement partiel de '.$amount.' EUR enregistre ('.$methodLabel.'). Reste a payer : '.number_format($remaining, 2, ',', ' ').' EUR.');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute('app_admin_clients_show', [
|
return $this->redirectToRoute('app_admin_clients_show', [
|
||||||
'id' => $advert->getCustomer()?->getId() ?? 0,
|
'id' => $advert->getCustomer()?->getId() ?? 0,
|
||||||
|
|||||||
@@ -641,6 +641,8 @@
|
|||||||
<form method="post" action="{{ path('app_admin_advert_resend', {id: a.id}) }}" class="inline" data-confirm="Renvoyer l'avis de paiement au client ?">
|
<form method="post" action="{{ path('app_admin_advert_resend', {id: a.id}) }}" class="inline" data-confirm="Renvoyer l'avis de paiement au client ?">
|
||||||
<button type="submit" class="px-3 py-1 bg-purple-500/20 text-purple-700 hover:bg-purple-500 hover:text-white font-bold uppercase text-[10px]transition-all">Renvoyer</button>
|
<button type="submit" class="px-3 py-1 bg-purple-500/20 text-purple-700 hover:bg-purple-500 hover:text-white font-bold uppercase text-[10px]transition-all">Renvoyer</button>
|
||||||
</form>
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if a.state == 'send' or (a.state != 'cancel' and a.state != 'accepted') %}
|
||||||
<button type="button" data-modal-open="modal-manual-pay-{{ a.id }}"
|
<button type="button" data-modal-open="modal-manual-pay-{{ a.id }}"
|
||||||
class="px-3 py-1 bg-green-500/20 text-green-700 hover:bg-green-500 hover:text-white font-bold uppercase text-[10px] transition-all">
|
class="px-3 py-1 bg-green-500/20 text-green-700 hover:bg-green-500 hover:text-white font-bold uppercase text-[10px] transition-all">
|
||||||
Enregistrer paiement
|
Enregistrer paiement
|
||||||
@@ -688,11 +690,20 @@
|
|||||||
|
|
||||||
{# Modals paiement manuel #}
|
{# Modals paiement manuel #}
|
||||||
{% for a in advertsList %}
|
{% for a in advertsList %}
|
||||||
{% if a.state == 'send' %}
|
{% if a.state == 'send' or (a.state != 'cancel' and a.state != 'accepted') %}
|
||||||
<div id="modal-manual-pay-{{ a.id }}" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/50">
|
<div id="modal-manual-pay-{{ a.id }}" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/50">
|
||||||
<div class="glass-heavy p-6 w-full max-w-md">
|
<div class="glass-heavy p-6 w-full max-w-md">
|
||||||
<h2 class="text-lg font-bold uppercase mb-4">Enregistrer un paiement</h2>
|
<h2 class="text-lg font-bold uppercase mb-4">Enregistrer un paiement</h2>
|
||||||
<p class="text-xs text-gray-500 mb-4">Avis {{ a.orderNumber.numOrder }} - {{ a.totalTtc }} €</p>
|
<p class="text-xs text-gray-500 mb-2">Avis {{ a.orderNumber.numOrder }} - Total : {{ a.totalTtc }} €</p>
|
||||||
|
{% set totalPaid = 0 %}
|
||||||
|
{% for p in a.payments %}
|
||||||
|
{% if p.type == 'success' %}
|
||||||
|
{% set totalPaid = totalPaid + p.amount %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if totalPaid > 0 %}
|
||||||
|
<p class="text-xs text-green-600 font-bold mb-2">Deja paye : {{ totalPaid|number_format(2, ',', ' ') }} € - Reste : {{ (a.totalTtc - totalPaid)|number_format(2, ',', ' ') }} €</p>
|
||||||
|
{% endif %}
|
||||||
<form method="post" action="{{ path('app_admin_advert_manual_payment', {id: a.id}) }}">
|
<form method="post" action="{{ path('app_admin_advert_manual_payment', {id: a.id}) }}">
|
||||||
<div class="grid grid-cols-1 gap-3 mb-4">
|
<div class="grid grid-cols-1 gap-3 mb-4">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user