diff --git a/.env b/.env index a86f994..371ccf0 100644 --- a/.env +++ b/.env @@ -83,9 +83,9 @@ STRIPE_PK=pk_test_51SUA22173W4aeFB1nO6oFfDZ12HOTffDKtCshhZ8rkUg6kUO2ZaQC0tK72rhE STRIPE_SK=sk_test_51SUA22173W4aeFB16EB2LxGI0hNvNJzFshDI98zRImWBIhSfzqOGAz5TlPxSpUWbj3x4COm6kmSsaal9FpQR1A7M0022DvjbbR STRIPE_WEBHOOKS_SECRET= -SIGN_URL=https://eb44-82-67-166-187.ngrok-free.app -STRIPE_BASEURL=https://eb44-82-67-166-187.ngrok-free.app -CONTRAT_BASEURL=https://eb44-82-67-166-187.ngrok-free.app +SIGN_URL=https://00ca-212-114-31-239.ngrok-free.app +STRIPE_BASEURL=https://00ca-212-114-31-239.ngrok-free.app +CONTRAT_BASEURL=https://00ca-212-114-31-239.ngrok-free.app MINIO_S3_URL= MINIO_S3_CLIENT_ID= diff --git a/src/Controller/Dashboard/HomeController.php b/src/Controller/Dashboard/HomeController.php index edf87d9..f79700a 100644 --- a/src/Controller/Dashboard/HomeController.php +++ b/src/Controller/Dashboard/HomeController.php @@ -51,9 +51,15 @@ class HomeController extends AbstractController $stats = $this->getUmamiStats(); $updates = $this->getSystemUpdates(); + $z = []; + foreach ($this->devisRepository->waitSign() as $item) { + if(!str_contains($item['state'],'refused')) { + $z[] = $item; + } + } return $this->render('dashboard/home.twig', [ 'product' => $this->productRepository->count([]), - 'devis_wait_sign' => $this->devisRepository->waitSign(), + 'devis_wait_sign' => count($z), 'customers' => $this->customerRepository->count([]), 'nbVisitor' => $stats['visitors'], 'nbView' => $stats['views'], diff --git a/src/Controller/Webhooks.php b/src/Controller/Webhooks.php index 1820704..df93ecf 100644 --- a/src/Controller/Webhooks.php +++ b/src/Controller/Webhooks.php @@ -2,11 +2,15 @@ namespace App\Controller; +use App\Entity\Contrats; use App\Entity\ContratsPayments; use App\Entity\Devis; use App\Entity\Product; use App\Entity\ProductReserve; use App\Kernel; +use App\Logger\AppLogger; +use App\Repository\ContratsRepository; +use App\Repository\DevisRepository; use App\Repository\ProductRepository; use App\Service\Mailer\Mailer; use App\Service\Pdf\PlPdf; @@ -71,7 +75,7 @@ class Webhooks extends AbstractController $pl->setPaymentSignedFile(new UploadedFile($tmpSigned, "confirmed-certificate-" . $pl->getId() . ".pdf", "application/pdf", null, true)); $pl->setUpdateAt(new \DateTimeImmutable('now')); $entityManager->persist($pl); - + // Update Reservation State if Accompte and Signed if ($pl->getType() === 'accompte' && $contrat->isSigned()) { $contrat->setReservationState('ready'); @@ -82,7 +86,7 @@ class Webhooks extends AbstractController if ($prestataire) { $dateStart = $contrat->getDateAt()->format('d/m/Y'); $dateEnd = $contrat->getEndAt()->format('d/m/Y'); - + $mailer->send( $prestataire->getEmail(), $prestataire->getSurname() . ' ' . $prestataire->getName(), @@ -97,7 +101,7 @@ class Webhooks extends AbstractController ); } } - + $entityManager->flush(); // --- ENVOI DES EMAILS --- @@ -159,4 +163,77 @@ class Webhooks extends AbstractController return new Response('Invalid Signature', 400); } + #[Route(path: '/webhooks/docuseal', name: 'webhooks_docuseal', options: ['sitemap' => false], methods: ['POST'])] + public function docuseal( + Mailer $mailer, + EntityManagerInterface $entityManager, + ContratsRepository $contratsRepository, + DevisRepository $devisRepository, + Client $client, + Request $request, + AppLogger $appLogger + ): Response { + $contentRaw = $request->getContent(); + $headers = $request->headers; + + // Vérification de sécurité (Header personnalisé) + if ($headers->has('X-Src') && $headers->get('X-Src') === "Ludik_Sign") { + $payload = json_decode($contentRaw); + + // Validation de la structure du payload + if (!isset($payload->data) || !isset($payload->data->metadata)) { + return new Response("Invalid payload structure", 400); + } + + $content = $payload->data; + $metadata = $content->metadata; + $status = $content->status ?? ''; + + // --- TRAITEMENT DES DEVIS --- + if (isset($metadata->type) && $metadata->type === "devis" && isset($metadata->id)) { + $devis = $devisRepository->find($metadata->id); + + if ($devis instanceof Devis) { + + // Cas 1 : Signature refusée par le client + if ($status === "declined") { + $reason = $content->decline_reason ?? 'Aucune raison spécifiée'; + + // Mise à jour du statut + $devis->setState("refused|" . $reason); + $entityManager->persist($devis); + $entityManager->flush(); + + // Notification au client (Confirmation de prise en compte du refus) + $customer = $devis->getCustomer(); + if ($customer) { + $mailer->send( + $customer->getEmail(), + $customer->getName() . " " . $customer->getSurname(), + "[Intranet Ludikevent] - Le client a refusé la signature du devis n°" . $devis->getNum(), + "mails/customer/devis_refuses.twig", + [ + 'devis' => $devis, + 'raison' => $reason, + ] + ); + } + + $appLogger->record('WEBHOOK', sprintf("Devis %s refusé par le client. Raison: %s", $devis->getNum(), $reason)); + + return new Response("ok-devis-declined"); + } + + // Cas 2 : Signature complétée (Optionnel - à implémenter selon vos besoins) + if ($status === "completed") { + // Logique de succès (ex: passage en contrat) + $appLogger->record('WEBHOOK', sprintf("Devis %s signé avec succès.", $devis->getNum())); + return new Response("ok-devis-completed"); + } + } + } + } + + return new Response("ignored"); + } } diff --git a/src/Repository/DevisRepository.php b/src/Repository/DevisRepository.php index b22dc3b..68d1446 100644 --- a/src/Repository/DevisRepository.php +++ b/src/Repository/DevisRepository.php @@ -42,12 +42,12 @@ class DevisRepository extends ServiceEntityRepository // } public function waitSign() { - return count( $this->createQueryBuilder('d') + return $this->createQueryBuilder('d') ->andWhere('d.state != :status') ->andWhere('d.state != :status2') ->setParameter('status','signed') ->setParameter('status2','cancel') - ->getQuery()->getArrayResult()); + ->getQuery()->getArrayResult(); } } diff --git a/templates/mails/customer/devis_refuses.twig b/templates/mails/customer/devis_refuses.twig new file mode 100644 index 0000000..2a6542a --- /dev/null +++ b/templates/mails/customer/devis_refuses.twig @@ -0,0 +1,45 @@ +{% extends 'mails/base.twig' %} + +{% block content %} + + + + Le devis n°{{ datas.devis.num }} a été refusé par le client {{ datas.devis.customer.name }} {{ datas.devis.customer.surname }}. + + + + + + + + + N° Devis : + {{ datas.devis.num }} + + + Client : + {{ datas.devis.customer.name }} {{ datas.devis.customer.surname }} + + + Raison du refus : + {{ datas.raison }} + + + Date : + {{ "now"|date("d/m/Y à H:i") }} + + + + + + + + + Ce devis est désormais marqué comme "Refusé" dans le CRM. Une relance commerciale est peut-être nécessaire. + + + GÉRER LE DEVIS + + + +{% endblock %}