src/Controller/AjaxController.php line 114

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\HistoriqueUtilisateur;
  4. use App\Entity\InfosSuivi;
  5. use App\Entity\Proposition;
  6. use App\Repository\HistoriqueUtilisateurRepository;
  7. use App\Repository\PropositionRepository;
  8. use DateTime;
  9. use App\Entity\Lot;
  10. use App\Entity\Prospect;
  11. use App\Service\Geocoder;
  12. use App\Service\ImagePdf;
  13. use App\Entity\Historique;
  14. use App\Entity\Impression;
  15. use App\Entity\PieceJointe;
  16. use App\Entity\Utilisateur;
  17. use App\Service\Notification;
  18. use Doctrine\ORM\EntityManager;
  19. use App\Repository\LotRepository;
  20. use App\Repository\VilleRepository;
  21. use App\Repository\ProspectRepository;
  22. use App\Repository\HistoriqueRepository;
  23. use Doctrine\ORM\EntityManagerInterface;
  24. use App\Repository\UtilisateurRepository;
  25. use App\Repository\ProgrammeRepository;
  26. use App\Repository\DepartementRepository;
  27. use phpDocumentor\Reflection\Types\This;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\Response;
  30. use Doctrine\ORM\Query\AST\NewObjectExpression;
  31. use Symfony\Component\Routing\Annotation\Route;
  32. use Symfony\Component\HttpFoundation\JsonResponse;
  33. use Symfony\Component\HttpFoundation\Session\Session;
  34. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  35. /**
  36.  * @Route("/ajax")
  37.  */
  38. class AjaxController extends AbstractController
  39. {
  40.     protected $notificationService;
  41.     public function __construct(Notification $notificationService)
  42.     {
  43.         $this->notificationService $notificationService;
  44.     }
  45.     /**
  46.      * @Route("/ville", name="ajax_ville")
  47.      */
  48.     public function ville(Request $requestVilleRepository $villeRepository): Response
  49.     {
  50.         $searchTerm $request->query->get('search'null);
  51.         $villes $villeRepository->findByNomReel($searchTerm);
  52.         $data = [];
  53.         foreach($villes as $ville) {
  54.             $data[] = [
  55.                 'value' => $ville->getNomReel(),
  56.                 'text' => $ville->getNomReel() . ' (' $ville->getCodePostal() . ')',
  57.                 'code_postal' => $ville->getCodePostal()
  58.             ];
  59.         }
  60.         return $this->json($data);
  61.     }
  62.     /**
  63.      * @Route("/departement", name="ajax_departement")
  64.      */
  65.     public function departement(Request $requestDepartementRepository $departementRepository): Response
  66.     {
  67.         $departements $departementRepository->findByNomOrCode($request->query->get('search'null));
  68.         $data = [];
  69.         foreach($departements as $departement) {
  70.             $data[] = [
  71.                 'id' => $departement->getId(),
  72.                 'text' => $departement->getNom() . ' (' $departement->getCode() . ')'
  73.             ];
  74.         }
  75.         return $this->json($data);
  76.     }
  77.     /**
  78.      * @Route("/code-postal", name="ajax_code_postal")
  79.      */
  80.     public function codePostal(Request $requestVilleRepository $villeRepository): Response
  81.     {
  82.         $searchTerm $request->query->get('search'null);
  83.         $villes $villeRepository->findByCodePostal($searchTerm);
  84.         $data = [];
  85.         foreach ($villes as $ville) {
  86.             $data[] = [
  87.                 'id' => $ville->getCodePostal(),
  88.                 'text' => $ville->getNomReel() . ' (' $ville->getCodePostal() . ')'
  89.             ];
  90.         }
  91.         return $this->json($data);
  92.     }
  93.     /**
  94.      * @Route("/lot", name="ajax_lot")
  95.      */
  96.     public function lot(Request $requestLotRepository $lotRepository): Response
  97.     {
  98.         $user $this->getUser();
  99.         $entreprise $user->getEntreprise();
  100.     
  101.         $lots $lotRepository->findByProgrammeRefTitreAndEntreprise($request->query->get('search'null), $entreprise$user);
  102.     
  103.         $data = [];
  104.         foreach($lots as $lot) {
  105.             $data[] = [
  106.                 'id' => $lot->getId(),
  107.                 'text' => (string)$lot,
  108.                 'reference' => $lot->getReference(),
  109.                 'programme' => $lot->getProgramme(),
  110.                 'type' => $lot->getType(),
  111.                 'ville' => $lot->getVille(),
  112.                 'codePostal' => $lot->getCodePostal()
  113.             ];
  114.         }
  115.         return $this->json([
  116.             'results' => $data
  117.         ]);
  118.     }
  119.     /**
  120.      * @Route("/prospect", name="ajax_prospect")
  121.      */
  122.     public function prospect(Request $requestProspectRepository $prospectRepository): Response
  123.     {
  124.         $prospects $prospectRepository->findByPrenomNom($request->query->get('search'null));
  125.         //dd($prospects);
  126.         $data = [];
  127.         foreach($prospects as $prospect) {
  128.             $data[] = [
  129.                 'id' => $prospect->getId(),
  130.                 'text' => $prospect->getEmprunteurPrenom()." ".$prospect->getEmprunteurNom(),
  131.                 'nom' => $prospect->getEmprunteurNom(),
  132.                 'prenom' => $prospect->getEmprunteurPrenom()
  133.             ];
  134.         }
  135.         return $this->json([
  136.             'results' => $data
  137.         ]);
  138.     }
  139.     /**
  140.      * @Route("/programme", name="ajax_programme")
  141.      */
  142.     public function programme(Request $requestProgrammeRepository $programmeRepository): Response
  143.     {
  144.         $user $this->getUser();
  145.         $entreprise $user->getEntreprise();
  146.     
  147.         $programmes $programmeRepository->findByNomOrPromoteurOrVilleAndEntreprise($request->query->get('search'null), $entreprise$user);
  148.         foreach($programmes as $p) {
  149.             $data[] = [
  150.                 'id' => $p->getId(),
  151.                 'text' => (string)$p . (trim((string)$p->getPromoteur()) != '' ' (' $p->getPromoteur() . ')' ''),
  152.                 'ville' =>(string)$p->getVille(),
  153.                 'programme' => (string)$p,
  154.                 'promoteur' => $p->getPromoteur(),
  155.             ];
  156.         }
  157.         return $this->json([
  158.             'results' => $data
  159.         ]);
  160.     }
  161.     /**
  162.      * @Route("/prospect/add/lot/{lotId}", name="ajax_prospect_add_lot", methods={"POST"})
  163.      */
  164.     public function addLotToProspect(Lot $lotId ,Request $requestProspectRepository $prospectRepositoryPropositionRepository $propositionRepositoryEntityManagerInterface $em): Response
  165.     {
  166.         $prospect $prospectRepository->findBy(['id' => $request->request->get('prospectId')]);
  167.         if(!empty($propositionRepository->findByLotAndProspect($lotId$prospect))){
  168.             return $this->json([
  169.                 'warning' => 'Ce lot est déja proposé à ce client'
  170.             ]);
  171.         }
  172.         $newProposition = new Proposition();
  173.         $newProposition->setLot($lotId);
  174.         $prospect[0]->addProposition($newProposition);
  175.         $em->persist($newProposition);
  176.         $em->flush();
  177.         return $this->json([
  178.             'success' => 'Proposition ajoutée'
  179.         ]);
  180.     }
  181.     /**
  182.      * @Route("/geocode/adresse", name="ajax_geocode_adresse")
  183.      */
  184.     public function geocodeAdresse(Request $requestGeocoder $geocoder): Response
  185.     {
  186.         $search $request->query->get('query');
  187.         $coords $geocoder->encode($search);
  188.         if($coords) {
  189.             return $this->json([
  190.                 'latitude' => $coords['lat'],
  191.                 'longitude' => $coords['lng']
  192.             ]);
  193.         } else {
  194.             return $this->json(false);
  195.         }
  196.     }
  197.     /**
  198.      * @Route("/send/impression/{lot}", name="ajax_send_impression")
  199.      */
  200.     public function sendImpression(Lot $lotRequest $requestUtilisateurRepository $utilisateurRepositoryProspectRepository $prospectRepEntityManagerInterface $emNotification $serviceNotificationHistoriqueRepository $historiqueRepository): Response
  201.     {
  202.         if ($request->isXmlHttpRequest()) {
  203.             $token $request->getSession()->get('token');
  204.             $data $request->request->get('form');
  205.             $commentaire $data['commentaire'];
  206.             if(trim($commentaire) == '')
  207.                 return $this->json([
  208.                     'status' => 'fail',
  209.                     'message' => 'Veuillez renseigner le champ de commentaire.'
  210.                 ]);
  211.             $prospect $prospectRep->findOneBy(['token' => $token]);
  212.             $historique $historiqueRepository->findOneBy(['prospect' => $prospect->getId()], ['dateheure' => 'DESC']);
  213.             if($historique == null)
  214.             {
  215.                 $historique = new Historique();
  216.                 $historique->setProspect($prospect);
  217.                 $historique->setModeEnvoi('automatique');
  218.                 $historique->setDateheure(new DateTime());
  219.                 foreach ($prospect->getPropositions() as $p) {
  220.                     $historique->addLot($p->getLot());
  221.                 }
  222.                 $em->persist($historique);
  223.             }
  224.             $impression = new Impression();
  225.             $impression->setHistorique($historique);
  226.             $impression->setProspect($prospect);
  227.             $impression->setCommentaire($commentaire);
  228.             $impression->setDateheure(new \DateTime());
  229.             $em->persist($impression);
  230.             $em->flush();
  231.             $res $serviceNotification->alertInterne($prospect$impression$lot$utilisateurRepository);
  232.             if(!$res)
  233.                 return $this->json([
  234.                     'status' => 'fail',
  235.                     'message' => 'Une erreur s\'est produite lors de l\'envoi de votre message.'
  236.                 ]);
  237.             return $this->json([
  238.                 'status' => 'success',
  239.                 'message' => 'Votre commentaire a bien été envoyé.'
  240.             ]);
  241.         }
  242.         return $this->json([
  243.             'status' => 'fail',
  244.             'message' => 'Une erreur s\'est produite lors de l\'envoi de votre message.'
  245.         ]);
  246.     }
  247.     /**
  248.      * @Route("/new/historique/{prospect}", name="ajax_new_historique")
  249.      */
  250.     public function newHistorique(Prospect $prospect nullRequest $requestEntityManagerInterface $em):Response
  251.     {
  252.         $modeEnvoi $request->query->get('modeEnvoi');
  253.         $contenu $request->query->get('msg');
  254.         $contenu str_replace('%0a'PHP_EOL$contenu);
  255.         $expediteur $this->container->get('security.token_storage')->getToken()->getUser();
  256.         $historique = new Historique();
  257.         $historique->setProspect($prospect);
  258.         $historique->setModeEnvoi($modeEnvoi);
  259.         $historique->setDateheure(new DateTime());
  260.         $historique->setContenu($contenu);
  261.         $historique->setEntreprise($prospect->getEntreprise());
  262.         if($expediteur instanceof Utilisateur) {
  263.             $historique->setExpediteur($expediteur);
  264.         }
  265.         foreach ($prospect->getPropositions() as $p) {
  266.             $historique->addLot($p->getLot());
  267.         }
  268.         $em->persist($historique);
  269.         $em->flush();
  270.         return $this->json([
  271.             'message' => 'Nouvelle proposition dans l\'historique.'
  272.         ]);
  273.     }
  274.     /**
  275.      * @Route("/pj/rotate", name="ajax_piece_jointe_rotate")
  276.      */
  277.     public function pieceJointeRotate(Request $request): Response
  278.     {
  279.         $fileName $request->query->get('query');
  280.         $degrees 90;
  281.         $strArray explode('.'$fileName);
  282.         $ext trim(strtolower(end($strArray)));
  283.         if($ext == 'png')
  284.         {
  285.             ImagePdf::rotateImage90Deg($fileName);
  286.             return $this->json($fileName);
  287.         }
  288.         if ($ext == 'jpg' || $ext == 'jpeg')
  289.         {
  290.             $path explode('/'$fileName);
  291.             $fileName end($path);
  292.             ImagePdf::rotateImage90Deg(PieceJointe::SAVE_PATH $fileName);
  293.             return $this->json(PieceJointe::SAVE_PATH $fileName);
  294.         }
  295.         return $this->json(false);
  296.     }
  297.     /**
  298.      * @Route("/envoi-mail-fiche", name="ajax_envoi_mail_fiche")
  299.      */
  300.     public function envoiMailFiche(Request $requestUtilisateurRepository $utilisateurRepositoryProspectRepository $prospectRepositoryEntityManagerInterface $em): JsonResponse
  301.     {
  302.         $auteurId $request->get('auteurId');
  303.         $prospectId $request->get('prospectId');
  304.         $userConnected $this->getUser();
  305.     
  306.         if ($auteurId || $prospectId) {
  307.             $this->notificationService->alertAuteurProspect($prospectId$auteurId$userConnected);
  308.             
  309.             $infoSuivi = new InfosSuivi();
  310.             $infoSuivi->setUtilisateur($utilisateurRepository->find($auteurId));
  311.             $infoSuivi->addProspect($prospectRepository->find($prospectId));
  312.             $infoSuivi->setType('client');
  313.             $infoSuivi->setDescription('Un nouveau client vous a été attribué : [prospect]');
  314.             $infoSuivi->setDate(new DateTime());
  315.             $infoSuivi->setLu(false);
  316.             $em->persist($infoSuivi);
  317.             $em->flush();
  318.             return $this->json([
  319.                 'status' => 'success',
  320.                 'message' => 'Email envoyé avec succès'
  321.             ]);
  322.         }
  323.     
  324.         return $this->json([
  325.             'status' => 'error',
  326.             'message' => 'Auteur non trouvé ou erreur d\'envoi'
  327.         ]);
  328.     }
  329.     /**
  330.      * @Route("/info-suivi/{id}/lu", name="ajax_info_suivi_lu", methods={"POST"})
  331.      */
  332.     public function setInfoSuiviLu(Request $requestInfosSuivi $infoSuivi): Response
  333.     {
  334.         $infoSuivi->setLu(true);
  335.         $entityManager $this->getDoctrine()->getManager();
  336.         $entityManager->flush();
  337.         return new Response();
  338.     }
  339.     /**
  340.      * @Route("/prospect/check-duplicate", name="ajax_prospect_check_duplicate")
  341.      */
  342.     public function checkProspectDuplicate(Request $requestProspectRepository $prospectRepository): JsonResponse
  343.     {
  344.         $nom trim($request->query->get('nom'''));
  345.         $prenom trim($request->query->get('prenom'''));
  346.         // Nouveaux champs co-emprunteur
  347.         $coNom trim($request->query->get('coNom'''));
  348.         $coPrenom trim($request->query->get('coPrenom'''));
  349.         $currentProspectId $request->query->get('currentId'null);
  350.         // Si absolument rien n'est renseigné → pas de check
  351.         if (
  352.             (empty($nom) || empty($prenom)) &&
  353.             (empty($coNom) || empty($coPrenom))
  354.         ) {
  355.             return $this->json([
  356.                 'exists' => false,
  357.                 'message' => 'Champs insuffisants pour une vérification'
  358.             ]);
  359.         }
  360.         $user $this->getUser();
  361.         if (!$user instanceof Utilisateur || !$user->getEntreprise()) {
  362.             return $this->json([
  363.                 'exists' => false,
  364.                 'error' => 'Utilisateur non authentifié ou entreprise non définie'
  365.             ]);
  366.         }
  367.         try {
  368.             // Charger le prospect actuel (pour exclusion)
  369.             $currentNom null;
  370.             $currentPrenom null;
  371.             $currentCoNom null;
  372.             $currentCoPrenom null;
  373.             if ($currentProspectId) {
  374.                 $currentProspect $prospectRepository->find($currentProspectId);
  375.                 if ($currentProspect) {
  376.                     $currentNom trim($currentProspect->getEmprunteurNom());
  377.                     $currentPrenom trim($currentProspect->getEmprunteurPrenom());
  378.                     $currentCoNom trim($currentProspect->getCoEmprunteurNom());
  379.                     $currentCoPrenom trim($currentProspect->getCoEmprunteurPrenom());
  380.                 }
  381.             }
  382.             // Vérifications séparées
  383.             $errors = [];
  384.             // Doublon emprunteur
  385.             if (!empty($nom) && !empty($prenom)) {
  386.                 $existingEmprunteur $prospectRepository->findExistingProspectByNomPrenom(
  387.                     $nom,
  388.                     $prenom,
  389.                     $user->getEntreprise(),
  390.                     $currentProspectId,
  391.                     $currentNom,
  392.                     $currentPrenom
  393.                 );
  394.                 if ($existingEmprunteur) {
  395.                     $errors['emprunteur'] = [
  396.                         'id' => $existingEmprunteur->getId(),
  397.                         'nom' => $existingEmprunteur->getEmprunteurNom(),
  398.                         'prenom' => $existingEmprunteur->getEmprunteurPrenom(),
  399.                         'email' => $existingEmprunteur->getEmprunteurEmail(),
  400.                         'dateCreation' => $existingEmprunteur->getDateheure() ? $existingEmprunteur->getDateheure()->format('d/m/Y H:i') : null,
  401.                         'auteur' => $existingEmprunteur->getAuteur() ? $existingEmprunteur->getAuteur()->getNomEtPrenom() : null,
  402.                     ];
  403.                 }
  404.             }
  405.             // Doublon co-emprunteur
  406.             if (!empty($coNom) && !empty($coPrenom)) {
  407.                 $existingCo $prospectRepository->findExistingProspectByCoNomPrenom(
  408.                     $coNom,
  409.                     $coPrenom,
  410.                     $user->getEntreprise(),
  411.                     $currentProspectId,
  412.                     $currentCoNom,
  413.                     $currentCoPrenom
  414.                 );
  415.                 if ($existingCo) {
  416.                     $errors['co'] = [
  417.                         'id' => $existingCo->getId(),
  418.                         'nom' => $existingCo->getCoEmprunteurNom(),
  419.                         'prenom' => $existingCo->getCoEmprunteurPrenom(),
  420.                         'email' => $existingCo->getCoEmprunteurEmail(),
  421.                         'dateCreation' => $existingCo->getDateheure() ? $existingCo->getDateheure()->format('d/m/Y H:i') : null,
  422.                         'auteur' => $existingCo->getAuteur() ? $existingCo->getAuteur()->getNomEtPrenom() : null,
  423.                     ];
  424.                 }
  425.             }
  426.             // Si aucun problème détecté
  427.             if (empty($errors)) {
  428.                 return $this->json([
  429.                     'exists' => false,
  430.                     'message' => 'Aucun doublon détecté'
  431.                 ]);
  432.             }
  433.             // Sinon renvoyer les deux erreurs potentielles
  434.             return $this->json([
  435.                 'exists' => true,
  436.                 'blocked' => true,
  437.                 'errors' => $errors
  438.             ]);
  439.         } catch (\Exception $e) {
  440.             return $this->json([
  441.                 'exists' => false,
  442.                 'error' => 'Erreur lors de la vérification des doublons',
  443.                 'exception' => $e
  444.             ], 500);
  445.         }
  446.     }
  447.     /**
  448.      * @Route("/programme/check-duplicate", name="ajax_programme_check_duplicate")
  449.      */
  450.     public function checkProgrammeDuplicate(Request $requestProgrammeRepository $programmeRepository): JsonResponse
  451.     {
  452.         $nom        trim((string) $request->query->get('nom'''));
  453.         $promoteur  trim((string) $request->query->get('promoteur'''));
  454.         $currentId  $request->query->get('currentId');
  455.         if ($nom === '' || \strlen($nom) < 2) {
  456.             return $this->json([
  457.                 'exists'  => false,
  458.                 'message' => 'Nom requis (≥ 2 caractères)',
  459.             ]);
  460.         }
  461.         $user $this->getUser();
  462.         if (!$user instanceof Utilisateur || !$user->getEntreprise()) {
  463.             return $this->json([
  464.                 'exists' => false,
  465.                 'error'  => 'Utilisateur non authentifié ou entreprise non définie',
  466.             ]);
  467.         }
  468.         try {
  469.             $existing $programmeRepository->findExistingProgrammeByNomPromoteur(
  470.                 $nom,
  471.                 $promoteur !== '' $promoteur null,
  472.                 $user->getEntreprise(),
  473.                 $currentId ? (int) $currentId null
  474.             );
  475.             if ($existing) {
  476.                 return $this->json([
  477.                     'exists'   => true,
  478.                     'blocked'  => true,
  479.                     'message'  => 'Un programme avec ce nom (et promoteur si renseigné) existe déjà',
  480.                     'programme' => [
  481.                         'id'        => $existing->getId(),
  482.                         'nom'       => $existing->getNom(),
  483.                         'promoteur' => $existing->getPromoteur(),
  484.                         'ville'     => $existing->getVille(),
  485.                     ],
  486.                 ]);
  487.             }
  488.             return $this->json([
  489.                 'exists'  => false,
  490.                 'message' => 'Aucun doublon détecté',
  491.             ]);
  492.         } catch (\Throwable $e) {
  493.             return $this->json([
  494.                 'exists' => false,
  495.                 'error'  => 'Erreur lors de la vérification des doublons',
  496.             ], 500);
  497.         }
  498.     }
  499.     /**
  500.      * @Route("/utilisateur/{id}/historique/list", name="ajax_user_histo_list", methods={"GET"})
  501.      */
  502.     public function historiqueList(
  503.         Utilisateur $id,
  504.         Request $request,
  505.         HistoriqueUtilisateurRepository $repo
  506.     ): JsonResponse {
  507.         $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  508.         $action  $request->query->get('action') ?: null;
  509.         $fromStr $request->query->get('from') ?: null;
  510.         $toStr   $request->query->get('to') ?: null;
  511.         $page    max(1, (int) $request->query->get('page'1));
  512.         $perPage max(1min(200, (int) $request->query->get('perPage'25)));
  513.         $offset  = ($page 1) * $perPage;
  514.         $from $fromStr ? new \DateTimeImmutable($fromStr ' 00:00:00') : null;
  515.         $to   $toStr   ? new \DateTimeImmutable($toStr   ' 23:59:59') : null;
  516.         $total $repo->countByFilters($id$action$from$to);
  517.         $rows  $repo->findByFilters($id$action$from$to$perPage$offset);
  518.         $items array_map(static function (HistoriqueUtilisateur $h) {
  519.             return [
  520.                 'id'         => $h->getId(),
  521.                 'createdAt'  => $h->getCreatedAt()->format('d/m/Y H:i'),
  522.                 'action'     => $h->getAction(),
  523.                 'action_label' => HistoriqueUtilisateur::labelFor($h->getAction()),
  524.                 'details'    => $h->getDetails(),
  525.             ];
  526.         }, $rows);
  527.         $pages   = (int) ceil($total max(1$perPage));
  528.         $hasMore $page $pages;
  529.         return $this->json([
  530.             'items'   => $items,
  531.             'total'   => $total,
  532.             'page'    => $page,
  533.             'perPage' => $perPage,
  534.             'pages'   => $pages,
  535.             'hasMore' => $hasMore,
  536.         ]);
  537.     }
  538.     /**
  539.      * @Route("/utilisateur/{id}/historique/purge", name="ajax_user_historique_purge", methods={"POST"})
  540.      */
  541.     public function purgeHistorique(
  542.         Utilisateur $user,
  543.         HistoriqueUtilisateurRepository $repo,
  544.         EntityManagerInterface $em
  545.     ): JsonResponse {
  546.         if (
  547.             !$this->isGranted('ROLE_DIRECTEUR')
  548.             && !$this->isGranted('ROLE_ADMIN')
  549.             && !$this->isGranted('ROLE_SUPERADMIN')
  550.         ) {
  551.             throw $this->createAccessDeniedException();
  552.         }
  553.         $count $repo->purgeByUser($user);
  554.         $em->flush();
  555.         return $this->json(['purged' => (int) $count]);
  556.     }
  557.     /**
  558.      * @Route("/historique/click-a-traiter", name="ajax_historique_click_a_traiter", methods={"POST"})
  559.      */
  560.     public function clickATraiter(
  561.         Request $request,
  562.         \App\Repository\HistoriqueUtilisateurRepository $repo,
  563.         \Doctrine\ORM\EntityManagerInterface $em,
  564.         \App\Repository\ProspectRepository $prospectRepository
  565.     ): \Symfony\Component\HttpFoundation\JsonResponse {
  566.         try {
  567.             $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  568.             /** @var \App\Entity\Utilisateur $user */
  569.             $user $this->getUser();
  570.             $prospectId = (int) $request->request->get('prospectId'0);
  571.             if ($prospectId <= 0) {
  572.                 return $this->json(['ok' => false'error' => 'prospectId manquant'], 400);
  573.             }
  574.             $prospect $prospectRepository->find($prospectId);
  575.             $email $prospect $prospect->getEmprunteurEmail() : null;
  576.             // MAJ dateCliqueATraiter uniquement si le prospect existe et est en statut "atraiter"
  577.             if ($prospect && $prospect->getStatut() === 'atraiter') {
  578.                 $prospect->setDateCliqueATraiter(new \DateTimeImmutable());
  579.             }
  580.             $details sprintf(
  581.                 'Clic liste A TRAITER sur prospect ID %d%s',
  582.                 $prospectId,
  583.                 $email sprintf(' (%s)'$email) : ''
  584.             );
  585.             $repo->log(
  586.                 $user,
  587.                 \App\Entity\HistoriqueUtilisateur::ACTION_CLICK_A_TRAITER,
  588.                 $details,
  589.                 'prospect',
  590.                 $prospectId
  591.             );
  592.             $em->flush();
  593.             return $this->json(['ok' => true]);
  594.         } catch (\Throwable $e) {
  595.             return $this->json([
  596.                 'ok'    => false,
  597.                 'error' => $e->getMessage(),
  598.             ], 500);
  599.         }
  600.     }
  601. }