src/Controller/AccueilController.php line 372

Open in your IDE?
  1. <?php
  2. // src/Controller/AccueilController
  3. /*
  4.  * 
  5.  * Date de modification:16/05/2025
  6.  * Description:Controller LayoutAccueil 5sur5 Séjour
  7.  *
  8.  */
  9. namespace App\Controller;
  10. use App\Entity\Fonctions;
  11. use App\Entity\User;
  12. use App\Entity\Ref;
  13. use App\Entity\Commande;
  14. use App\Entity\Typeproduit;
  15. use App\Service\AttachementService;
  16. use App\Service\BlogService;
  17. use App\Service\EmailsCmdService;
  18. use App\Service\SejourService;
  19. use App\Service\SiteService;
  20. use App\Service\TypeProduiteService;
  21. use App\Service\UserService;
  22. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  23. use Symfony\Component\Routing\Annotation\Route;
  24. use Symfony\Component\HttpFoundation\Response;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\JsonResponse;
  27. use Doctrine\ORM\EntityManagerInterface;
  28. use Symfony\Component\Mailer\MailerInterface;
  29. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  30. use Symfony\Component\Mime\Address;
  31. use Psr\Log\LoggerInterface;
  32. class AccueilController extends AbstractController
  33. {
  34.     private $typeProduiteService;
  35.     private $siteService;
  36.     private $blogService;
  37.     private $UserService;
  38.     private $sejourService;
  39.     private $attachementService;
  40.     private $mailer;
  41.     private $logger;
  42.     private $emailsCmdService;
  43.     public function __construct(TypeProduiteService $typeProduiteServiceSiteService $siteServiceBlogService $blogServiceUserService $UserServiceSejourService $sejourServiceAttachementService $attachementServiceMailerInterface $mailerLoggerInterface $loggerEmailsCmdService $emailsCmdService)
  44.     {
  45.         $this->typeProduiteService $typeProduiteService;
  46.         $this->siteService $siteService;
  47.         $this->blogService $blogService;
  48.         $this->UserService $UserService;
  49.         $this->sejourService $sejourService;
  50.         $this->attachementService $attachementService;
  51.         $this->mailer $mailer;
  52.         $this->logger $logger;
  53.         $this->emailsCmdService $emailsCmdService;
  54.     }
  55.     /**
  56.      * @Route("/Accueil5sur5", name="layoutAccueil")
  57.      * */
  58.     public function layoutAccueil()
  59.     {
  60.         return $this->render('Accueil/layoutAccueil.html.twig');
  61.     }
  62.     /**
  63.      * @Route("/Accueil5sur5/header_layoutAccueil", name="header_layoutAccueil")
  64.      */
  65.     public function header(Request $request): Response
  66.     {
  67.         $produit $this->typeProduiteService;
  68.         $liste $produit->produitlistType();
  69.         // dd($liste);
  70.         $session $request->getSession();
  71.         $Products $session->get("Panier");
  72.         if ($Products == Null) {
  73.             $Products = [];
  74.         }
  75.         return $this->render('Accueil/header.html.twig', [
  76.             'produit' => $liste,
  77.             'Products' => $Products,
  78.         ]);
  79.     }
  80.     /**
  81.      * @Route("/Accueil5sur5/header_Parent", name="header_Parent")
  82.      */
  83.     public function header_Parent(Request $request): Response
  84.     {
  85.         $produit $this->typeProduiteService;
  86.         $liste $produit->produitlistType();
  87.         // dd($liste);
  88.         $session $request->getSession();
  89.         $Products $session->get("Panier");
  90.         if ($Products == Null) {
  91.             $Products = [];
  92.         }
  93.         return $this->render('Accueil/headerParents.html.twig', [
  94.             'produit' => $liste,
  95.             'Products' => $Products,
  96.         ]);
  97.     }
  98.     /**
  99.      * @Route("/Accueil5sur5/headerLogin", name="headerLogin")
  100.      */
  101.     public function headerLogin(Request $request): Response
  102.     {
  103.         $produit $this->typeProduiteService;
  104.         $liste $produit->produitlistType();
  105.         // dd($liste);
  106.         $session $request->getSession();
  107.         $Products $session->get("Panier");
  108.         if ($Products == Null) {
  109.             $Products = [];
  110.         }
  111.         return $this->render('Accueil/headerLogin.html.twig', [
  112.             'produit' => $liste,
  113.             'Products' => $Products,
  114.         ]);
  115.     }
  116.     /**
  117.      * @Route("/", name="page_Accueil")
  118.      */
  119.     public function PageAccueil()
  120.     {
  121.         $produit $this->typeProduiteService;
  122.         $liste $produit->produitlistType();
  123.         $siteservice $this->siteService;
  124.         $site $siteservice->getActiveSite();
  125.         $list $this->blogService->allblog();
  126.         //dd($list);
  127.         return $this->render('Accueil/PageAccueil.html.twig', ["site" => $site'list' => $list'produit' => $liste]);
  128.     }
  129.     /**
  130.      * @Route("/Parent/", name="Parent")
  131.      */
  132.     public function Acceuil(Request $request)
  133.     {
  134.         $produit $this->typeProduiteService;
  135.         $liste $produit->produitlistType();
  136.         $siteservice $this->siteService;
  137.         $site $siteservice->getActiveSite();
  138.         $list $this->blogService->allblog();
  139.         $session $request->getSession();
  140.         $Products $session->get("Panier");
  141.         if ($Products == Null) {
  142.             $Products = [];
  143.         }
  144.         return $this->render('Accueil/PageAccueil.html.twig', ["site" => $site'list' => $list'produit' => $liste'Products' => $Products]);
  145.     }
  146.     /**
  147.      * @Route("/Accueil5sur5/footer_layoutAccueil", name="footer_layoutAccueil")
  148.      */
  149.     public function footer()
  150.     {
  151.         return $this->render('Accueil/footer.html.twig');
  152.     }
  153.     /**
  154.      * @Route("/Accompagnateur/register", name="accomp_register",methods={"POST","GET"})
  155.      */
  156.     public function register(Request $request)
  157.     {
  158.         // Forcer type_user=EF si la requête vient de la page écoles publiques
  159.         $referer $request->headers->get('referer');
  160.         if ($referer && strpos($referer'/ecoles-publiques/creer') !== false) {
  161.             $request->request->set('type_user''EF');
  162.             error_log("🏫 Création depuis page écoles publiques → Force type_user=EF");
  163.         }
  164.         
  165.         ini_set("max_execution_time", -1);
  166.         ini_set('memory_limit''-1');
  167.         $em $this->getDoctrine()->getManager();
  168.         $UserService $this->UserService;
  169.         $SejourService $this->sejourService;
  170.         $AttachementService $this->attachementService;
  171.         $nom $request->get("nom_acc");
  172.         $prenom $request->get('prenom_acc');
  173.         $etablisment $request->get("etablisment");
  174.         $fonction $request->get("fonction");
  175.         $EntityFonction $em->getRepository(Fonctions::class)->find($fonction);
  176.         if ($EntityFonction) {
  177.             $nameFonction $EntityFonction->getName();
  178.         } else {
  179.             $nameFonction "";
  180.         }
  181.         $adressetablisment $request->get("adressetablisment");
  182.         // prix et reverse
  183.         $prixcnxparent 2.90;
  184.         $prixcnxpartenaire 0;
  185.         $reversecnxpart 0;
  186.         $reverseventepart 0;
  187.         $phoneacc $request->get("phone_acc");
  188.         $mail $request->get("email");
  189.         $password $request->get("password");
  190.         $role "ROLE_ACC";
  191.         $themSejour $request->get('theme_sejour');
  192.         $adressSejour $request->get("adress_sejour");
  193.         $codePostal $request->get("codePostal");
  194.         $dateDebut $request->get("date_debut_sejour");
  195.         $FinSejour $request->get("date_fin_sejour");
  196.         $AgeDugroupe $request->get("age_dugroupe_sejour");
  197.         $NbEnfant $request->get("NbEnfant");
  198.         $pays $request->get("pays");
  199.         $ville $request->get("ville");
  200.         $CODEpOSTALetablisment $request->get("CODEpOSTALetablisment");
  201.         $villeetablisment $request->get("villeetablisment");
  202.         
  203.         // Récupérer le type de séjour depuis le formulaire (EP, EF, PF)
  204.         $type_user $request->get("type_user");
  205.         if (!$type_user) {
  206.             $type_user "EP"// Par défaut: École Publique (parents paient)
  207.         }
  208.     
  209.         // Mapper le type_user vers le type de séjour et connpay
  210.         // Logique du code séjour : [Type][Pay][Timestamp]
  211.         // Type: E=École, P=Partenaire, C=CSE
  212.         // Pay: P=Payant (parents), F=Free (gratuit/structure)
  213.         switch ($type_user) {
  214.             case 'EF':
  215.                 // École Française (page dédiée) = École + Gratuit
  216.         $type "ECOLES/AUTRES";
  217.                 $connpay 0// Gratuit (0 = Free)
  218.                 break;
  219.             case 'PF':
  220.                 // Partenaire Financé (structure prend en charge) = Partenaire + Structure finance
  221.                 $type "PARTENAIRES/VOYAGISTES";
  222.                 $connpay 0// Structure finance (0 = Free)
  223.                 break;
  224.             case 'EP':
  225.             default:
  226.                 // École Publique (parents paient par défaut) = École + Parents paient
  227.                 $type "ECOLES/AUTRES";
  228.                 $connpay 1// Parents paient (1 = Payant)
  229.                 break;
  230.         }
  231.         
  232.         error_log("🔍 Type reçu du formulaire: type_user=$type_user → Type séjour=$type, connpay=$connpay");
  233.      
  234.         $bytes random_bytes(5);
  235.         $passAcommpa bin2hex($bytes);
  236.         if ($NbEnfant) {
  237.             $NbEnfant $NbEnfant;
  238.         } else {
  239.             $NbEnfant 0;
  240.         }
  241.         $dateSJoue = new \Datetime();
  242.         $Milliseconde $dateSJoue->format('u');
  243.         $annes $dateSJoue->format('y');
  244.         $joours $dateSJoue->format('d');
  245.         $joours $dateSJoue->format('t');
  246.         $emailaccf "Acompa" $annes $joours $Milliseconde "@fictif.com";
  247.         //CREATION ACCOMPAGNATEUR
  248.         $accomp $UserService->creationNewAcommpa($nom$prenom$etablisment$nameFonction$adressetablisment$phoneacc$emailaccf$role$passAcommpa$mail);
  249.         $accomp->setIdFonction($EntityFonction);
  250.         $em->persist($accomp);
  251.         $em->flush();
  252.         //CREATION PARTENAIRE
  253.         $part $em->getRepository(User::class)->VerifierAddresseEmailPartenaire($mail'ROLE_PARTENAIRE');
  254.         if (is_null($part)) {
  255.             $part $UserService->creationNewUser($nom$prenom$etablisment$nameFonction$adressetablisment$phoneacc$mail$passAcommpa"ROLE_PARTENAIRE");
  256.             $part->setIdFonction($EntityFonction);
  257.             $em->persist($part);
  258.             $em->flush();
  259.         }
  260.         //CREATION ETABLISSEMENT + PARTENAIRE
  261.         $Etablisment $UserService->creationNewEtablisment($part$nom$prenom$etablisment$fonction$adressetablisment$phoneacc$mail"ROLE_PARTENAIRE"$password$prixcnxparent$prixcnxpartenaire$reversecnxpart$reverseventepart);
  262.         if ($CODEpOSTALetablisment == "") {
  263.             $CODEpOSTALetablisment null;
  264.         }
  265.         $Etablisment->setCodepostaleatb($CODEpOSTALetablisment);
  266.         $Etablisment->setVille($villeetablisment);
  267.         $em->persist($Etablisment);
  268.         $em->flush();
  269.         //CREATION SEJOUR ACCOM + PARTENAIRE + ETABILSSEMENT
  270.         // Ne pas surcharger $connpay via la fonction (ex: VIP)
  271.         // Le code séjour doit refléter exclusivement le choix utilisateur (type_user)
  272.         $sejour $SejourService->CreationNouveauSejourParAccompagnateur($themSejour$adressSejour$dateDebut$FinSejour$AgeDugroupe$type$NbEnfant$connpay$pays$ville$prixcnxparent$prixcnxpartenaire$reversecnxpart$reverseventepart);
  273.         $sejour->setCodePostal(intval($codePostal));
  274.         $SejourService->affecterAccompaniateur($sejour$accomp);
  275.         $SejourService->affecterPartenaire($sejour$part);
  276.         $SejourService->affecteretablisment($sejour$Etablisment);
  277.         $em->persist($sejour);
  278.         $em->flush();
  279.         //AFFECTAION LOGO TO USER PARTENAIRE ADN ACCOMPAGNATEUR
  280.         if ($request->request->has('path')) {
  281.             $ty "logo séjour";
  282.             $AttachementService->creationLogoSejour($accomp$request->get('path'), $ty);
  283.             $AttachementService->creationLogoSejour($part$request->get('path'), $ty);
  284.         }
  285.         $TypeSejour 8;
  286.         
  287.         // DEBUG: Log avant envoi email
  288.         error_log("🔔 AVANT ENVOI EMAIL - Sejour ID: " $sejour->getId() . ", Email: " $accomp->getReponseemail());
  289.         
  290.         $UserService->EnvoyerEmailAcommpatActivationNewMail($sejour$accomp);
  291.     
  292.         error_log("🔔 APRÈS ENVOI EMAIL");
  293.        
  294.         $session $request->getSession();
  295.         $session->set('Sejour'$sejour->getId());
  296.         //$this->redirectToRoute('app_back_Acommpa');
  297.         return new JsonResponse(["idSejour" => $sejour->getId()]);
  298.     }
  299.     //inscription du parent 
  300.     /**
  301.      * @Route("/Parent/register", name="parent_register",methods={"POST","GET"})
  302.      */
  303.     public function registerparent(Request $request)
  304.     {
  305.         $UserService $this->UserService;
  306.         //
  307.         $nom $request->get("nomparent");
  308.         $prenom $request->get('prenomparent');
  309.         $mailparent $request->get("mailprent");
  310.         $numtel $request->get("numtel");
  311.         $passwordparent $request->get("passwordparent");
  312.         $confirmpassword $request->get("confirmpassword");
  313.         $notifsms $request->get("sms");
  314.         $notifmail $request->get('mailnotif');
  315.         if ($confirmpassword != $passwordparent) {
  316.             return new JsonResponse('erorpasswordconfirm');
  317.         }
  318.         $role "ROLE_PARENT";
  319.         $verification $UserService->verifmailold($mailparent);
  320.         //var_dump($verification);
  321.         if ($verification == NULL) {
  322.             $accomp $UserService->creationNewParent($nom$prenom$mailparent$numtel$role$passwordparent$notifsms$notifmail);
  323.             return new JsonResponse('done');
  324.         } else {
  325.             return new JsonResponse('eror');
  326.         }
  327.     }
  328.     /**
  329.      * @Route("/Accueil5sur5/5sur5", name="sur5")
  330.      */
  331.     public function sur5()
  332.     {
  333.         $produit $this->typeProduiteService;
  334.         $liste $produit->produitlistType();
  335.         //dd($liste);
  336.         return $this->render('Accueil/5sur5.html.twig', [
  337.             'produit' => $liste,
  338.         ]);
  339.     }
  340.     /**
  341.      * @Route("/Parent/Accueil5sur5/5sur5", name="5sur5Parent")
  342.      */
  343.     public function sur5Parent()
  344.     {
  345.         $produit $this->typeProduiteService;
  346.         $liste $produit->produitlistType();
  347.         //dd($liste);
  348.         return $this->render('Accueil/5sur5.html.twig', [
  349.             'produit' => $liste,
  350.         ]);
  351.     }
  352.     /**
  353.      * @Route("/Accueil5sur5/album/{id}", name="album")
  354.      */
  355.     public function produitlist($id)
  356.     {
  357.         $produit $this->typeProduiteService;
  358.         $liste $produit->produitlistType();
  359.         $produit $id;
  360.         //dd($liste);
  361.         return $this->render('Accueil/album.html.twig', [
  362.             'produit' => $liste,
  363.             'showArt' => $produit,
  364.         ]);
  365.     }
  366.     /**
  367.      * @Route("/Parent/Accueil5sur5/album/{id}", name="albumParent")
  368.      */
  369.     public function produitlistParent($id)
  370.     {
  371.         $produit $this->typeProduiteService;
  372.         $liste $produit->produitlistType();
  373.         // dd($liste);
  374.         $produit $id;
  375.         return $this->render('Accueil/album.html.twig', [
  376.             'produit' => $liste,
  377.             'showArt' => $produit,
  378.         ]);
  379.     }
  380. /**
  381.      * @Route("/Accueil5sur5/Boutique_Souvenirs", name="boutique5sur5_Souvenir")
  382.      */
  383.     public function boutique5sur5()
  384.     {
  385.        $produit $this->typeProduiteService;
  386.         $liste $produit->produitlistTypeConditionnement();
  387.       
  388.      
  389.         return $this->render('Accueil/boutique_5sur5.html.twig', [
  390.          
  391.         
  392.             'produit' => $liste,
  393.             
  394.         ]);
  395.     }
  396.     /**
  397.      * @Route("/Accueil5sur5/AlaUne", name="AlaUne")
  398.      */
  399.     public function AlaUne()
  400.     {
  401.         $blogsbolt $this->blogService;
  402.         $list $blogsbolt->allblog();
  403.         //dd($list);
  404.         return $this->render('Accueil/AlaUne.html.twig', ['list' => $list]);
  405.     }
  406.     /**
  407.      * @Route("/Parent/Accueil5sur5/AlaUne", name="AlaUneParent")
  408.      */
  409.     public function AlaUneParent()
  410.     {
  411.         $blogsbolt $this->blogService;
  412.         $list $blogsbolt->allblog();
  413.         //dd($list);
  414.         return $this->render('Accueil/AlaUneParent.html.twig', ['list' => $list]);
  415.     }
  416.     /**
  417.      * @Route("/Accueil5sur5/DetailsAlaUne/{id}", name="DetailsAlaUne")
  418.      */
  419.     public function DetailsAlaUne($id)
  420.     {
  421.         $blo $this->blogService;
  422.         $blog $blo->myblog($id);
  423.         return $this->render('Accueil/DetailsAlaUne.html.twig', ['blog' => $blog]);
  424.     }
  425.     /**
  426.      * @Route("/ServiceClient", name="ServiceClient")
  427.      * */
  428.     public function ServiceClient()
  429.     {
  430.         $produit $this->typeProduiteService;
  431.         $liste $produit->produitlistType();
  432.         // dd($liste);
  433.         return $this->render('Accueil/ServiceClient.html.twig', [
  434.             'produit' => $liste,
  435.         ]);
  436.     }
  437.     /**
  438.      * @Route("/Besoindaide", name="Besoindaide")
  439.      */
  440.     public function Besoindaide(): Response
  441.     {
  442.         $produit $this->typeProduiteService;
  443.         $liste $produit->produitlistType();
  444.         // dd($liste);
  445.         return $this->render('Accueil/Besoindaide.html.twig', [
  446.             'produit' => $liste,
  447.         ]);
  448.     }
  449.     /**
  450.      * @Route("/Mentionlegale", name="Mentionlegale")
  451.      */
  452.     public function Mentionlegale()
  453.     {
  454.         return $this->render('Accueil/mentionlegal.html.twig', []);
  455.     }
  456.      /**
  457.      * @Route("/Mentions_legales", name="Mentions_legales")
  458.      */
  459.     public function Mentions_legales()
  460.     {
  461.         return $this->render('Accueil/mentionlegal.html.twig', []);
  462.     }
  463.        /**
  464.      * @Route("/Conditons_generales", name="Conditons_generales")
  465.      */
  466.     public function Conditons_generales()
  467.     {
  468.         return $this->render('Accueil/Condition.html.twig', []);
  469.     }
  470.     /**
  471.      * @Route("/Conditongeneral", name="Conditongeneral")
  472.      */
  473.     public function Conditongeneral()
  474.     {
  475.         return $this->render('Accueil/Condition.html.twig', []);
  476.     }
  477.     /**
  478.      * @Route("/Politique", name="Politique")
  479.      */
  480.     public function Politique()
  481.     {
  482.         return $this->render('Accueil/politique.html.twig', []);
  483.     }
  484.     /**
  485.      * @Route("/unsubscribe-user", name="unsubscribe_user")
  486.      */
  487.     public function unsubscribeUser(Request $requestEntityManagerInterface $em): Response
  488.     {
  489.         $email $request->query->get('email');
  490.         
  491.         if (!$email) {
  492.             return $this->render('unsubscribe/error.html.twig', [
  493.                 'message' => 'Email manquant'
  494.             ]);
  495.         }
  496.         $user $em->getRepository(User::class)->findOneBy(['email' => $email]);
  497.         if (!$user) {
  498.             return $this->render('unsubscribe/error.html.twig', [
  499.                 'message' => 'Utilisateur non trouvé'
  500.             ]);
  501.         }
  502.         $user->setShowpubprod('unsuscribe');
  503.         $em->flush();
  504.         return $this->render('unsubscribe/success.html.twig', [
  505.             'email' => $email
  506.         ]);
  507.     }
  508.     /**
  509.      * @Route("/contact", name="app_contact", methods={"POST"})
  510.      */
  511.     public function processContactForm(Request $request): Response
  512.     {
  513.         try {
  514.             // Récupérer les données du formulaire (support des anciens et nouveaux noms)
  515.             $name $request->request->get('name') ?: $request->request->get('fullname');
  516.             $organization $request->request->get('organization') ?: $request->request->get('org');
  517.             $email $request->request->get('email');
  518.             $telephone $request->request->get('telephone') ?: $request->request->get('phone');
  519.             $sejoursCount $request->request->get('sejours_count') ?: $request->request->get('sejours');
  520.             $message $request->request->get('message''');
  521.             $topic $request->request->get('topic''contact');
  522.             $objet $request->request->get('objet''contact');
  523.             $pack $request->request->get('pack''');
  524.             $consent $request->request->get('consent');
  525.             
  526.             // Support ancien format avec 'subject'
  527.             $subject $request->request->get('subject');
  528.             // Validation des données
  529.             if (empty($name) || empty($email) || empty($organization) || empty($consent)) {
  530.                 return new JsonResponse([
  531.                     'success' => false,
  532.                     'message' => 'Tous les champs obligatoires doivent être remplis (nom, email, établissement, consentement).'
  533.                 ], 400);
  534.             }
  535.             if (!filter_var($emailFILTER_VALIDATE_EMAIL)) {
  536.                 return new JsonResponse([
  537.                     'success' => false,
  538.                     'message' => 'L\'adresse email n\'est pas valide.'
  539.                 ], 400);
  540.             }
  541.             // Préparer le sujet selon le type de demande
  542.             if (empty($subject)) {
  543.                 $currentDate = new \DateTime();
  544.                 if ($objet === 'expert') {
  545.                     $subject 'Demande expert_' $currentDate->format('d/m/Y');
  546.                 } elseif ($objet === 'demo' || $topic === 'demo') {
  547.                     $subject 'Demande demo_' $currentDate->format('d/m/Y');
  548.                 } else {
  549.                 $subject 'Nouveau message de contact - 5sur5séjour';
  550.                 }
  551.             }
  552.             // Créer l'email
  553.             $emailContent = (new TemplatedEmail())
  554.                 ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  555.                 ->to(new Address('ramzi.benlarbi@gmail.com''Ramzi Benlarbi'))
  556.                 ->addCc(new Address('yousra.tlich@gmail.com''Yousra Tlich'))
  557.                 ->addCc(new Address('partenariat@5sur5sejour.com''Partenariat 5sur5séjour'))
  558.                 ->subject($subject)
  559.                 ->htmlTemplate('emails/contact_form.html.twig')
  560.                 ->context([
  561.                     'name' => $name,
  562.                     'organization' => $organization,
  563.                     'email' => $email,
  564.                     'telephone' => $telephone,
  565.                     'sejours_count' => $sejoursCount,
  566.                     'subject' => $subject,
  567.                     'message' => $message,
  568.                     'topic' => $topic,
  569.                     'objet' => $objet,
  570.                     'pack' => $pack,
  571.                     'date' => new \DateTime()
  572.                 ]);
  573.             // Envoyer l'email
  574.             $this->mailer->send($emailContent);
  575.             // Logger le succès
  576.             $this->logger->info('Email de contact envoyé avec succès', [
  577.                 'from' => $email,
  578.                 'name' => $name,
  579.                 'subject' => $subject
  580.             ]);
  581.             return new JsonResponse([
  582.                 'success' => true,
  583.                 'message' => 'Votre message a été envoyé avec succès ! Nous vous répondrons dans les plus brefs délais.'
  584.             ]);
  585.         } catch (\Exception $e) {
  586.             // Logger l'erreur
  587.             $this->logger->error('Erreur lors de l\'envoi de l\'email de contact', [
  588.                 'error' => $e->getMessage(),
  589.                 'trace' => $e->getTraceAsString()
  590.             ]);
  591.             return new JsonResponse([
  592.                 'success' => false,
  593.                 'message' => 'Une erreur est survenue lors de l\'envoi du message. Veuillez réessayer plus tard.'
  594.             ], 500);
  595.         }
  596.     }
  597.     /**
  598.      * @Route("/contact/demo", name="app_contact_demo", methods={"POST"})
  599.      */
  600.     public function processDemoForm(Request $request): Response
  601.     {
  602.         try {
  603.             // Récupérer les données du formulaire de démo
  604.             $fullname $request->request->get('fullname');
  605.             $org $request->request->get('org');
  606.             $email $request->request->get('email');
  607.             $phone $request->request->get('phone');
  608.             $message $request->request->get('message');
  609.             $topic $request->request->get('topic');
  610.             $pack $request->request->get('pack');
  611.             $consent $request->request->get('consent');
  612.             // Validation des données
  613.             if (empty($fullname) || empty($org) || empty($email) || empty($consent)) {
  614.                 return new JsonResponse([
  615.                     'success' => false,
  616.                     'message' => 'Tous les champs obligatoires doivent être remplis et le consentement accepté.'
  617.                 ], 400);
  618.             }
  619.             if (!filter_var($emailFILTER_VALIDATE_EMAIL)) {
  620.                 return new JsonResponse([
  621.                     'success' => false,
  622.                     'message' => 'L\'adresse email n\'est pas valide.'
  623.                 ], 400);
  624.             }
  625.             // Préparer le sujet avec la date
  626.             $currentDate = new \DateTime();
  627.             $subject 'Demande demo_' $currentDate->format('d/m/Y');
  628.             // Créer l'email pour la demande de démo
  629.             $emailContent = (new TemplatedEmail())
  630.                 ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  631.                 ->to(new Address('ramzi.benlarbi@gmail.com''Ramzi Benlarbi'))
  632.                 ->addCc(new Address('yousra.tlich@gmail.com''Yousra Tlich'))
  633.                 ->addCc(new Address('partenariat@5sur5sejour.com''Partenariat 5sur5séjour'))
  634.                 ->subject($subject)
  635.                 ->htmlTemplate('emails/demo_request.html.twig')
  636.                 ->context([
  637.                     'fullname' => $fullname,
  638.                     'org' => $org,
  639.                     'email' => $email,
  640.                     'phone' => $phone,
  641.                     'message' => $message,
  642.                     'topic' => $topic,
  643.                     'pack' => $pack,
  644.                     'date' => $currentDate
  645.                 ]);
  646.             // Envoyer l'email
  647.             $this->mailer->send($emailContent);
  648.             // Logger le succès
  649.             $this->logger->info('Email de demande de démo envoyé avec succès', [
  650.                 'from' => $email,
  651.                 'fullname' => $fullname,
  652.                 'org' => $org,
  653.                 'topic' => $topic
  654.             ]);
  655.             return new JsonResponse([
  656.                 'success' => true,
  657.                 'message' => 'Votre demande de démo a été envoyée avec succès ! Nous vous recontacterons dans les 24 heures.'
  658.             ]);
  659.         } catch (\Exception $e) {
  660.             // Logger l'erreur
  661.             $this->logger->error('Erreur lors de l\'envoi de l\'email de demande de démo', [
  662.                 'error' => $e->getMessage(),
  663.                 'trace' => $e->getTraceAsString()
  664.             ]);
  665.             return new JsonResponse([
  666.                 'success' => false,
  667.                 'message' => 'Une erreur est survenue lors de l\'envoi de la demande. Veuillez réessayer plus tard.'
  668.             ], 500);
  669.         }
  670.     }
  671.     /**
  672.      * @Route("/Accueil5sur5/Pack_Annuel_Partenaires", name="pack_annuel_partenaires")
  673.      */
  674.     public function packAnnuelPartenaires()
  675.     {
  676.         return $this->render('Accueil/pack_annuel_partenaires.html.twig');
  677.     }
  678.     /**
  679.      * @Route("/Accueil5sur5/Pack_Access", name="pack_access")
  680.      * @Route("/Accueil5sur5/Pack_Decouverte", name="pack_decouverte")
  681.      */
  682.     public function packAccess()
  683.     {
  684.         return $this->render('Accueil/pack_access.html.twig');
  685.     }
  686.     /**
  687.      * @Route("/Accueil5sur5/Pack_Serenite", name="pack_serenite")
  688.      */
  689.     public function packSerenite()
  690.     {
  691.         return $this->render('Accueil/pack_serenite.html.twig');
  692.     }
  693.     /**
  694.      * @Route("/checkout/pack/{pack}", name="checkout_pack", defaults={"pack"="serenite"})
  695.      */
  696.     public function checkoutPack(string $pack)
  697.     {
  698.         // Configuration des packs
  699.         $packsConfig = [
  700.             'decouverte' => [
  701.                 'id' => 'decouverte',
  702.                 'name' => 'Pack Découverte',
  703.                 'subtitle' => 'Abonnement annuel',
  704.                 'price' => 290,
  705.                 'price_ht' => '290 € HT',
  706.                 'onboarding' => 'Inclus',
  707.                 'vocal_price' => '+5 € / séjour',
  708.                 'features' => [
  709.                     'Séjours illimités toute l\'année',
  710.                     'Multi-sites pour une équipe',
  711.                     'Reporting mensuel & facturation',
  712.                     'Support prioritaire individuel'
  713.                 ],
  714.                 'info' => 'Plusieurs séjours par an ? Tarif dégressif automatique !'
  715.             ],
  716.             'serenite' => [
  717.                 'id' => 'serenite',
  718.                 'name' => 'Pack Sérénité',
  719.                 'subtitle' => 'Abonnement annuel',
  720.                 'price' => 490,
  721.                 'price_ht' => '490 € HT',
  722.                 'onboarding' => 'Inclus',
  723.                 'vocal_price' => '+5 € / séjour',
  724.                 'features' => [
  725.                     'Séjours illimités toute l\'année',
  726.                     'Multi-sites pour une équipe',
  727.                     'Reporting mensuel & facturation',
  728.                     'Support prioritaire individuel'
  729.                 ],
  730.                 'info' => 'Plusieurs séjours par an ? Tarif dégressif automatique !'
  731.             ],
  732.             'pro_illimite' => [
  733.                 'id' => 'pro_illimite',
  734.                 'name' => 'Pack Pro Illimité',
  735.                 'subtitle' => 'Abonnement annuel',
  736.                 'price' => 790,
  737.                 'price_ht' => '790 € HT',
  738.                 'onboarding' => 'Inclus + Formation avancée',
  739.                 'vocal_price' => 'Inclus',
  740.                 'features' => [
  741.                     'Séjours illimités toute l\'année',
  742.                     'Multi-sites pour une équipe',
  743.                     'Reporting mensuel & facturation',
  744.                     'Support prioritaire individuel',
  745.                     'Voix téléphonique illimitée',
  746.                     'Formation avancée de l\'équipe'
  747.                 ],
  748.                 'info' => 'Le meilleur rapport qualité/prix pour les structures avec plusieurs séjours !'
  749.             ]
  750.         ];
  751.         
  752.         // Vérifier que le pack existe
  753.         if (!isset($packsConfig[$pack])) {
  754.             throw $this->createNotFoundException('Pack non trouvé');
  755.         }
  756.         return $this->render('Accueil/checkout_pack.html.twig', [
  757.             'pack' => $pack,
  758.             'packConfig' => $packsConfig[$pack]
  759.         ]);
  760.     }
  761.     /**
  762.      * @Route("/checkout/process", name="checkout_process_pack", methods={"POST"})
  763.      */
  764.     public function checkoutProcessPack(Request $requestMailerInterface $mailer)
  765.     {
  766.         try {
  767.             error_log('🔍 CHECKOUT START - Processing form submission');
  768.             
  769.             // Récupération des données du formulaire
  770.             $data = [
  771.                 'pack_id' => $request->request->get('pack_id'),
  772.                 'payment_method' => $request->request->get('payment_method'),
  773.                 'company_name' => $request->request->get('company_name'),
  774.                 'company_type' => $request->request->get('company_type'),
  775.                 'siren' => $request->request->get('siren'),
  776.                 'phone' => $request->request->get('phone'),
  777.                 'address' => $request->request->get('address'),
  778.                 'postal_code' => $request->request->get('postal_code'),
  779.                 'city' => $request->request->get('city'),
  780.                 'first_name' => $request->request->get('first_name'),
  781.                 'last_name' => $request->request->get('last_name'),
  782.                 'email' => $request->request->get('email'),
  783.                 'role' => $request->request->get('role'),
  784.                 'need_onboarding' => $request->request->get('need_onboarding') ? true false,
  785.             ];
  786.             error_log('📋 Data received: ' json_encode($data));
  787.             // Validation
  788.             $requiredFields = ['pack_id''payment_method''company_name''company_type''phone'
  789.                               'address''postal_code''city''first_name''last_name''email''role'];
  790.             
  791.             foreach ($requiredFields as $field) {
  792.                 if (empty($data[$field])) {
  793.                     error_log('❌ Missing required field: ' $field);
  794.                     $this->addFlash('error''Tous les champs obligatoires doivent être remplis.');
  795.                     return $this->redirectToRoute('checkout_pack', ['pack' => $data['pack_id'] ?? 'serenite']);
  796.                 }
  797.             }
  798.             error_log('✅ Validation passed');
  799.             // ==================== CRÉER LA COMMANDE EN BASE DE DONNÉES ====================
  800.             $em $this->getDoctrine()->getManager();
  801.             $commande null;
  802.             
  803.             // Si c'est un paiement RIB ou Devis, créer la commande maintenant
  804.             if (in_array($data['payment_method'], ['transfer''rib''bank_transfer''quote''devis'])) {
  805.                 try {
  806.                     error_log('📦 Création commande pack pour: ' $data['pack_id']);
  807.                     
  808.                     // Créer ou récupérer l'utilisateur
  809.                     $userRepository $em->getRepository(User::class);
  810.                     $user $userRepository->findOneBy(['email' => $data['email']]);
  811.                     
  812.                     if (!$user) {
  813.                         $user = new User();
  814.                         $user->setEmail($data['email']);
  815.                         $user->setNom($data['last_name']);
  816.                         $user->setPrenom($data['first_name']);
  817.                         $user->setTelephone($data['phone'] ?? '');
  818.                         $user->setNometablisment($data['company_name'] ?? '');
  819.                         $mdpTemp substr(md5(uniqid()), 08);
  820.                         $user->setPassword(password_hash($mdpTempPASSWORD_BCRYPT));
  821.                         $user->setRoles(['ROLE_PARTENAIRE']);
  822.                         $user->setStatut(1);
  823.                         $em->persist($user);
  824.                         $em->flush();
  825.                         error_log('✅ Utilisateur créé: ' $user->getEmail());
  826.                     }
  827.                     
  828.                     // Déterminer les montants
  829.                     $packPrices = [
  830.                         'serenite' => ['ht' => 490'ttc' => 588],
  831.                         'decouverte' => ['ht' => 290'ttc' => 348],
  832.                     ];
  833.                     $prices $packPrices[$data['pack_id']] ?? $packPrices['serenite'];
  834.                     
  835.                     // Récupérer le statut "en attente"
  836.                     $statutEnAttente $em->getRepository(Ref::class)->find(1);
  837.                     if (!$statutEnAttente) {
  838.                         $statutEnAttente = new Ref();
  839.                         $statutEnAttente->setLibiller('En attente');
  840.                         $em->persist($statutEnAttente);
  841.                         $em->flush();
  842.                     }
  843.                     
  844.                     // Créer la commande
  845.                     $commande = new Commande();
  846.                     $commande->setIdUser($user);
  847.                     $commande->setStatut($statutEnAttente);
  848.                     $commande->setMontantht($prices['ht']);
  849.                     $commande->setMontantrth($prices['ttc']);
  850.                     $commande->setMontanenv($prices['ttc']);
  851.                     $commande->setTva(20);
  852.                     $commande->setDateCreateCommande(new \DateTime());
  853.                     $commande->setDateExpidition((new \DateTime())->modify('+12 months'));
  854.                     $commande->setPeriode('annuel');
  855.                     $commande->setPaymentType('rib');
  856.                     $commande->setNumComande(time());
  857.                     
  858.                     $em->persist($commande);
  859.                     $em->flush();
  860.                     
  861.                     error_log('✅ Commande créée: ID=' $commande->getId() . ' N°' $commande->getNumComande());
  862.                     
  863.                 } catch (\Exception $e) {
  864.                     error_log('❌ Erreur création commande: ' $e->getMessage());
  865.                     // Continuer quand même pour envoyer les emails
  866.                 }
  867.             }
  868.             // Stocker en session AVANT d'envoyer les emails
  869.             $data['commande_id'] = $commande $commande->getId() : null;
  870.             $data['commande_numero'] = $commande $commande->getNumComande() : null;
  871.             $request->getSession()->set('checkout_data'$data);
  872.             error_log('💾 Data stored in session');
  873.             // Envoyer les emails de manière asynchrone (ne pas bloquer la requête)
  874.             try {
  875.                 error_log('📧 Attempting to send email to team...');
  876.                 
  877.                 // Envoyer email à l'équipe 5sur5
  878.                 $emailToTeam = (new TemplatedEmail())
  879.                     ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  880.                     ->to('contact@5sur5sejour.com')
  881.                     ->cc('yousra.tlich@gmail.com''ramzi.benlarbi@gmail.com')
  882.                     ->subject('Nouvelle souscription Pack ' strtoupper($data['pack_id']) . ' - ' $data['company_name'])
  883.                     ->htmlTemplate('emails/checkout_notification_team.html.twig')
  884.                     ->context([
  885.                         'data' => $data,
  886.                         'date' => new \DateTime()
  887.                     ]);
  888.                 $mailer->send($emailToTeam);
  889.                 error_log('✅ Email to team sent');
  890.                 // Envoyer email de confirmation au client
  891.                 $emailToClient = (new TemplatedEmail())
  892.                     ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  893.                     ->to($data['email'])
  894.                     ->subject('Confirmation de votre souscription - 5sur5 Séjour')
  895.                     ->htmlTemplate('emails/checkout_confirmation_client.html.twig')
  896.                     ->context([
  897.                         'data' => $data,
  898.                         'date' => new \DateTime()
  899.                     ]);
  900.                 $mailer->send($emailToClient);
  901.                 error_log('✅ Email to client sent');
  902.                 
  903.             } catch (\Exception $emailError) {
  904.                 // Log l'erreur mais ne bloque pas le processus
  905.                 error_log('⚠️ Email error (non-blocking): ' $emailError->getMessage());
  906.             }
  907.             // Redirection selon le mode de paiement
  908.             error_log('🔄 Redirecting to success page, method: ' $data['payment_method']);
  909.             
  910.             // 🧪 MODE TEST : Le paiement en ligne est automatiquement en succès
  911.             error_log('🧪 [MODE TEST] Paiement en ligne simulé comme réussi');
  912.             
  913.             switch ($data['payment_method']) {
  914.                 case 'online':
  915.                     // Simulation de paiement en ligne réussi (mode test)
  916.                     error_log('✅ [TEST] Paiement en ligne simulé - SUCCÈS automatique');
  917.                     $this->addFlash('success''✅ Paiement réussi ! (Mode Test - Paiement simulé)');
  918.                     return $this->redirectToRoute('checkout_success', ['method' => 'online']);
  919.                     
  920.                 case 'transfer':
  921.                     $this->addFlash('info''Demande de virement enregistrée. Vous recevrez les coordonnées bancaires par email.');
  922.                     return $this->redirectToRoute('checkout_success', ['method' => 'transfer']);
  923.                     
  924.                 case 'quote':
  925.                     $this->addFlash('info''Demande de devis enregistrée. Vous recevrez le devis par email.');
  926.                     return $this->redirectToRoute('checkout_success', ['method' => 'quote']);
  927.                     
  928.                 default:
  929.                     error_log('❌ Invalid payment method: ' $data['payment_method']);
  930.                     throw new \Exception('Mode de paiement invalide');
  931.             }
  932.         } catch (\Exception $e) {
  933.             error_log('❌ CHECKOUT ERROR: ' $e->getMessage());
  934.             error_log('Stack trace: ' $e->getTraceAsString());
  935.             $this->addFlash('error''Une erreur est survenue. Veuillez réessayer. Détail: ' $e->getMessage());
  936.             return $this->redirectToRoute('checkout_pack', ['pack' => $request->request->get('pack_id''serenite')]);
  937.         }
  938.     }
  939.     /**
  940.      * @Route("/checkout/success/{method}", name="checkout_success")
  941.      */
  942.     public function checkoutSuccess(Request $requeststring $method)
  943.     {
  944.         $data $request->getSession()->get('checkout_data');
  945.         
  946.         if (!$data) {
  947.             return $this->redirectToRoute('page_Accueil');
  948.         }
  949.         return $this->render('Accueil/checkout_success.html.twig', [
  950.             'data' => $data,
  951.             'method' => $method
  952.         ]);
  953.     }
  954.     /**
  955.      * @Route("/Accueil5sur5/Pack_Pro_Illimite", name="pack_pro_illimite")
  956.      */
  957.     public function packProIllimite()
  958.     {
  959.         return $this->render('Accueil/pack_pro_illimite.html.twig');
  960.     }
  961.     /**
  962.      * @Route("/bank-transfer-request", name="bank_transfer_request", methods={"POST"})
  963.      */
  964.     public function bankTransferRequest(Request $requestEntityManagerInterface $em): JsonResponse
  965.     {
  966.         try {
  967.             $this->logger->info('🔍 Début de la demande de RIB');
  968.             
  969.             // Accepter les deux formats de paramètres
  970.             $fullname $request->request->get('full_name') ?: $request->request->get('rib_fullname');
  971.             $emailUser $request->request->get('billing_email') ?: $request->request->get('rib_email');
  972.             $phone $request->request->get('phone') ?: $request->request->get('rib_phone');
  973.             $org $request->request->get('company') ?: $request->request->get('rib_org');
  974.             $message $request->request->get('message') ?: $request->request->get('rib_message');
  975.             
  976.             // Paramètres spécifiques au pack
  977.             $packId $request->request->get('pack_id');
  978.             $participants $request->request->get('participants');
  979.             $totalAmount $request->request->get('total_amount');
  980.             $startDate $request->request->get('start_date');
  981.             $endDate $request->request->get('end_date');
  982.             $theme $request->request->get('theme');
  983.             $accompagnateur $request->request->get('accompagnateur');
  984.             $this->logger->info('📝 Données reçues', [
  985.                 'fullname' => $fullname,
  986.                 'email' => $emailUser,
  987.                 'pack_id' => $packId,
  988.                 'participants' => $participants,
  989.                 'total_amount' => $totalAmount,
  990.                 'theme' => $theme,
  991.                 'start_date' => $startDate,
  992.                 'end_date' => $endDate
  993.             ]);
  994.             // Validation basique
  995.             if (empty($fullname) || empty($emailUser)) {
  996.                 return new JsonResponse([
  997.                     'success' => false,
  998.                     'message' => 'Le nom et l\'email sont obligatoires.'
  999.                 ], 400);
  1000.             }
  1001.             // Générer un numéro de demande unique
  1002.             $requestNumber 'RIB-' date('Ymd') . '-' strtoupper(substr(md5(uniqid()), 06));
  1003.             $this->logger->info('🔢 Numéro de demande généré: ' $requestNumber);
  1004.             // Créer ou récupérer l'utilisateur accompagnateur
  1005.             try {
  1006.                 $this->logger->info('👤 Recherche utilisateur: ' $emailUser);
  1007.                 $userRepository $em->getRepository(User::class);
  1008.                 $user $userRepository->findOneBy(['email' => $emailUser]);
  1009.                 
  1010.                 if (!$user) {
  1011.                     $this->logger->info('➕ Création nouvel utilisateur');
  1012.                     $user = new User();
  1013.                     $user->setEmail($emailUser);
  1014.                     $user->setNom($fullname);
  1015.                     $user->setPrenom('');
  1016.                     $user->setTelephone($phone ?? '');
  1017.                     $user->setNometablisment($org ?? '');
  1018.                     
  1019.                     // Générer un mot de passe temporaire
  1020.                     $mdpTemp substr(md5(uniqid()), 08);
  1021.                     $user->setPassword(password_hash($mdpTempPASSWORD_BCRYPT));
  1022.                     $user->setRoles(['ROLE_ACCOMPAGNATEUR']);
  1023.                     $user->setStatut(1);
  1024.                     
  1025.                     $em->persist($user);
  1026.                     $em->flush();
  1027.                     
  1028.                     $this->logger->info('✅ Utilisateur créé: ID=' $user->getId());
  1029.                 } else {
  1030.                     $this->logger->info('✅ Utilisateur existant trouvé: ID=' $user->getId());
  1031.                 }
  1032.             } catch (\Exception $userError) {
  1033.                 $this->logger->error('❌ Erreur création utilisateur', [
  1034.                     'error' => $userError->getMessage(),
  1035.                     'trace' => $userError->getTraceAsString()
  1036.                 ]);
  1037.                 throw $userError;
  1038.             }
  1039.             
  1040.             // Déterminer si c'est un pack annuel (serenite/decouverte) ou un séjour simple
  1041.             $isPack in_array($packId, ['serenite''decouverte''Pack Sérénité''Pack Découverte']);
  1042.             $this->logger->info('🔍 Détection type de demande', [
  1043.                 'pack_id' => $packId,
  1044.                 'isPack' => $isPack 'OUI' 'NON',
  1045.                 'test_array' => ['serenite''decouverte''Pack Sérénité''Pack Découverte']
  1046.             ]);
  1047.             
  1048.             $sejour null;
  1049.             $commande null;
  1050.             
  1051.             if ($isPack) {
  1052.                 // ==================== CRÉATION COMMANDE PACK ====================
  1053.                 try {
  1054.                     $this->logger->info('📦 Création commande pack: ' $packId);
  1055.                     
  1056.                     // Mapping pack → labeletype
  1057.                     $packNames = [
  1058.                         'decouverte' => 'Pack Découverte',
  1059.                         'serenite' => 'Pack Sérénité',
  1060.                         'Pack Découverte' => 'Pack Découverte',
  1061.                         'Pack Sérénité' => 'Pack Sérénité'
  1062.                     ];
  1063.                     $packLabel $packNames[$packId] ?? 'Pack Sérénité';
  1064.                     
  1065.                     // Récupérer le produit en BDD
  1066.                     $typeProduit $em->getRepository(Typeproduit::class)->findOneBy([
  1067.                         'labeletype' => $packLabel
  1068.                     ]);
  1069.                     
  1070.                     // Récupérer le statut "en attente"
  1071.                     $statutEnAttente $em->getRepository(Ref::class)->find(1);
  1072.                     if (!$statutEnAttente) {
  1073.                         $statutEnAttente = new Ref();
  1074.                         $statutEnAttente->setLibiller('En attente');
  1075.                         $em->persist($statutEnAttente);
  1076.                         $em->flush();
  1077.                     }
  1078.                     
  1079.                     // Déterminer les montants du pack
  1080.                     $defaultsByPack = [
  1081.                         'Pack Sérénité' => ['ht' => 490'ttc' => 588],
  1082.                         'Pack Découverte' => ['ht' => 290'ttc' => 348],
  1083.                     ];
  1084.                     $montantHt $typeProduit $typeProduit->getMontantHt() : null;
  1085.                     $montantTtc $typeProduit $typeProduit->getMontantTTC() : null;
  1086.                     
  1087.                     if (empty($montantHt) || empty($montantTtc)) {
  1088.                         $fallback $defaultsByPack[$packLabel] ?? $defaultsByPack['Pack Sérénité'];
  1089.                         $montantHt $montantHt ?: $fallback['ht'];
  1090.                         $montantTtc $montantTtc ?: $fallback['ttc'];
  1091.                     }
  1092.                     
  1093.                     // Créer la commande avec statut "en attente"
  1094.                     $commande = new Commande();
  1095.                     $commande->setIdUser($user);
  1096.                     $commande->setStatut($statutEnAttente);
  1097.                     $commande->setMontantht($montantHt);
  1098.                     $commande->setMontantrth($montantTtc);
  1099.                     $commande->setMontanenv($montantTtc);
  1100.                     $commande->setTva(20);
  1101.                     
  1102.                     // Dates d'abonnement: début maintenant, fin dans 12 mois
  1103.                     $startDateTime = new \DateTime();
  1104.                     $endDateTime = (clone $startDateTime)->modify('+12 months');
  1105.                     
  1106.                     $commande->setDateCreateCommande($startDateTime);
  1107.                     $commande->setDateExpidition($endDateTime);
  1108.                     $commande->setPeriode('annuel');
  1109.                     $commande->setPaymentType('rib');
  1110.                     $commande->setNumComande(time());
  1111.                     
  1112.                     $this->logger->info('💾 Avant persist/flush commande');
  1113.                     $em->persist($commande);
  1114.                     $this->logger->info('💾 Après persist, avant flush');
  1115.                     $em->flush();
  1116.                     $this->logger->info('💾 Après flush');
  1117.                     
  1118.                     $commandeId $commande->getId();
  1119.                     $this->logger->info('✅ Commande pack créée: ID=' $commandeId ' Montant=' $montantTtc '€');
  1120.                     
  1121.                     // Vérifier que la commande existe vraiment en BDD
  1122.                     $commandeVerif $em->getRepository(Commande::class)->find($commandeId);
  1123.                     if ($commandeVerif) {
  1124.                         $this->logger->info('✅ VÉRIFICATION: Commande #' $commandeId ' existe bien en BDD');
  1125.                     } else {
  1126.                         $this->logger->error('❌ VÉRIFICATION: Commande #' $commandeId ' N\'EXISTE PAS en BDD !');
  1127.                     }
  1128.                     
  1129.                 } catch (\Exception $commandeError) {
  1130.                     $this->logger->error('❌ Erreur création commande pack', [
  1131.                         'error' => $commandeError->getMessage(),
  1132.                         'trace' => $commandeError->getTraceAsString()
  1133.                     ]);
  1134.                     // NE PAS continuer si la création échoue
  1135.                     return new JsonResponse([
  1136.                         'success' => false,
  1137.                         'message' => 'Erreur lors de la création de la commande: ' $commandeError->getMessage()
  1138.                     ], 500);
  1139.                 }
  1140.                 
  1141.             } else {
  1142.                 // ==================== CRÉATION SÉJOUR SIMPLE PF ====================
  1143.                 try {
  1144.                     $this->logger->info('🏕️ Création du séjour simple PF');
  1145.                     $dateDebut $startDate ?: date('Y-m-d');
  1146.                     $dateFin $endDate ?: date('Y-m-d'strtotime($dateDebut ' +7 days'));
  1147.                     $themeTexte $theme ?: 'Séjour';
  1148.                     $nbParticipants $participants ?: 10;
  1149.                     
  1150.                     $sejour $this->sejourService->CreationNouveauSejour(
  1151.                         $themeTexte,              // themSejour
  1152.                         '',                       // adressSejour
  1153.                         '',                       // codePostal
  1154.                         $dateDebut,              // dateDebut
  1155.                         $dateFin,                // FinSejour
  1156.                         '6-10 ans',              // AgeDugroupe
  1157.                         'PF',                    // type (Partenaire Financé)
  1158.                         $user->getId(),          // userid
  1159.                         $nbParticipants,         // NbEnfant
  1160.                         0,                       // connpay (0 = non payé)
  1161.                         'France',                // pays
  1162.                         '',                      // ville
  1163.                         null,                    // prixcnxparent
  1164.                         null,                    // prixcnxpartenaire
  1165.                         null,                    // reversecnxpart
  1166.                         null                     // reverseventepart
  1167.                     );
  1168.                     
  1169.                     // Récupérer ou créer le statut "attente_paiement"
  1170.                     $statutAttentePaiement $em->getRepository(Ref::class)->findOneBy(['libiller' => 'attente_paiement']);
  1171.                     
  1172.                     if (!$statutAttentePaiement) {
  1173.                         $this->logger->warning('⚠️ Statut "attente_paiement" non trouvé');
  1174.                     } else {
  1175.                         $sejour->setStatut($statutAttentePaiement);
  1176.                         $em->flush();
  1177.                         $this->logger->info('✅ Statut défini: ' $statutAttentePaiement->getLibiller());
  1178.                     }
  1179.                     
  1180.                     $this->logger->info('✅ Séjour créé: Code=' $sejour->getCodeSejour() . ' ID=' $sejour->getId());
  1181.                 } catch (\Exception $sejourError) {
  1182.                     $this->logger->error('❌ Erreur création séjour', [
  1183.                         'error' => $sejourError->getMessage(),
  1184.                         'trace' => $sejourError->getTraceAsString()
  1185.                     ]);
  1186.                     throw $sejourError;
  1187.                 }
  1188.             }
  1189.             // Envoyer email à l'équipe avec les informations complètes
  1190.             $emailContext = [
  1191.                 'fullname' => $fullname,
  1192.                 'user_email' => $emailUser,
  1193.                 'phone' => $phone,
  1194.                 'org' => $org,
  1195.                 'message' => $message,
  1196.                 'pack_id' => $packId,
  1197.                 'participants' => $participants,
  1198.                 'total_amount' => $totalAmount,
  1199.                 'start_date' => $startDate,
  1200.                 'end_date' => $endDate,
  1201.                 'theme' => $theme,
  1202.                 'accompagnateur' => $accompagnateur,
  1203.                 'request_number' => $requestNumber,
  1204.             ];
  1205.             
  1206.             // Ajouter les infos spécifiques selon le type
  1207.             if ($isPack && $commande) {
  1208.                 $emailContext['commande_id'] = $commande->getId();
  1209.                 $emailContext['commande_numero'] = $commande->getNumComande();
  1210.                 $emailContext['montant_ht'] = $commande->getMontantht();
  1211.                 $emailContext['montant_ttc'] = $commande->getMontantrth();
  1212.                 $emailContext['is_pack'] = true;
  1213.             } else if ($sejour) {
  1214.                 $emailContext['code_sejour'] = $sejour->getCodeSejour();
  1215.                 $emailContext['sejour_id'] = $sejour->getId();
  1216.                 $emailContext['is_pack'] = false;
  1217.             }
  1218.             
  1219.             $subjectPrefix $isPack '📦 Demande RIB Pack Annuel' '🏦 Demande RIB Paiement Séjour Simple';
  1220.             
  1221.             // Ajouter le numéro de commande au sujet si c'est un pack
  1222.             $subjectSuffix $requestNumber;
  1223.             if ($isPack && $commande) {
  1224.                 $subjectSuffix .= ' - Commande #' $commande->getNumComande();
  1225.             }
  1226.             
  1227.             $teamEmail = (new TemplatedEmail())
  1228.                 ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  1229.                 ->to('partenariat@5sur5sejour.com')
  1230.                 ->cc('ramzi.benlarbi@gmail.com''yousra.tlich@gmail.com')
  1231.                 ->subject($subjectPrefix ' - ' $org ' - ' $subjectSuffix)
  1232.                 ->htmlTemplate('emails/bank_transfer_request_team.html.twig')
  1233.                 ->context($emailContext);
  1234.             $this->mailer->send($teamEmail);
  1235.             // Email de confirmation au client avec RIB
  1236.             $ribDetails = [
  1237.                 'iban' => 'FR76 1010 7001 5300 0123 4567 890',
  1238.                 'bic' => 'BREDFRPPXXX',
  1239.                 'beneficiaire' => '5SUR5 SEJOUR',
  1240.                 'reference' => $requestNumber
  1241.             ];
  1242.             // Préparer le contexte email client
  1243.             $clientEmailContext = [
  1244.                 'fullname' => $fullname,
  1245.                 'request_number' => $requestNumber,
  1246.                 'rib' => $ribDetails,
  1247.                 'pack_id' => $packId,
  1248.                 'participants' => $participants,
  1249.                 'total_amount' => $totalAmount,
  1250.                 'start_date' => $startDate,
  1251.                 'end_date' => $endDate,
  1252.                 'theme' => $theme,
  1253.                 'accompagnateur' => $accompagnateur,
  1254.                 'org' => $org,
  1255.             ];
  1256.             
  1257.             // Ajouter les infos spécifiques
  1258.             if ($isPack && $commande) {
  1259.                 $clientEmailContext['commande_id'] = $commande->getId();
  1260.                 $clientEmailContext['commande_numero'] = $commande->getNumComande();
  1261.                 $clientEmailContext['montant_ht'] = $commande->getMontantht();
  1262.                 $clientEmailContext['montant_ttc'] = $commande->getMontantrth();
  1263.                 $clientEmailContext['is_pack'] = true;
  1264.             } else if ($sejour) {
  1265.                 $clientEmailContext['code_sejour'] = $sejour->getCodeSejour();
  1266.                 $clientEmailContext['sejour_id'] = $sejour->getId();
  1267.                 $clientEmailContext['is_pack'] = false;
  1268.             }
  1269.             
  1270.             $clientEmail = (new TemplatedEmail())
  1271.                 ->from(new Address('info@5sur5sejour.com''5sur5 Séjour'))
  1272.                 ->to($emailUser)
  1273.                 ->subject('RIB et Facture Proforma - ' $requestNumber ' - 5sur5 Séjour')
  1274.                 ->htmlTemplate('emails/bank_transfer_request_client.html.twig')
  1275.                 ->context($clientEmailContext);
  1276.             $this->mailer->send($clientEmail);
  1277.             return new JsonResponse([
  1278.                 'success' => true,
  1279.                 'message' => 'Votre demande a été envoyée avec succès ! Vous allez recevoir le RIB et la facture proforma par email.',
  1280.                 'requestNumber' => $requestNumber
  1281.             ]);
  1282.         } catch (\Exception $e) {
  1283.             $this->logger->error('Erreur lors de l\'envoi de la demande de RIB', [
  1284.                 'error' => $e->getMessage(),
  1285.                 'trace' => $e->getTraceAsString()
  1286.             ]);
  1287.             return new JsonResponse([
  1288.                 'success' => false,
  1289.                 'message' => 'Erreur: ' $e->getMessage(),
  1290.                 'error' => $e->getMessage(),
  1291.                 'trace' => $e->getTraceAsString()
  1292.             ], 500);
  1293.         }
  1294.     }
  1295.     /**
  1296.      * @Route("/pack-request-submit", name="pack_request_submit", methods={"POST"})
  1297.      */
  1298.     public function packRequestSubmit(Request $request): JsonResponse
  1299.     {
  1300.         try {
  1301.             $fullname $request->request->get('pack_fullname');
  1302.             $email $request->request->get('pack_email');
  1303.             $phone $request->request->get('pack_phone');
  1304.             $org $request->request->get('pack_org');
  1305.             $packType $request->request->get('pack_type');
  1306.             $message $request->request->get('pack_message');
  1307.             // Validation basique
  1308.             if (empty($fullname) || empty($email) || empty($packType)) {
  1309.                 return new JsonResponse([
  1310.                     'success' => false,
  1311.                     'message' => 'Le nom, l\'email et le type de pack sont obligatoires.'
  1312.                 ], 400);
  1313.             }
  1314.             // Envoyer email à l'équipe
  1315.             $email = (new TemplatedEmail())
  1316.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1317.                 ->to('contact@5sur5sejour.fr')
  1318.                 ->subject('Demande de Pack Partenaire - ' $fullname)
  1319.                 ->htmlTemplate('emails/pack_request_team.html.twig')
  1320.                 ->context([
  1321.                     'fullname' => $fullname,
  1322.                     'email' => $email,
  1323.                     'phone' => $phone,
  1324.                     'org' => $org,
  1325.                     'packType' => $packType,
  1326.                     'message' => $message
  1327.                 ]);
  1328.             $this->mailer->send($email);
  1329.             // Email de confirmation au client
  1330.             $clientEmail = (new TemplatedEmail())
  1331.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1332.                 ->to($email)
  1333.                 ->subject('Demande de Pack Partenaire reçue - 5sur5 Séjour')
  1334.                 ->htmlTemplate('emails/pack_request_partner.html.twig')
  1335.                 ->context([
  1336.                     'fullname' => $fullname,
  1337.                     'packType' => $packType
  1338.                 ]);
  1339.             $this->mailer->send($clientEmail);
  1340.             return new JsonResponse([
  1341.                 'success' => true,
  1342.                 'message' => 'Votre demande de pack partenaire a été envoyée avec succès ! Nous vous recontacterons dans les 24 heures.'
  1343.             ]);
  1344.         } catch (\Exception $e) {
  1345.             $this->logger->error('Erreur lors de l\'envoi de la demande de pack', [
  1346.                 'error' => $e->getMessage(),
  1347.                 'trace' => $e->getTraceAsString()
  1348.             ]);
  1349.             return new JsonResponse([
  1350.                 'success' => false,
  1351.                 'message' => 'Une erreur est survenue lors de l\'envoi de la demande. Veuillez réessayer plus tard.'
  1352.             ], 500);
  1353.         }
  1354.     }
  1355.     /**
  1356.      * @Route("/checkout-create-session", name="checkout_create_session", methods={"POST"})
  1357.      */
  1358.     public function checkoutCreateSession(Request $request): JsonResponse
  1359.     {
  1360.         try {
  1361.             $company $request->request->get('company');
  1362.             $contactName $request->request->get('contact_name');
  1363.             $email $request->request->get('email');
  1364.             $phone $request->request->get('phone');
  1365.             $packType $request->request->get('pack_type');
  1366.             $address $request->request->get('address');
  1367.             $city $request->request->get('city');
  1368.             $postalCode $request->request->get('postal_code');
  1369.             $siret $request->request->get('siret');
  1370.             // Validation basique
  1371.             if (empty($company) || empty($contactName) || empty($email) || empty($packType)) {
  1372.                 return new JsonResponse([
  1373.                     'success' => false,
  1374.                     'message' => 'Les champs obligatoires doivent être remplis.'
  1375.                 ], 400);
  1376.             }
  1377.             // Envoyer email à l'équipe
  1378.             $email = (new TemplatedEmail())
  1379.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1380.                 ->to('contact@5sur5sejour.fr')
  1381.                 ->subject('Nouvelle souscription en ligne - ' $company)
  1382.                 ->htmlTemplate('emails/checkout_request_team.html.twig')
  1383.                 ->context([
  1384.                     'company' => $company,
  1385.                     'contactName' => $contactName,
  1386.                     'email' => $email,
  1387.                     'phone' => $phone,
  1388.                     'packType' => $packType,
  1389.                     'address' => $address,
  1390.                     'city' => $city,
  1391.                     'postalCode' => $postalCode,
  1392.                     'siret' => $siret
  1393.                 ]);
  1394.             $this->mailer->send($email);
  1395.             // Email de confirmation au client
  1396.             $clientEmail = (new TemplatedEmail())
  1397.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1398.                 ->to($email)
  1399.                 ->subject('Souscription reçue - 5sur5 Séjour')
  1400.                 ->htmlTemplate('emails/checkout_request_client.html.twig')
  1401.                 ->context([
  1402.                     'company' => $company,
  1403.                     'contactName' => $contactName,
  1404.                     'packType' => $packType
  1405.                 ]);
  1406.             $this->mailer->send($clientEmail);
  1407.             return new JsonResponse([
  1408.                 'success' => true,
  1409.                 'message' => 'Votre souscription a été enregistrée avec succès ! Nous vous recontacterons dans les 24 heures pour finaliser l\'activation.'
  1410.             ]);
  1411.         } catch (\Exception $e) {
  1412.             $this->logger->error('Erreur lors de l\'enregistrement de la souscription', [
  1413.                 'error' => $e->getMessage(),
  1414.                 'trace' => $e->getTraceAsString()
  1415.             ]);
  1416.             return new JsonResponse([
  1417.                 'success' => false,
  1418.                 'message' => 'Une erreur est survenue lors de l\'enregistrement. Veuillez réessayer plus tard.'
  1419.             ], 500);
  1420.         }
  1421.     }
  1422.     /**
  1423.      * @Route("/quote-request", name="quote_request", methods={"POST"})
  1424.      */
  1425.     public function quoteRequest(Request $request): JsonResponse
  1426.     {
  1427.         try {
  1428.             $orgType $request->request->get('org_type');
  1429.             $orgName $request->request->get('org_name');
  1430.             $contactName $request->request->get('contact_name');
  1431.             $email $request->request->get('email');
  1432.             $phone $request->request->get('phone');
  1433.             $packType $request->request->get('pack_type');
  1434.             $address $request->request->get('address');
  1435.             $city $request->request->get('city');
  1436.             $postalCode $request->request->get('postal_code');
  1437.             $message $request->request->get('message');
  1438.             // Validation basique
  1439.             if (empty($orgType) || empty($orgName) || empty($contactName) || empty($email) || empty($packType)) {
  1440.                 return new JsonResponse([
  1441.                     'success' => false,
  1442.                     'message' => 'Les champs obligatoires doivent être remplis.'
  1443.                 ], 400);
  1444.             }
  1445.             // Envoyer email à l'équipe
  1446.             $email = (new TemplatedEmail())
  1447.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1448.                 ->to('contact@5sur5sejour.fr')
  1449.                 ->subject('Demande de devis - ' $orgName)
  1450.                 ->htmlTemplate('emails/quote_request_team.html.twig')
  1451.                 ->context([
  1452.                     'orgType' => $orgType,
  1453.                     'orgName' => $orgName,
  1454.                     'contactName' => $contactName,
  1455.                     'email' => $email,
  1456.                     'phone' => $phone,
  1457.                     'packType' => $packType,
  1458.                     'address' => $address,
  1459.                     'city' => $city,
  1460.                     'postalCode' => $postalCode,
  1461.                     'message' => $message
  1462.                 ]);
  1463.             $this->mailer->send($email);
  1464.             // Email de confirmation au client
  1465.             $clientEmail = (new TemplatedEmail())
  1466.                 ->from(new Address('noreply@5sur5sejour.fr''5sur5 Séjour'))
  1467.                 ->to($email)
  1468.                 ->subject('Demande de devis reçue - 5sur5 Séjour')
  1469.                 ->htmlTemplate('emails/quote_request_client.html.twig')
  1470.                 ->context([
  1471.                     'orgName' => $orgName,
  1472.                     'contactName' => $contactName,
  1473.                     'packType' => $packType
  1474.                 ]);
  1475.             $this->mailer->send($clientEmail);
  1476.             return new JsonResponse([
  1477.                 'success' => true,
  1478.                 'message' => 'Votre demande de devis a été envoyée avec succès ! Nous vous recontacterons dans les 24 heures.'
  1479.             ]);
  1480.         } catch (\Exception $e) {
  1481.             $this->logger->error('Erreur lors de l\'envoi de la demande de devis', [
  1482.                 'error' => $e->getMessage(),
  1483.                 'trace' => $e->getTraceAsString()
  1484.             ]);
  1485.             return new JsonResponse([
  1486.                 'success' => false,
  1487.                 'message' => 'Une erreur est survenue lors de l\'envoi de la demande. Veuillez réessayer plus tard.'
  1488.             ], 500);
  1489.         }
  1490.     }
  1491. }