src/Controller/ReservationController.php line 726

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Client;
  4. use App\Entity\Client\BillingInfos;
  5. use App\Entity\Product\Famille;
  6. use App\Entity\RDV;
  7. use App\Entity\RDVProduct;
  8. use App\Entity\Salon;
  9. use App\Entity\Site;
  10. use App\Form\ClientType;
  11. use App\Form\RDVType;
  12. use App\Repository\ClientRepository;
  13. use App\Repository\CompanyRepository;
  14. use App\Repository\FamilleRepository;
  15. use App\Repository\ProductRepository;
  16. use App\Repository\ProductServiceRepository;
  17. use App\Repository\RDVProductRepository;
  18. use App\Repository\RDVRepository;
  19. use App\Repository\SalonRepository;
  20. use App\Repository\SessionSalonRepository;
  21. use App\Repository\SousFamilleRepository;
  22. use App\Service\CreateUserService;
  23. use App\Service\MailService;
  24. use App\Service\PaytweakService;
  25. use App\Traits\RDVManagerTrait;
  26. use Doctrine\Persistence\ManagerRegistry;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  30. use Symfony\Component\HttpFoundation\Request;
  31. /**
  32.  * @Route("/reservation")
  33.  */
  34. class ReservationController extends AbstractController
  35. {
  36.     use RDVManagerTrait;
  37.     /**
  38.      * @Route("/", name="rdv_index")
  39.      */
  40.     public function index(SalonRepository $salonRepository): Response
  41.     {
  42.         return $this->render('reservation/index.html.twig', [
  43.             'types' => Site::getSiteTypes(),
  44.             'services' => Salon::getServices(),
  45.             'salons' => $salonRepository->findSalonsByTypeAndService(Site::TYPE_SSRSalon::SERVICE_COIFFURE),
  46.         ]);
  47.     }
  48.     /**
  49.      * @Route("/{salon}", name="rdv_category_selection", methods={"GET"})
  50.      */
  51.     public function categorySelection(Salon $salonFamilleRepository $familleRepository): Response
  52.     {
  53.         $familles $familleRepository->findBy(['isReservation' => true]);
  54.         $typeSalon $salon->getService();
  55.         foreach ($familles as $key => $famille) {
  56.             if (preg_match('/esthétique|esthetique/i'$famille->getName()) && $typeSalon === 'coiffure') {
  57.                 unset($familles[$key]);
  58.             }
  59.             if (preg_match('/coiffure/i'$famille->getName()) && $typeSalon === 'esthetique') {
  60.                 unset($familles[$key]);
  61.             }
  62.         }
  63.         return $this->render('reservation/category_selection.html.twig', [
  64.             'salon' => $salon,
  65.             'familles' => $familles
  66.         ]);
  67.     }
  68.     /**
  69.      * @Route("/{salon}/{famille}", name="rdv_product_selection")
  70.      */
  71.     public function productSelection(
  72.         Salon $salon,
  73.         Famille $famille,
  74.         ProductRepository $productRepository,
  75.         ProductServiceRepository $productServiceRepository,
  76.         SousFamilleRepository $sousFamilleRepository,
  77.         Request $request,
  78.         ManagerRegistry $doctrine,
  79.         PaytweakService $paytweakService,
  80.         ClientRepository $clientRepository,
  81.         SessionSalonRepository $sessionSalonRepository,
  82.         RDVRepository $rdvRepository
  83.     ): Response {
  84.         $typeSite $salon->getSite()->getType();
  85.         $products $productRepository->getProductsByFamily($famille);
  86.         $productIds array_map(function ($e) {
  87.             return $e->getId();
  88.         }, $products);
  89.         $sousFamilleIds array_map(function ($e) {
  90.             return $e->getSousFamille()->getId();
  91.         }, $products);
  92.         $service $this->serviceName(strtolower($famille->getName()));
  93.         $productServices $productServiceRepository->findByProductIds($productIds);
  94.         $rdv = new RDV();
  95.         $form $this->createForm(RDVType::class, $rdv, [
  96.             'view' => 'client',
  97.             'famille' => $famille,
  98.             'productIds' => $productIds
  99.         ]);
  100.         $form->handleRequest($request);
  101.         if ($form->isSubmitted() && $form->isValid()) {
  102.             /** @var array $params */
  103.             $params $request->request->get('rdv');
  104.             $session $request->getSession();
  105.             $session->clear();
  106.             $session->set('recurrence'$params['recurrence']);
  107.             $session->set('civilite'$params['civilite']);
  108.             $session->set('lastname'$params['lastname']);
  109.             $session->set('firstname'$params['firstname']);
  110.             $session->set('email'$params['email']);
  111.             $session->set('hasAddService'$params['hasAddService']);
  112.             $session->set('comment'$params['comment']);
  113.             $session->set('isSession'true);
  114.             foreach ($params['products'] as $productId) {
  115.                 $product $productRepository->findOneById((int)$productId);
  116.                 if ($product->getSousFamille()->isOneChoice()) { // radio
  117.                     $session->set('sousfamille_' $product->getSousFamille()->getId(), (int) $productId);
  118.                 } else { //checkbox
  119.                     $session->set('product_' $productId, (int) $productId);
  120.                 }
  121.             }
  122.             if (empty($params['start'])) {
  123.                 $this->addFlash('danger''Une erreur s\'est produite lors que vous êtes retourné en arrière, veuillez réessayer');
  124.                 return $this->redirectToRoute('rdv_product_selection', [
  125.                     'salon' => $salon->getId(),
  126.                     'famille' => $famille->getId(),
  127.                 ]);
  128.             }
  129.             // check if date available
  130.             $isDateAvailable $this->checkDateAvailability($params['start'], $rdvRepository$salon);
  131.             if ($isDateAvailable === false) {
  132.                 $this->addFlash('danger''La date n\'est pas disponible, veuillez réessayer');
  133.                 return $this->redirectToRoute('rdv_product_selection', [
  134.                     'salon' => $salon->getId(),
  135.                     'famille' => $famille->getId(),
  136.                 ]);
  137.             }
  138.             $clientExist null;
  139.             $orderIdPaytweak null;
  140.             $paymentLink false;
  141.             $em $doctrine->getManager();
  142.             // save the product for the rdv
  143.             if (!empty($form->getExtraData())) {
  144.                 $products $form->getExtraData()['products'];
  145.                 $rdvProducts = [];
  146.                 foreach ($products as $productId) {
  147.                     $product $productRepository->findOneById((int)$productId);
  148.                     $rdvProduct = new RDVProduct();
  149.                     $rdvProduct->setProduct($product);
  150.                     $rdvProduct->setRdv($rdv);
  151.                     $rdvProducts[] = $rdvProduct;
  152.                 }
  153.                 $clientExist $clientRepository->findOneBy([
  154.                     'lastname' => $params['lastname'],
  155.                     'firstname' => $params['firstname'],
  156.                     'civilite' => $params['civilite'],
  157.                     'site' => $salon->getSite(),
  158.                 ]);
  159.                 // check also
  160.                 if($clientExist && ($clientExist->getStatusProspect() == Client::STATUS_INACTIF || $clientExist->getStatusProspect() == Client::STATUS_PARTI )){
  161.                     $clientExist null;
  162.                 }
  163.                 if($clientExist){
  164.                     /** @var RDV $lastRDV */
  165.                     $lastRDV $this->RDVManager->getRepository()->findOneByClientAndToken($clientExist);
  166.                     if($lastRDV){
  167.                         $paymentLink $lastRDV->getPaymentLink();
  168.                         $path parse_url($paymentLinkPHP_URL_PATH);
  169.                         $orderIdPaytweak basename($path);
  170.                     }
  171.                     $rdv->setClient($clientExist);
  172.                 }
  173.                                 /** @var SessionSalon $sessionSalon */
  174.                 $date = new \DateTime($params['start']);
  175.                 $sessionSalon $sessionSalonRepository->findSessionBySalonAndDate($salon$date);
  176.                 $end = clone $date;
  177.                 $sessionLength $typeSite === Site::TYPE_EHPAD '+15 minutes' '+30 minutes';
  178.                 $end->modify($sessionLength);
  179.                 $rdv->setStart($date);
  180.                 $rdv->setEnd($end);
  181.                 $rdv->setIntervenant($sessionSalon[0]->getIntervenant());
  182.                 $rdv->setRdvProducts($rdvProducts);
  183.                 $rdv->setStatus(RDV::STATUS_NON_PAYE);
  184.                 $rdv->setSalon($salon);
  185.                 $rdv->setIsPlatform(true);
  186.                 $em->persist($rdv);
  187.                 $em->flush();
  188.             }
  189.             else {
  190.                 $this->addFlash('danger''Aucun forfait selectionné');
  191.                 return $this->redirectToRoute('rdv_product_selection', [
  192.                     'salon' => $salon->getId(),
  193.                     'famille' => $famille->getId(),
  194.                 ]);
  195.             }
  196.             // api call for Paytweak
  197.             if($clientExist && $paymentLink){
  198.                 $rdv->setStatus(RDV::STATUS_PLANIFIER);
  199.                 $em->persist($rdv);
  200.                 $em->flush();
  201.             }
  202.             else {
  203.                 $response $paytweakService->createLink($orderIdPaytweak);
  204.                 if ($response['code'] !== 'OK') {
  205.                     // delete rdv if api KO
  206.                     $em->remove($rdv);
  207.                     $em->flush();
  208.                     $this->addFlash('danger''Une erreur s\'est produite, veuillez réessayer');
  209.                     return $this->redirectToRoute('rdv_product_selection', [
  210.                         'salon' => $salon->getId(),
  211.                         'famille' => $famille->getId(),
  212.                     ]);
  213.                 }
  214.                 else { // for payment
  215.                     $rdv->setOrderId($response['order_id']);
  216.                     $rdv->setPaymentLink($response['url']);
  217.                     $em->persist($rdv);
  218.                     $em->flush();
  219.                 }
  220.             }
  221.             // redirect to payment if client is fully authenticated
  222.             if ($clientExist) {
  223.                 return $this->redirectToRoute('rdv_summary', [
  224.                     'salon' => $salon->getId(),
  225.                     'famille' => $famille->getId(),
  226.                     'rdv' => $rdv,
  227.                     'alreadyPaid' => !!$paymentLink
  228.                 ]);
  229.             } else {
  230.                 $this->addFlash('info''Veuillez remplir votre fiche client avant de procéder au paiement');
  231.                 $session $request->getSession();
  232.                 $session->set('civilite'$params['civilite']);
  233.                 $session->set('lastname'$params['lastname']);
  234.                 $session->set('firstname'$params['firstname']);
  235.                 $session->set('email'$params['email']);
  236.                 return $this->redirectToRoute('new_client', [
  237.                     'salon' => $salon->getId(),
  238.                     'famille' => $famille->getId(),
  239.                     'rdv' => $rdv->getId(),
  240.                 ]);
  241.             }
  242.         }
  243.         $datesCalendar $this->prepareDatesCalendar($sessionSalonRepository$rdvRepository$service$salon); // available dates for calendar picker
  244.         $halfHour in_array($typeSite, [Site::TYPE_SSRSite::TYPE_RESIDENCE]); // 15 or 30 min
  245.         return $this->render('reservation/product_selection.html.twig', [
  246.             'salon' => $salon->getId(),
  247.             'products' => $products,
  248.             'famille' => $famille,
  249.             'sousFamilles' => $sousFamilleRepository->findByFamille($famille),
  250.             'productServices' => $productServices,
  251.             'form' => $form->createView(),
  252.             'sousFamilleIds' => $sousFamilleIds,
  253.             'service' => $service,
  254.             'minuteIncrement' => $halfHour 30 15,
  255.             'maxTime' => $halfHour '17:30' '17:45',
  256.             'availableDateTime' => $datesCalendar['availableDateTime'],
  257.             'datesToDisable' => $datesCalendar['datesToDisable']
  258.         ]);
  259.     }
  260.     /**
  261.      * @Route("/{salon}/{famille}/{rdv}/client/new", name="new_client")
  262.      */
  263.     public function newClient(
  264.         Salon $salon,
  265.         Famille $famille,
  266.         RDV $rdv,
  267.         Request $request,
  268.         ManagerRegistry $doctrine,
  269.         CreateUserService $createUserService,
  270.         ClientRepository $clientRepository,
  271.         CompanyRepository $companyRepository
  272.     ): Response {
  273.         $client = new Client();
  274.         $form $this->createForm(ClientType::class, $client, ['isReservation' => true]);
  275.         $form->handleRequest($request);
  276.         if ($form->isSubmitted() && $form->isValid()) {
  277.             if ($rdv->getClient() !== null) { // avoid creating multiple instances
  278.                 return $this->redirectToRoute('rdv_summary', [
  279.                     'salon' => $salon->getId(),
  280.                     'famille' => $famille->getId(),
  281.                     'rdv' => $rdv,
  282.                 ]);
  283.             }
  284.             $em $doctrine->getManager();
  285.             // create new User
  286.             $createUserService->checkAndAddUser(
  287.                 $client,
  288.                 $doctrine
  289.             );
  290.             // check if client is already created
  291.             $clientExists $clientRepository->findOneBy([
  292.                 'civilite' => $client->getCivilite(),
  293.                 'lastname' => $client->getLastname(),
  294.                 'firstname' => $client->getFirstname(),
  295.                 'site' => $salon->getSite(),
  296.             ]);
  297.             // create new Client if don't exist
  298.             if ($clientExists === null || $clientExists->getStatusProspect() === Client::STATUS_PARTI ||  $clientExists->getStatusProspect() === Client::STATUS_INACTIF ) {
  299.                 // new billing infos
  300.                 $billingInfos = new BillingInfos();
  301.                 $company $companyRepository->findOneBy(['mail' => 'contact@silverbeaute.com']);
  302.                 $billingInfos->setCompany($company);
  303.                 $billingInfos->setBillingMode(BillingInfos::BILLING_MODE_TTC);
  304.                 $billingInfos->setAccount('411' $client->getLastname());
  305.                 $billingInfos->setEmail($client->getEmail());
  306.                 $billingInfos->setSendMode(BillingInfos::SEND_MODE_EMAIL);
  307.                 $em->persist($billingInfos);
  308.                 $em->flush();
  309.                 $client->setBillingInfos($billingInfos);
  310.                 $client->setSite($salon->getSite());
  311.                 $em->persist($client);
  312.                 $em->flush();
  313.                 $client->setIdentifier($client->getId() . ' ' $client->getLastname());
  314.                 $em->persist($client);
  315.                 $em->flush();
  316.                 $rdv->setClient($client); // link client with rdv
  317.             } else {
  318.                 $rdv->setClient($clientExists);
  319.             }
  320.             $em->persist($rdv);
  321.             $em->flush();
  322.             // redirect to summary page after new client is created
  323.             return $this->redirectToRoute('rdv_summary', [
  324.                 'salon' => $salon->getId(),
  325.                 'famille' => $famille->getId(),
  326.                 'rdv' => $rdv,
  327.             ]);
  328.         }
  329.         return $this->render('reservation/new_client.html.twig', [
  330.             'form' => $form->createView(),
  331.         ]);
  332.     }
  333.     /**
  334.      * @Route("/{salon}/{famille}/{rdv}/summary/{alreadyPaid}", name="rdv_summary")
  335.      */
  336.     public function summary(
  337.         Salon $salon,
  338.         Famille $famille,
  339.         RDV $rdv,
  340.         RDVProductRepository $RdvProductRepository,
  341.         Request $request,
  342.         $alreadyPaid null
  343.     ): Response {
  344.         $total 0;
  345.         $products = [];
  346.         $rdvProducts $RdvProductRepository->findBy(['rdv' => $rdv]);
  347.         foreach ($rdvProducts as $rdvProduct) {
  348.             $product $rdvProduct->getProduct();
  349.             $products[] = $product;
  350.             $total += $product->getPriceSellTTCA();
  351.         }
  352.         $session $request->getSession();
  353.         return $this->render('reservation/summary.html.twig', [
  354.             'salon' => $salon,
  355.             'famille' => $famille,
  356.             'products' => $products,
  357.             'total' => $total,
  358.             'rdv' => $rdv,
  359.             'email' => $session->get('email'),
  360.             'alreadyPaid' => $alreadyPaid
  361.         ]);
  362.     }
  363.     /**
  364.      * Page confirmation prepayment
  365.      * @Route("/confirmation/paiement/success", name="rdv_confirmation_payment")
  366.      */
  367.     public function confirmationPayment(
  368.         Request $request,
  369.         RDVRepository $rdvRepository
  370.     ): Response {
  371.         $linkId $request->query->get('id');
  372.         $rdv $rdvRepository->findRdvWithLinkId($linkId);
  373.         return $this->render('reservation/confirmation_payment.html.twig', [
  374.             'rdv' => $rdv,
  375.         ]);
  376.     }
  377.     /**
  378.      * @Route("/search/for/get-salons", name="get_salons")
  379.      */
  380.     public function getSalons(Request $requestSalonRepository $salonRepository): Response
  381.     {
  382.         $type $request->query->get('type');
  383.         $salon $request->query->get('salon');
  384.         $service $request->query->get('service');
  385.         $salons $salonRepository->findSalonsByTypeServiceSalonText($type$service$salon);
  386.         return $this->render('reservation/list_salons.html.twig', [
  387.             'salons' => $salons,
  388.         ]);
  389.     }
  390.     /**
  391.      * @Route("/search/for/get-salon-availability", name="get_salon_availability")
  392.      */
  393.     public function getSalonAvailability(
  394.         Request $request,
  395.         SessionSalonRepository $sessionSalonRepository,
  396.         SalonRepository $salonRepository,
  397.         RDVRepository $rdvRepository
  398.     ) {
  399.         $messageDates = [];
  400.         $isDateAvailable false;
  401.         $service str_replace('é''e'$request->query->get('service'));
  402.         $salon $salonRepository->find((int) $request->query->get('salonId'));
  403.         // if no date available, then give the future dates availables
  404.         $limit 5;
  405.         $datesAvailable $this->getAvailability(
  406.             $sessionSalonRepository,
  407.             $rdvRepository,
  408.             $service,
  409.             $salon,
  410.             $limit
  411.         );
  412.         // format array result
  413.         $tabDates = [];
  414.         if (!empty($datesAvailable)) {
  415.             foreach ($datesAvailable as $key => $dateAvailable) {
  416.                 $tabDates[$key] = $dateAvailable['minTime'];
  417.             }
  418.         }
  419.         if (count($tabDates) > 0) {
  420.             $messageDates $tabDates;
  421.             $isDateAvailable true;
  422.         }
  423.         return $this->json([
  424.             'template' => $this->render('reservation/dates_available.html.twig', [
  425.                 'isDateAvailable' => $isDateAvailable,
  426.                 'dates' => $messageDates
  427.             ])->getContent(),
  428.         ]);
  429.     }
  430.     /**
  431.      * @Route("/search/for/get-intervenant-date", name="get_intervenant_date")
  432.      */
  433.     public function getIntervenantByDateRdv(
  434.         Request $request,
  435.         SessionSalonRepository $sessionSalonRepository,
  436.         SalonRepository $salonRepository
  437.     ) {
  438.         $salon $salonRepository->find((int) $request->query->get('salonId'));
  439.         $date = new \DateTime($request->query->get('date'));
  440.         $sessionSalon $sessionSalonRepository->findSessionBySalonAndDate($salon$date);
  441.         $intervenant $sessionSalon[0]->getIntervenant();
  442.         return $this->json([
  443.             'intervenant' => $intervenant->getFullname(),
  444.         ]);
  445.     }
  446.     /**
  447.      * find if the given date is available
  448.      * @param string $dateStr
  449.      * @param RDVRepository $rdvRepository
  450.      * @param Salon $salon
  451.      *
  452.      * @return boolean
  453.      */
  454.     private function checkDateAvailability($dateStr$rdvRepository$salon)
  455.     {
  456.         $givenDate = new \DateTime($dateStr);
  457.         $now = new \DateTime('now');
  458.         $rdvDatesTaken $this->getRdvDatesTaken($rdvRepository$salon);
  459.         if ($givenDate <= $now) { // if the date is in the past
  460.             return false;
  461.         }
  462.         if (in_array($givenDate$rdvDatesTaken)) {
  463.             return false;
  464.         }
  465.         return true;
  466.     }
  467.     /**
  468.      * Get active RDV by salon and return dates
  469.      * @param RDVRepository $rdvRepository
  470.      * @param Salon $salon
  471.      *
  472.      * @return array
  473.      */
  474.     private function getRdvDatesTaken($rdvRepository$salon): array
  475.     {
  476.         // get active rdvs
  477.         $rdvs $rdvRepository->findForRdvWithSalonAndStatus($salon);
  478.         $rdvDatesTaken = [];
  479.         foreach ($rdvs as $rdv) {
  480.             $rdvDatesTaken[] = $rdv->getStart();
  481.         }
  482.         return $rdvDatesTaken;
  483.     }
  484.     /**
  485.      * Get dates available for a salon
  486.      * @param SessionSalonRepository $sessionSalonRepository
  487.      * @param RDVRepository $rdvRepository
  488.      * @param string $service
  489.      * @param Salon $salon
  490.      * @param int $limit
  491.      *
  492.      * @return array
  493.      */
  494.     private function getAvailability(
  495.         $sessionSalonRepository,
  496.         $rdvRepository,
  497.         $service,
  498.         $salon,
  499.         $limit null
  500.     ): array {
  501.         $typeSite $salon->getSite() ? $salon->getSite()->getType()  : null;
  502.         $isEhpad $typeSite === Site::TYPE_EHPAD true false;
  503.         $rdvDatesTaken $this->getRdvDatesTaken($rdvRepository$salon);
  504.         $sessionSalons $sessionSalonRepository->findSalonAvailability($salon$service''$limit);
  505.         $datesAvailable = [];
  506.         $lengthSession $isEhpad 'PT15M' 'PT30M';
  507.         // init opening/closing time
  508. //        $openingTimeStr = Salon::DEFAULT_OPENING_TIME;
  509. //        $closingTimeStr = Salon::DEFAULT_CLOSING_TIME;
  510. //
  511. //        // get salon times
  512. //        if ($salon->getOpeningTime() && $salon->getClosingTime()) {
  513. //            $openingTimeStr = $salon->getOpeningTime()->format('H:i:s');
  514. //            $closingTimeStr = $salon->getClosingTime()->format('H:i:s');
  515. //        }
  516.         foreach ($sessionSalons as $sessionSalon) {
  517.             // Get all session in a day
  518.             $timezone = new \DateTimeZone('Europe/Paris');
  519.             $period = new \DatePeriod(
  520.                 new \DateTime($sessionSalon->getStart()->format('d-m-Y H:i:s' ),$timezone),
  521.                 new \DateInterval($lengthSession),
  522.                 new \DateTime($sessionSalon->getEnd() ? $sessionSalon->getEnd()->format('d-m-Y H:i:s') : $sessionSalon->getStart()->format('d-m-Y 18:00:00' ),$timezone)
  523.             );
  524.             // save available spots
  525.             $rdvAvailableBySessionSalon = [];
  526.             $now = new \DateTime('now'$timezone);
  527.             foreach ($period as $p) {
  528.                 if ($p >= $now && !in_array($p$rdvDatesTaken)) {
  529.                     $rdvAvailableBySessionSalon[] = $p->format('H:i');
  530.                 }
  531.             }
  532.             $datesAvailable[$sessionSalon->getStart()->format('d-m-Y')]['minTime'] = $rdvAvailableBySessionSalon;
  533.         }
  534.         return $datesAvailable;
  535.     }
  536.     /**
  537.      * @Route("/search/for/get-additionnal-products", name="get_additionnal_products")
  538.      */
  539.     public function getAdditionnalProducts(Request $requestProductServiceRepository $productServiceRepository)
  540.     {
  541.         $productId $request->query->get('productId');
  542.         if ($productId !== '') {
  543.             $productServices $productServiceRepository->findBy(['product' => $productId]);
  544.         }
  545.         return $this->render('reservation/additionnal_services_popup.html.twig', [
  546.             'productServices' => $productServices ?? []
  547.         ]);
  548.     }
  549.     /**
  550.      * Return text if coiffure or esthétique
  551.      * @param string $name
  552.      *
  553.      * @return string
  554.      */
  555.     private function serviceName($name): string
  556.     {
  557.         if (strpos($name'coiffure') !== false) {
  558.             $text 'coiffure';
  559.         } else if (strpos($name'esthétique') !== false) {
  560.             $text 'esthétique';
  561.         } else {
  562.             $text '';
  563.         }
  564.         return $text;
  565.     }
  566.     /**
  567.      * @Route("/docs/privacy-policy/politique-de-confidentialite", name="privacy_policy")
  568.      */
  569.     public function privacyPolicy(): Response
  570.     {
  571.         return $this->render('reservation/privacy_policy.html.twig');
  572.     }
  573.     /**
  574.      * send mail confirmation to client
  575.      * @Route("/search/for/send-confirmation-rdv", name="send_confirmation_rdv")
  576.      */
  577.     public function sendConfirmationRdv(
  578.         Request $request,
  579.         MailService $mailService,
  580.         FamilleRepository $familleRepository,
  581.         RDVRepository $rdvRepository
  582.     ) {
  583.         $famille $familleRepository->findOneById((int)$request->query->get('familleId'));
  584.         $rdv $rdvRepository->findOneById((int)$request->query->get('rdvId'));
  585.         $typeService strpos(strtolower($famille->getName()), 'coiffure') !== false 'de coiffure' 'd’esthétique';
  586.         $mailService->sendConfirmationRdv(
  587.             $request->query->get('email'),
  588.             [
  589.                 'rdv' => $rdv,
  590.                 'client' => $rdv->getClient(),
  591.                 'typeService' => $typeService,
  592.             ]
  593.         );
  594.         return $this->json($rdv->getPaymentLink());
  595.     }
  596.     /**
  597.      * Prepare dates for calendar
  598.      * @param mixed $sessionSalonRepository
  599.      * @param mixed $rdvRepository
  600.      * @param mixed $service
  601.      * @param mixed $salon
  602.      *
  603.      * @return array
  604.      */
  605.     private function prepareDatesCalendar($sessionSalonRepository$rdvRepository$service$salon): array
  606.     {
  607.         // available dates for calendar picker
  608.         $availableDates $this->getAvailability($sessionSalonRepository$rdvRepository$service$salon);
  609.         $availableDatetimeFormatted = [];
  610.         $availableDatetimeList = [];
  611.         $datesToDisable = [];
  612.         // convert format date
  613.         foreach ($availableDates as $key => $availableDate) {
  614.             $formattedDate = new \DateTime($key);
  615.             $availableDatetimeFormatted[$formattedDate->format('d-m-Y')] = $availableDate;
  616.             $availableDatetimeList[] = $formattedDate->format('d-m-Y');
  617.         }
  618.         // get disabled dates
  619.         $now = new \DateTime('now');
  620.         $end = clone $now;
  621.         $period = new \DatePeriod(
  622.             $now,
  623.             new \DateInterval('P1D'),
  624.             $end->modify('+12 month')
  625.         );
  626.         foreach ($period as $date) {
  627.             if (!in_array($date->format('d-m-Y'), $availableDatetimeList)) {
  628.                 $datesToDisable[] = $date->format('d-m-Y');
  629.             }
  630.         }
  631.         return [
  632.             'availableDateTime' => json_encode($availableDatetimeFormatted),
  633.             'datesToDisable' => json_encode($datesToDisable),
  634.         ];
  635.     }
  636.     /**
  637.      * @Route("/docs/cgv/politique-de-confidentialite", name="general_terms_conditions")
  638.      */
  639.     public function generalTermsAndConditions(): Response
  640.     {
  641.         return $this->render('reservation/general_terms_conditions.html.twig');
  642.     }
  643. }