src/Controller/TasksController.php line 1866

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Litige;
  4. use App\Entity\LitigeStatusHistory;
  5. use App\Entity\Signature;
  6. use App\Event\AddTaskCommentEvent;
  7. use App\Helpers\JwtHelper;
  8. use App\Repository\CarriersRepository;
  9. use App\Repository\CompanysRepository;
  10. use App\Repository\DriversRepository;
  11. use App\Repository\EntrepriseAdresseHistoryRepository;
  12. use App\Repository\GoodsRepository;
  13. use App\Repository\LitigeRepository;
  14. use App\Repository\RefCountryRepository;
  15. use App\Repository\RefStatusRepository;
  16. use App\Repository\SignatureRepository;
  17. use App\Repository\TaskCommentRepository;
  18. use App\Repository\TaskDriverRepository;
  19. use App\Repository\TaskRepository;
  20. use App\Repository\TasksStatusHistoryRepository;
  21. use App\Repository\TaskTrackingRepository;
  22. use App\Repository\TaskVehiculeRepository;
  23. use App\Repository\TourneeRepository;
  24. use App\Repository\TourneeTaskRepository;
  25. use App\Repository\UserRepository;
  26. use App\Repository\VehiculesRepository;
  27. use App\Services\CompanyService;
  28. use App\Services\LitigeService;
  29. use App\Services\MailingAttempsFailedService;
  30. use App\Services\SendMailService;
  31. use App\Services\SignatureService;
  32. use App\Services\TasksService;
  33. use App\Services\UploadService;
  34. use DateTime;
  35. use Doctrine\Persistence\ManagerRegistry;
  36. use Dompdf\Dompdf;
  37. use Dompdf\Options;
  38. use FPDISigep;
  39. use Nelmio\ApiDocBundle\Annotation\Security;
  40. use OpenApi\Annotations as OA;
  41. use Psr\Log\LoggerInterface;
  42. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  43. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  44. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  45. use Symfony\Component\HttpFoundation\File\UploadedFile;
  46. use Symfony\Component\HttpFoundation\JsonResponse;
  47. use Symfony\Component\HttpFoundation\Request;
  48. use Symfony\Component\HttpFoundation\Response;
  49. use Symfony\Component\Mailer\MailerInterface;
  50. use Symfony\Component\Mime\Address;
  51. use Symfony\Component\Routing\Annotation\Route;
  52. use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
  53. use App\Services\PdfGeneratorService;
  54. use Doctrine\ORM\EntityManagerInterface;
  55. class TasksController extends AbstractController
  56. {
  57.     private $mailer;
  58.     private $_tasksService;
  59.     private $_uploadService;
  60.     private $_companyService;
  61.     private $_taskRepository;
  62.     private $_refStatusRepository;
  63.     private $_userRepository;
  64.     private $_signatureRepository;
  65.     private $_taskDriverRepository;
  66.     private $_driversRepository;
  67.     private $_taskVehiculeRepository;
  68.     private $_carriersRepository;
  69.     private $_companysRepository;
  70.     private $_refCountryRepository;
  71.     private $_vehiculeRepository;
  72.     private $_tokenGenerator;
  73.     private $_signatureService;
  74.     private $_sendMailService;
  75.     private $_taskStatusHistoryRepository;
  76.     private $_goodsRepository;
  77.     private $_entrepriseAdresseHistoryRepository;
  78.     private $_taskCommentRepository;
  79.     private $_doctrine;
  80.     private $_dispatcher;
  81.     private $_taskTrakingRepository;
  82.     private $_litigeRepository;
  83.     private $_litigeService;
  84.     private $logger;
  85.     private $_mailingAttempsFailedService;
  86.     private $_tourneeRepository;
  87.     private $_tourneeTaskRepository;
  88.     private $jwtHelper;
  89.     private $_params;
  90.     private $_pdfGeneratorService;
  91.     public function __construct(
  92.         TasksService                       $tasksService,
  93.         CompanyService                     $companyService,
  94.         UploadService                      $uploadService,
  95.         TaskRepository                     $taskRepository,
  96.         RefStatusRepository                $refStatusRepository,
  97.         UserRepository                     $userRepository,
  98.         SignatureRepository                $signatureRepository,
  99.         TaskDriverRepository               $taskDriverRepository,
  100.         DriversRepository                  $driversRepository,
  101.         TaskVehiculeRepository             $taskVehiculeRepository,
  102.         CarriersRepository                 $carriersRepository,
  103.         CompanysRepository                 $companysRepository,
  104.         RefCountryRepository               $refCountryRepository,
  105.         TokenGeneratorInterface            $tokenGenerator,
  106.         SignatureService                   $signatureService,
  107.         SendMailService                    $sendMailService,
  108.         VehiculesRepository                $vehiculesRepository,
  109.         TasksStatusHistoryRepository       $tasksStatusHistoryRepository,
  110.         GoodsRepository                    $goodsRepository,
  111.         EntrepriseAdresseHistoryRepository $entrepriseAdresseHistoryRepository,
  112.         TaskCommentRepository              $taskCommentRepository,
  113.         MailerInterface                    $mailer,
  114.         ManagerRegistry                    $doctrine,
  115.         EventDispatcherInterface           $dispatcher,
  116.         TaskTrackingRepository             $trakingRepository,
  117.         LitigeRepository                   $litigeRepository,
  118.         LitigeService                      $litigeService,
  119.         LoggerInterface                    $logger,
  120.         MailingAttempsFailedService        $mailingAttempsFailedService,
  121.         TourneeRepository                  $tourneeRepository,
  122.         TourneeTaskRepository              $tourneeTaskRepository,
  123.         JwtHelper                          $jwtHelper,
  124.         ParameterBagInterface              $params,
  125.         PdfGeneratorService                $pdfGeneratorService
  126.     )
  127.     {
  128.         $this->_tasksService = $tasksService;
  129.         $this->_companyService = $companyService;
  130.         $this->_uploadService = $uploadService;
  131.         $this->_taskRepository = $taskRepository;
  132.         $this->_refStatusRepository = $refStatusRepository;
  133.         $this->_userRepository = $userRepository;
  134.         $this->_signatureRepository = $signatureRepository;
  135.         $this->_taskDriverRepository = $taskDriverRepository;
  136.         $this->_driversRepository = $driversRepository;
  137.         $this->_taskVehiculeRepository = $taskVehiculeRepository;
  138.         $this->_carriersRepository = $carriersRepository;
  139.         $this->_companysRepository = $companysRepository;
  140.         $this->_refCountryRepository = $refCountryRepository;
  141.         $this->_signatureService = $signatureService;
  142.         $this->_sendMailService = $sendMailService;
  143.         $this->_tokenGenerator = $tokenGenerator;
  144.         $this->_vehiculeRepository = $vehiculesRepository;
  145.         $this->_taskStatusHistoryRepository = $tasksStatusHistoryRepository;
  146.         $this->_goodsRepository = $goodsRepository;
  147.         $this->_entrepriseAdresseHistoryRepository = $entrepriseAdresseHistoryRepository;
  148.         $this->_taskCommentRepository = $taskCommentRepository;
  149.         $this->_doctrine = $doctrine;
  150.         $this->_dispatcher = $dispatcher;
  151.         $this->mailer = $mailer;
  152.         $this->_taskTrakingRepository = $trakingRepository;
  153.         $this->_litigeRepository = $litigeRepository;
  154.         $this->_litigeService = $litigeService;
  155.         $this->logger = $logger;
  156.         $this->_mailingAttempsFailedService = $mailingAttempsFailedService;
  157.         $this->_tourneeRepository = $tourneeRepository;
  158.         $this->_tourneeTaskRepository = $tourneeTaskRepository;
  159.         $this->jwtHelper = $jwtHelper;
  160.         $this->_params = $params;
  161.         $this->_pdfGeneratorService = $pdfGeneratorService;
  162.     }
  163.     private function canFinalizeSignature($task, Signature $signatureObj, string $typeSignature): bool
  164.     {
  165.         $prefix = ($typeSignature === 'expediteur') ? 'Signature du remettant' : 'Signature du destinataire';
  166.         $existingComment = $this->_taskCommentRepository->findSignatureCommentByTaskAndPrefix($task->getId(), $prefix);
  167.         // Si la signature a déjà été finalisée avec son événement d'historique, on verrouille toute modification
  168.         if ($existingComment !== null) {
  169.             return false;
  170.         }
  171.         $lastStatus = $this->_taskStatusHistoryRepository->findStatusByTaskId($task->getId());
  172.         if (empty($lastStatus)) {
  173.             return false;
  174.         }
  175.         $slug = $lastStatus[0]['slug'];
  176.         if ($slug === 'started') {
  177.             return true;
  178.         }
  179.         if ($slug === 'finished' && isset($lastStatus[0]['date']) && $lastStatus[0]['date'] instanceof \DateTimeInterface) {
  180.             // Si la signature avait déjà été modifiée avant (signed_at != signed_driver_at) mais sans événement, ou si elle vient d'être initiée,
  181.             // on autorise dans un délai maximal de 15 minutes (900 secondes) après la clôture de la mission.
  182.             $now = new DateTime();
  183.             $diffInSeconds = $now->getTimestamp() - $lastStatus[0]['date']->getTimestamp();
  184.             if ($diffInSeconds <= 900) {
  185.                 return true;
  186.             }
  187.         }
  188.         return false;
  189.     }
  190.     private function dispatchSignatureCommentIfNotExists($task, Signature $signatureObj, string $typeSignature): void
  191.     {
  192.         $prefix = ($typeSignature === 'expediteur') ? 'Signature du remettant' : 'Signature du destinataire';
  193.         $existingComment = $this->_taskCommentRepository->findSignatureCommentByTaskAndPrefix($task->getId(), $prefix);
  194.         if ($existingComment === null) {
  195.             $nom_contact = $signatureObj->getNom();
  196.             $datetime = $signatureObj->getSignedAt() ?: new DateTime();
  197.             $date_time = $datetime->format('d/m/Y à H:i');
  198.             $message = "$prefix le $date_time par $nom_contact.";
  199.             $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, null, $message, $task);
  200.             $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  201.         }
  202.     }
  203.     #[Route('/api/delete/planned-at/{id}/{userId}', name: 'app_delete_planned_at', methods: ['GET', "POST"])]
  204.     public function delete_planned_at(Request $request, $id, $userId)
  205.     {
  206.         $auth = $this->jwtHelper->verifyJwt($request, []);
  207.         if (is_string($auth)) {
  208.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  209.         }
  210.         $task = $this->_taskRepository->find($id);
  211.         $status_ = $this->_refStatusRepository->findStatusBy("mission", "prog_in_progress");
  212.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  213.         $this->_tasksService->updatePlannedAt($task, null);
  214.         $this->_tasksService->addStatusTaskHistory($task, $status);
  215.         // événement
  216.         $user = $this->_userRepository->find($userId);
  217.         $message = "La date de planification est supprimée.";
  218.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  219.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  220.         return new JsonResponse(['message' => "Date de planification supprimée avec succès.", 'status' => 200], Response::HTTP_OK);
  221.     }
  222.     #[Route('/api/signatures/{mission_id}', name: 'app_signatures_mission', methods: ['GET', "POST"])]
  223.     public function signatures_mission(Request $request, $mission_id)
  224.     {
  225.         $auth = $this->jwtHelper->verifyJwt($request, []);
  226.         if (is_string($auth)) {
  227.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  228.         }
  229.         $signatures = $this->_signatureRepository->findSigByTask($mission_id);
  230.         $arrToReturn = [];
  231.         switch (count($signatures)) {
  232.             case 1 :
  233.                 {
  234.                     $arrToReturn[$signatures[0]['type_signature']] = $signatures;
  235.                 }
  236.                 break;
  237.             case 2 :
  238.                 {
  239.                     foreach ($signatures as $signature) {
  240.                         $arrToReturn[$signature['type_signature']][] = $signature;
  241.                     }
  242.                 }
  243.                 break;
  244.         }
  245.         return new JsonResponse(['signatures' => $arrToReturn, 'length' => count($arrToReturn), 'status' => 200], Response::HTTP_OK);
  246.     }
  247.     #[Route('/api/change/driver/mission/{id}', name: 'app_change_driver_mission', methods: ['POST'])]
  248.     public function change_driver_mission(Request $request, $id)
  249.     {
  250.         $auth = $this->jwtHelper->verifyJwt($request, []);
  251.         if (is_string($auth)) {
  252.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  253.         }
  254.         //recuperation du data from request.
  255.         $data = json_decode($request->getContent(), true);
  256.         
  257.         $task = $this->_taskRepository->find($id);
  258.         
  259.         // service de modification global des chauffeurs.
  260.         $this->_tasksService->changeDriversOfMission($data, $task);
  261.         
  262.         $user = $this->_userRepository->find($data['user_id']);
  263.         // événement
  264.         $message = "Chauffeurs modifiés.";
  265.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  266.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  267.         return new JsonResponse(['message' => "Changement fait avec succès!", 'status' => 200], Response::HTTP_OK);
  268.     }
  269.     #[Route('/api/change/vehicule/mission/{id}', name: 'app_change_vehicule_mission', methods: ['POST'])]
  270.     public function change_vehicule_mission(Request $request, $id, \Psr\Log\LoggerInterface $logger)
  271.     {
  272.         $auth = $this->jwtHelper->verifyJwt($request, []);
  273.         if (is_string($auth)) {
  274.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  275.         }
  276.         //recuperation du data from request.
  277.         $data = json_decode($request->getContent(), true);
  278.         $logger->error('PAYLOAD RECEIVED FOR CHANGE VEHICLE: ' . json_encode($data));
  279.         $task = $this->_taskRepository->find($id);
  280.         // service de modification global des véhicules.
  281.         $this->_tasksService->changeVehiculesOfMission($data, $task);
  282.         
  283.         $user = $this->_userRepository->find($data['user_id']);
  284.         // événement
  285.         $message = "Véhicules modifiés.";
  286.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  287.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  288.         return new JsonResponse(['message' => "Changement fait avec succès!", 'status' => 200], Response::HTTP_OK);
  289.     }
  290.     #[Route('/api/change/company/mission/{id}/{type_company}', name: 'app_change_company_mission', methods: ['POST'])]
  291.     public function change_company_mission(Request $request, $id, $type_company)
  292.     {
  293.         $auth = $this->jwtHelper->verifyJwt($request, []);
  294.         if (is_string($auth)) {
  295.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  296.         }
  297.         //recuperation du data from request.
  298.         $data = json_decode($request->getContent(), true);
  299.         // get carrier of connected user
  300.         $user = $this->_userRepository->find($data['user_id']);
  301.         $data['carrier'] = $this->_carriersRepository->find($user->getCarriers());;
  302.         // get mission by id
  303.         $task = $this->_taskRepository->find($id);
  304.         // get company by expediteur_id
  305.         if (
  306.             (isset($data['expediteur_ou_destinataire_id'])) && ($data['expediteur_ou_destinataire_id'] == "undefined") ||
  307.             (isset($data['expediteur_ou_destinataire_id'])) && ($data['expediteur_ou_destinataire_id'] == 0)
  308.         ) {
  309.             $data['type'] = "2";
  310.             $data['country'] = $this->_refCountryRepository->find($data['ref_country_id_exp']);
  311.             $lat_long = $this->_companyService->getLatLongFromAddress($data['formattedAddress']);
  312.             $map = explode(',', $lat_long);
  313.             $mapLat = $map[0];
  314.             $mapLong = $map[1];
  315.             $data['lat'] = $mapLat;
  316.             $data['long'] = $mapLong;
  317.         } else {
  318.             $expediteur_ou_destinataire = $this->_companysRepository->find($data['expediteur_ou_destinataire_id']);
  319.             $data['expediteur_ou_destinataire'] = $expediteur_ou_destinataire;
  320.         }
  321.         // service d'ajout.
  322.         $this->_tasksService->changeComapnyOfMission($data, $task, $type_company);
  323.         switch ($type_company) {
  324.             case "expediteur":
  325.                 $message = "L'expéditeur est changé.";
  326.                 break;
  327.             case "destinataire":
  328.                 $message = "Le destinataire est changé.";
  329.                 break;
  330.         }
  331.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  332.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  333.         return new JsonResponse(['message' => "Changement lieu expéditeur fait avec succès !", 'status' => 200], Response::HTTP_OK);
  334.     }
  335.     #[Route('/api/change/contractor/mission/{id}', name: 'app_change_contractor_mission', methods: ['POST'])]
  336.     public function change_contractor_mission(Request $request, $id)
  337.     {
  338.         $auth = $this->jwtHelper->verifyJwt($request, []);
  339.         if (is_string($auth)) {
  340.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  341.         }
  342.         //recuperation du data from request.
  343.         $data = json_decode($request->getContent(), true);
  344.         // get carrier of connected user
  345.         $user = $this->_userRepository->find($data['user_id']);
  346.         $data['carrier'] = $this->_carriersRepository->find($user->getCarriers());;
  347.         // get mission by id
  348.         $task = $this->_taskRepository->find($id);
  349.         // get company by donneur_id
  350.         if (
  351.             (isset($data['donneur_id'])) && ($data['donneur_id'] == "undefined") ||
  352.             (isset($data['donneur_id'])) && ($data['donneur_id'] == 0)
  353.         ) {
  354.             $data['type'] = "1";
  355.             $data['country'] = $this->_refCountryRepository->find($data['ref_country_id']);
  356.             $lat_long = $this->_companyService->getLatLongFromAddress($data['formattedAddress']);
  357.             $map = explode(',', $lat_long);
  358.             $mapLat = $map[0];
  359.             $mapLong = $map[1];
  360.             $data['lat'] = $mapLat;
  361.             $data['long'] = $mapLong;
  362.         } else {
  363.             $donneur = $this->_companysRepository->find($data['donneur_id']);
  364.             $data['donneur'] = $donneur;
  365.         }
  366.         $this->_tasksService->changeDonneurOfMission($data, $task);
  367.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, "Le donneur d'ordre est changé.", $task);
  368.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  369.         return new JsonResponse(['message' => "Changement du donneur fait avec succès !", 'status' => 200], Response::HTTP_OK);
  370.     }
  371.     #[Route('/api/upload/image/{id}/{carrierId}', name: 'app_upload_image_ionic')]
  372.     public function upload_image_ionic($id, $carrierId)
  373.     {
  374.         $uploadDir = "uploads/";
  375.         $uploadedFile = $uploadDir . basename($_FILES['image_0']['name']);
  376.         $uploaded = move_uploaded_file($_FILES['image_0']['tmp_name'], $uploadedFile);
  377.         $uploadedFileObj = new UploadedFile(
  378.             $uploadDir . $_FILES['image_0']['name'],
  379.             $_FILES['image_0']['name'],
  380.             $_FILES['image_0']['type'],
  381.             $_FILES['image_0']['error'],
  382.             true
  383.         );
  384.         try {
  385.             $uploadedFileObj->move($uploadDir, $_FILES['image_0']['name']);
  386.             $data['litige'] = $this->_litigeRepository->findOneBy(['id' => $id]);
  387.             $data['carrier'] = $this->_carriersRepository->findOneBy(['id' => $carrierId]);
  388.             $this->_uploadService->uploadFile($uploadedFileObj, $data);
  389.         } catch (\Exception $e) {
  390.             die('Error moving file: ' . $e->getMessage());
  391.         }
  392.         return new JsonResponse(['message' => "Upload fait avec succès !", 'status' => 200], Response::HTTP_OK);
  393.     }
  394.     #[Route('/api/upload/image/{goodId}', name: 'app_upload_image_good_ionic')]
  395.     public function upload_image_good_ionic($goodId)
  396.     {
  397.         $good = $this->_goodsRepository->findOneBy(['id' => $goodId]);
  398.         $data['good'] = $good;
  399.         $uploadDir = "uploads/";
  400.         $uploadedFile = $uploadDir . basename($_FILES['march_file']['name']);
  401.         $uploaded = move_uploaded_file($_FILES['march_file']['tmp_name'], $uploadedFile);
  402.         $uploadedFileObj = new UploadedFile(
  403.             $uploadDir . $_FILES['march_file']['name'],
  404.             $_FILES['march_file']['name'],
  405.             $_FILES['march_file']['type'],
  406.             $_FILES['march_file']['error'],
  407.             true
  408.         );
  409.         try {
  410.             $uploadedFileObj->move($uploadDir, $_FILES['march_file']['name']);
  411.             $this->_uploadService->uploadFile($uploadedFileObj, $data);
  412.         } catch (\Exception $e) {
  413.             die('Error moving file: ' . $e->getMessage());
  414.         }
  415.         return new JsonResponse(['message' => "Upload fait avec succès !", 'status' => 200], Response::HTTP_OK);
  416.     }
  417.     #[Route('/api/upload/{missionId}/annexes', name: 'upload_image_doc_ionic')]
  418.     public function upload_image_doc_ionic($missionId)
  419.     {
  420.         $this->logger->info("mission id : " . $missionId);
  421.         $this->logger->info("files : " . $_FILES);
  422.         $task = $this->_taskRepository->findOneBy(['id' => $missionId]);
  423.         $data['task'] = $task;
  424.         $uploadDir = "uploads/";
  425.         $uploadedFile = $uploadDir . basename($_FILES['docs_annex']['name']);
  426.         $uploaded = move_uploaded_file($_FILES['docs_annex']['tmp_name'], $uploadedFile);
  427.         $uploadedFileObj = new UploadedFile(
  428.             $uploadDir . $_FILES['docs_annex']['name'],
  429.             $_FILES['docs_annex']['name'],
  430.             $_FILES['docs_annex']['type'],
  431.             $_FILES['docs_annex']['error'],
  432.             true
  433.         );
  434.         try {
  435.             $uploadedFileObj->move($uploadDir, $_FILES['docs_annex']['name']);
  436.             $this->_uploadService->uploadFile($uploadedFileObj, $data);
  437.         } catch (\Exception $e) {
  438.             die('Error moving file: ' . $e->getMessage());
  439.         }
  440.         return new JsonResponse(['message' => "Upload fait avec succès !", 'status' => 200], Response::HTTP_OK);
  441.     }
  442.     #[Route('/api/upload/{missionId}/formalities', name: 'upload_image_form_douan_ionic')]
  443.     public function upload_image_form_douan_ionic($missionId)
  444.     {
  445.         $task = $this->_taskRepository->findOneBy(['id' => $missionId]);
  446.         $data['task'] = $task;
  447.         $uploadDir = "uploads/";
  448.         $uploadedFile = $uploadDir . basename($_FILES['form_douan']['name']);
  449.         $uploaded = move_uploaded_file($_FILES['form_douan']['tmp_name'], $uploadedFile);
  450.         $uploadedFileObj = new UploadedFile(
  451.             $uploadDir . $_FILES['form_douan']['name'],
  452.             $_FILES['form_douan']['name'],
  453.             $_FILES['form_douan']['type'],
  454.             $_FILES['form_douan']['error'],
  455.             true
  456.         );
  457.         try {
  458.             $uploadedFileObj->move($uploadDir, $_FILES['form_douan']['name']);
  459.             $this->_uploadService->uploadFile($uploadedFileObj, $data);
  460.         } catch (\Exception $e) {
  461.             die('Error moving file: ' . $e->getMessage());
  462.         }
  463.         return new JsonResponse(['message' => "Upload fait avec succès !", 'status' => 200], Response::HTTP_OK);
  464.     }
  465.     #[Route('/api/add/good/{taskId}', name: 'app_add_goods_ionic')]
  466.     public function add_good_ionic(Request $request, $taskId)
  467.     {
  468.         $auth = $this->jwtHelper->verifyJwt($request, []);
  469.         if (is_string($auth)) {
  470.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  471.         }
  472.         // Récupération des données de la requête
  473.         $data = json_decode($request->getContent(), true);
  474. //        $data = $request->request->all();
  475.         $task = $this->_taskRepository->findOneBy(['id' => $taskId]);
  476.         $good = $this->_tasksService->addGood($task, $data);
  477.         return new JsonResponse(['good_id' => $good->getId(), 'status' => 200], Response::HTTP_OK);
  478.     }
  479.     #[Route('/api/add/signature-exp', name: 'app_add_signature', methods: ['POST'])]
  480.     public function add_signature(Request $request): JsonResponse
  481.     {
  482.         $auth = $this->jwtHelper->verifyJwt($request, []);
  483.         if (is_string($auth)) {
  484.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  485.         }
  486.         // Récupération des données
  487.         $user = $this->_userRepository->findOneBy(['id' => $request->request->get('user_id')]);
  488.         // Initialisation du tableau de données pour le service
  489.         $data = [];
  490.         $data['task'] = $this->_taskRepository->findOneBy(['id' => $request->request->get('task_id')]);
  491.         $data['expediteur'] = $this->_companysRepository->findOneBy(["id" => $request->request->get('id_exp')]);
  492.         // Mapping des champs du formulaire
  493.         $data['arrivee_a_exp'] = $request->request->get('arrivee_a_exp');
  494.         $data['depart_a_exp'] = $request->request->get('depart_a_exp');
  495.         $data['prestations_annexes_exp'] = $request->request->get('prestations_annexes_exp');
  496.         $data['reserves_eventuelles_exp'] = $request->request->get('reserves_eventuelles_exp');
  497.         $data['emailExp'] = $request->request->get('emailExp');
  498.         $data['nom_contactExp'] = $request->request->get('nom_contactExp');
  499.         $data['driver'] = $user->getDriver();
  500.         $data['carrier'] = $user->getCarriers();
  501.         $data["typeLitige"] = "chauffeur_expediteur";
  502.         $data["typeSignature"] = "expediteur"; // Important pour le filtre
  503.         $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  504.         if ($last_status_task[0]['slug'] == "started") {
  505.             // 1. Recherche de l'existant
  506.             $existingSignature = $this->_signatureRepository->findOneBy([
  507.                 'task' => $data['task'],
  508.                 'type_signature' => 'expediteur'
  509.             ]);
  510.             if ($existingSignature) {
  511.                 // Si la signature du contact est déjà actée (différente de l'init chauffeur), on ne touche à rien.
  512.                 $signedAt = $existingSignature->getSignedAt();
  513.                 $signedDriverAt = $existingSignature->getSignedDriverAt();
  514.                 if ($signedAt !== null && $signedDriverAt !== null && $signedAt != $signedDriverAt) {
  515.                     // La signature est finalisée par le client. On renvoie l'ID existant sans update.
  516.                     return new JsonResponse([
  517.                         'task_id' => $data['task']->getId(),
  518.                         'signature_id' => $existingSignature->getId(),
  519.                         'status' => 200,
  520.                         'message' => 'Signature already finalized'
  521.                     ], Response::HTTP_OK);
  522.                 }
  523.                 $signature = $existingSignature;
  524.             } else {
  525.                 // CAS 2 : Elle n'existe pas, on en crée une nouvelle
  526.                 $signature = new Signature();
  527.             }
  528.             // 2. On appelle le service qui va hydrater l'objet (nouveau ou existant) et flush
  529.             $this->_signatureService->addSignature($signature, $data);
  530.             // -------------------------------------------------------
  531.             // Gestion du Litige
  532.             $litigeId = null;
  533.             if(isset($data['reserves_eventuelles_exp']) && $data['reserves_eventuelles_exp']) {
  534.                 // On pourrait appliquer la même logique "Find or Create" pour le litige ici si nécessaire
  535.                 // Pour l'instant on garde ta logique de création
  536.                 $litigeInstance = new Litige();
  537.                 $this->_litigeService->addLitige($litigeInstance, $data);
  538.                 $litigeId = $litigeInstance->getId();
  539.                 $litigeStatusHistory = new LitigeStatusHistory();
  540.                 $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  541.                 if (!empty($status)) {
  542.                     $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  543.                     $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litigeInstance, $statusObj);
  544.                 }
  545.             }
  546.             // Construction de la réponse
  547.             $responseArray = [
  548.                 'task_id' => $data['task']->getId(),
  549.                 'signature_id' => $signature->getId(), // On renvoie l'ID de la signature (utile pour le front)
  550.                 'status' => 200
  551.             ];
  552.             if ($litigeId) {
  553.                 $responseArray['litige_id'] = $litigeId;
  554.             }
  555.             return new JsonResponse($responseArray, Response::HTTP_OK);
  556.         }
  557.         return new JsonResponse(['message' => 'Task not started', 'status' => 400], Response::HTTP_BAD_REQUEST);
  558.     }
  559.     #[Route('/api/add/signature-dest', name: 'app_add_signature_dest', methods: ['POST'])]
  560.     public function add_signature_dest(Request $request): JsonResponse
  561.     {
  562.         $auth = $this->jwtHelper->verifyJwt($request, []);
  563.         if (is_string($auth)) {
  564.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  565.         }
  566.         // Récupération user et entités liées
  567.         $user = $this->_userRepository->findOneBy(['id' => $request->request->get('user_id')]);
  568.         $data = [];
  569.         $data['driver'] = $user->getDriver();
  570.         $data['carrier'] = $user->getCarriers();
  571.         $data['task'] = $this->_taskRepository->find(['id' => $request->request->get('task_id')]);
  572.         $data['destinataire'] = $this->_companysRepository->findOneBy(["id" => $request->request->get('id_dest')]);
  573.         // Configuration type
  574.         $data["typeSignature"] = "destinataire";
  575.         $data["typeLitige"] = "chauffeur_destinataire";
  576.         // Mapping des champs
  577.         $data['arrivee_a_dest'] = $request->request->get('arrivee_a_dest');
  578.         $data['depart_a_dest'] = $request->request->get('depart_a_dest');
  579.         $data['prestations_annexes_dest'] = $request->request->get('prestations_annexes_dest');
  580.         $data['reserves_eventuelles_dest'] = $request->request->get('reserves_eventuelles_dest');
  581.         $data['emailDest'] = $request->request->get('emailDest');
  582.         $data['nom_contactDest'] = $request->request->get('nom_contactDest');
  583.         $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  584.         if ($last_status_task[0]['slug'] == "started") {
  585.             // --- CORRECTION : LOGIQUE UPSERT (Find Or Create) ---
  586.             // 1. Recherche d'une signature existante pour ce destinataire sur cette tâche
  587.             $existingSignature = $this->_signatureRepository->findOneBy([
  588.                 'task' => $data['task'],
  589.                 'type_signature' => 'destinataire'
  590.             ]);
  591.             if ($existingSignature) {
  592.                 $signedAt = $existingSignature->getSignedAt();
  593.                 $signedDriverAt = $existingSignature->getSignedDriverAt();
  594.                 if ($signedAt !== null && $signedDriverAt !== null && $signedAt != $signedDriverAt) {
  595.                     return new JsonResponse([
  596.                         'task_id' => $data['task']->getId(),
  597.                         'signature_id' => $existingSignature->getId(),
  598.                         'status' => 200,
  599.                         'message' => 'Signature already finalized'
  600.                     ], Response::HTTP_OK);
  601.                 }
  602.                 $signature = $existingSignature;
  603.             } else {
  604.                 // INSERT : On crée un nouvel objet
  605.                 $signature = new Signature();
  606.             }
  607.             // 2. Hydratation via le service (persist/flush inclus dans le service)
  608.             $this->_signatureService->addSignature($signature, $data);
  609.             // ----------------------------------------------------
  610.             // Gestion du litige ( inchangée )
  611.             $litigeId = null;
  612.             if(isset($data['reserves_eventuelles_dest']) && $data['reserves_eventuelles_dest']) {
  613.                 $litigeInstance = new Litige();
  614.                 $this->_litigeService->addLitige($litigeInstance, $data);
  615.                 $litigeId = $litigeInstance->getId();
  616.                 $litigeStatusHistory = new LitigeStatusHistory();
  617.                 $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  618.                 if (!empty($status)) {
  619.                     $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  620.                     $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litigeInstance, $statusObj);
  621.                 }
  622.             }
  623.             // Construction de la réponse
  624.             $responseArray = [
  625.                 'task_id' => $data['task']->getId(),
  626.                 'signature_id' => $signature->getId(), // ID stable retourné
  627.                 'status' => 200
  628.             ];
  629.             if ($litigeId) {
  630.                 $responseArray['litige_id'] = $litigeId;
  631.             }
  632.             return new JsonResponse($responseArray, Response::HTTP_OK);
  633.         }
  634.         return new JsonResponse(['message' => 'Task not started', 'status' => 400], Response::HTTP_BAD_REQUEST);
  635.     }
  636.     #[Route('/api/litiges/{id}/status', name: 'change_litige_status', methods: ['POST'])]
  637.     public function changeLitigeStatus(int $id, Request $request): JsonResponse
  638.     {
  639.         $auth = $this->jwtHelper->verifyJwt($request, []);
  640.         if (is_string($auth)) {
  641.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  642.         }
  643.         // Lire et décoder le contenu de la requête
  644.         $content = json_decode($request->getContent(), true);
  645.         // Récupérer le litige par son ID
  646.         $litige = $this->_litigeRepository->findOneBy(['id' => $id]);
  647.         if (!$litige) {
  648.             return new JsonResponse(['message' => 'Litige not found'], 404);
  649.         }
  650.         $statusSlug = $content['statusSlug'] ?? null;
  651.         // Valider le statut slug
  652.         if (!$statusSlug) {
  653.             return new JsonResponse(['message' => 'Status slug is required'], 400);
  654.         }
  655.         // Récupérer le RefStatus par son slug
  656.         $refStatus = $this->_refStatusRepository->findOneBy(['slug' => $statusSlug]);
  657.         if (!$refStatus) {
  658.             return new JsonResponse(['message' => 'Invalid status slug'], 400);
  659.         }
  660.         $litigeStatusHistory = new LitigeStatusHistory();
  661.         $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litige, $refStatus);
  662.         // Retourner une réponse de succès
  663.         return new JsonResponse(['message' => 'Statut changé avec succès !']);
  664.     }
  665.     #[Route('/api/litiges/{carrierId}', name: 'api_litiges_details', methods: ['GET', "POST"])]
  666.     public function litiges(Request $request, int $carrierId): JsonResponse
  667.     {
  668.         $auth = $this->jwtHelper->verifyJwt($request, []);
  669.         if (is_string($auth)) {
  670.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  671.         }
  672.         $litiges = $this->_litigeRepository->findLitigesByCarrier($carrierId);
  673.         foreach ($litiges as &$litige) {
  674.             $litigeObj = $this->_litigeRepository->findOneBy(['id' => $litige['id']]);
  675.             $litige['path_image'] = ($litigeObj->getUploads() != null && !$litigeObj->getUploads()->isEmpty() ? $_SERVER['SERVER_NAME'] . $litigeObj->getUploads()->last()->getPath() : "");
  676.         }
  677.         unset($litige);
  678.         return $this->json($litiges);
  679.     }
  680.     // litiges dans le tableau de bord
  681.     #[Route('/api/litiges/resolus/{carrierId}', name: 'api_list_litiges_resolus', methods: ['GET', "POST"])]
  682.     public function litiges_resolus(Request $request, int $carrierId): JsonResponse
  683.     {
  684.         $auth = $this->jwtHelper->verifyJwt($request, []);
  685.         if (is_string($auth)) {
  686.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  687.         }
  688.         $litiges = $this->_litigeRepository->findResolvedLitigesByCarrier($carrierId, "ouvert");
  689.         foreach ($litiges as &$litige) {
  690.             $litigeObj = $this->_litigeRepository->findOneBy(['id' => $litige['id']]);
  691.             $litige['path_image'] = ($litigeObj->getUploads() != null && !$litigeObj->getUploads()->isEmpty() ? $_SERVER['SERVER_NAME'] . $litigeObj->getUploads()->last()->getPath() : "");
  692.         }
  693.         unset($litige);
  694.         return $this->json($litiges);
  695.     }
  696.     #[Route('/api/litiges/{carrierId}/{userId}', name: 'api_litiges_carrier_user', methods: ['GET', "POST"])]
  697.     public function litiges_mobile(Request $request, $carrierId, $userId): JsonResponse
  698.     {
  699.         $auth = $this->jwtHelper->verifyJwt($request, []);
  700.         if (is_string($auth)) {
  701.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  702.         }
  703.         $user = $this->_userRepository->findOneBy(['id' => $userId]);
  704.         $all_litiges = $this->_litigeRepository->findLitigesByCarrierAndDriver($carrierId, $user->getDriver()->getId());
  705.         $length = count($all_litiges);
  706.         $litigesGroupedByTask = [];
  707.         for ($i = 0; $i < $length; $i++) {
  708.             $litigeObj = $this->_litigeRepository->findOneBy(['id' => $all_litiges[$i]['id']]);
  709.             $currentTaskId = $all_litiges[$i]['taskId'];
  710.             $all_litiges[$i]['path_image'] = ($litigeObj->getUploads() != null && !$litigeObj->getUploads()->isEmpty() ? $_SERVER['SERVER_NAME'] . $litigeObj->getUploads()->last()->getPath() : "");
  711.             $litigesGroupedByTask[$currentTaskId][] = $all_litiges[$i];
  712.         }
  713.         return $this->json($litigesGroupedByTask);
  714.     }
  715.     #[Route('/api/add/result/signature-exp', name: 'app_add_signature_exp_result', methods: ['POST'])]
  716.     public function add_signature_exp_result(Request $request)
  717.     {
  718.         try {
  719.             $taskId = $request->request->get('task_id');
  720.             // Récupération sécurisée de la signature
  721.             $signature = $this->_signatureRepository->findSigByTaskAndType($taskId, "expediteur");
  722.             if (!$signature) {
  723.                 return new JsonResponse(['message' => "Signature introuvable", 'status' => 404], 404);
  724.             }
  725.             $signatureObj = $this->_signatureRepository->find(['id' => $signature[0]['id']]);
  726.             $task = $this->_taskRepository->find(['id' => $taskId]);
  727.             // 1. Nettoyage et typage des données GPS (Fix "null" string)
  728.             $data = $request->request->all();
  729.             $lat = $request->request->get('latitude');
  730.             $long = $request->request->get('longitude');
  731.             $data['latitude'] = ($lat && $lat !== 'null') ? (float)$lat : null;
  732.             $data['longitude'] = ($long && $long !== 'null') ? (float)$long : null;
  733.             file_put_contents(__DIR__ . '/../../var/log/mobile_payload.log', json_encode($data) . PHP_EOL, FILE_APPEND);
  734.             $this->logger->critical("DATA FROM MOBILE SIGNATURE EXP: " . json_encode($data));
  735.             $data['reserves_eventuelles_result_exp'] = $request->request->get('reserves_eventuelles_result_exp');
  736.             $data['carrier'] = $task->getCarrier();
  737.             $data['task'] = $task;
  738.             $data['typeLitige'] = "expediteur";
  739.             $data['expediteur'] = $this->_companysRepository->findOneBy(["id" => $task->getSender()->getId()]);
  740.             $data['driver'] = $this->_driversRepository->findOneBy(['id' => $signatureObj->getDriver()->getId()]);
  741.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  742.             if ($this->canFinalizeSignature($task, $signatureObj, "expediteur")) {
  743.                 // 2. Mise à jour GPS et Signature
  744.                 $this->_signatureService->updateSignatureLongLat($signatureObj, $data);
  745.                 $this->_signatureService->updateSignature($signatureObj, $data, "expediteur");
  746.                 // 3. Événement d'historique (immédiat et sans doublon)
  747.                 $this->dispatchSignatureCommentIfNotExists($task, $signatureObj, "expediteur");
  748.                 // 4. Régénération du PDF avec les données de signature à jour
  749.                 $pdfResult = null;
  750.                 try {
  751.                     $pdfResult = $this->_pdfGeneratorService->generateForMission($task, $task->getCarrier() ? $task->getCarrier()->getId() : null);
  752.                 } catch (\Exception $e) {
  753.                     $this->logger->error("Erreur génération PDF lors de signature EXP : " . $e->getMessage());
  754.                 }
  755.                 // --- FIX CRITIQUE USER PRINCIPAL ---
  756.                 $usersFound = $this->_userRepository->findUserByCarrierAndRole($task->getCarrier()->getId(), "ROLE_PRINCIPAL_USER");
  757.                 $principalUserArray = null;
  758.                 $principalUserObj = null;
  759.                 if (!empty($usersFound) && isset($usersFound[0])) {
  760.                     $principalUserArray = $usersFound[0];
  761.                     $principalUserObj = $this->_userRepository->findOneBy(['id' => $principalUserArray['id']]);
  762.                 } else {
  763.                     $this->logger->warning("Signature Exp: Aucun ROLE_PRINCIPAL_USER trouvé pour le carrier " . $task->getCarrier()->getId());
  764.                 }
  765.                 // 5. Gestion des réserves (Litige)
  766.                 if(!empty($data['reserves_eventuelles_result_exp'])){
  767.                     $litige = new Litige();
  768.                     $this->_litigeService->addLitige($litige, $data);
  769.                     $litigeStatusHistory = new LitigeStatusHistory();
  770.                     $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  771.                     $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  772.                     $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litige, $statusObj);
  773.                     $litigeObject = $this->_litigeRepository->findOneBy(['id' => $litige->getId()]);
  774.                     $data['litige'] = $litigeObject;
  775.                 }
  776.                 // 6. Gestion de l'Upload (SORTI du bloc réserves)
  777.                 $nbrFiles = (int)$request->request->get('nbr_files');
  778.                 if ($nbrFiles > 0) {
  779.                     for ($i = 0; $i < $nbrFiles; $i++) {
  780.                         $uploadedFile = $request->files->get('image_' . $i);
  781.                         if ($uploadedFile) {
  782.                             $useCarrierFolder = ($principalUserObj && $principalUserObj->getCarriers() != null);
  783.                             if ($useCarrierFolder) {
  784.                                 $this->_uploadService->uploadFileBlob($uploadedFile, $data['carrier'], $data);
  785.                             } else {
  786.                                 $this->_uploadService->uploadFileBlob($uploadedFile, null, $data);
  787.                             }
  788.                         }
  789.                     }
  790.                 }
  791.                 // 7. Envoi Email (Protégé par try/catch)
  792.                 try {
  793.                     switch ($task->getCmr()) {
  794.                         case "cmr":
  795.                             $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $signatureObj->getTask()->getId() . ".pdf";
  796.                             break;
  797.                         case "internationale":
  798.                             $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $signatureObj->getTask()->getId() . ".pdf";
  799.                             break;
  800.                     }
  801.                     $attach = null;
  802.                     if (isset($pathLV) && file_exists($pathLV)) {
  803.                         $attach = ["allow" => "yes", "file" => $pathLV];
  804.                     }
  805.                     $admin_emails = $this->_userRepository->findUserByCarrierAndRole(null, "ROLE_ADMIN_USER");
  806.                     $admins = [];
  807.                     foreach($admin_emails as $admin_email){ $admins[] = $admin_email['email']; }
  808.                     $support_mail_address = $this->_params->get('support_mail_address');
  809.                     $from_mail_address = $this->_params->get('from_mail_address');
  810.                     $context = [
  811.                         "url" => $request->request->get('url_infos_exp_dest'),
  812.                         "back_url" => $_ENV['BACK_URL'],
  813.                         "urlDocutransFr" => $_ENV['Docutrans_FR_URL'],
  814.                         "support_mail_address" => $support_mail_address
  815.                     ];
  816.                     // Construction de la liste des destinataires
  817.                     $recipients = [];
  818.                     if ($principalUserArray) {
  819.                         $recipients[] = $principalUserArray['email'];
  820.                     }
  821.                     if ($signatureObj->getEmail()) $recipients[] = $signatureObj->getEmail();
  822.                     if ($signatureObj->getDriver() && $signatureObj->getDriver()->getUser() && $signatureObj->getDriver()->getUser()->getEmail()) {
  823.                         $recipients[] = $signatureObj->getDriver()->getUser()->getEmail();
  824.                     }
  825.                     if ($signatureObj->getSender() && $signatureObj->getSender()->getEmail()) {
  826.                         $recipients[] = $signatureObj->getSender()->getEmail();
  827.                     }
  828.                     $recipients = array_unique($recipients);
  829.                     // Condition Mailjet sécurisée
  830.                     $isMailjet = ($principalUserArray && $principalUserArray['contact_mailjet'] && $signatureObj->getDriver() && $signatureObj->getDriver()->getUser() && $signatureObj->getDriver()->getUser()->isContactMailjet());
  831.                     if ($isMailjet) {
  832.                         $this->_sendMailService->sendTemplatedMail(
  833.                             new Address($from_mail_address, ""),
  834.                             $recipients,
  835.                             new Address($support_mail_address, ""),
  836.                             $admin_emails,
  837.                             $attach,
  838.                             "[DOCUTRANS] Lettre de voiture " . $signatureObj->getTask()->getId() . " - confirmation de signature de l'expéditeur",
  839.                             "add_signature_exp_result",
  840.                             $context
  841.                         );
  842.                     } else {
  843.                         $data_email['from'] = $from_mail_address;
  844.                         $data_email['toArray'] = $recipients;
  845.                         $data_email['replyTo'] = $support_mail_address;
  846.                         $data_email['cci'] = $admins;
  847.                         $data_email['template'] = 'add_signature_exp_result';
  848.                         $data_email['context'] = $context;
  849.                         $data_email['carrier'] = $data['carrier'];
  850.                         $data_email['etat'] = 0;
  851.                         $data_email['attach'] = $attach;
  852.                         $data_email['subject'] = "[DOCUTRANS] Lettre de voiture " . $signatureObj->getTask()->getId() . " - confirmation de signature de l'expéditeur";
  853.                         $data_email['sent_date'] = new \DateTime();
  854.                         $this->_mailingAttempsFailedService->add_row($data_email);
  855.                     }
  856.                 } catch (\Exception $e) {
  857.                     $this->logger->error("Erreur envoi mail signature EXP (non-bloquant) : " . $e->getMessage());
  858.                 }
  859.                 // Réponse OK
  860.                 $responseData = ['message' => "Mis à jour effectué avec succès.", 'status' => 200];
  861.                 if ($pdfResult) {
  862.                     $responseData['url'] = $pdfResult['url'];
  863.                     $responseData['fileName'] = $pdfResult['fileName'];
  864.                 }
  865.                 if(isset($litige)) {
  866.                     $responseData['litige_id'] = $litige->getId();
  867.                 }
  868.                 return new JsonResponse($responseData, Response::HTTP_OK);
  869.             }
  870.             return new JsonResponse(['message' => "Statut incorrect ou signature déjà validée", 'status' => 400], 400);
  871.         } catch (\Exception $e) {
  872.             $this->logger->critical("CRASH SIGNATURE EXP : " . $e->getMessage());
  873.             return new JsonResponse(['error' => $e->getMessage()], 500);
  874.         }
  875.     }
  876.     #[Route('/api/add/result/signature-dest', name: 'app_add_signature_dest_result', methods: ['POST'])]
  877.     public function add_signature_dest_result(Request $request)
  878.     {
  879.         try {
  880.             $taskId = $request->request->get('task_id');
  881.             // Récupération des signatures (Exp et Dest)
  882.             $signatureExp = $this->_signatureRepository->findSigByTaskAndType($taskId, "expediteur");
  883.             $signatureDest = $this->_signatureRepository->findSigByTaskAndType($taskId, "destinataire");
  884.             if (!$signatureDest) {
  885.                 return new JsonResponse(['message' => "Signature destinataire introuvable"], 404);
  886.             }
  887.             // Objets signatures
  888.             // On gère le cas où la signature expéditeur n'existe pas encore (rare mais possible)
  889.             $signatureObjExp = ($signatureExp) ? $this->_signatureRepository->find(['id' => $signatureExp[0]['id']]) : null;
  890.             $signatureObjDest = $this->_signatureRepository->find(['id' => $signatureDest[0]['id']]);
  891.             $task = $this->_taskRepository->find(['id' => $taskId]);
  892.             // 1. Nettoyage et typage GPS
  893.             $data = $request->request->all();
  894.             $lat = $request->request->get('latitude');
  895.             $long = $request->request->get('longitude');
  896.             $data['latitude'] = ($lat && $lat !== 'null') ? (float)$lat : null;
  897.             $data['longitude'] = ($long && $long !== 'null') ? (float)$long : null;
  898.             $data['reserves_eventuelles_result_dest'] = $request->request->get('reserves_eventuelles_result_dest');
  899.             $data['carrier'] = $task->getCarrier();
  900.             $data['task'] = $task;
  901.             $data['typeLitige'] = "destinataire";
  902.             $data['destinataire'] = $this->_companysRepository->findOneBy(["id" => $task->getConsignee()->getId()]);
  903.             $data['driver'] = $this->_driversRepository->findOneBy(['id' => $signatureObjDest->getDriver()->getId()]);
  904.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  905.             if ($this->canFinalizeSignature($task, $signatureObjDest, "destinataire")) {
  906.                 // 2. Mise à jour GPS et Signature
  907.                 $this->_signatureService->updateSignatureLongLat($signatureObjDest, $data);
  908.                 $this->_signatureService->updateSignature($signatureObjDest, $data, "destinataire");
  909.                 // 3. Événement d'historique (immédiat et sans doublon)
  910.                 $this->dispatchSignatureCommentIfNotExists($task, $signatureObjDest, "destinataire");
  911.                 // 4. Régénération du PDF avec les données de signature à jour
  912.                 $pdfResult = null;
  913.                 try {
  914.                     $pdfResult = $this->_pdfGeneratorService->generateForMission($task, $task->getCarrier() ? $task->getCarrier()->getId() : null);
  915.                 } catch (\Exception $e) {
  916.                     $this->logger->error("Erreur génération PDF lors de signature DEST : " . $e->getMessage());
  917.                 }
  918.                 // --- FIX CRITIQUE USER PRINCIPAL (Défensif) ---
  919.                 $usersFound = $this->_userRepository->findUserByCarrierAndRole($task->getCarrier()->getId(), "ROLE_PRINCIPAL_USER");
  920.                 $principalUserArray = null;
  921.                 $principalUserObj = null;
  922.                 if (!empty($usersFound) && isset($usersFound[0])) {
  923.                     $principalUserArray = $usersFound[0];
  924.                     $principalUserObj = $this->_userRepository->findOneBy(['id' => $principalUserArray['id']]);
  925.                 } else {
  926.                     $this->logger->warning("Signature Dest: Aucun ROLE_PRINCIPAL_USER trouvé pour le carrier " . $task->getCarrier()->getId());
  927.                 }
  928.                 // 5. Gestion Réserves / Litige
  929.                 if(!empty($data['reserves_eventuelles_result_dest'])){
  930.                     $litige = new Litige();
  931.                     $this->_litigeService->addLitige($litige, $data);
  932.                     $litigeStatusHistory = new LitigeStatusHistory();
  933.                     $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  934.                     $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  935.                     $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litige, $statusObj);
  936.                     $litigeObject = $this->_litigeRepository->findOneBy(['id' => $litige->getId()]);
  937.                     $data['litige'] = $litigeObject;
  938.                 }
  939.                 // 6. Gestion Upload (SORTI du bloc réserves)
  940.                 $nbrFiles = (int)$request->request->get('nbr_files');
  941.                 if ($nbrFiles > 0) {
  942.                     for ($i = 0; $i < $nbrFiles; $i++) {
  943.                         $uploadedFile = $request->files->get('image_' . $i);
  944.                         if ($uploadedFile) {
  945.                             $useCarrierFolder = ($principalUserObj && $principalUserObj->getCarriers() != null);
  946.                             if ($useCarrierFolder) {
  947.                                 $this->_uploadService->uploadFileBlob($uploadedFile, $data['carrier'], $data);
  948.                             } else {
  949.                                 $this->_uploadService->uploadFileBlob($uploadedFile, null, $data);
  950.                             }
  951.                         }
  952.                     }
  953.                 }
  954.                 // 7. Envoi Email (Protégé par try/catch)
  955.                 try {
  956.                     switch ($task->getCmr()) {
  957.                         case "cmr":
  958.                             $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $signatureObjDest->getTask()->getId() . ".pdf";
  959.                             break;
  960.                         case "internationale":
  961.                             $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $signatureObjDest->getTask()->getId() . ".pdf";
  962.                             break;
  963.                     }
  964.                     $attach = null;
  965.                     if (isset($pathLV) && file_exists($pathLV)) {
  966.                         $attach = ["allow" => "yes", "file" => $pathLV];
  967.                     }
  968.                     $admin_emails = $this->_userRepository->findUserByCarrierAndRole(null, "ROLE_ADMIN_USER");
  969.                     $admins = [];
  970.                     foreach($admin_emails as $admin_email){ $admins[] = $admin_email['email']; }
  971.                     $support_mail_address = $this->_params->get('support_mail_address');
  972.                     $from_mail_address = $this->_params->get('from_mail_address');
  973.                     $context = [
  974.                         "url" => $request->request->get('url_infos_exp_dest'),
  975.                         "back_url" => $_ENV['BACK_URL'],
  976.                         "urlDocutransFr" => $_ENV['Docutrans_FR_URL'],
  977.                         "support_mail_address" => $support_mail_address
  978.                     ];
  979.                     // Construction de la liste des destinataires
  980.                     $recipients = [];
  981.                     if ($principalUserArray) $recipients[] = $principalUserArray['email'];
  982.                     if ($signatureObjDest->getEmail()) $recipients[] = $signatureObjDest->getEmail();
  983.                     if ($signatureObjDest->getDriver() && $signatureObjDest->getDriver()->getUser() && $signatureObjDest->getDriver()->getUser()->getEmail()) {
  984.                         $recipients[] = $signatureObjDest->getDriver()->getUser()->getEmail();
  985.                     }
  986.                     // Ajout des emails de l'expéditeur (entreprise et contact ayant signé)
  987.                     if ($signatureObjExp) {
  988.                         if ($signatureObjExp->getEmail()) {
  989.                             $recipients[] = $signatureObjExp->getEmail();
  990.                         }
  991.                         if ($signatureObjExp->getSender() && $signatureObjExp->getSender()->getEmail()) {
  992.                             $recipients[] = $signatureObjExp->getSender()->getEmail();
  993.                         }
  994.                     }
  995.                     // Ajout du destinataire final si différent du signataire
  996.                     if ($signatureObjDest->getConsignee() && $signatureObjDest->getConsignee()->getEmail()) {
  997.                         $recipients[] = $signatureObjDest->getConsignee()->getEmail();
  998.                     }
  999.                     // Dédoublonnage des emails
  1000.                     $recipients = array_unique($recipients);
  1001.                     // Condition Mailjet
  1002.                     $isMailjet = ($principalUserArray && $principalUserArray['contact_mailjet'] && $signatureObjDest->getDriver() && $signatureObjDest->getDriver()->getUser() && $signatureObjDest->getDriver()->getUser()->isContactMailjet());
  1003.                     if ($isMailjet) {
  1004.                         $this->_sendMailService->sendTemplatedMail(
  1005.                             new Address($from_mail_address, ""),
  1006.                             $recipients,
  1007.                             new Address($support_mail_address, ""),
  1008.                             $admin_emails,
  1009.                             $attach,
  1010.                             '[DOCUTRANS] Lettre de voiture ' . $signatureObjDest->getTask()->getId() . ' - confirmation de signature du destinataire',
  1011.                             "add_signature_dest_result",
  1012.                             $context
  1013.                         );
  1014.                     } else {
  1015.                         $data_email['from'] = $from_mail_address;
  1016.                         $data_email['toArray'] = $recipients;
  1017.                         $data_email['replyTo'] = $support_mail_address;
  1018.                         $data_email['cci'] = $admins;
  1019.                         $data_email['template'] = 'add_signature_dest_result';
  1020.                         $data_email['context'] = $context;
  1021.                         $data_email['carrier'] = $data['carrier'];
  1022.                         $data_email['etat'] = 0;
  1023.                         $data_email['attach'] = $attach;
  1024.                         $data_email['subject'] = '[DOCUTRANS] Lettre de voiture ' . $signatureObjDest->getTask()->getId() . ' - confirmation de signature du destinataire';
  1025.                         $data_email['sent_date'] = new \DateTime();
  1026.                         $this->_mailingAttempsFailedService->add_row($data_email);
  1027.                     }
  1028.                 } catch (\Exception $e) {
  1029.                     $this->logger->error("Erreur envoi mail signature DEST (non-bloquant) : " . $e->getMessage());
  1030.                 }
  1031.                 // Réponse OK
  1032.                 $responseData = ['message' => "Mis à jour effectué avec succès.", 'status' => 200];
  1033.                 if ($pdfResult) {
  1034.                     $responseData['url'] = $pdfResult['url'];
  1035.                     $responseData['fileName'] = $pdfResult['fileName'];
  1036.                 }
  1037.                 if(isset($litige)) {
  1038.                     $responseData['litige_id'] = $litige->getId();
  1039.                 }
  1040.                 return new JsonResponse($responseData, Response::HTTP_OK);
  1041.             }
  1042.             return new JsonResponse(['message' => "Statut incorrect ou signature déjà validée", 'status' => 400], 400);
  1043.         } catch (\Exception $e) {
  1044.             $this->logger->critical("CRASH SIGNATURE DEST : " . $e->getMessage());
  1045.             return new JsonResponse(['error' => $e->getMessage()], 500);
  1046.         }
  1047.     }
  1048.     #[Route('/api/add/result/signature-expediteur', name: 'app_add_signature_expediteur_result', methods: ['POST'])]
  1049.     public function add_signature_expediteur_result(Request $request)
  1050.     {
  1051.         //recuperation du data from request.
  1052. //        $data = json_decode($request->getContent(), true);
  1053. //        $data = $request->request->all();
  1054.         $signature = $this->_signatureRepository->findSigByTaskAndType($request->request->get('task_id'), "expediteur");
  1055.         $signatureObj = $this->_signatureRepository->find(['id' => $signature[0]['id']]);
  1056.         $task = $this->_taskRepository->find(['id' => $request->request->get('task_id')]);
  1057.         // data
  1058.         $data['latitude'] = $request->request->get('latitude');
  1059.         $data['longitude'] = $request->request->get('longitude');
  1060.         $data['reserves_eventuelles_result_exp'] = $request->request->get('reserves_eventuelles_result_exp');
  1061.         $data['carrier'] = $task->getCarrier();
  1062.         $data['task'] = $task;
  1063.         $data['typeLitige'] = "expediteur";
  1064.         $data['expediteur'] = $this->_companysRepository->findOneBy(["id" => $task->getSender()->getId()]);
  1065.         $data['driver'] = $this->_driversRepository->findOneBy(['id' => $signatureObj->getDriver()->getId()]);
  1066.         // data
  1067.         $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  1068.         if ($last_status_task[0]['slug'] == "started") {
  1069.             // update
  1070.             $this->_signatureService->updateSignatureLongLat($signatureObj, $data);
  1071.             // get user principal of carrier of task
  1072.             $user = $this->_userRepository->findUserByCarrierAndRole($task->getCarrier()->getId(), "ROLE_PRINCIPAL_USER");
  1073.             $userObj = $this->_userRepository->findOneBy(['id' => $user[0]['id']]);
  1074.             if(isset($data['reserves_eventuelles_result_exp']) && $data['reserves_eventuelles_result_exp']){
  1075.                 $litige = new Litige();
  1076.                 // Appliquer les modifications au litige via le service dédié
  1077.                 $this->_litigeService->addLitige($litige, $data);
  1078.                 $litigeStatusHistory = new LitigeStatusHistory();
  1079.                 // Trouver le statut "ouvert" pour les litiges
  1080.                 $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  1081.                 // Trouver un statut spécifique en utilisant l'ID de ce statut
  1082.                 $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  1083.                 // Ajouter l'historique de statut de litige en utilisant le service des signatures
  1084.                 $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litige, $statusObj);
  1085.             }
  1086.             // envoie mail à l'expéditeur
  1087.             switch ($task->getCmr()) {
  1088.                 case "cmr":
  1089.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $signatureObj->getTask()->getId() . ".pdf";
  1090.                     break;
  1091.                 case "internationale":
  1092.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $signatureObj->getTask()->getId() . ".pdf";
  1093.                     break;
  1094.             }
  1095.             $attach = array(
  1096.                 "allow" => "yes",
  1097.                 "file" => $pathLV
  1098.             );
  1099.             $admin_emails = $this->_userRepository->findUserByCarrierAndRole(null, "ROLE_ADMIN_USER");
  1100.             $admins= [];
  1101.             foreach($admin_emails as $admin_email){
  1102.                 $admins[] = $admin_email['email'];
  1103.             }
  1104.             $support_mail_address = $this->_params->get('support_mail_address');
  1105.             $from_mail_address = $this->_params->get('from_mail_address');
  1106.             $context = [
  1107.                 "url" => $request->request->get('url_infos_exp_dest')
  1108.             ];
  1109.             if ($userObj->isContactMailjet() && $signatureObj->getDriver()->getUser()->isContactMailjet()) {
  1110.                 $this->_sendMailService->sendTemplatedMail(
  1111.                     new Address($from_mail_address, ""),
  1112.                     array($user[0]['email'], $signatureObj->getEmail(), $signatureObj->getDriver()->getUser()->getEmail(), $signatureObj->getSender()->getEmail()),
  1113.                     new Address($support_mail_address, ""),
  1114.                     $admin_emails,
  1115.                     $attach,
  1116.                     "[DOCUTRANS] Lettre de voiture " . $signatureObj->getTask()->getId() . " - confirmation de signature de l'expéditeur",
  1117.                     "add_signature_exp_result",
  1118.                     $context
  1119.                 );
  1120.             } else {
  1121.                 $data_email['from'] = $from_mail_address;
  1122.                 $data_email['toArray'] = array($user[0]['email'], $signatureObj->getEmail(), $signatureObj->getDriver()->getUser()->getEmail(), $signatureObj->getSender()->getEmail());
  1123.                 $data_email['replyTo'] = $support_mail_address;
  1124.                 $data_email['cci'] = $admins;
  1125.                 $data_email['template'] = 'add_signature_exp_result';
  1126.                 $data_email['context'] = $context;
  1127.                 $data_email['carrier'] = $data['carrier'];
  1128.                 $data_email['etat'] = 0;
  1129.                 $data_email['attach'] = $attach;
  1130.                 $data_email['subject'] = "[DOCUTRANS] Lettre de voiture " . $signatureObj->getTask()->getId() . " - confirmation de signature de l'expéditeur";
  1131.                 $data_email['sent_date'] = new \DateTime();
  1132.                 $this->_mailingAttempsFailedService->add_row($data_email);
  1133.             }
  1134.             // événement
  1135.             $nom_contact = $signatureObj->getNom();
  1136.             $datetime = new DateTime();
  1137.             $date_time = $datetime->format('d/m/Y à H:i');
  1138.             $message = "Signature du remettant le $date_time par $nom_contact.";
  1139.             $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, null, $message, $task);
  1140.             $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1141.             if(isset($data['reserves_eventuelles_result_exp']) && $data['reserves_eventuelles_result_exp']){
  1142.                 return new JsonResponse(['message' => "Mis à jour effectué avec succès.", 'litige_id' => $litige->getId(), 'status' => 200], Response::HTTP_OK);
  1143.             }else{
  1144.                 return new JsonResponse(['message' => "Mis à jour effectué avec succès.", 'status' => 200], Response::HTTP_OK);
  1145.             }
  1146.         }
  1147.     }
  1148.     #[Route('/api/add/result/signature-destinataire', name: 'app_add_signature_destinataire_result', methods: ['POST'])]
  1149.     public function add_signature_destinataire_result(Request $request)
  1150.     {
  1151.         //recuperation du data from request.
  1152. //        $data = json_decode($request->getContent(), true);
  1153.         //$data = $request->request->all();
  1154.         $signatureExp = $this->_signatureRepository->findSigByTaskAndType($request->request->get('task_id'), "expediteur");
  1155.         $signatureDest = $this->_signatureRepository->findSigByTaskAndType($request->request->get('task_id'), "destinataire");
  1156. //        $signature = $this->_signatureRepository->findSigByTaskAndType($request->request->get('task_id'), "destinataire");
  1157. //        $signatureObj = $this->_signatureRepository->find(['id' => $signature[0]['id']]);
  1158.         $signatureObjExp = $this->_signatureRepository->find(['id' => $signatureExp[0]['id']]);
  1159.         $signatureObjDest = $this->_signatureRepository->find(['id' => $signatureDest[0]['id']]);
  1160.         $task = $this->_taskRepository->find(['id' => $request->request->get('task_id')]);
  1161.         // data
  1162.         $data['latitude'] = $request->request->get('latitude');
  1163.         $data['longitude'] = $request->request->get('longitude');
  1164.         $data['reserves_eventuelles_result_dest'] = $request->request->get('reserves_eventuelles_result_dest');
  1165.         $data['carrier'] = $task->getCarrier();
  1166.         $data['task'] = $task;
  1167.         $data['typeLitige'] = "destinataire";
  1168.         $data['destinataire'] = $this->_companysRepository->findOneBy(["id" => $task->getConsignee()->getId()]);
  1169.         $data['driver'] = $this->_driversRepository->findOneBy(['id' => $signatureObjDest->getDriver()->getId()]);
  1170.         // data
  1171.         $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($data['task']->getId());
  1172.         if ($last_status_task[0]['slug'] == "started") {
  1173.             // update
  1174.             $this->_signatureService->updateSignatureLongLat($signatureObjDest, $data);
  1175.             // get user principal of carrier of task
  1176.             $user = $this->_userRepository->findUserByCarrierAndRole($task->getCarrier()->getId(), "ROLE_PRINCIPAL_USER");
  1177.             $userObj = $this->_userRepository->findOneBy(['id' => $user[0]['id']]);
  1178.             if(isset($data['reserves_eventuelles_result_dest']) && $data['reserves_eventuelles_result_dest']){
  1179.                 $litige = new Litige();
  1180.                 $this->_litigeService->addLitige($litige, $data);
  1181.                 $litigeStatusHistory = new LitigeStatusHistory();
  1182.                 // Trouver le statut "ouvert" pour les litiges
  1183.                 $status = $this->_refStatusRepository->findStatusBy("litige", "ouvert");
  1184.                 // Trouver un statut spécifique en utilisant l'ID de ce statut
  1185.                 $statusObj = $this->_refStatusRepository->findOneBy(['id' => $status[0]['id']]);
  1186.                 // Ajouter l'historique de statut de litige en utilisant le service des signatures
  1187.                 $this->_litigeService->addLitigeStatusHistory($litigeStatusHistory, $litige, $statusObj);
  1188.             }
  1189.             // envoie mail au destinataire
  1190.             switch ($task->getCmr()) {
  1191.                 case "cmr":
  1192.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $signatureObjDest->getTask()->getId() . ".pdf";
  1193.                     break;
  1194.                 case "internationale":
  1195.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $signatureObjDest->getTask()->getId() . ".pdf";
  1196.                     break;
  1197.             }
  1198.             $emails = [];
  1199.             if ($signatureObjDest->getConsignee() != null) {
  1200.                 $emails = array(
  1201.                     $user[0]['email'], $signatureObjDest->getEmail(),
  1202.                     $signatureObjDest->getDriver()->getUser()->getEmail(),
  1203.                     $signatureObjExp->getSender()->getEmail(),
  1204.                     $signatureObjDest->getConsignee()->getEmail(),
  1205.                 );
  1206.             } else {
  1207.                 $emails = array(
  1208.                     $user[0]['email'], $signatureObjDest->getEmail(),
  1209.                     $signatureObjDest->getDriver()->getUser()->getEmail(),
  1210.                     $signatureObjExp->getSender()->getEmail()
  1211.                 );
  1212.             }
  1213.             $attach = array(
  1214.                 "allow" => "yes",
  1215.                 "file" => $pathLV
  1216.             );
  1217.             $admin_emails = $this->_userRepository->findUserByCarrierAndRole(null, "ROLE_ADMIN_USER");
  1218.             $admins= [];
  1219.             foreach($admin_emails as $admin_email){
  1220.                 $admins[] = $admin_email['email'];
  1221.             }
  1222.             $support_mail_address = $this->_params->get('support_mail_address');
  1223.             $from_mail_address = $this->_params->get('from_mail_address');
  1224.             $context = [
  1225.                 "url" => $request->request->get('url_infos_exp_dest')
  1226.             ];
  1227.             if ($userObj->isContactMailjet() && $signatureObjDest->getDriver()->getUser()->isContactMailjet()) {
  1228.                 $this->_sendMailService->sendTemplatedMail(
  1229.                     new Address($from_mail_address, ""),
  1230.                     $emails,
  1231.                     new Address($support_mail_address, ""),
  1232.                     $admin_emails,
  1233.                     $attach,
  1234.                     '[DOCUTRANS] Lettre de voiture ' . $signatureObjDest->getTask()->getId() . ' - confirmation de signature du destinataire',
  1235.                     "add_signature_dest_result",
  1236.                     $context
  1237.                 );
  1238.             } else {
  1239.                 $data_email['from'] = $from_mail_address;
  1240.                 $data_email['toArray'] = $emails;
  1241.                 $data_email['replyTo'] = $support_mail_address;
  1242.                 $data_email['cci'] = $admins;
  1243.                 $data_email['template'] = 'add_signature_dest_result';
  1244.                 $data_email['context'] = $context;
  1245.                 $data_email['carrier'] = $data['carrier'];
  1246.                 $data_email['etat'] = 0;
  1247.                 $data_email['attach'] = $attach;
  1248.                 $data_email['subject'] = '[DOCUTRANS] Lettre de voiture ' . $signatureObjDest->getTask()->getId() . ' - confirmation de signature du destinataire';
  1249.                 $data_email['sent_date'] = new \DateTime();
  1250.                 $this->_mailingAttempsFailedService->add_row($data_email);
  1251.             }
  1252.             // événement
  1253.             $nom_contact = $signatureObjDest->getNom();
  1254.             $datetime = new DateTime();
  1255.             $date_time = $datetime->format('d/m/Y à H:i');
  1256.             $message = "Signature du destinataire le $date_time par $nom_contact.";
  1257.             $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, null, $message, $task);
  1258.             $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1259.             if(isset($data['reserves_eventuelles_result_dest']) && $data['reserves_eventuelles_result_dest']){
  1260.                 return new JsonResponse(['message' => "Mis à jour effectué avec succès.", 'litige_id' => $litige->getId(), 'status' => 200], Response::HTTP_OK);
  1261.             }else{
  1262.                 return new JsonResponse(['message' => "Mis à jour effectué avec succès.", 'status' => 200], Response::HTTP_OK);
  1263.             }
  1264.         }
  1265.     }
  1266.     #[Route('/api/add/mission', name: 'app_add_mission', methods: ['POST'])]
  1267.     public function add_mission(Request $request)
  1268.     {
  1269.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1270.         if (is_string($auth)) {
  1271.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1272.         }
  1273.         //recuperation du data from request.
  1274. //        $data = json_decode($request->getContent(), true);
  1275.         $data_mission_form = $request->request->all();
  1276.         //$data = $request->request->all();
  1277.         // get carrier of connected user
  1278. //        $data_files = $data['data_files'];
  1279.         $data_mission_form['carrier'] = $this->_carriersRepository->find($data_mission_form['carrier_id']);
  1280.         $data_mission_form['user'] = $this->_userRepository->find($data_mission_form['user_id']);
  1281.         // get company by id
  1282.         if (isset($data_mission_form['donneur_id']) && $data_mission_form['donneur_id'] != "undefined") {
  1283.             $data_mission_form['donneur'] = $this->_companysRepository->find($data_mission_form['donneur_id']);
  1284.         }
  1285.         if ($data_mission_form['expediteur_id'] != "undefined") {
  1286.             $data_mission_form['expediteur'] = $this->_companysRepository->find($data_mission_form['expediteur_id']);
  1287.         }
  1288.         if ($data_mission_form['destinataire_id'] != "undefined") {
  1289.             $data_mission_form['destinataire'] = $this->_companysRepository->find($data_mission_form['destinataire_id']);
  1290.         }
  1291.         $chauffeurs = [];
  1292.         if ($data_mission_form['chauffeur_id'] != null) {
  1293.             foreach ($data_mission_form['chauffeur_id'] as $chauff_id) {
  1294.                 $chauffeurs[] = $this->_driversRepository->findOneBy(['id' => $chauff_id]);
  1295.             }
  1296.         }
  1297.         $data_mission_form['chauffeurs'] = $chauffeurs;
  1298.         $vehicules = [];
  1299.         foreach ($data_mission_form['vehicule_id'] as $vehicule_id) {
  1300.             $vehicules[] = $this->_vehiculeRepository->findOneBy(['id' => $vehicule_id]);
  1301.         }
  1302.         $data_mission_form['vehicules'] = $vehicules;
  1303.         // service d'ajout.
  1304.         $mission_id = $this->_tasksService->addMission($data_mission_form, $request);
  1305.         $task = $this->_taskRepository->find($mission_id);
  1306.         $data_mission_form['task'] = $task;
  1307.         if ($data_mission_form['from_where'] == "web") {
  1308.             // upload and saving files
  1309.             $nbr_files = $request->request->get('nbr_files');
  1310.             for ($i = 0; $i < $nbr_files; $i++) {
  1311.                 $uploadedFile = $request->files->get('file_' . $i);
  1312.                 if ($uploadedFile) {
  1313.                     $upload = $this->_uploadService->uploadFile($uploadedFile, $data_mission_form);
  1314.                 }
  1315.             }
  1316.         }
  1317.         if ($data_mission_form['planned_at'] == null) {
  1318.             $status_ = $this->_refStatusRepository->findStatusBy("mission", "prog_in_progress");
  1319.         } else {
  1320.             $status_ = $this->_refStatusRepository->findStatusBy("mission", "ready");
  1321.         }
  1322.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  1323.         $this->_tasksService->addStatusTaskHistory($task, $status);
  1324.         $message = "Création de mission.";
  1325.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $this->_userRepository->findOneBy(['id' => $data_mission_form['user_id']]), $message, $task);
  1326.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1327.         return new JsonResponse(['message' => "Ajout mission faite avec succès!", 'id' => $task->getId(), 'status' => 200], Response::HTTP_OK);
  1328.     }
  1329.     #[Route('/api/start/task/{id}/{userId}', name: 'app_start_task', methods: ['GET', "POST"])]
  1330.     public function start_task(Request $request, $id, $userId)
  1331.     {
  1332.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1333.         if (is_string($auth)) {
  1334.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1335.         }
  1336.         $status_ = $this->_refStatusRepository->findStatusBy("mission", "started");
  1337.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  1338.         $task = $this->_taskRepository->findOneBy(['id' => $id]);
  1339.         $user = $this->_userRepository->findOneBy(['id' => $userId]);
  1340.         if ($task->getTaskDrivers()->isEmpty() && $user && $user->getDriver()) {
  1341.             $taskDriver = new \App\Entity\TaskDriver();
  1342.             $taskDriver->setTasks($task);
  1343.             $taskDriver->setDrivers($user->getDriver());
  1344.             $taskDriver->setDisplayOrder(1);
  1345.             $this->_doctrine->getManager()->persist($taskDriver);
  1346.             $this->_doctrine->getManager()->flush();
  1347.         }
  1348.         // événement
  1349.         $this->_tasksService->addStatusTaskHistory($task, $status);
  1350.         $message = "Mission démarrée.";
  1351.         // événement
  1352.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  1353.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1354.         return new JsonResponse(['message' => "Mission démarrée !", 'status' => 200], Response::HTTP_OK);
  1355.     }
  1356.     #[Route('/api/stop/task/{id}/{userId}', name: 'app_stop_task', methods: ['POST'])]
  1357.     public function stop_task(Request $request, $id, $userId)
  1358.     {
  1359.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1360.         if (is_string($auth)) {
  1361.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1362.         }
  1363.         $data = json_decode($request->getContent(), true);
  1364.         $user = $this->_userRepository->findOneBy(['id' => $userId]);
  1365.         switch ($data['status']) {
  1366.             case 'finished':
  1367.                 {
  1368.                     $status_ = $this->_refStatusRepository->findStatusBy("mission", "finished");
  1369.                     $message = "Mission terminée.";
  1370.                 }
  1371.                 break;
  1372.             case 'technical_problem':
  1373.                 {
  1374.                     $status_ = $this->_refStatusRepository->findStatusBy("mission", "technical_problem");
  1375.                     $message = "Mission arrêtée à cause d'un problème technique.";
  1376.                 }
  1377.                 break;
  1378.         }
  1379.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  1380.         $task = $this->_taskRepository->findOneBy(['id' => $id]);
  1381.         $this->_tasksService->addStatusTaskHistory($task, $status);
  1382.         // événement
  1383.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  1384.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1385.         if ($data['status'] == 'finished') {
  1386.             switch ($task->getCmr()) {
  1387.                 case "cmr":
  1388.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $task->getId() . ".pdf";
  1389.                     break;
  1390.                 case "internationale":
  1391.                     $pathLV = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $task->getId() . ".pdf";
  1392.                     break;
  1393.             }
  1394.             $attach = array(
  1395.                 "allow" => "yes",
  1396.                 "file" => $pathLV
  1397.             );
  1398.             $admin_emails = $this->_userRepository->findUserByCarrierAndRole(null, "ROLE_ADMIN_USER");
  1399.             $admins= [];
  1400.             foreach($admin_emails as $admin_email){
  1401.                 $admins[] = $admin_email['email'];
  1402.             }
  1403.             $support_mail_address = $this->_params->get('support_mail_address');
  1404.             $from_mail_address = $this->_params->get('from_mail_address');
  1405.             $context = [
  1406.                 "num_mission" => $task->getId(),
  1407.                 "carrier_name" => $task->getCarrier()->getRasionSociale(),
  1408.                 "back_url" => $_ENV['BACK_URL'],
  1409.                 "urlDocutransFr" => $_ENV['Docutrans_FR_URL']
  1410.             ];
  1411.             /**
  1412.              * On envoie le mail au Donneur d'Ordre si il existe.
  1413.              */
  1414.             if($task->getContractor() != null){
  1415.                 if ($user->isContactMailjet() && $task->getContractor()->getEmail()) {
  1416.                     $this->_sendMailService->sendTemplatedMail(
  1417.                         new Address($from_mail_address, ""),
  1418.                         array($task->getContractor()->getEmail()),
  1419.                         new Address($support_mail_address, ""),
  1420.                         $admin_emails,
  1421.                         $attach,
  1422.                         "[DOCUTRANS] Lettre de voiture numéro " . $task->getId(),
  1423.                         "donneur_dordre",
  1424.                         $context
  1425.                     );
  1426.                 } else {
  1427.                     $data_email['from'] = $from_mail_address;
  1428.                     $data_email['toArray'] = array($task->getContractor()->getEmail());
  1429.                     $data_email['replyTo'] = $support_mail_address;
  1430.                     $data_email['cci'] = $admins;
  1431.                     $data_email['template'] = 'donneur_dordre';
  1432.                     $data_email['context'] = $context;
  1433.                     $data_email['carrier'] = $task->getCarrier();
  1434.                     $data_email['etat'] = 0;
  1435.                     $data_email['attach'] = $attach;
  1436.                     $data_email['subject'] = "[DOCUTRANS] Lettre de voiture numéro " . $task->getId();
  1437.                     $data_email['sent_date'] = new \DateTime();
  1438.                     $this->_mailingAttempsFailedService->add_row($data_email);
  1439.                 }
  1440.             }
  1441.         }
  1442.         return new JsonResponse(['message' => "Mission terminée !", 'status' => 200], Response::HTTP_OK);
  1443.     }
  1444.     #[Route('/api/cancel/task/{id}/{userId}', name: 'app_cancel_task', methods: ['GET', "POST"])]
  1445.     public function cancel_task(Request $request, $id, $userId)
  1446.     {
  1447.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1448.         if (is_string($auth)) {
  1449.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1450.         }
  1451.         $data = json_decode($request->getContent(), true);
  1452.         $status_ = $this->_refStatusRepository->findStatusBy("mission", "cancel");
  1453.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  1454.         $task = $this->_taskRepository->findOneBy(['id' => $id]);
  1455.         $this->_tasksService->addStatusTaskHistory($task, $status);
  1456.         // événement
  1457.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $this->_userRepository->findOneBy(['id' => $userId]), "Mission annulée : ".$data['message'], $task);
  1458.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  1459.         return new JsonResponse(['message' => "Mission annulée !", 'status' => 200], Response::HTTP_OK);
  1460.     }
  1461.     #[Route('/api/in-progress/tasks/{carrierId}', name: 'app_in_progress_tasks', methods: ['GET', "POST"])]
  1462.     public function in_progress_tasks(Request $request, $carrierId): Response
  1463.     {
  1464.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1465.         if (is_string($auth)) {
  1466.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1467.         }
  1468.         $missions = $this->_taskStatusHistoryRepository->findTasksBySlug($carrierId, "started");
  1469.         $missions_arr = [];
  1470.         foreach ($missions as &$mission) {
  1471.             $chauffeurs = $this->_taskDriverRepository->getDriversOfTask($mission['id']);
  1472.             $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1473.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($mission['id']);
  1474.             $mission['chauffeurs'] = $chauffeurs;
  1475.             $mission['vehicules'] = $vehicules;
  1476.             $mission['task_status'] = $last_status_task;
  1477.             if (($last_status_task[0]['slug'] == "started") && ($last_status_task[0]['type'] == "mission")) {
  1478.                 $missions_arr[] = $mission;
  1479.             }
  1480.         }
  1481.         unset($mission);
  1482.         return new JsonResponse(['missions' => $missions_arr, 'status' => 200]);
  1483.     }
  1484.     #[Route('/api/ready/tasks/{carrierId}', name: 'app_ready_tasks', methods: ['GET', "POST"])]
  1485.     public function ready_tasks(Request $request, $carrierId): Response
  1486.     {
  1487.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1488.         if (is_string($auth)) {
  1489.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1490.         }
  1491.         $missions = $this->_taskStatusHistoryRepository->findTasksBySlug($carrierId, "ready");
  1492.         $missions_arr = [];
  1493.         foreach ($missions as &$mission) {
  1494.             $chauffeurs = $this->_taskDriverRepository->getDriversOfTask($mission['id']);
  1495.             $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1496.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($mission['id']);
  1497.             $mission['chauffeurs'] = $chauffeurs;
  1498.             $mission['vehicules'] = $vehicules;
  1499.             $mission['task_status'] = $last_status_task;
  1500.             if (($last_status_task[0]['slug'] == "ready") && ($last_status_task[0]['type'] == "mission")) {
  1501.                 $missions_arr[] = $mission;
  1502.             }
  1503.         }
  1504.         unset($mission);
  1505.         return new JsonResponse(['missions' => $missions_arr, 'status' => 200]);
  1506.     }
  1507.     #[Route('/api/finished/tasks/{carrierId}', name: 'app_finished_tasks', methods: ['GET', "POST"])]
  1508.     public function finished_tasks(Request $request, $carrierId): Response
  1509.     {
  1510.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1511.         if (is_string($auth)) {
  1512.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1513.         }
  1514.         $missions = $this->_taskStatusHistoryRepository->findTasksBySlug($carrierId, 'finished');
  1515.         $missions_arr = [];
  1516.         foreach ($missions as &$mission) {
  1517.             $chauffeurs = $this->_taskDriverRepository->getDriversOfTask($mission['id']);
  1518.             $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1519.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($mission['id']);
  1520.             $mission['chauffeurs'] = $chauffeurs;
  1521.             $mission['vehicules'] = $vehicules;
  1522.             $mission['task_status'] = $last_status_task;
  1523.             if (($last_status_task[0]['slug'] == "finished") && ($last_status_task[0]['type'] == "mission")) {
  1524.                 $missions_arr[] = $mission;
  1525.             }
  1526.         }
  1527.         unset($mission);
  1528.         return new JsonResponse(['missions' => $missions_arr, 'status' => 200]);
  1529.     }
  1530.     #[Route('/api/all/tasks/{carrierId}', name: 'app_all_tasks', methods: ['GET', "POST"])]
  1531.     public function index(Request $request, $carrierId): Response
  1532.     {
  1533.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1534.         if (is_string($auth)) {
  1535.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1536.         }
  1537.         $missions = $this->_taskRepository->findAllTasks($carrierId);
  1538.         $missions_arr = [];
  1539.         foreach ($missions as &$mission) {
  1540.             // get goods by task id
  1541.             $goods = $this->_goodsRepository->findGoodsByTaskId($mission['id']);
  1542.             $chauffeurs = $this->_taskDriverRepository->getDriversOfTask($mission['id']);
  1543.             $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1544.             // get status mission
  1545.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($mission['id']);
  1546.             $mission['goods'] = $goods;
  1547.             $mission['chauffeurs'] = $chauffeurs;
  1548.             $mission['vehicules'] = $vehicules;
  1549.             $mission['task_status'] = $last_status_task;
  1550.             $missions_arr[] = $mission;
  1551.         }
  1552.         unset($mission);
  1553.         return new JsonResponse(['missions' => $missions_arr, 'status' => 200]);
  1554.     }
  1555.     #[Route('/api/all/tasks/{carrierId}/{companyId}', name: 'app_all_tasks_by_company', methods: 'POST')]
  1556.     public function task_company(Request $request, $carrierId, $companyId): Response
  1557.     {
  1558.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1559.         if (is_string($auth)) {
  1560.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1561.         }
  1562.         $data = json_decode($request->getContent(), true);
  1563.         $user = $this->_userRepository->find($data['user_id']);
  1564.         $oneCompanyObj = $this->_companysRepository->find($companyId);
  1565.         if ($user->getCarriers() === $oneCompanyObj->getCarrier()) {
  1566.             $missions = $this->_taskRepository->findAllTasksBy($companyId, $carrierId);
  1567.             $missions_arr = [];
  1568.             foreach ($missions as &$mission) {
  1569.                 $chauffeurs = $this->_taskDriverRepository->getDriversOfTask($mission['id']);
  1570.                 $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1571.                 $mission['chauffeurs'] = $chauffeurs;
  1572.                 $mission['vehicules'] = $vehicules;
  1573.                 $missions_arr[] = $mission;
  1574.             }
  1575.             unset($mission);
  1576.             return new JsonResponse(['missions' => $missions_arr, 'status' => 200]);
  1577.         } else {
  1578.             throw $this->createNotFoundException();
  1579.         }
  1580.     }
  1581.     #[Route('/api/all/tasks/driver/{carrierId}/{driverId}', name: 'app_all_tasks_by_driver', methods: 'POST')]
  1582.     public function task_driver(Request $request, $carrierId, $driverId): Response
  1583.     {
  1584.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1585.         if (is_string($auth)) {
  1586.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1587.         }
  1588.         $data = json_decode($request->getContent(), true);
  1589.         $user = $this->_userRepository->find($data['user_id']);
  1590.         $oneDriverObj = $this->_driversRepository->find($driverId);
  1591.         if ($user->getCarriers() === $oneDriverObj->getCarrier()) {
  1592.             $missions = $this->_taskDriverRepository->getTasksByDriver($driverId, $carrierId);
  1593.             $missions_arr = [];
  1594.             foreach ($missions as &$mission) {
  1595.                 $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($mission['id']);
  1596.                 $mission['chauffeur'] = $mission['first_name'] . " " . $mission['last_name'];
  1597.                 $mission['vehicules'] = $vehicules;
  1598.                 $missions_arr[] = $mission;
  1599.             }
  1600.             unset($mission);
  1601.             return new JsonResponse(["missions_driver" => $missions_arr, "status" => 200], Response::HTTP_OK);
  1602.         } else {
  1603.             throw $this->createNotFoundException();
  1604.         }
  1605.     }
  1606.     #[Route('/api/tasks/vehicule/date', name: 'app_tasks_vehicule_date', methods: 'POST')]
  1607.     public function tasks_vehicule(Request $request): Response
  1608.     {
  1609.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1610.         if (is_string($auth)) {
  1611.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1612.         }
  1613.         $data = json_decode($request->getContent(), true);
  1614. //        $data = $request->request->all();
  1615.         if (isset($data['createdBy']) && $data['createdBy']) {
  1616.             $missions = $this->_taskRepository->findCreatedTasks($data);
  1617.         } else {
  1618.             $missions = $this->_tasksService->getTasksByVehiculePlannedAt($data);
  1619.         }
  1620.         $missions_arr = [];
  1621.         foreach ($missions as &$mission) {
  1622.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($mission['id']);
  1623.             $task = $this->_taskRepository->findOneBy(['id' => $mission['id']]);
  1624.             $mission['nbrLitiges'] = count($task->getLitiges());
  1625.             $mission['driver_id'] = (isset($data['createdBy']) && $data['createdBy'] ? "" : $mission['driver_id']);
  1626.             $mission['last_status_task'] = (count($last_status_task) != 0 ? $last_status_task[0]['label'] : "");
  1627.             $mission['last_status_task_slug'] = (count($last_status_task) != 0 ? $last_status_task[0]['slug'] : "");
  1628. //            if(($last_status_task[0]['slug'] != "finished") && ($last_status_task[0]['slug'] != "technical_problem")){
  1629.             if ($mission['planned_at'] != null) {
  1630.                 if (isset($data['createdBy']) && $data['createdBy']) {
  1631.                     $plannedAtFormatted = ($mission['planned_at'])->format('Y-m-d');
  1632.                 } else {
  1633.                     $plannedAtFormatted = (new \DateTime($mission['planned_at']))->format('Y-m-d');
  1634.                 }
  1635.                 $missions_arr[$plannedAtFormatted][] = $mission;
  1636. //                }
  1637.             }
  1638.         }
  1639.         unset($mission);
  1640.         return new JsonResponse(["missions_vehicule" => $missions_arr, "status" => 200], Response::HTTP_OK);
  1641.     }
  1642.     #[Route('/api/reorder/tasks/', name: 'app_reorder_tasks', methods: 'POST')]
  1643.     public function reorder(Request $request): Response
  1644.     {
  1645.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1646.         if (is_string($auth)) {
  1647.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1648.         }
  1649.         $data = json_decode($request->getContent(), true);
  1650.         //$data = $request->request->all();
  1651.         $i = 1;
  1652.         foreach ($data as $task) {
  1653.             $task_id = $task['id'];
  1654.             $tournee_id = $task['tournee_id'];
  1655.             // get driver
  1656.             $tournee = $this->_tourneeRepository->findOneBy(['id' => $tournee_id]);
  1657.             // get task
  1658.             $task = $this->_taskRepository->findOneBy(['id' => $task_id]);
  1659.             // get TaskDriver Object
  1660.             $tournee_task = $this->_tourneeTaskRepository->findOneBy(['tournee' => $tournee, 'task' => $task]);
  1661.             $this->_tasksService->updateDisplayOrder($tournee_task, $i);
  1662.             $i++;
  1663.         }
  1664.         return new JsonResponse(['message' => "Ordres changées !", 'status' => 200]);
  1665.     }
  1666.     #[Route('/api/task/{id}/{carrierId}', name: 'app_one_task', methods: 'POST')]
  1667.     public function task(Request $request, $id): Response
  1668.     {
  1669.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1670.         if (is_string($auth)) {
  1671.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1672.         }
  1673.         $data = json_decode($request->getContent(), true);
  1674. //        $data = $request->request->all();
  1675.         $mission = $this->_taskRepository->findOneBy(['id' => $id]);
  1676.         $user = $this->_userRepository->find($data['user_id']);
  1677.         if ($user->getCarriers() === $mission->getCarrier()) {
  1678.             $last_status_task = $this->_taskStatusHistoryRepository->findStatusByTaskId($id);
  1679.             // get goods by task id
  1680.             $goods = $this->_goodsRepository->findGoodsByTaskId($id);
  1681.             foreach ($goods as $key => $good) {
  1682.                 $goodObj = $this->_goodsRepository->findOneBy(['id' => $good['id']]);
  1683.                 $document = $goodObj->getUploads()->toArray();
  1684.                 $goods[$key]['document'] = $this->_uploadService->getFiles($document);
  1685.             }
  1686.             $tasks_comments = $this->_taskCommentRepository->findTaskComByTaskId($id);
  1687.             $chauffeurs = $this->_taskDriverRepository->findDriversByTaskId($id);
  1688.             $vehicules = $this->_taskVehiculeRepository->findVehiculesByTaskId($id);
  1689.             $files = $this->_uploadService->getFiles($mission->getUploads()->toArray());
  1690.             $signatures = $this->_signatureRepository->findSigByTask($mission->getId());
  1691.             $litigesArray = [];
  1692.             foreach ($mission->getLitiges() as $litige) {
  1693.                 $type = "";
  1694.                 switch ($litige->getType()) {
  1695.                     case "chauffeur_expediteur" :
  1696.                         $type = "Chauffeur à l'expédition";
  1697.                         break;
  1698.                     case "chauffeur_destinataire" :
  1699.                         $type = "Chauffeur à la livraison";
  1700.                         break;
  1701.                     case "expediteur" :
  1702.                         $type = "Expédition";
  1703.                         break;
  1704.                     case "destinataire" :
  1705.                         $type = "Livraison";
  1706.                         break;
  1707.                 }
  1708.                 // Créez un tableau associatif pour chaque litige
  1709.                 $litigeData = [
  1710.                     'id' => ($litige->getId()),
  1711.                     'taskid' => ($litige->getTask() != null ? $litige->getTask()->getId() : ""),
  1712.                     'destinataire' => ($litige->getConsignee() != null ? $litige->getConsignee()->getCompanyName() : ""),
  1713.                     'expediteur' => ($litige->getSender() != null ? $litige->getSender()->getCompanyName() : ""),
  1714.                     'possiblereservations' => $litige->getPossibleReservations(),
  1715.                     'statuslitige' => ($litige->getLitigeStatusHistories() != null ? $litige->getLitigeStatusHistories()->last()->getStatus()->getLabel() : ""),
  1716.                     'litigeStatusSlug' => ($litige->getLitigeStatusHistories() != null ? $litige->getLitigeStatusHistories()->last()->getStatus()->getSlug() : ""),
  1717.                     'litigetype' => $litige->getType(),
  1718.                     'chauffeur' => ($litige->getDriver() != null ? $litige->getDriver()->getFirstName() . " " . $litige->getDriver()->getLastName() : ""),
  1719.                     'typeLitige' => $type,
  1720.                     'pathimage' => ($litige->getUploads() != null && !$litige->getUploads()->isEmpty() ? $_SERVER['SERVER_NAME'] . $litige->getUploads()->last()->getPath() : ""),
  1721.                     'imagename' => ($litige->getUploads() != null && !$litige->getUploads()->isEmpty() ? $litige->getUploads()->last()->getOriginaleName() : ""),
  1722.                     'viewable_name' => ($litige->getUploads() != null && !$litige->getUploads()->isEmpty() ? $litige->getUploads()->last()->getViewableName() : "")
  1723.                 ];
  1724.                 // Ajoutez les données du litige au tableau des litiges
  1725.                 $litigesArray[] = $litigeData;
  1726.             }
  1727.             $signatures = $this->_signatureRepository->findSigByTask($mission->getId());
  1728.             $arrToReturn = [];
  1729.             switch (count($signatures)) {
  1730.                 case 1 :
  1731.                     {
  1732.                         $arrToReturn[$signatures[0]['type_signature']] = $signatures;
  1733.                     }
  1734.                     break;
  1735.                 case 2 :
  1736.                     {
  1737.                         foreach ($signatures as $signature) {
  1738.                             $arrToReturn[$signature['type_signature']][] = $signature;
  1739.                         }
  1740.                     }
  1741.                     break;
  1742.             }
  1743.             $array_element = array(
  1744.                 "label_status" => $last_status_task[0]['label'],
  1745.                 "id" => $mission->getId(),
  1746.                 "id_exp" => ($mission->getSender() != null ? $mission->getSender()->getId() : null),
  1747.                 "id_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getId() : null),
  1748.                 "donneur_ordre" => ($mission->getContractor() != null ? $mission->getContractor()->getCompanyName() : null),
  1749.                 "destinataire" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCompanyName() : null),
  1750.                 "adresse_dest1" => ($mission->getConsignee() != null ? $mission->getConsignee()->getAdr1() : null),
  1751.                 "adresse_dest2" => ($mission->getConsignee() != null ? $mission->getConsignee()->getAdr2() : null),
  1752.                 "tel_phonecode_dest1" => ($mission->getConsignee() != null ? '(+' . $mission->getConsignee()->getRefCountry()->getPhonecode() . ')' . $mission->getConsignee()->getTel1() : null),
  1753.                 "tel_phonecode_dest2" => ($mission->getConsignee() != null ? '(+' . $mission->getConsignee()->getRefCountry()->getPhonecode() . ')' . $mission->getConsignee()->getTel2() : null),
  1754.                 "tel_dest1" => ($mission->getConsignee() != null ? $mission->getConsignee()->getTel1() : null),
  1755.                 "tel_dest2" => ($mission->getConsignee() != null ? $mission->getConsignee()->getTel2() : null),
  1756.                 "email_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getEmail() : null),
  1757.                 "lat_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getLat() : null),
  1758.                 "lng_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getLng() : null),
  1759.                 "cp_zip_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCpZip() : null),
  1760.                 "city_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCity() : null),
  1761.                 "cedex_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCedex() : null),
  1762.                 "infos_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getInformations() : null),
  1763.                 "typeDest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getType() : null),
  1764.                 "expediteur" => ($mission->getSender() != null ? $mission->getSender()->getCompanyName() : null),
  1765.                 "adresse_exp1" => ($mission->getSender() != null ? $mission->getSender()->getAdr1() : null),
  1766.                 "adresse_exp2" => ($mission->getSender() != null ? $mission->getSender()->getAdr2() : null),
  1767.                 "nicename_exp" => ($mission->getSender() != null ? $mission->getSender()->getRefCountry()->getNicename() : null),
  1768.                 "nicename_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getRefCountry()->getNicename() : null),
  1769.                 "tel_phonecode_exp1" => ($mission->getSender() != null ? '(+' . $mission->getSender()->getRefCountry()->getPhonecode() . ')' . $mission->getSender()->getTel1() : null),
  1770.                 "tel_phonecode_exp2" => ($mission->getSender() != null ? '(+' . $mission->getSender()->getRefCountry()->getPhonecode() . ')' . $mission->getSender()->getTel2() : null),
  1771.                 "tel_exp1" => ($mission->getSender() != null ? $mission->getSender()->getTel1() : null),
  1772.                 "tel_exp2" => ($mission->getSender() != null ? $mission->getSender()->getTel2() : null),
  1773.                 "email_exp" => ($mission->getSender() != null ? $mission->getSender()->getEmail() : null),
  1774.                 "lat_exp" => ($mission->getSender() != null ? $mission->getSender()->getLat() : null),
  1775.                 "lng_exp" => ($mission->getSender() != null ? $mission->getSender()->getLng() : null),
  1776.                 "cp_zip_exp" => ($mission->getSender() != null ? $mission->getSender()->getCpZip() : null),
  1777.                 "city_exp" => ($mission->getSender() != null ? $mission->getSender()->getCity() : null),
  1778.                 "cedex_exp" => ($mission->getSender() != null ? $mission->getSender()->getCedex() : null),
  1779.                 "infos_exp" => ($mission->getSender() != null ? $mission->getSender()->getInformations() : null),
  1780.                 "typeExp" => ($mission->getSender() != null ? $mission->getSender()->getType() : null),
  1781.                 "code_client_exp" => ($mission->getSender() != null ? $mission->getSender()->getCompanysCodeClient() : null),
  1782.                 "code_client_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCompanysCodeClient() : null),
  1783.                 "planned_at" => $mission->getPlannedAt(),
  1784.                 "custom_formalities" => $mission->getCustomFormalities(),
  1785.                 "instructions" => $mission->getInstructions(),
  1786.                 "seal_number" => $mission->getSealNumber(),
  1787. //                "un_number" => $mission->getUnNumber(),
  1788.                 "cmr" => $mission->getCmr(),
  1789.                 "mission" => $mission->getMission(),
  1790.                 "presta_ann_sender_planned" => $mission->getPrestaAnnSenderPlanned(),
  1791.                 "presta_ann_consignee_planned" => $mission->getPrestaAnnConsigneePlanned(),
  1792.                 "attached_docs" => $mission->getAttachedDocs(),
  1793.                 "goods" => $goods,
  1794.                 "chauffeurs" => $chauffeurs,
  1795.                 "vehicules" => $vehicules,
  1796.                 "files" => $files,
  1797.                 "task_status" => $last_status_task,
  1798.                 "tasks_comments" => $tasks_comments,
  1799.                 "pallet_europe" => $mission->getPalletEurope(),
  1800.                 "pallet_other" => $mission->getPalletOther(),
  1801.                 "pallet_80_120" => $mission->getPallet80120(),
  1802.                 "pallet_100_120" => $mission->getPallet100120(),
  1803.                 "ref_country_id_exp" => ($mission->getSender() != null ? $mission->getSender()->getRefCountry()->getId() : null),
  1804.                 "ref_country_id_dest" => ($mission->getConsignee() != null ? $mission->getConsignee()->getRefCountry()->getId() : null),
  1805.                 "created_by_id" => ($mission->getCreatedBy() != null ? $mission->getCreatedBy()->getId() : null),
  1806.                 "can_download_LV" => (count($signatures) > 0 ? "can" : "can_not"),
  1807.                 "litiges" => $litigesArray,
  1808.                 "signatures" => $arrToReturn,
  1809.                 "id_donneur_dordre" => ($mission->getContractor() != null ? $mission->getContractor()->getId() : null),
  1810.             );
  1811.             return new JsonResponse(['mission' => $array_element, 'status' => 200]);
  1812.         } else {
  1813.             throw $this->createNotFoundException();
  1814.         }
  1815.     }
  1816.     #[Route('/api/pdf/task/{id}/{carrierId}', name: 'app_pdf_task', methods: ['GET', "POST"])]
  1817.     public function generate_pdf(Request $request, $id, $carrierId)
  1818.     {
  1819.         $auth = $this->jwtHelper->verifyJwt($request, []);
  1820.         if (is_string($auth)) {
  1821.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  1822.         }
  1823.         $mission = $this->_taskRepository->findOneBy(['id' => $id]);
  1824.         // get goods by task id
  1825.         $goods = $this->_goodsRepository->findGoodsByTaskId($mission->getId());
  1826.         $cmr = ($mission->getCmr() == "cmr" ? "Nationale" : "Internationale");
  1827.         switch ($mission->getMission()) {
  1828.             case 'enlev_livr':
  1829.                 $type_mission = "Enlévement + Livraison";
  1830.                 break;
  1831.             case 'enlev':
  1832.                 $type_mission = "Enlévement";
  1833.                 break;
  1834.             case 'livr':
  1835.                 $type_mission = "Livraison";
  1836.                 break;
  1837.         }
  1838.         $array_element = array(
  1839.             "id" => $mission->getId(),
  1840.             "destinataire" => ($mission->getConsignee() != null ? $mission->getConsignee()->getCompanyName() : null),
  1841.             "expediteur" => ($mission->getSender() != null ? $mission->getSender()->getCompanyName() : null),
  1842.             "custom_formalities" => ($mission->getCustomFormalities() == "" ? "----" : $mission->getCustomFormalities()),
  1843.             "instructions" => ($mission->getInstructions() == "" ? "----" : $mission->getInstructions()),
  1844.             "label_number" => ($mission->getLabelNumber() == "" ? "----" : $mission->getLabelNumber()),
  1845.             "seal_number" => ($mission->getSealNumber() == "" ? "----" : $mission->getSealNumber()),
  1846. //            "un_number" => ($mission->getUnNumber() == "" ? "----" : $mission->getUnNumber()),
  1847.             "dangerous_goods" => ($mission->getDangerousGoods() == "" ? "----" : $mission->getDangerousGoods()),
  1848.             "obligatory_enclosure_declaration" => ($mission->getObligatoryEnclosureDeclaration() == "" ? "----" : $mission->getObligatoryEnclosureDeclaration()),
  1849.             "packing_group" => ($mission->getPackingGroup() == "" ? "----" : $mission->getPackingGroup()),
  1850.             "cmr" => $cmr,
  1851.             "mission" => $type_mission,
  1852.             "presta_ann_sender_planned" => $mission->getPrestaAnnSenderPlanned(),
  1853.             "presta_ann_consignee_planned" => $mission->getPrestaAnnConsigneePlanned(),
  1854.             "attached_docs" => ($mission->getAttachedDocs() == "" ? "----" : $mission->getAttachedDocs()),
  1855.             "temperature_dirigee" => ($mission->getTemperatureDirigee() == "" ? "----" : $mission->getTemperatureDirigee()),
  1856.             "goods" => $goods
  1857.         );
  1858.         $pdfOptions = new Options();
  1859.         $pdfOptions->set('defaultFont', 'Arial');
  1860.         $dompdf = new Dompdf($pdfOptions);
  1861.         $html = $this->renderView('mission/pdf_details_task.html.twig', [
  1862.             'data_task' => $array_element
  1863.         ]);
  1864.         $dompdf->loadHtml($html);
  1865.         $dompdf->setPaper('A4', 'portrait');
  1866.         $dompdf->render();
  1867.         $dompdf->stream("mypdf.pdf", [
  1868.             "Attachment" => false
  1869.         ]);
  1870.         exit;
  1871.     }
  1872.     #[Route('/api/write/pdf/task/{id}/{carrierId}', name: 'app_write_pdf_task', methods: 'POST')]
  1873.     public function write_pdf(
  1874.         Request $request,
  1875.                 $id,
  1876.                 $carrierId,
  1877.                 PdfGeneratorService $pdfGeneratorService, // Injection du nouveau service
  1878.                 SignatureService $signatureService,       // Injection pour l'écriture
  1879.                 EntityManagerInterface $entityManager    // Injection pour le flush
  1880.     ) {
  1881.         $data = json_decode($request->getContent(), true);
  1882.         $mission = $this->_taskRepository->find($id);
  1883.         if (!$mission) {
  1884.             return new JsonResponse(['error' => 'Mission non trouvée'], 404);
  1885.         }
  1886.         // --- ETAPE 1 : LOGIQUE D'ÉCRITURE (Conditionnelle) ---
  1887.         // C'est ici qu'on gère la demande de l'app mobile "Legacy"
  1888.         if (isset($data['update_contact_sign']) && $data['update_contact_sign'] === true) {
  1889.             try {
  1890.                 // On délègue l'écriture au service dédié
  1891.                 $updatedSignature = $signatureService->handleMobileSignature($mission, $data);
  1892.                 // On s'assure que tout est bien enregistré avant de générer le PDF
  1893.                 $entityManager->flush();
  1894.                 if ($updatedSignature !== null && $updatedSignature->getTypeSignature()) {
  1895.                     $this->dispatchSignatureCommentIfNotExists($mission, $updatedSignature, $updatedSignature->getTypeSignature());
  1896.                 }
  1897.                 // On rafraichit la mission pour être sûr d'avoir les données à jour (liens signatures, etc.)
  1898.                 $entityManager->refresh($mission);
  1899.             } catch (\Exception $e) {
  1900.                 // En prod, log l'erreur ici
  1901.                 return new JsonResponse(['error' => "Erreur lors de la sauvegarde de la signature : " . $e->getMessage()], 500);
  1902.             }
  1903.         }
  1904.         // --- ETAPE 2 : GÉNÉRATION DU PDF (Read-Only) ---
  1905.         // Le service PDF ne touche pas à la base, il ne fait que lire.
  1906.         try {
  1907.             $result = $pdfGeneratorService->generateForMission($mission, $carrierId);
  1908.             return new JsonResponse([
  1909.                 'url' => $result['url'],
  1910.                 'fileName' => $result['fileName']
  1911.             ], Response::HTTP_OK);
  1912.         } catch (\Exception $e) {
  1913.             return new JsonResponse(['error' => "Erreur lors de la génération du PDF : " . $e->getMessage()], 500);
  1914.         }
  1915.     }
  1916.     function splitIntoThreeWordSentences($paragraph)
  1917.     {
  1918.         $words = preg_split('/\s+/', trim($paragraph));
  1919.         $sentences = [];
  1920.         for ($i = 0; $i < count($words); $i += 3) {
  1921.             $chunk = array_slice($words, $i, 3);
  1922.             $sentences[] = implode(' ', $chunk);
  1923.         }
  1924.         return $sentences;
  1925.     }
  1926. //    #[Route('/api/write/pdf/task/dest/{id}/{carrierId}', name: 'app_write_pdf_task_dest', methods: 'POST')]
  1927. //    public function write_dest_pdf(Request $request, $id, $carrierId)
  1928. //    {
  1929. //        $data = json_decode($request->getContent(), true);
  1930. //        //$data = $request->request->all();
  1931. ////        $mission = $this->_taskRepository->findOneBy(['id' => $id]);
  1932. ////        $signature = $this->_signatureRepository->findSigByTaskAndType($id, $data['type_signature']);
  1933. ////        $signatureObj = $this->_signatureRepository->find(['id' => $signature[0]['id']]);
  1934. ////        $this->_signatureService->updateFirstSignature($signatureObj, $data);
  1935. ////
  1936. ////        // arrivé à et départ à
  1937. ////        // arrivé à
  1938. ////        $arrive_at_obj = $signatureObj->getArriveAt();
  1939. ////        $arriv_at = explode(' ', $arrive_at_obj->format('d-m-Y H:i:s'));
  1940. ////        $heure_arriv = explode(':', $arriv_at[1]);
  1941. ////        // départ à
  1942. ////        $departure_at_obj = $signatureObj->getDepartureAt();
  1943. ////        $dep_at = explode(' ', $departure_at_obj->format('d-m-Y H:i:s'));
  1944. ////        $heure_dep = explode(':', $dep_at[1]);
  1945. ////        $presta_ann = $signatureObj->getPrestaAnn();
  1946. ////        $nom_contact = $signatureObj->getNom();
  1947. ////        $possible_reservations = $signatureObj->getPossibleReservations();
  1948. ////        $possible_reservations_contact = $signatureObj->getPossibleReservationsContact();
  1949. ////        // destinataire
  1950. ////        $signedAt = $signatureObj->getSignedAt();
  1951. ////        $signedDriverAt = $signatureObj->getSignedDriverAt();
  1952. ////        $rendues = $signatureObj->getRendues();
  1953. ////        $livrees = $signatureObj->getLivrees();
  1954. ////        $non_rendues = $signatureObj->getNonRendues();
  1955. ////        $nomChauffeur = ucfirst($signature[0]['first_name']) . " " . ucfirst($signature[0]['last_name']);
  1956. //
  1957. //        require_once $_SERVER['DOCUMENT_ROOT'] . '/pdf_classes/fpdi.php';
  1958. //        require_once $_SERVER['DOCUMENT_ROOT'] . '/pdf_classes/html2pdf.php';
  1959. //        if ($mission->getCmr() == "cmr") {
  1960. //            $pdf = new FPDISigep();
  1961. //            $pdf->SetAutoPageBreak(true, 0);
  1962. //            $filename = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_nationnale_HD_" . $id . ".pdf";
  1963. //            // get the page count
  1964. //            $pageCount = $pdf->setSourceFile($filename);
  1965. //            // iterate through all pages
  1966. //            //for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
  1967. //            // import a page
  1968. //            $templateId = $pdf->importPage(1);
  1969. //            // get the size of the imported page
  1970. //            $size = $pdf->getTemplateSize($templateId);
  1971. //            // create a page (landscape or portrait depending on the imported page size)
  1972. //            if ($size['w'] > $size['h']) {
  1973. //                $pdf->AddPage('L', array($size['w'], $size['h']));
  1974. //            } else {
  1975. //                $pdf->AddPage('P', array($size['w'], $size['h']));
  1976. //            }
  1977. //            // use the imported page
  1978. //            $pdf->useTemplate($templateId);
  1979. //            $pdf->SetTextColor(195, 40, 40);
  1980. //            $pdf->SetFont('Helvetica', '', 8);
  1981. //
  1982. //            $text_height = 36;
  1983. //            $start_x = $pdf->GetX();
  1984. //
  1985. //
  1986. //
  1987. //            $newFileName = "/uploads/missions/lettre_voiture_nationnale_HD_" . $id . ".pdf";
  1988. //            $newFileNamePath = $_SERVER['DOCUMENT_ROOT'] . $newFileName;
  1989. //            $pdf->Output($newFileNamePath, "F");
  1990. //            $url = "https://" . $_SERVER['SERVER_NAME'] . $newFileName;
  1991. //            $fileName = "lettre_voiture_nationnale_HD_" . $id . ".pdf";
  1992. //
  1993. //            return new JsonResponse(['url' => $url, 'fileName' => $fileName], Response::HTTP_OK);
  1994. ////            header('Access-Control-Allow-Origin: *');
  1995. //
  1996. //            //return base64_encode($pdf->Output($newFileNamePath, "F"));
  1997. //        }
  1998. //        if ($mission->getCmr() == 'internationale') {
  1999. //            $pdf = new FPDISigep();
  2000. //            $pdf->SetAutoPageBreak(true, 0);
  2001. //            $filename = $_SERVER['DOCUMENT_ROOT'] . "/uploads/missions/lettre_voiture_europeenne_HD_" . $id . ".pdf";
  2002. //            // get the page count
  2003. //            $pageCount = $pdf->setSourceFile($filename);
  2004. //            // import a page
  2005. //            $templateId = $pdf->importPage(1);
  2006. //            // get the size of the imported page
  2007. //            $size = $pdf->getTemplateSize($templateId);
  2008. //            // create a page (landscape or portrait depending on the imported page size)
  2009. //            if ($size['w'] > $size['h']) {
  2010. //                $pdf->AddPage('L', array($size['w'], $size['h']));
  2011. //            } else {
  2012. //                $pdf->AddPage('P', array($size['w'], $size['h']));
  2013. //            }
  2014. //            // use the imported page
  2015. //            $pdf->useTemplate($templateId);
  2016. //            $pdf->SetTextColor(195, 40, 40);
  2017. //            $pdf->SetFont('Helvetica', '', 10);
  2018. //
  2019. //            $text_height = 36;
  2020. //            $start_x = $pdf->GetX();
  2021. //
  2022. //
  2023. //            $newFileName = "/uploads/missions/lettre_voiture_europeenne_HD_" . $id . ".pdf";
  2024. //            $newFileNamePath = $_SERVER['DOCUMENT_ROOT'] . $newFileName;
  2025. //            $pdf->Output($newFileNamePath, "F");
  2026. //            $url = "https://" . $_SERVER['SERVER_NAME'] . $newFileName;
  2027. //            $fileName = "lettre_voiture_europeenne_HD_" . $id . ".pdf";
  2028. //
  2029. //            return new JsonResponse(['url' => $url, 'fileName' => $fileName], Response::HTTP_OK);
  2030. ////            header('Access-Control-Allow-Origin: *');
  2031. //
  2032. //            //return base64_encode($pdf->Output($newFileNamePath, "F"));
  2033. //        }
  2034. //    }
  2035.     #[Route('/api/update/planned-at-date/{userId}', name: 'app_update_planned_at_date', methods: ['POST'])]
  2036.     public function update_planned_at($userId, Request $request)
  2037.     {
  2038.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2039.         if (is_string($auth)) {
  2040.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2041.         }
  2042.         //recuperation du data from request.
  2043.         $data = json_decode($request->getContent(), true);
  2044.         $task = $this->_taskRepository->findOneBy(["id" => $data['mission_id']]);
  2045.         $this->_tasksService->updatePlannedAt($task, new DateTime($data['planned_at']));
  2046.         $status_ = $this->_refStatusRepository->findStatusBy("mission", "ready");
  2047.         $status = $this->_refStatusRepository->findOneBy(['id' => $status_[0]['id']]);
  2048.         $this->_tasksService->addStatusTaskHistory($task, $status);
  2049.         // événement
  2050.         $user = $this->_userRepository->findOneBy(["id" => $userId]);
  2051.         $message = "La date de planification est modifiée.";
  2052.         $addTaskCommentEvent = new AddTaskCommentEvent($this->_doctrine, $user, $message, $task);
  2053.         $this->_dispatcher->dispatch($addTaskCommentEvent, AddTaskCommentEvent::ADD_TASK_COMMENT_EVENT);
  2054.         return new JsonResponse(['message' => "success", 'status' => 200], Response::HTTP_OK);
  2055.     }
  2056.     #[Route('/api/task/add/comment/{userId}', name: 'app_task_add_comment', methods: ['POST'])]
  2057.     public function task_add_comment($userId, Request $request)
  2058.     {
  2059.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2060.         if (is_string($auth)) {
  2061.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2062.         }
  2063.         //recuperation du data from request.
  2064.         $data = json_decode($request->getContent(), true);
  2065.         $task = $this->_taskRepository->findOneBy(["id" => $data['mission_id']]);
  2066.         $user = $this->_userRepository->findOneBy(["id" => $userId]);
  2067.         $data['user'] = $user;
  2068.         $data['task'] = $task;
  2069.         $this->_tasksService->setTaskComment($data);
  2070.         return new JsonResponse(['message' => "success", "status" => 200], Response::HTTP_OK);
  2071.     }
  2072.     #[Route('/api/upload/details/task', name: 'app_upload_details_task', methods: ['POST'])]
  2073.     public function upload_files_task(Request $request)
  2074.     {
  2075.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2076.         if (is_string($auth)) {
  2077.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2078.         }
  2079.         //recuperation du data from request.
  2080.         $user_id = $request->request->get('user_id');
  2081.         $task_id = $request->request->get('task_id');
  2082.         $nbr_files = $request->request->get('nbr_files');
  2083.         // get connected user
  2084.         $user = $this->_userRepository->find($user_id);
  2085.         // get carrier
  2086.         $carrier = $user->getCarriers();
  2087.         $data['task'] = $this->_taskRepository->find($task_id);
  2088.         $data['user'] = $user;
  2089.         $data['carrier'] = $carrier;
  2090.         for ($i = 0; $i < $nbr_files; $i++) {
  2091.             $uploadedFile = $request->files->get('file_' . $i);
  2092.             if ($uploadedFile) {
  2093.                 $upload = $this->_uploadService->uploadFile($uploadedFile, $data);
  2094.             }
  2095.         }
  2096.         return new JsonResponse(['message' => "success", 'status' => 200], Response::HTTP_OK);
  2097.     }
  2098.     #[Route('/api/task/tracking', name: 'app_task_tracking', methods: ['POST'])]
  2099.     public function task_tracking(Request $request)
  2100.     {
  2101.         $data = json_decode($request->getContent(), true);
  2102.         $data['task'] = $this->_taskRepository->findOneBy(['id' => $data['task_id']]);
  2103.         $this->_tasksService->addTaskTracking($data);
  2104.         return new JsonResponse(['message' => "success", 'status' => 200], Response::HTTP_OK);
  2105.     }
  2106.     #[Route('/api/driver/tracking', name: 'app_driver_tracking', methods: ['POST'])]
  2107.     public function driver_tracking(Request $request)
  2108.     {
  2109.         $data = json_decode($request->getContent(), true);
  2110.         if (!isset($data['user_id'])) {
  2111.             return new JsonResponse(['message' => "User id is missing", 'status' => 400], Response::HTTP_BAD_REQUEST);
  2112.         }
  2113.         $user = $this->_userRepository->find($data['user_id']);
  2114.         if (!$user) {
  2115.             return new JsonResponse(['message' => "User not found", 'status' => 404], Response::HTTP_NOT_FOUND);
  2116.         }
  2117.         $driver = $this->_driversRepository->findOneBy(['user' => $user]);
  2118.         if ($driver) {
  2119.             $taskDrivers = $this->_taskDriverRepository->findBy(['driver' => $driver]);
  2120.             foreach($taskDrivers as $td) {
  2121.                 $task = $td->getTasks();
  2122.                 if ($task) {
  2123.                     $lastStatus = $this->_taskStatusHistoryRepository->findStatusByTaskId($task->getId());
  2124.                     if (isset($lastStatus[0]) && $lastStatus[0]['slug'] === 'started') {
  2125.                         $data['task'] = $task;
  2126.                         $this->_tasksService->addTaskTracking($data);
  2127.                     }
  2128.                 }
  2129.             }
  2130.         }
  2131.         return new JsonResponse(['message' => "success", 'status' => 200], Response::HTTP_OK);
  2132.     }
  2133.     /**
  2134.      * Récupération de tous les chauffeurs affectés à une mission.
  2135.      * @OA\Tag(name="Missions")
  2136.      * @Security(name="Vyront")
  2137.      * @OA\Response(
  2138.      *     response=200,
  2139.      *     description="Retourne la liste des chauffeurs affectés à une mission."
  2140.      * )
  2141.      */
  2142.     #[Route('/api/chauffeurs/task/{id}', name: 'app_task_chauffeurs', methods: ['GET', "POST"])]
  2143.     public function task_chauffeurs(Request $request, $id)
  2144.     {
  2145.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2146.         if (is_string($auth)) {
  2147.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2148.         }
  2149.         return new JsonResponse(['chauffeurs' => $this->_taskDriverRepository->findDriversByTaskId($id), "status" => 200], Response::HTTP_OK);
  2150.     }
  2151.     /**
  2152.      * Récupération de toutes les véhicules affectées à une mission.
  2153.      * @OA\Tag(name="Missions")
  2154.      * @Security(name="Vyront")
  2155.      * @OA\Response(
  2156.      *     response=200,
  2157.      *     description="Retourne la liste des véhicules affectées à une mission."
  2158.      * )
  2159.      */
  2160.     #[Route('/api/vehicules/task/{id}', name: 'app_task_vehicules', methods: ['GET', "POST"])]
  2161.     public function task_vehicules(Request $request, $id)
  2162.     {
  2163.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2164.         if (is_string($auth)) {
  2165.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2166.         }
  2167.         return new JsonResponse(['vehicules' => $this->_taskVehiculeRepository->findVehiculesByTaskId($id), "status" => 200], Response::HTTP_OK);
  2168.     }
  2169.     /**
  2170.      * Détachement d'un chauffeur d'une mission.
  2171.      * @OA\Tag(name="Missions")
  2172.      * @Security(name="Vyront")
  2173.      * @OA\Response(
  2174.      *     response=200,
  2175.      *     description="Retourne un message de succès."
  2176.      * )
  2177.      */
  2178.     #[Route('/api/task/{id}/driver/{driver_id}/remove', name: 'app_detach_chauff_task', methods: ['POST'])]
  2179.     public function detach_chauff_task(Request $request, $id, $driver_id)
  2180.     {
  2181.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2182.         if (is_string($auth)) {
  2183.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2184.         }
  2185.         $taskDriver = $this->_taskDriverRepository->findOneBy(['task' => $id, 'driver' => $driver_id]);
  2186.         $this->_taskDriverRepository->remove($taskDriver, true);
  2187.         return new JsonResponse(['message' => "Le chauffeur a été détaché avec succès !", "status" => 200], Response::HTTP_OK);
  2188.     }
  2189.     /**
  2190.      * Détachement d'une véhicule d'une mission.
  2191.      * @OA\Tag(name="Missions")
  2192.      * @Security(name="Vyront")
  2193.      * @OA\Response(
  2194.      *     response=200,
  2195.      *     description="Retourne un message de succès."
  2196.      * )
  2197.      */
  2198.     #[Route('/api/task/{id}/vehicule/{vehicule_id}/remove', name: 'app_detach_vehicule_task', methods: ['POST'])]
  2199.     public function detach_vehicule_task(Request $request, $id, $vehicule_id)
  2200.     {
  2201.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2202.         if (is_string($auth)) {
  2203.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2204.         }
  2205.         $taskVehicule = $this->_taskVehiculeRepository->findOneBy(['task' => $id, 'vehicule' => $vehicule_id]);
  2206.         $this->_taskVehiculeRepository->remove($taskVehicule, true);
  2207.         return new JsonResponse(['message' => "La véhicule a été détachée avec succès !", "status" => 200], Response::HTTP_OK);
  2208.     }
  2209.     #[Route('/api/driver-position/{taskId}', name: 'app_driver_position', methods: ['GET', "POST"])]
  2210.     public function driver_position(Request $request, $taskId)
  2211.     {
  2212.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2213.         if (is_string($auth)) {
  2214.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2215.         }
  2216.         $position = $this->_taskTrakingRepository->getLastPosition($taskId);
  2217.         return new JsonResponse(['position' => $position, "status" => 200], Response::HTTP_OK);
  2218.     }
  2219.     #[Route('/api/google-map-directions', name: 'app_get_google_map_directions', methods: ['POST'])]
  2220.     public function get_google_map_directions(Request $request)
  2221.     {
  2222.         $auth = $this->jwtHelper->verifyJwt($request, []);
  2223.         if (is_string($auth)) {
  2224.             return new JsonResponse(['message' => $auth, 'status' => 401], JsonResponse::HTTP_UNAUTHORIZED);
  2225.         }
  2226.         $data = json_decode($request->getContent(), true);
  2227.         $googleMapDirections = $this->_tasksService->getGoogleMapDirections($data);
  2228.         return new JsonResponse(["googleMapDirectionData" => $googleMapDirections, "status" => 200], Response::HTTP_OK);
  2229.     }
  2230. }