src/Controller/ProductController.php line 212

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Component\Routing\Annotation\Route;
  10. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  11. use Symfony\Component\HttpFoundation\Cookie;
  12. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  13. use GuzzleHttp\Client;
  14. use App\Entity\commande;
  15. use App\Entity\Transaction;
  16. use App\Entity\Typologie;
  17. use App\Entity\Residence;
  18. use App\Entity\mediaResidence;
  19. use App\Entity\Language;
  20. use App\Entity\InfosResidence;
  21. use App\Entity\Package;
  22. use App\Entity\InfosFormuleBase;
  23. use App\Entity\InfosDiscover;
  24. use App\Entity\InfosDiscoverLink;
  25. use App\Entity\InfosEvent;
  26. use App\Entity\OptionResidence;
  27. use App\Entity\Destination;
  28. use App\Exception\ProductGoneWithSuggestionsException;
  29. use App\Exception\ProductNotFoundWithSuggestionsException;
  30. use App\Repository\TransactionRepository;
  31. use App\Utils\Residences;
  32. use App\Utils\IresaManager;
  33. use App\Utils\UpdateTraductions;
  34. use App\Services\ToolService;
  35. use App\Services\TravellerService;
  36. use App\Services\SeasonService;
  37. use App\Services\SlugRouterService;
  38. /**
  39.  * @Route("/{_locale}", requirements={"_locale": "en|fr"})
  40.  */
  41. class ProductController extends AbstractController
  42. {
  43.     /**
  44.      * @var EntityManagerInterface
  45.      */
  46.     private $em;
  47.     
  48.      /**
  49.      * @var SessionInterface
  50.      */
  51.     private $session;
  52.     private $flashbag;
  53.     private $user;
  54.     private $seasonService;
  55.     private $residenceService;
  56.     private $iresaManager;
  57.     private $toolService;
  58.     private $updateTraductions;
  59.     private $travellerService;
  60.     private $slugRouterService;
  61.     function __construct(EntityManagerInterface $em,  SessionInterface $sessionSeasonService $seasonServiceResidences $residenceServiceIresaManager $iresaManagerToolService $toolServiceUpdateTraductions $updateTraductionsTravellerService $travellerServiceSlugRouterService $slugRouterService) {
  62.         $this->em $em;
  63.         $session $session;
  64.         $this->flashbag $session->getFlashBag();
  65.         
  66.         $this->seasonService $seasonService;
  67.         $this->residenceService $residenceService;
  68.         $this->iresaManager $iresaManager;
  69.         $this->toolService $toolService;
  70.         $this->updateTraductions $updateTraductions;
  71.         $this->travellerService $travellerService;
  72.         $this->slugRouterService $slugRouterService;
  73.     }
  74.     /**
  75.      * Route de compatibilité - Ancienne structure avec ID
  76.      * Redirige 301 vers la nouvelle structure sans ID
  77.      * @Route("/produit/{slug}/{id}", name="ac_platform_produit", requirements={"id"="\d+"})
  78.      */
  79.     public function produitLegacyRedirect(Request $requeststring $slugint $id): Response
  80.     {
  81.         $locale $request->getLocale();
  82.         $lang $this->em->getRepository(Language::class)->findOneByCode($locale);
  83.         
  84.         // Charger la résidence par idiresa
  85.         $residence $this->em->getRepository(Residence::class)->findOneBy(['idiresa' => $id]);
  86.         
  87.         if (!$residence) {
  88.             throw $this->createNotFoundException('Résidence inexistante');
  89.         }
  90.         
  91.         // Trouver l'OptionResidence pour cette langue
  92.         $optionResidence $this->em->getRepository(OptionResidence::class)->findOneBy([
  93.             'residence' => $residence,
  94.             'lang' => $lang
  95.         ]);
  96.         
  97.         if (!$optionResidence) {
  98.             throw $this->createNotFoundException('Résidence non disponible dans cette langue');
  99.         }
  100.         
  101.         // Récupérer le slug canonique
  102.         $canonicalSlug $optionResidence->getCanonical();
  103.         if (empty($canonicalSlug)) {
  104.             // Fallback sur le slug historique si pas de canonical
  105.             $canonicalSlug $residence->getSlug() ?: $slug;
  106.         }
  107.         
  108.         // Préserver les query parameters
  109.         $queryParams $request->query->all();
  110.         
  111.         return $this->redirectToRoute('ac_platform_produit_slug'
  112.             array_merge(['slug' => $canonicalSlug], $queryParams), 
  113.             301
  114.         );
  115.     }
  116.     /**
  117.      * Route principale - Nouvelle structure avec slug uniquement
  118.      * @Route("/residence/{slug}", name="ac_platform_produit_slug")
  119.      */
  120.     public function produit(Request $requeststring $slug): Response 
  121.     {
  122.         $locale $request->getLocale();
  123.         
  124.         // Résoudre le slug vers une OptionResidence
  125.         $result $this->slugRouterService->resolveResidenceSlug($slug$locale);
  126.         
  127.         if (!$result) {
  128.             throw $this->createNotFoundException('Résidence non trouvée');
  129.         }
  130.         
  131.         // Vérifier si on doit rediriger vers le slug canonique
  132.         if (!$result['is_canonical'] && !empty($result['canonical_slug'])) {
  133.             // Préserver les query parameters
  134.             $queryParams $request->query->all();
  135.             
  136.             return $this->redirectToRoute('ac_platform_produit_slug'
  137.                 array_merge(['slug' => $result['canonical_slug']], $queryParams), 
  138.                 301
  139.             );
  140.         }
  141.         
  142.         // Récupérer l'OptionResidence et la Residence depuis le résultat
  143.         $optionResidence $result['entity'];
  144.         
  145.         $residence $optionResidence->getResidence();
  146.         $id $residence->getIdiresa(); // Récupérer l'ID depuis l'entité
  147.         
  148.         $session $request->getSession();
  149.         $message = [];
  150.         $themes null;
  151.         $prestationDefault null;
  152.         $listDurees = [];
  153.         $listDatesDebut = [];
  154.         $services null;
  155.         $selectedFormule 0;
  156.         $selectedHebergement null;
  157.         $packages = [];
  158.         if ($session->has('formule')) {
  159.             $message[] = "Formule en session";
  160.             $selectedFormule $session->get('formule');
  161.         }
  162.         $lang  $this->em->getRepository(Language::class)->findOneByCode($locale);
  163.         $lang_default  $this->em->getRepository(Language::class)->findOneByCode('fr');
  164.         
  165.         /* Instanciation des services */
  166.         $season $this->seasonService->getSeason();
  167.         $this->residenceService->setLocale($locale);
  168.         
  169.         $comm_status true;
  170.         if($id != $this->travellerService->travellers['idResidence'] || $session == "renew") {
  171.             $this->travellerService->init();
  172.             $this->travellerService->travellers['idResidence'] = $id;
  173.             $session->remove('idPrestation');
  174.             $session->remove('idPresta');
  175.             $session->remove('hebergement');
  176.             $session->remove('formule');
  177.             $session->remove('resas');
  178.             $session->remove('comment');
  179.             $session->remove('tarifs');
  180.             $session->remove('codepromo');
  181.             $session->remove('idPack');
  182.             $session->remove('idtyposelected');
  183.             $session->remove('residence');
  184.         }
  185.         
  186.         $session->set('residence' , ['slug' => $slug'id' => $id]);
  187.         // Vérification si la résidence est "Non reconduite" (discontinued)
  188.         if($residence && $residence->getDiscontinued()) {
  189.             // Si des suggestions de résidences sont définies, on redirige vers la première active
  190.             if($optionResidence && $optionResidence->getReplacementSuggestions()->count() > 0) {
  191.                 $residences = [];
  192.                 foreach($optionResidence->getReplacementSuggestions() as $suggestion) {
  193.                     $suggestedResidence $suggestion->getResidence();
  194.                     if($suggestedResidence && $suggestedResidence->getCommercialisation() && !$suggestedResidence->getDiscontinued()) {
  195.                         $residences[] = [
  196.                             'residence' => $suggestedResidence,
  197.                             'infosResidence' => $this->em->getRepository(InfosResidence::class)->findOneBy([
  198.                                 'residence' => $suggestedResidence,
  199.                                 'lang' => $lang
  200.                             ]),
  201.                             'infosFormuleBase' => $this->em->getRepository(InfosFormuleBase::class)->findOneBy([
  202.                                 'residence' => $suggestedResidence,
  203.                                 'lang' => $lang
  204.                             ]),
  205.                         ];
  206.                     }
  207.                 }
  208.                 throw new ProductGoneWithSuggestionsException('Résidence inexistante'$residences);
  209.             }
  210.         }
  211.         
  212.         $residence_id $residence->getId();
  213.         $params_default = [
  214.             'lang' => $lang_default,
  215.             'residence' => $residence
  216.         ];
  217.         $params_trad = [
  218.             'lang' => $lang,
  219.             'residence' => $residence
  220.         ];
  221.         $breadCrumb $this->residenceService->getBreadcrumb($residence);
  222.         
  223.         $infosResidence $this->em->getRepository(InfosResidence::class)->findOneBy($params_trad);
  224.         if(!$infosResidence) {
  225.             $infosResidence $this->em->getRepository(InfosResidence::class)->findOneBy($params_default);
  226.         }
  227.         $formules $this->em->getRepository(Package::class)->findOnPageBy($params_trad);
  228.         if(!$formules) {
  229.             $formules $this->em->getRepository(Package::class)->findOnPageBy($params_default);
  230.         }
  231.         
  232.         $formuleBase $this->em->getRepository(InfosFormuleBase::class)->findOneBy($params_trad);
  233.         if(!$formuleBase) {
  234.             $formuleBase $this->em->getRepository(InfosFormuleBase::class)->findOneBy($params_default);
  235.         }
  236.         
  237.         $formules array_merge([$formuleBase], $formules);
  238.         $typologies $this->em->getRepository(Typologie::class)->findOnPageBy($params_trad);
  239.         if(!$typologies) {
  240.             $typologies $this->em->getRepository(Typologie::class)->findOnPageBy($params_default);
  241.         }
  242.         
  243.         $listDiscover $this->em->getRepository(InfosDiscover::class)->findBy($params_trad);
  244.         if(!$listDiscover) {
  245.             $listDiscover $this->em->getRepository(InfosDiscover::class)->findBy($params_default);
  246.         }
  247.         $listDiscoverLink $this->em->getRepository(InfosDiscoverLink::class)->findBy($params_trad);
  248.         if(!$listDiscoverLink) {
  249.             $listDiscoverLink $this->em->getRepository(InfosDiscoverLink::class)->findBy($params_default);
  250.         }
  251.         $listEvent $this->em->getRepository(InfosEvent::class)->findBy($params_trad);
  252.         if(!$listEvent) {
  253.             $listEvent $this->em->getRepository(InfosEvent::class)->findBy($params_default);
  254.         }
  255.         $slidesHeaderDefault $this->em->getRepository(mediaResidence::class)->findByLocation($residence_id"header"$lang_default$season);
  256.         $slidesContentDefault $this->em->getRepository(mediaResidence::class)->findByLocation($residence_id"content"$lang_default$season);
  257.         $slidesHeader $this->em->getRepository(mediaResidence::class)->findByLocation($residence_id"header"$lang$season);
  258.         if(is_null($slidesHeader)) {
  259.             $slidesHeader $slidesHeaderDefault;
  260.         }
  261.         $slidesContent $this->em->getRepository(mediaResidence::class)->findByLocation($residence_id"content"$lang$season);
  262.         if(is_null($slidesContent)) {
  263.             $slidesContent $slidesContentDefault;
  264.         }
  265.         $dispoResidence $optionResidence->getEtat();
  266.         if(!$dispoResidence) {
  267.             // Récupérer des suggestions d'hébergements alternatifs
  268.             $suggestions $this->findAlternativeResidences($residence$breadCrumb$locale3);
  269.             $aff_date $request->query->get('aff_date'false);
  270.             $vars = [
  271.                 "aff_date" => $aff_date,
  272.                 "id" => $id,
  273.                 "comm_status" => $comm_status,
  274.                 "slug" => $slug,
  275.                 "residence" => $residence,
  276.                 "current_entity" => $residence,
  277.                 "current_entity_type" => 'Residence',
  278.                 "infosResidence" => $infosResidence,
  279.                 "slidesHeader" => $slidesHeader,
  280.                 "slidesContent" => $slidesContent,
  281.                 "themes" => $themes,
  282.                 'breadCrumb' => $breadCrumb,
  283.                 'suggestions' => $suggestions
  284.             ];
  285.             return $this->render('/front/Produit/produit_indispo.html.twig'$vars);
  286.         }
  287.         
  288.         
  289.         /* on récupère les paramètres de recherche s'il y en a */
  290.         
  291.         /*
  292.          * par défaut on teste les dispos pour une durée de 7 jours
  293.          */
  294.       
  295.         // Recherche des données colonne de droite
  296.         $now = new \DateTime();
  297.         $duree 7
  298.         
  299.         // On regarde s'il y a des prestations dans l'année
  300.         $datearrivee = (new \Datetime())->modify('+ 1 day')->format("Y-m-d");
  301.         $prestations $this->residenceService->getPrestations($id$datearrivee$duree$request->getLocale(), 360);
  302.         
  303.         if(count($prestations['ListReponses']) > 0)  {
  304.             if ($request->getMethod() == 'POST') { // Maj des participants
  305.                 $this->travellerService->setTravellers($request->request);
  306.             }
  307.             if($request->query->has("datearrivee")) {
  308.                 $session->remove('formule');
  309.                 $session->remove('hebergement');
  310.                 $tdatearrivee =  $request->query->get("datearrivee");
  311.                 $duree = (int) $request->query->has("duree") ? $request->query->get("duree") : 7;
  312.                 if($this->toolService->validateDate($tdatearrivee'Y-m-d') || $this->toolService->validateDate($tdatearrivee'd/m/Y')) {
  313.                     $datearrivee =  $tdatearrivee;
  314.                     $access false;
  315.                     $this->travellerService->setTravellers($request->query);
  316.                     $this->travellerService->setDateDuree($datearrivee$duree);
  317.                 }
  318.             } else {
  319.                 if(empty($this->travellerService->travellers['actdatearrivee'])) {
  320.                     /* 
  321.                         On recherche une prestation par défaut, 
  322.                         la première date disponible 
  323.                         et le tarif le moins cher en affichant à partir de
  324.                     */
  325.                     // si oui on recherche la prestation par défaut et la première date de disponibilité à partir de tomorrow
  326.                     $obj = [
  327.                         "IdLieuHebergement" => $id,
  328.                         "NbDates" => 1
  329.                     ];
  330.                     
  331.                     $dispoPrice $this->iresaManager->getDispoPrice($obj);
  332.                     if ($dispoPrice['ListPrestations']) {   // plusieurs formules existent
  333.                         foreach ($dispoPrice['ListPrestations'] as $formule => $prestation) { 
  334.                             $dispoPricePrestations [] = $prestation;
  335.                         }
  336.                     }
  337.                     $tdatearrivee $dispoPricePrestations[0]['DateDebut'] ;
  338.                     $duree $dispoPricePrestations[0]['Duree'];
  339.                     $datearrivee = \DateTime::createFromFormat("Y-m-d"$tdatearrivee)->format('d/m/Y');
  340.                     $this->travellerService->setTravellers($request->query);
  341.                     $this->travellerService->setDateDuree($datearrivee$duree);
  342.                     
  343.                 }
  344.             }
  345.             
  346.             $dateDebutDefault $this->travellerService->travellers['actdatearrivee'];
  347.             $datearrivee $this->travellerService->travellers['actdatearrivee'];
  348.             $duree $this->travellerService->travellers['actnbnuits'];
  349.             $type $request->query->get('type');
  350.             $delta $type == "planning" 31 0;
  351.             
  352.             /* BEGIN  DUPLICATE CODE  BLOC 1*/
  353.             $planning $this->residenceService->getPlanning($request$datearrivee$duree$type$delta$residence );
  354.             if ($planning == "redirect"
  355.             { 
  356.                 if($request->isXmlHttpRequest()) {// Envoi signale de redirection via ajax
  357.                     $response = new Response("{'redirect': true}");
  358.                     $response->headers->set('Content-Type''application/json');
  359.                     return $response;
  360.                 } else { // Redirection vers le produit
  361.                     return $this->redirectToRoute('ac_platform_produit', ['slug' => $slug'id' => $id]);
  362.                 }
  363.             }
  364.             $packages $planning['packages'];
  365.             $prestations $planning['prestations'];
  366.             $listDatesDebut $planning['listDatesDebut'];
  367.             $listDurees $planning['listDurees'];
  368.             $idPrestationDefault $planning['idPrestationDefault'];
  369.             /* END  DUPLICATE CODE  BLOC 1*/
  370.         }
  371.         $comm_status true;
  372.         if(count($prestations['ListReponses']) == 0) {
  373.             $comm_status false;
  374.             $idPrestationDefault null;
  375.         }
  376.         if(!$comm_status) {
  377.             $produit null;
  378.             $formules null;
  379.             $reponses null;
  380.         }
  381.         
  382.         $comm_status true;
  383.         
  384.         $vars = array(
  385.             "id" => $id,
  386.             "comm_status" => $comm_status,
  387.             "slug" => $slug,
  388.             "residence" => $residence,
  389.             "dispoResidence" => $dispoResidence,
  390.             "current_entity" => $residence,  // Pour le menu de changement de langue
  391.             "current_entity_type" => 'Residence',  // Type d'entité pour le menu
  392.             "travellers" => $this->travellerService->getTravellers(),
  393.             "typos" => $typologies,                                 // Contenu des typologies
  394.             "formuleBase" => $formuleBase,                           // contenu des packages et formule de base
  395.             "formules" => $formules,    
  396.             "packages" => $packages,
  397.             "prestations" => $prestations,
  398.             "infosResidence" => $infosResidence,
  399.             "listDiscover" => $listDiscover,
  400.             "listDiscoverLink" =>$listDiscoverLink,
  401.             "listEvent" => $listEvent,
  402.             "slidesHeader" => $slidesHeader,
  403.             "slidesContent" => $slidesContent,
  404.             "themes" => $themes,
  405.             "prestationDefault" => $prestationDefault,
  406.             "listDurees" => json_encode($listDureesJSON_UNESCAPED_SLASHES),
  407.             "duree" => $duree//$listDurees[0],
  408.             "listDatesDebut" => json_encode($listDatesDebut),
  409.             "idPrestationDefault" => $idPrestationDefault,
  410.             'selectedFormule' => $selectedFormule,
  411.             'selectedHebergement' => $selectedHebergement,
  412.             'toolService' => $this->toolService,
  413.             'breadCrumb' => $breadCrumb
  414.         );
  415.         return $this->render('/front/Produit/produit.html.twig'$vars);
  416.     }
  417.     /**
  418.      * Redirige vers une destination active en remontant la hiérarchie
  419.      */
  420.     private function redirectToActiveDestination(Residence $residenceLanguage $lang): Response
  421.     {
  422.         // Récupération de la destination parente de la résidence
  423.         $destinationIresa $residence->getDestinationIdiresa();
  424.         
  425.         if ($destinationIresa) {
  426.             // Recherche de résidences actives dans la même destination
  427.             $activeResidences $this->em->getRepository(Residence::class)->createQueryBuilder('r')
  428.                 ->innerJoin(OptionResidence::class, 'o''WITH''o.residence = r.id')
  429.                 ->where('r.destinationIdiresa = :destinationId')
  430.                 ->andWhere('r.commercialisation = true')
  431.                 ->andWhere('r.discontinued = false')  
  432.                 ->andWhere('o.etat = true')
  433.                 ->andWhere('o.lang = :lang')
  434.                 ->setParameter('destinationId'$destinationIresa)
  435.                 ->setParameter('lang'$lang)
  436.                 ->setMaxResults(1)
  437.                 ->getQuery()
  438.                 ->getResult();
  439.             
  440.             if (!empty($activeResidences)) {
  441.                 $activeResidence $activeResidences[0];
  442.                 //$slug = $this->toolService->slugify($activeResidence->getNom());
  443.                 $slug $activeResidence->getSlug();
  444.                 return $this->redirectToRoute('ac_platform_produit', [
  445.                     'slug' => $slug
  446.                     'id' => $activeResidence->getIdIresa()
  447.                 ]);
  448.             }
  449.             
  450.             // Si aucune résidence active dans la destination, rediriger vers la page destination
  451.             $params = [
  452.                 'lang_id' => $lang->getId(),
  453.                 'code_traduction' => $destinationIresa
  454.             ];
  455.             
  456.             $destination $this->em->getRepository(Destination::class)->findOneByLang($params);
  457.             if ($destination) {
  458.                 $slug $destination->getCanonical();
  459.                 return $this->redirectToRoute('ac_platform_destination_slug', [
  460.                     'slug' => $slug,
  461.                 ]);
  462.             }
  463.         }
  464.         
  465.         // En dernier recours, rediriger vers l'accueil
  466.         return $this->redirectToRoute('ac_platform_homepage');
  467.     }
  468.     
  469.     /**
  470.      * @Route("/produit/refresh", name="ac_platform_produit_refresh")
  471.      */
  472.     public function productRefresh(Request $request)
  473.     {
  474.         $session $request->getSession();
  475.         $type $request->query->get('type');
  476.         $delta $type == "month" 31 0;
  477.         
  478.         $message = [];
  479.         $message[] = "Refresh typologies";
  480.         
  481.         $locale $request->getLocale();
  482.         
  483.         $now = new \DateTime();
  484.         $lang  $this->em->getRepository(Language::class)->findOneByCode($locale);
  485.         
  486.         
  487.         
  488.         $this->residenceService->setLocale($locale);
  489.         
  490.         $travellers $this->travellerService->travellers;
  491.         if($travellers['idResidence'] != $request->query->get('id')) {
  492.             $travellers['idResidence'] = $request->query->get('id');
  493.             $this->travellerService->travellers $travellers;
  494.         }
  495.         
  496.         //$id = $request->query->get('id');
  497.         $id $this->travellerService->travellers['idResidence'];
  498.         
  499.         $datearrivee $request->query->get('datearrivee');
  500.         $duree $request->query->get('duree');
  501.         $datearrivee $this->toolService->dateFrToEn($datearrivee);
  502.         $dateDebutDefault $datearrivee;
  503.         $this->travellerService->setDateDuree($datearrivee$duree);
  504.         
  505.         $residence =  $this->em->getRepository(Residence::class)->findOneBy(['idiresa' => $id]);
  506.         if(!$residence) {
  507.             throw $this->createNotFoundException('Résidence inexistante');
  508.         }
  509.         $params = [
  510.             'lang' => $lang,
  511.             'residence' => $residence
  512.         ];
  513.         $typologies $this->em->getRepository(Typologie::class)->findOnPageBy($params);
  514.         $packages $this->em->getRepository(Package::class)->findOnPageBy($params);
  515.         /* BEGIN  DUPLICATE CODE  BLOC 1*/
  516.         $planning $this->residenceService->getPlanning($request$datearrivee$duree$type$delta$residence );
  517.        
  518.         if (isset($planning['redirect']))  {
  519.             if($request->isXmlHttpRequest()) {// Envoi signale de redirection via ajax
  520.                 $response = new Response("{'redirect': true}");
  521.                 $response->headers->set('Content-Type''application/json');
  522.                 return $response;
  523.             } else { // Redirection vers le produit
  524.                 //$residence_nom = str_replace("*", "", $residence->getNom());
  525.                 //$residence_slug = $this->toolService->slugify($residence_nom);
  526.                 $residence_slug $residence->getSlug();
  527.                 return $this->redirectToRoute('ac_platform_produit', ['slug' => $residence_slug'id' => $id]);
  528.             }
  529.         }
  530.         $packages $planning['packages'];
  531.         $formuleBase $packages[0];
  532.         $prestations $planning['prestations'];
  533.         $listDatesDebut $planning['listDatesDebut'];
  534.         $listDatesFin $planning['listDatesFin'];
  535.         $listDurees $planning['listDurees'];
  536.         $idPrestationDefault $planning['idPrestationDefault'];
  537.         
  538.         /* END  DUPLICATE CODE  BLOC 1*/
  539.         
  540.         $session->set('idPrestation'$idPrestationDefault);
  541.         
  542.         $selectedFormule 0;
  543.         $selectedHebergement null;
  544.         
  545.         if ($session->has('formule')) {
  546.             $message[] = "Formule en session";
  547.             $selectedFormule $session->get('formule');
  548.         }
  549.         
  550.         $hebergement $session->get('hebergement');
  551.         if (!is_null($hebergement)) {
  552.             $hebergement $session->get('hebergement');
  553.             $selectedHebergement $hebergement->IdPrestation;
  554.         }
  555.         $vars = [
  556.             "message" => $message,
  557.             'delta' => $delta,
  558.             "listDatesDebut" => $listDatesDebut,
  559.             "listDatesFin" => $listDatesFin,
  560.             "typos" => $typologies,
  561.             "listDurees" => $listDurees,
  562.             "prestations" => $prestations,                            // contenu des packages et formule de base
  563.             "formuleBase" => $formuleBase,
  564.             "packages" => $packages,
  565.             "planning" => $planning,
  566.             "idPrestationDefault" => $idPrestationDefault,
  567.             "dateDebutDefault" => $datearrivee,
  568.             "duree" => $duree,
  569.             "travellers" => $this->travellerService->getTravellers(),
  570.             "debug" => [
  571.                 'ListReponses' => $prestations['ListReponses'] ,
  572.                 'packages' => $packages,
  573.                 'Travellers' => $this->travellerService->getTravellers()
  574.             ]
  575.         ];
  576.         $response = new Response();
  577.         $response->setContent(json_encode($varsJSON_UNESCAPED_SLASHES));
  578.         $response->headers->set('Symfony-Debug-Toolbar-Replace'1);
  579.         $response->headers->set('Content-Type''application/json');
  580.         return $response;
  581.     }
  582.     
  583.     /**
  584.      * @Route("/getHebergements", name="ac_platform_getHebergements")
  585.      */
  586.     public function getHebergements(Request $request) { 
  587.         $locale $request->getLocale();
  588.         $session $request->getSession();
  589.         $mode "";
  590.         $method "html";
  591.         $prestations $request->request->get('prestations');
  592.         if($request->query->has('edit')) {$mode "edit";}
  593.         if($request->query->has('method')) {$method $request->request->get('method');}
  594.         
  595.         $this->residenceService->setLocale($locale);
  596.         
  597.         $selectedHebergementId null;
  598.         if ($session->has('hebergement')) {
  599.             $selectedHebergement $session->get('hebergement');
  600.             $selectedHebergementId $selectedHebergement->IdPrestation;
  601.         }
  602.         
  603.         $hebergements $this->residenceService->getHebergements($prestations$selectedHebergementId$mode);
  604.         if($method == "ajax") {
  605.             return new JsonResponse($hebergements);
  606.         }
  607.         return new Response($hebergements);
  608.     }
  609.     /**
  610.      * @Route("/setcodepromo", name="ac_platform_setcodepromo")
  611.      */
  612.     public function setcodepromo(Request $request)
  613.     {
  614.         $session $request->getSession();
  615.         $codepromo $request->request->get("codepromo");
  616.         $session->set('codepromo'$codepromo);
  617.         
  618.         return new JsonResponse($codepromo);
  619.     }
  620.     /**
  621.      * @Route("/setSessionVar", name="product_setSessionVar")
  622.      */
  623.     public function setSessionVar(Request $request) {
  624.         $session $request->getSession();
  625.         $var $request->request->get("var");
  626.         $value $request->request->get("value");
  627.         $ret $session->set($var$value);
  628.         return new JsonResponse($ret);
  629.     }
  630.      /**
  631.      * @Route("/setSession", name="ac_platform_setSession")
  632.      */
  633.     public function setSession(Request $request)
  634.     {
  635.         $session $request->getSession();
  636.         $id $request->request->get("id");
  637.         $val $request->request->get("val");
  638.         $session->set($id$val);
  639.         return new JsonResponse($id."done".$val);
  640.     }
  641.     
  642.     /**
  643.      * @Route("/participants", name="ac_platform_participants")
  644.      */
  645.     public function participants(Request $request)
  646.     {
  647.         $retour = array();
  648.         return $this->render('/front/Recherche/participants.html.twig'$retour);
  649.     }
  650.     /**
  651.      * @Route("/setages", name="ac_platform_setages")
  652.      */
  653.     public function setages(Request $request)
  654.     {
  655.         
  656.         $travellers $this->travellerService->travellers;
  657.         if($travellers['idResidence'] != $request->request->get('id')) {
  658.             $travellers['idResidence'] = $request->request->get('id');
  659.             $this->travellerService->travellers $travellers;
  660.         }
  661.         $result =  $this->travellerService->setTravellers($request->request);
  662.         return new JsonResponse($result);
  663.     }
  664.     /**
  665.      * @Route("/getages", name="ac_platform_getages")
  666.      */
  667.     public function getages(Request $request)
  668.     {
  669.         $type $request->query->get("type""enfants");
  670.      
  671.         $travellers $this->travellerService->travellers;
  672.         $nb 0;
  673.         if($request->request->has("nb" $type)) {
  674.             $nb $request->request->get("nb" $type);
  675.         } else {
  676.             $nb $travellers['actnb' $type];
  677.         }
  678.         $error 0;
  679.         foreach($travellers['ages' $type] as $ages) {
  680.             if (empty($ages)) {$error ++;}
  681.         }
  682.         
  683.         $maxDate date("Y-m-d");
  684.         if($type == "enfants") {
  685.             $date18YearsAgo strtotime("-18 years");
  686.             $minDate date("Y-m-d"$date18YearsAgo);
  687.         } elseif($type == "bebes") {
  688.             $date2YearsAgo strtotime("-2 years");
  689.             $minDate date("Y-m-d"$date2YearsAgo);
  690.         }
  691.         $retour = array(
  692.             "nb" $type => $nb,
  693.             "minDate" => $minDate,
  694.             "maxDate" => $maxDate,
  695.             "travellers" => $travellers,
  696.             "error" => $error
  697.         );
  698.         return $this->render('/front/Recherche/ages_' $type '.html.twig'$retour);
  699.     }
  700.     
  701.      /**
  702.      * @Route("/majFormule", name="ac_platform_majFormule")
  703.      */
  704.     public function majFormule()
  705.     {
  706.         return $this->render('/front/Reservation/majformule.html.twig');
  707.     }
  708.     public function mobile()
  709.     {
  710.         return $this->render('/front/Recherche/mobile.html.twig');
  711.     }
  712.     public function gettarif(Request $request)
  713.     {
  714.         $idpack $request->request->get("idpack");
  715.         $idtypo $request->request->get("idtypo");
  716.         $retour = array(
  717.             "reponse" => null,
  718.             "defaultcontenutypo" => null,
  719.             "defaultcontenuformule" => null
  720.         );
  721.         return $this->render('/front/Produit/recaptarif.html.twig'$retour);
  722.     }
  723.     public function adultes($nbadultes 1)
  724.     {
  725.         return $this->render('/front/Moteur/adultes.html.twig', ['nbadultes' => $nbadultes]);
  726.     }
  727.     
  728.     public function enfants($nbenfants 0)
  729.     {
  730.         return $this->render('/front/Moteur/enfants.html.twig', ['nbenfants' => $nbenfants]);
  731.     }
  732.     
  733.     public function bebes($nbbebes 0)
  734.     {
  735.         return $this->render('/front/Moteur/bebes.html.twig', ['nbbebes' => $nbbebes]);
  736.     }
  737.     /**
  738.      * Trouve des hébergements alternatifs en fonction de la hiérarchie de destinations
  739.      */
  740.     private function findAlternativeResidences($currentResidence, array $breadCrumbstring $localeint $maxSuggestions 3): array
  741.     {
  742.         $lang $this->em->getRepository(\App\Entity\Language::class)->findOneBy(['code' => $locale]);
  743.         if (!$lang) {
  744.             return [];
  745.         }
  746.         $fiches = [];
  747.         $currentResidenceId $currentResidence->getId();
  748.         $currentResidenceIdiresa $currentResidence->getIdiresa();
  749.         // Parcourir le breadcrumb du plus spécifique au plus général (inverse)
  750.         // Le breadcrumb contient : [Accueil, Pays, Région, Ville, ...]
  751.         $reversedBreadCrumb array_reverse($breadCrumb);
  752.         
  753.         foreach ($reversedBreadCrumb as $level) {
  754.             // Ignorer l'accueil ou niveaux sans id
  755.             if (!isset($level['id']) || empty($level['id'])) {
  756.                 continue;
  757.             }
  758.             
  759.             $destinationId $level['id'];
  760.             
  761.             // Récupérer la Destination pour obtenir son code_traduction
  762.             $destination $this->em->getRepository(\App\Entity\Destination::class)->find($destinationId);
  763.             if (!$destination) {
  764.                 continue;
  765.             }
  766.             
  767.             $destinationCodeTraduction $destination->getCodeTraduction();
  768.             
  769.             // Appeler IRESA pour récupérer les hébergements disponibles
  770.             $datearrivee = (new \DateTime())->modify('+1 day')->format('Y-m-d');
  771.             $listDurees = [714215432];
  772.             
  773.             $availabilityResult $this->iresaManager->findBestAvailability($destinationCodeTraduction$datearrivee$listDurees);
  774.             
  775.             if ($availabilityResult === false || !isset($availabilityResult['result'])) {
  776.                 continue;
  777.             }
  778.             
  779.             $result $availabilityResult['result'];
  780.             $hebergements $result["FichesLieuHebergement"] ?? [];
  781.             $reponses $result["ListReponses"];
  782.             // Filtrer pour exclure la résidence courante            
  783.             
  784.             $this->residenceService->setLocale($locale);
  785.             $fiches $this->residenceService->getSejours($hebergements$reponses$lang);
  786.             if (empty($fiches)) {
  787.                 continue;
  788.             }
  789.             
  790.             // Si on a trouvé au moins une suggestion à ce niveau, on s'arrête
  791.             if (count($fiches) > 0) {
  792.                 return $fiches;
  793.             }
  794.         }
  795.         
  796.         return $fiches;
  797.     }
  798. }