src/Controller/PlanningController.php line 1589

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Billing;
  4. use App\Entity\Client;
  5. use App\Entity\Company;
  6. use App\Entity\Contract;
  7. use App\Entity\Intervenant;
  8. use App\Entity\LogCancel;
  9. use App\Entity\LogPlanning;
  10. use App\Entity\LogRDV;
  11. use App\Entity\Product;
  12. use App\Entity\RDV;
  13. use App\Entity\RDVProduct;
  14. use App\Entity\Salon;
  15. use App\Entity\Session;
  16. use App\Entity\SessionSalon;
  17. use App\Entity\Site;
  18. use App\Entity\User;
  19. use App\Form\AddSessionSalonType;
  20. use App\Form\CompanyType;
  21. use App\Form\FilterType;
  22. use App\Form\RDVType;
  23. use App\Form\ReplanningIntervenantType;
  24. use App\Form\ReplanningType;
  25. use App\Form\SessionSalonType;
  26. use App\Manager\ReglementManager;
  27. use App\Message\SendingPlanning;
  28. use App\Repository\BillingRepository;
  29. use App\Repository\ClientRepository;
  30. use App\Repository\IntervenantRepository;
  31. use App\Repository\ProductRepository;
  32. use App\Repository\RDVProductRepository;
  33. use App\Repository\RDVRepository;
  34. use App\Repository\SalonRepository;
  35. use App\Repository\SessionSalonRepository;
  36. use App\Service\MailService;
  37. use App\Service\PaytweakService;
  38. use App\Traits\BillingManagerTrait;
  39. use App\Traits\MailServiceTrait;
  40. use App\Traits\ManagerTrait;
  41. use App\Traits\RDVManagerTrait;
  42. use DateTime;
  43. use Doctrine\Common\Collections\ArrayCollection;
  44. use Doctrine\ORM\EntityManagerInterface;
  45. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  46. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  47. use Psr\Log\LoggerInterface;
  48. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  49. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  50. use Symfony\Component\Form\FormFactoryInterface;
  51. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  52. use Symfony\Component\HttpFoundation\JsonResponse;
  53. use Symfony\Component\HttpFoundation\RedirectResponse;
  54. use Symfony\Component\HttpFoundation\Request;
  55. use Symfony\Component\HttpFoundation\Response;
  56. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  57. use Symfony\Component\HttpFoundation\StreamedResponse;
  58. use Symfony\Component\Messenger\MessageBusInterface;
  59. use Symfony\Component\Routing\Annotation\Route;
  60. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  61. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  62. use Symfony\Component\Security\Csrf\CsrfTokenManager;
  63. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  64. use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
  65. use Symfony\Component\Serializer\Serializer;
  66. use Symfony\Component\Serializer\SerializerInterface;
  67. /**
  68.  * @Route("/planning")
  69.  */
  70. class PlanningController extends AbstractController
  71. {
  72.     use RDVManagerTrait;
  73.     use ManagerTrait;
  74.     use BillingManagerTrait;
  75.     use MailServiceTrait;
  76.     /**
  77.      * @Route("/site", methods={"GET"})
  78.      * @Template()
  79.      */
  80.     public function site(SerializerInterface $serializer): array
  81.     {
  82.         $em $this->managerRegistry;
  83.         $sessions $em->getRepository(RDV::class)->findForPlanning();
  84.         $sites $em->getRepository(Site::class)->findAll();
  85.         $intervenants $em->getRepository(Intervenant::class)->findAll();
  86.         $companies $em->getRepository(Company::class)->findAll();
  87.         $rdv = new RDV();
  88.         $form $this->createForm(RDVType::class, $rdv);
  89.         $sessions $serializer->serialize($sessions'json', [
  90.             'groups' => 'rdv',
  91.             'circular_reference_handler' => function ($object) {
  92.                 return $object->getId();
  93.             }
  94.         ]);
  95.         //dump($sessions);die;
  96.         return [
  97.             'sites' => $sites,
  98.             'intervenants' => $intervenants,
  99.             'sessions' => $sessions,
  100.             'companies' => $companies,
  101.             'form' => $form->createView()
  102.         ];
  103.     }
  104.     /**
  105.      * TODO: not in use
  106.      * @Route("/intervenant", methods={"GET"})
  107.      * @Template()
  108.      */
  109.     public function intervenant(SerializerInterface $serializer): array
  110.     {
  111.         $em $this->managerRegistry;
  112.         $sessions $em->getRepository(RDV::class)->findAll();
  113.         $rdv = new RDV();
  114.         $form $this->createForm(RDVType::class, $rdv);
  115.         $sessions $serializer->serialize($sessions'json', [
  116.             'groups' => 'rdv',
  117.             'circular_reference_handler' => function ($object) {
  118.                 return $object->getId();
  119.             }
  120.         ]);        //dump($sessions);die;
  121.         return [
  122.             'sessions' => $sessions,
  123.             'form' => $form->createView()
  124.         ];
  125.     }
  126.     /**
  127.      * @Route("/envoiPlanning")
  128.      */
  129.     public function envoiPlanning(MessageBusInterface $messageBus): RedirectResponse
  130.     {
  131.         $this->addFlash('success''Envoi pris en compte. ');
  132.         $messageBus->dispatch(new SendingPlanning());
  133.         return $this->redirectToRoute('app_planning_pilotage');
  134.     }
  135.     /**
  136.      * @Route("/liste", methods={"GET","POST"})
  137.      * @Template()
  138.      */
  139.     public function liste(
  140.         Request $request,
  141.         RDVRepository $RDVRepository,
  142.         SessionSalonRepository $sessionSalonRepository,
  143.         ProductRepository  $productRepository,
  144.         ClientRepository $clientRepository,
  145.         BillingRepository $billingRepository
  146.     ): array {
  147.         $em $this->managerRegistry;
  148.         // date ajdh
  149.         //$sessions = $repository->findFromToday();
  150.         $sites $em->getRepository(Site::class)->findAll();
  151.         $rdv = new RDV();
  152.         $status $request->query->get('status');
  153.         $client $request->query->get('client');
  154.         $clientId $request->query->get('client_id');
  155.         $clientFind null;
  156.         if ($clientId) {
  157.             $clientFind $clientRepository->find($clientId);
  158.             $rdv->setClient($clientFind);
  159.             $salon $clientFind->getSite()->getSalons();
  160.             $first =  $salon->first();
  161.             if ($first) {
  162.                 $rdv->setSalon($first);
  163.             }
  164.         }
  165.         $formFilter $this->createForm(FilterType::class, null, ['status' => $status'client' => $clientFind]);
  166.         $form $this->createForm(RDVType::class, $rdv, ['withCustomPicker' => true]);
  167.         $formReplanning $this->createForm(ReplanningType::class, null);
  168.         $formReplanning2 $this->createForm(ReplanningIntervenantType::class, null);
  169.         $formReplanning->handleRequest($request);
  170.         $formReplanning2->handleRequest($request);
  171.         $formFilter->handleRequest($request);
  172.         $sessions $RDVRepository->findByFilter(nullnull$clientnullnull$status$clientId);
  173.         $sessionsResult =[];
  174.         /** @var RDV $session */
  175.         foreach ($sessions as $session) {
  176.             $client $session->getClient();
  177.             if($client){
  178.                 $billings $client->getBillings();
  179.                 /** @var Billing $billing */
  180.                 $lastBilling = [];
  181.                 $billings $billingRepository->searchUnpaid($client);
  182.                 $session->paid null;
  183.                 $currentDate = new \DateTime();
  184.                 if (count($billings) > 0) {
  185.                     $myLastElement end($billings);
  186.                     $diff $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
  187.                     $session->paid =  abs($diff);
  188.                 }
  189.             }
  190. //            $products = $productRepository->getProductsArrayByRDV($session['id']);
  191. //            $session['products'] = $products;
  192. //
  193. //            $session['label'] = RDV::getRDVLabel($session['status']);
  194. //            $sessionRdv = $RDVRepository->find($session['id']);
  195. //            $session['ttc'] = $sessionRdv->ttc();
  196.             $sessionsResult[] = $session;
  197.         }
  198.         // replannification
  199.         if ($formReplanning->isSubmitted() && $formReplanning->isValid()) {
  200.             $this->RDVManager->replannification($formReplanning);
  201.             $em->getManager()->flush();
  202.         }
  203.         if ($formReplanning2->isSubmitted() && $formReplanning2->isValid()) {
  204.             $this->RDVManager->replannificationIntervenant($formReplanning2);
  205.             $em->getManager()->flush();
  206.         }
  207.         if ($formFilter->isSubmitted() && $formFilter->isValid()) {
  208.             $intervenant $formFilter->getData()['intervenant'];
  209.             $site $formFilter->getData()['site'];
  210.             $client $formFilter->getData()['client'];
  211.             $start $formFilter->getData()['start'];
  212.             $status $formFilter->getData()['status'];
  213.             $end $formFilter->getData()['end'];
  214.             $salon $formFilter->getData()['salon'];
  215.             $request->getSession()->set('intervenant'$intervenant);
  216.             $request->getSession()->set('site'$site);
  217.             $request->getSession()->set('client'$client);
  218.             $request->getSession()->set('start'$start);
  219.             $request->getSession()->set('end'$end);
  220.             $request->getSession()->set('salon'$salon);
  221.             $sessions $RDVRepository->findByFilter($intervenant$site$client$start$end$status$clientIdnull$salon);
  222.             foreach ($sessions as $session) {
  223.                 $client $session->getClient();
  224.                 $session->paid null;
  225.                 if($client){
  226.                     $billings $client->getBillings();
  227.                     /** @var Billing $billing */
  228.                     $lastBilling = [];
  229.                     $billings $billingRepository->searchUnpaid($client);
  230.                     $currentDate = new \DateTime();
  231.                     if (count($billings) > 0) {
  232.                         $myLastElement end($billings);
  233.                         $diff $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
  234.                         $session->paid =  abs($diff);
  235.                     }
  236.                 }
  237.                 $sessionsResult[] = $session;
  238.             }
  239.             $sessionsResult $sessions;
  240.         }
  241.         return [
  242.             'sessions' => $sessionsResult,
  243.             'form' => $form->createView(),
  244.             'formReplanning' => $formReplanning->createView(),
  245.             'formReplanning2' => $formReplanning2->createView(),
  246.             'formFilter' => $formFilter->createView(),
  247.             'sites' => $sites,
  248.             'intervenant' => $request->getSession()->get('intervenant'),
  249.         ];
  250.     }
  251.     /**
  252.      * @Route("/listeBO", methods={"GET","POST"}, name="app_planning_liste_bo")
  253.      * @Template()
  254.      */
  255.     public function listeBO(
  256.         Request                $request,
  257.         SerializerInterface    $serializer,
  258.         SessionSalonRepository $sessionSalonRepository,
  259.         SalonRepository        $salonRepository,
  260.         IntervenantRepository  $intervenantRepository,
  261.         RDVRepository $RDVRepository
  262.     ): Response {
  263.         $salonQuery $request->query->get('salon');
  264.         $intervenantQuery $request->query->get('intervenant');
  265.         $dateDebut $request->query->get('date_debut');
  266.         $dateFin $request->query->get('date_fin');
  267.         $user $this->getUser();
  268.         $sessions $sessionSalonRepository->findAllMax($salonQuery$intervenantQuery$dateDebut$dateFin$user);
  269.         /** @var SessionSalon $session */
  270.         foreach ($sessions as $session) {
  271.             $rdvs $RDVRepository->countRDVsBySalonAndDate($session->getSalon(), $session->getStart());
  272.             $totalCa 0;
  273.             /** @var RDV $rdv */
  274.             $i 0;
  275.             foreach ($rdvs as $rdv){
  276.                 /** @var RDVProduct $rdvProduct */
  277.                 foreach ($rdv->getRdvProducts() as $rdvProduct) {
  278.                     $grid $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
  279.                     switch ($grid) {
  280.                         case 1:
  281.                             $price $rdvProduct->getProduct()->getPriceHtA();
  282.                             break;
  283.                         case 2:
  284.                             $price $rdvProduct->getProduct()->getPriceHtB();
  285.                             break;
  286.                         case 3:
  287.                             $price $rdvProduct->getProduct()->getPriceHtC();
  288.                             break;
  289.                         case 4:
  290.                             $price $rdvProduct->getProduct()->getPriceHtD();
  291.                             break;
  292.                     }
  293.                     $totalCa += $price;
  294.                 }
  295.                 $i++;
  296.             }
  297.             $session->startRDV $session->getStart();
  298.             // Assuming $session->getRdvs() returns a collection of rdvs
  299.             $session->rdvCount $i;
  300.             $session->rdvCA number_format(round($totalCa2), 2'.''');
  301.         }
  302.         $salons $salonRepository->findAll();
  303.         $intervenants $intervenantRepository->findAll();
  304.         return $this->render('planning/liste_bo.html.twig', [
  305.             'dateDebut' => $dateDebut,
  306.             'dateFin' =>  $dateFin,
  307.             'sessions' => $sessions,
  308.             'salons' => $salons,
  309.             'intervenants' => $intervenants
  310.         ]);
  311.     }
  312.     /**
  313.      * @Route("/coiffeurListe", methods={"GET","POST"})
  314.      * @Template()
  315.      * @param Request $request
  316.      * @param RDVRepository $repository
  317.      * @return array
  318.      */
  319.     public function coiffeurListe(
  320.         Request $request,
  321.         RDVRepository $repository,
  322.         SessionSalonRepository $sessionSalonRepository,
  323.         RDVRepository $RDVRepository,
  324.         ClientRepository  $clientRepository,
  325.         ProductRepository  $productRepository,
  326.         BillingRepository $billingRepository,
  327.         PaytweakService  $paytweakService
  328.     ): array {
  329.         $em $this->managerRegistry;
  330.         // date ajdh
  331.         //$sessions = $repository->findFromToday();
  332.         $sites $em->getRepository(Site::class)->findAll();
  333.         $rdv = new RDV();
  334.         $status $request->query->get('status');
  335.         $client $request->query->get('client');
  336.         $clientId $request->query->get('client_id');
  337.         $formFilter $this->createForm(FilterType::class, null, ['status' => $status'client' => $client]);
  338.         $form $this->createForm(
  339.             RDVType::class,
  340.             $rdv,
  341.             ['withCustomPicker' => true]
  342.         );
  343.         $formReplanning $this->createForm(ReplanningType::class, null);
  344.         $formReplanning->handleRequest($request);
  345.         $formReplanning2 $this->createForm(ReplanningType::class, null);
  346.         $formReplanning2->handleRequest($request);
  347.         $formFilter->handleRequest($request);
  348.         $sessions $repository->findByFilterCoiffeuse(nullnull$clientnullnull$status$clientId$this->getUser());
  349.         $sessionsResult =  [];
  350.         /** @var Session $session */
  351.         foreach ($sessions as $session) {
  352.             $session['client'] = null;
  353.             if (isset($session['client_id'])) {
  354.                 $client $clientRepository->find($session['client_id']);
  355.                 $session['client'] = $client;
  356.             }
  357.             if ($client == null)
  358.                 continue;
  359.             $billings $client->getBillings();
  360.             /** @var Billing $billing */
  361.             $lastBilling = [];
  362.             $billings $billingRepository->searchUnpaid($client);
  363.             $session['paid'] = null;
  364.             $currentDate = new \DateTime();
  365.             if (count($billings) > 0) {
  366.                 $myLastElement end($billings);
  367.                 $diff $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
  368.                 $session['paid'] =  abs($diff);
  369.             }
  370.             $products $productRepository->getProductsArrayByRDV($session['id']);
  371.             $session['products'] = $products;
  372.             $session['label'] = RDV::getRDVLabel($session['status']);
  373.             $sessionRdv $RDVRepository->find($session['id']);
  374.             $rdvBillings $sessionRdv->getRDVBillings();
  375.             $billingCodes = [];
  376.             foreach ($rdvBillings as $rdvBilling) {
  377.                 // Assuming the billing object has a getCode() method
  378.                 $billingCodes[] = $rdvBilling->getBilling()->getCode();
  379.             }
  380.             $session['ttc'] = $sessionRdv->ttc();
  381.             $session['qrimage']= null;
  382.             $link = ($rdvBillings && isset($rdvBillings[0]) && $rdvBillings[0]->getBilling()) ? $rdvBillings[0]->getBilling()->getLinkPaytweak() : null;
  383.             if($link){
  384. //                try {
  385. //                    $res = $paytweakService->getLink($rdvBillings[0]->getBilling()->getCompany(), $rdvBillings[0]->getBilling()->getCode());
  386. //                    if ($res['code'] === PaytweakService::CODE_OK) {
  387. //                        $item = reset($res);
  388. //                        if (isset($link['qrcode'])){
  389. //                            $session['qrimage'] =  $item['qrcode'];
  390. //                        }
  391. //                    }
  392. //
  393. //
  394. //                }
  395. //                catch (\Exception $exception){
  396. //
  397. //                }
  398.                 $prefix "https://paytweak.link/";
  399.                 if($rdvBillings[0]->getBilling()->getCompany()->getId() === 2){
  400.                     $prefix "https://silver-beaute.link/";
  401.                 }
  402.                 $link $prefix $rdvBillings[0]->getBilling()->getLinkPaytweak();
  403.             }
  404.             $session['qrlink'] =  $link;
  405.             $session['codeBilling'] = implode(",",$billingCodes);
  406.             $sessionsResult[] = $session;
  407.         }
  408.         // replannification
  409.         if ($formReplanning->isSubmitted() && $formReplanning->isValid()) {
  410.             $this->RDVManager->replannification($formReplanning);
  411.             $em->getManager()->flush();
  412.         }
  413.         // replannificcation  interrvenant
  414.         if ($formReplanning2->isSubmitted() && $formReplanning2->isValid()) {
  415.             $this->RDVManager->replannification($formReplanning2);
  416.             $em->getManager()->flush();
  417.         }
  418.         if ($formFilter->isSubmitted() && $formFilter->isValid()) {
  419.             $intervenant $formFilter->getData()['intervenant'];
  420.             $site $formFilter->getData()['site'];
  421.             $client $formFilter->getData()['client'];
  422.             $start $formFilter->getData()['start'];
  423.             $status $formFilter->getData()['status'];
  424.             $salon $formFilter->getData()['salon'];
  425.             $end $formFilter->getData()['end'];
  426.             $request->getSession()->set('intervenant'$intervenant);
  427.             $request->getSession()->set('site'$site);
  428.             $request->getSession()->set('client'$client);
  429.             $request->getSession()->set('start'$start);
  430.             $request->getSession()->set('end'$end);
  431.             $sessions $repository->findByFilterCoiffeuse($intervenant$site$client$start$end$statusnullnull$salon);
  432.             $sessionsResult =  [];
  433.             foreach ($sessions as $session) {
  434.                 $client null;
  435.                 if ($session['client_id']) {
  436.                     $client $clientRepository->find($session['client_id']);
  437.                 }
  438.                 $products $productRepository->getProductsArrayByRDV($session['id']);
  439.                 $session['products'] = $products;
  440.                 $session['client'] = $client;
  441.                 $session['label'] = RDV::getRDVLabel($session['status']);
  442.                 $billings = [];
  443.                 if ($client) {
  444.                     $billings $billingRepository->searchUnpaid($client);
  445.                 }
  446.                 $session['paid'] = null;
  447.                 $currentDate = new \DateTime();
  448.                 if (count($billings) > 0) {
  449.                     $myLastElement end($billings);
  450.                     $diff $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
  451.                     $session['paid'] =  abs($diff);
  452.                 }
  453.                 $sessionRdv $RDVRepository->find($session['id']);
  454.                 $rdvBillings $sessionRdv->getRDVBillings();
  455.                 $billingCodes = [];
  456.                 foreach ($rdvBillings as $rdvBilling) {
  457.                     // Assuming the billing object has a getCode() method
  458.                     $billingCodes[] = $rdvBilling->getBilling()->getCode();
  459.                 }
  460.                 $session['codeBilling'] = implode(",",$billingCodes);
  461.                 $link = ($rdvBillings && isset($rdvBillings[0]) && $rdvBillings[0]->getBilling()) ? $rdvBillings[0]->getBilling()->getLinkPaytweak() : null;
  462.                 if($link){
  463. //                    try {
  464. //                        $res = $paytweakService->getLink($rdvBillings[0]->getBilling()->getCompany(), $rdvBillings[0]->getBilling()->getCode());
  465. //                        if ($res['code'] === PaytweakService::CODE_OK) {
  466. //                            $item = reset($res);
  467. //                            if (isset($link['qrcode'])){
  468. //                                $session['qrimage'] =  $item['qrcode'];
  469. //                            }
  470. //                        }
  471. //
  472. //
  473. //                    }
  474. //                    catch (\Exception $exception){
  475. //
  476. //                    }
  477.                     $prefix "https://paytweak.link/";
  478.                     if($rdvBillings[0]->getBilling()->getCompany()->getId() === 2){
  479.                         $prefix "https://silver-beaute.link/";
  480.                     }
  481.                     $link $prefix $rdvBillings[0]->getBilling()->getLinkPaytweak();
  482.                 }
  483.                 $session['qrlink'] =  $link;
  484.                 $session['ttc'] = $sessionRdv->ttc();
  485.                 $sessionsResult[] = $session;
  486.             }
  487.         }
  488.         return [
  489.             'sessions' => $sessionsResult,
  490.             'form' => $form->createView(),
  491.             'formReplanning' => $formReplanning->createView(),
  492.             'formReplanning2' => $formReplanning2->createView(),
  493.             'formFilter' => $formFilter->createView(),
  494.             'sites' => $sites,
  495.             'intervenant' => $request->getSession()->get('intervenant'),
  496.         ];
  497.     }
  498.     /**
  499.      * @Route("/new", methods={"GET","POST"})
  500.      */
  501.     public function new(Request $request): Response
  502.     {
  503.         $company = new Company();
  504.         $form $this->createForm(CompanyType::class, $company);
  505.         $form->handleRequest($request);
  506.         if ($form->isSubmitted() && $form->isValid()) {
  507.             $entityManager $this->getDoctrine()->getManager();
  508.             $entityManager->persist($company);
  509.             $entityManager->flush();
  510.             return $this->redirectToRoute('company_index');
  511.         }
  512.         return $this->render('company/new.html.twig', [
  513.             'company' => $company,
  514.             'form' => $form->createView(),
  515.         ]);
  516.     }
  517.     /**
  518.      * @Route("/newJOS", methods={"GET","POST"})
  519.      */
  520.     public function newJOS(Request $request): Response
  521.     {
  522.         $em $this->getDoctrine()->getManager();
  523.         $sessionSalon = new SessionSalon();
  524.         $form $this->createForm(AddSessionSalonType::class, $sessionSalon, []);
  525.         $form->handleRequest($request);
  526.         if ($form->isSubmitted() && $form->isValid()) {
  527.             $em->persist($sessionSalon);
  528.             $em->flush();
  529.             return $this->redirectToRoute('app_planning_pilotage');
  530.         }
  531.         return $this->render('planning/newJOS.html.twig', [
  532.             'session' => $sessionSalon,
  533.             'form' => $form->createView()
  534.         ]);
  535.     }
  536.     /**
  537.      * @Route("/pilotage-expoitation", methods={"GET","POST"})
  538.      */
  539.     public function pilotage(
  540.         Request                $request,
  541.         SerializerInterface    $serializer,
  542.         SessionSalonRepository $sessionSalonRepository,
  543.         SalonRepository        $salonRepository,
  544.         IntervenantRepository  $intervenantRepository
  545.     ): Response {
  546.         $salonQuery $request->query->get('salon');
  547.         $intervenantQuery $request->query->get('intervenant');
  548.         $dateDebut $request->query->get('date_debut');
  549.         $dateFin $request->query->get('date_fin');
  550.         $user $this->getUser();
  551.         $sessions $sessionSalonRepository->findAllMax($salonQuery$intervenantQuery$dateDebut$dateFin$user);
  552.         $salons $salonRepository->findAll();
  553.         $intervenants $intervenantRepository->findAll();
  554.         //        $sessions = $serializer->serialize($sessions, 'json', [
  555.         //            'groups' => 'rdv',
  556.         //            'circular_reference_handler' => function ($object) {
  557.         //                return $object->getId();
  558.         //            }
  559.         //        ]);
  560.         return $this->render('planning/pilotage.html.twig', [
  561.             'dateDebut' => $dateDebut,
  562.             'dateFin' =>  $dateFin,
  563.             'sessions' => $sessions,
  564.             'salons' => $salons,
  565.             'intervenants' => $intervenants
  566.         ]);
  567.     }
  568.     /**
  569.      * @Route("/calendrier-expoitation", methods={"GET","POST"})
  570.      */
  571.     public function calendrier(
  572.         Request                $request,
  573.         RDVRepository           $rdvRepository,
  574.         SessionSalonRepository $sessionSalonRepository,
  575.         SalonRepository        $salonRepository,
  576.         IntervenantRepository  $intervenantRepository
  577.     ): Response {
  578.         $salonQuery $request->query->get('salon');
  579.         $intervenantQuery $request->query->get('intervenant');
  580.         $dateDebut $request->query->get('date_debut');
  581.         $dateFin $request->query->get('date_fin');
  582.         $metier $request->query->get('metier');
  583.         $status $request->query->get('status');
  584.         $zoneGeographique $request->query->get('zoneGeographique');
  585.         $user $this->getUser();
  586.         $sessions $sessionSalonRepository->findCalendar($salonQuery$intervenantQuery$dateDebut$dateFin$user$zoneGeographique$metier$status);
  587.         $intervenantsFilter $intervenantRepository->findAll();
  588.         $intervenants = [];
  589.         $ressources = [];
  590.         $events = [];
  591.         $ca = [];
  592.         $rdvsNumber = [];
  593.         $sessionsIds = [];
  594.         $joursReposColor '#794cf6';
  595.         $jourReposDays = [];
  596.         $key 1;
  597.         usort($sessions, function($a$b) {
  598.             // Prioritize "IDF" by moving it to the front.
  599.             if ($a['zoneGeographique'] === 'IDF' && $b['zoneGeographique'] !== 'IDF') {
  600.                 return -1;
  601.             } elseif ($a['zoneGeographique'] !== 'IDF' && $b['zoneGeographique'] === 'IDF') {
  602.                 return 1;
  603.             }
  604.             // Prioritize "Coiffeur" by moving it to the front.
  605.             if ($a['metier'] === Intervenant::METIER_COIFFEUR && $b['metier'] !== Intervenant::METIER_COIFFEUR) {
  606.                 return -1;
  607.             } elseif ($a['metier'] !== Intervenant::METIER_COIFFEUR && $b['metier'] === Intervenant::METIER_COIFFEUR) {
  608.                 return 1;
  609.             }
  610.             // For other values, use standard string comparison for 'zoneGeographique'.
  611.             $zoneComparison strcmp($a['zoneGeographique'], $b['zoneGeographique']);
  612.             if ($zoneComparison !== 0) {
  613.                 return $zoneComparison;
  614.             }
  615.             // For other values, use standard string comparison for 'metier'.
  616.             $metierComparison strcmp($a['metier'], $b['metier']);
  617.             if ($metierComparison !== 0) {
  618.                 return $metierComparison;
  619.             }
  620.             // For other values, use standard string comparison for 'intervenant_last_name'.
  621.             return strcmp($a['intervenant_last_name'], $b['intervenant_last_name']);
  622.         });
  623.         foreach ($sessions as &$session) {
  624.             // dd($session);
  625.             // // get chiffre d'affaire et totale des rdvs  par salon
  626.             // if (!in_array($session['salon_id'], $sessionsIds)) {
  627.             //     $rdvs = $rdvRepository->findBy(['salon' => $session['salon_id'], 'intervenant' => $session['intervenant_id']]);
  628.             //     $rdvsNumber[$session['salon_id']] = count($rdvs);
  629.             //     $totalHt = $this->calculateTotalHtForRDVs($rdvs);
  630.             //     $sessionsIds[] = $session['salon_id'];
  631.             //     $ca[$session['salon_id']] = number_format($totalHt, 2);
  632.             // }
  633.             $name htmlspecialchars($session['salon_name'], ENT_QUOTES'UTF-8');
  634.             $intervenants[]=[
  635.                 'id' => $session['intervenant_id'],
  636.                 'firstname' => $session['intervenant_first_name'],
  637.                 'lastname' => $session['intervenant_last_name'],
  638.             ];
  639.             $hourEnd $session['end'] ? $session['end']->format('H:i') : '';
  640.             $title = ($session['observation'] ? "❶ " "") . ($session['actionArealiser'] ? "🚩 " "") . $name " - Horaire: {$session['start']->format('H:i')} " $hourEnd;
  641.             $eventColor $this->getColorForSessionStatus($session['status']);
  642.             $events[] = [
  643.                 'start' => $session['start']->format('Y-m-d\TH:i'),
  644.                 'end' => $session['end'] ? $session['end']->format('Y-m-d\TH:i') : $session['start']->format('Y-m-d\T23:59'),
  645.                 'title' => $title,
  646.                 //'allDay' => true,
  647.                 'color' => $eventColor,
  648.                 'resource' => $session['intervenant_id'],
  649.                 'event_id' => $session['session_id']
  650.             ];
  651.             if (isset($session['absence_start']) && isset($session['absence_end'])) {
  652.                 $heureDebut $session['absence_start_time'] ?? '00:00';
  653.                 $heureFin $session['absence_end_time'] ?? '23:59';
  654.                 $absenceStart $this->createDateTimeObject($session['absence_start'], $heureDebut);
  655.                 $absenceEnd $this->createDateTimeObject($session['absence_end'], $heureFin);
  656.                 $dateRange $absenceStart->format('d-m-Y H:i') . ' - ' $absenceEnd->format('d-m-Y H:i');
  657.                 $absenceEvent = [
  658.                     'start' => $absenceStart->format('Y-m-d\TH:i'),
  659.                     'end' => $absenceEnd->format('Y-m-d\TH:i'),
  660.                     'title' => 'Absence: ' $session['motif'] . '  ' $session['absence_comment'] .' -- Date : ' $dateRange,
  661.                     'resource' => $session['intervenant_id'],
  662.                     'event_id' => 'absence_' $session['session_id'],
  663.                     'color' => '#ff9c04',
  664.                 ];
  665.                 $events[] = $absenceEvent;
  666.             }
  667.             //intervenant_id
  668.             $ressources[$session['intervenant_id']] = [
  669.                 'id' => $session['intervenant_id'],
  670.                 'name' => $session["intervenant_last_name"] . " " $session["intervenant_first_name"],
  671.                 'color' => '#34c8e0'
  672.             ];
  673.             $key++;
  674.         }
  675.         $holidays $this->getHolidays();
  676.         $holidayColor '#ff0000';
  677.         $exist = [];
  678.         foreach ($sessions as $sessionRepo) {
  679.             $endDate = (new DateTime("now"))->modify("+1 years");
  680.             $startDate = (new DateTime("now"))->modify("-5 months");
  681.             if ((!in_array($sessionRepo['intervenant_id'], $exist)) ){
  682.                 foreach ($holidays as $holiday) {
  683.                     $events[] = [
  684.                         'start' => $holiday->format('Y-m-d\T00:00'),
  685.                         'end' => $holiday->format('Y-m-d\T23:59'),
  686.                         'title' => 'Holiday',
  687.                         'color' => $holidayColor,
  688.                         'resource' => $sessionRepo['intervenant_id'],
  689.                         'event_id' => 'holiday_' $holiday->format('Ymd'),
  690.                     ];
  691.                 }
  692.                 if ( $sessionRepo['joursRepos'] !== null ) {
  693.                     while ($startDate <= $endDate) {
  694.                         $joursrepos $sessionRepo['joursRepos'];
  695.                         asort($joursrepos);
  696.                         foreach ($joursrepos as $key => $reposDay) {
  697.                             if ($startDate->format('w') == $reposDay) {
  698.                                 $events[] = [
  699.                                     'start' => $startDate->format('Y-m-d\T00:00'),
  700.                                     'end' => $startDate->format('Y-m-d\T23:59'),
  701.                                     'title' => 'Repos',
  702.                                     'color' => $joursReposColor,
  703.                                     'resource' => $sessionRepo['intervenant_id'],
  704.                                     'event_id' => 'repos_' rand(100010000) . '_' $sessionRepo['session_id']
  705.                                 ];
  706.                             }
  707.                         }
  708.                         $startDate->modify('+1 days');
  709.                     }
  710.                 }
  711.                 $exist[] = $sessionRepo['intervenant_id'];
  712.             }
  713.         }
  714.         $salons $salonRepository->findAll();
  715.         return $this->render('planning/calendar.html.twig', [
  716.             'intervenantsFilter' => $intervenantsFilter,
  717.             'dateDebut' => $dateDebut,
  718.             'dateFin' =>  $dateFin,
  719.             'sessions' => $events,
  720.             'ressources' => array_values($ressources),
  721.             'salons' => $salons,
  722.             'intervenants' => json_encode($intervenants)
  723.         ]);
  724.     }
  725.     public function createDateTimeObject($absenceDate$heure)
  726.     {
  727.         $heure strlen($heure) !== $heure $heure ':00';
  728.         return \DateTime::createFromFormat('d-m-Y H:i'$absenceDate ' ' $heure);
  729.     }
  730.     public function getColorForSessionStatus($status) {
  731.         switch ($status) {
  732.             case 'modifier':
  733.                 return 'rgb(255, 245, 97)';
  734.             case 'event':
  735.                 return '#FF5733';
  736.             case 'indisponible':
  737.                 return '#707070';
  738.             default:
  739.                 return 'rgb(52, 200, 224)';
  740.         }
  741.     }
  742.     public function calculateTotalHtForRDVs($rdvs) {
  743.         $totalHt 0;
  744.         foreach ($rdvs as $rdv) {
  745.             $rdvProductsArray iterator_to_array($rdv->getRdvProducts());
  746.             foreach ($rdv->getRDVBillings() as $RDVBilling) {
  747.                 $billing $RDVBilling->getBilling();
  748.                 $rdv $RDVBilling->getRDV();
  749.                 if ($billing->getStatus() === Billing::STATUS_SENT || $billing->getStatus() === Billing::STATUS_REGLEE) {
  750.                     $products array_map(function ($rdvProduct) {
  751.                         return $rdvProduct->getProduct()->getId();
  752.                     }, $rdvProductsArray);
  753.                     foreach ($billing->getBillingItems() as $item) {
  754.                         if (in_array($item->getProduct()->getId(), $products)) {
  755.                             $ht $item->getPrice() * $item->getQuantity();
  756.                             if ($item->getDiscount()) {
  757.                                 $totalHt += $ht - ($ht $item->getDiscount() / 100);
  758.                             } else {
  759.                                 $totalHt += $ht;
  760.                             }
  761.                         }
  762.                     }
  763.                 }
  764.             }
  765.         }
  766.         return $totalHt;
  767.     }
  768.     /**
  769.      * Get holidays for the current year and the next year.
  770.      *
  771.      * @param null $year
  772.      * @return array
  773.      * @throws \Exception
  774.      */
  775.     public function getHolidays($year null)
  776.     {
  777.         // If $year is not specified, use the current year
  778.         if ($year === null) {
  779.             $currentYear intval(date('Y'));
  780.         } else {
  781.             $currentYear intval($year);
  782.         }
  783.         // Calculate the next year
  784.         $nextYear $currentYear 1;
  785.         $dateTimeHoliday = array();
  786.         $easterDate easter_date($currentYear);
  787.         $easterDay date('j'$easterDate);
  788.         $easterMonth date('n'$easterDate);
  789.         $easterYear date('Y'$easterDate);
  790.         $holidays = array(
  791.             // Fixed holidays
  792.             gmmktime(00011$currentYear), // New Year's Day
  793.             gmmktime(00051$currentYear), // Labor Day
  794.             gmmktime(00058$currentYear), // Victory in Europe Day
  795.             gmmktime(000714$currentYear), // Bastille Day
  796.             gmmktime(000815$currentYear), // Assumption Day
  797.             gmmktime(000111$currentYear), // All Saints' Day
  798.             gmmktime(0001111$currentYear), // Armistice Day
  799.             gmmktime(0001225$currentYear), // Christmas Day
  800.             // Holidays dependent on Easter
  801.             gmmktime(000$easterMonth$easterDay 1$currentYear), // Easter Monday
  802.             gmmktime(000$easterMonth$easterDay 39$currentYear), // Ascension
  803.             gmmktime(000$easterMonth$easterDay 50$currentYear), // Pentecost
  804.         );
  805.         $easterDateNextYear easter_date($nextYear);
  806.         $easterDayNextYear date('j'$easterDateNextYear);
  807.         $easterMonthNextYear date('n'$easterDateNextYear);
  808.         $holidaysNextYear = array(
  809.             // Fixed holidays
  810.             gmmktime(00011$nextYear), // New Year's Day
  811.             gmmktime(00051$nextYear), // Labor Day
  812.             gmmktime(00058$nextYear), // Victory in Europe Day
  813.             gmmktime(000714$nextYear), // Bastille Day
  814.             gmmktime(000815$nextYear), // Assumption Day
  815.             gmmktime(000111$nextYear), // All Saints' Day
  816.             gmmktime(0001111$nextYear), // Armistice Day
  817.             gmmktime(0001225$nextYear), // Christmas Day
  818.             // Holidays dependent on Easter
  819.             gmmktime(000$easterMonthNextYear$easterDayNextYear 1$nextYear), // Easter Monday
  820.             gmmktime(000$easterMonthNextYear$easterDayNextYear 39$nextYear), // Ascension
  821.             gmmktime(000$easterMonthNextYear$easterDayNextYear 50$nextYear), // Pentecost
  822.         );
  823.         $holidays array_merge($holidays$holidaysNextYear);
  824.         // Add holidays for the next year
  825. //        foreach ($holidays as $holiday) {
  826. //            $holidayNextYear = $holiday + 31536000; // Add one year in seconds
  827. //            $holidays[] = $holidayNextYear;
  828. //        }
  829.         // Sort the holidays
  830.         sort($holidays);
  831.         foreach ($holidays as $value) {
  832.             $dateTimeHoliday[] = new \DateTime('@' $value, new \DateTimeZone('Europe/Paris'));
  833.         }
  834.         return $dateTimeHoliday;
  835.     }
  836.     /**
  837.      * @Route("/send_email", name="send_email", methods={"POST"})
  838.      */
  839.     public function sendEmail(MailService $mailServiceRequest $requestIntervenantRepository $intervenantRepository)
  840.     {
  841.         $id $request->request->all()['id'];
  842.         $intervenant $intervenantRepository->find($id);
  843.         $email $intervenant->getEmail();
  844.         if (!$email) {
  845.             $email $intervenant->getEmailPro();
  846.             if (!$email) {
  847.                 $user $intervenant->getUser();
  848.                 if (!$user) {
  849.                     return new JsonResponse('Utilisateur non trouvé'400);
  850.                 }
  851.                 $email $user->getEmail();
  852.             }
  853.         }
  854.         $mailService->sendToIntervenant(
  855.             $email,
  856.             [
  857.                 'intervenant' => $intervenant
  858.             ]
  859.         );
  860.         return new JsonResponse('ok'200);
  861.     }
  862.     /**
  863.      * @Route("/generateForm", methods={"GET","POST"})
  864.      */
  865.     public function generateForm(
  866.         Request                $request,
  867.         SessionSalonRepository  $sessionSalonRepository,
  868.         FormFactoryInterface $formFactory,
  869.         UrlGeneratorInterface  $urlGenerator
  870.     ): Response {
  871.         $sessionSalonQuery $request->request->get('sessionSalon');
  872.         $sessionSalon $sessionSalonRepository->find($sessionSalonQuery);
  873.         $actionUrl $urlGenerator->generate('planning_handle_form'); // Replace with your actual route name
  874.         $form $formFactory->create(AddSessionSalonType::class, $sessionSalon, [
  875.             'action' => $actionUrl,
  876.         ]);
  877.         $form->add('sessionSalon'HiddenType::class, [
  878.             'data' => $sessionSalon->getId(),
  879.             'mapped' => false
  880.         ]);
  881.         // Render the form view separately
  882.         $formView $this->renderView('planning/SessionSalon/_form.html.twig', [
  883.             'form' => $form->createView(),
  884.         ]);
  885.         return new JsonResponse(['view' => $formView]);
  886.     }
  887.     /**
  888.      * @Route("/handleForm", methods={"GET","POST"}, name="planning_handle_form")
  889.      */
  890.     public function handleForm(
  891.         Request                $request,
  892.         EntityManagerInterface  $entityManager,
  893.         RDVRepository $RDVRepository,
  894.         SessionSalonRepository  $sessionSalonRepository,
  895.         IntervenantRepository $intervenantRepository
  896.     ): Response {
  897.         $sessionSalonId $request->request->get('add_session_salon')['sessionSalon'];
  898.         // Retrieve the sessionSalon entity from the repository
  899.         /** @var SessionSalon $sessionSalon */
  900.         $sessionSalon $sessionSalonRepository->find($sessionSalonId);
  901.         $dateSession $sessionSalon->getStart();
  902.         $oldIntervenant $sessionSalon->getIntervenant(); // JOS INTERVENANT
  903.         $form $this->createForm(AddSessionSalonType::class,$sessionSalon);
  904.         $form->handleRequest($request);
  905.         if ($form->isSubmitted()) {
  906.             if ($sessionSalon) {
  907.                 $day $request->request->get('add_session_salon')['start']['date']['day'];
  908.                 $month $request->request->get('add_session_salon')['start']['date']['month'];
  909.                 $year $request->request->get('add_session_salon')['start']['date']['year'];
  910.                 $hour $request->request->get('add_session_salon')['start']['time']['hour'];
  911.                 $minute $request->request->get('add_session_salon')['start']['time']['minute'];
  912.                 $dayEnd $request->request->get('add_session_salon')['end']['date']['day'];
  913.                 $monthEnd $request->request->get('add_session_salon')['end']['date']['month'];
  914.                 $yearEnd $request->request->get('add_session_salon')['end']['date']['year'];
  915.                 $hourEnd $request->request->get('add_session_salon')['end']['time']['hour'];
  916.                 $minuteEnd $request->request->get('add_session_salon')['end']['time']['minute'];
  917.                 $timestamp strtotime("$year-$month-$day $hour:$minute");
  918.                 $timestampEnd strtotime("$yearEnd-$monthEnd-$dayEnd $hourEnd:$minuteEnd");
  919.                 $dateTime \DateTime::createFromFormat('U'$timestamp);
  920.                 $intervenantId $request->request->get('add_session_salon')['intervenant']; // INTERVENANT CHOOSE
  921.                 $intervenant $intervenantRepository->find($intervenantId);
  922.                 $rdvs $RDVRepository->replanifierDate($oldIntervenant$sessionSalon->getSalon(), $dateSession);
  923.                 $logplanning = new LogPlanning();
  924.                 $logplanning->setIntervenantOld($oldIntervenant);
  925.                 $logplanning->setNewIntervenant($intervenant);
  926.                 $logplanning->setSessionSalon($sessionSalon);
  927.                 $entityManager->persist($logplanning);
  928.                 $entityManager->flush();
  929.                 /** @var RDV $rdv */
  930.                 foreach ($rdvs as $rdv) {
  931.                     $dateTimeStart \DateTime::createFromFormat('U'$timestamp);
  932.                     $dateTimeEnd \DateTime::createFromFormat('U'$timestampEnd);
  933.                     $dateTimeStart->setTime(
  934.                         $rdv->getStart()->format('H'),    // Hours
  935.                         $rdv->getStart()->format('i'),    // Minutes
  936.                         $rdv->getStart()->format('s')     // Seconds
  937.                     );
  938.                     $dateTimeEnd->setTime(
  939.                         $rdv->getEnd()->format('H'),    // Hours
  940.                         $rdv->getEnd()->format('i'),    // Minutes
  941.                         $rdv->getEnd()->format('s')     // Seconds
  942.                     );
  943.                     $rdv->setStart($dateTimeStart);
  944.                     $rdv->setEnd($dateTimeEnd);
  945.                     $rdv->setIntervenant($intervenant);
  946.                     $entityManager->persist($rdv);
  947.                 }
  948. //                // replanification
  949.                 // take all rdv from the JOS intervenant of today and set up to the new intervenant/
  950. //                $rdvs = $RDVRepository->replanifierIntervenant($oldIntervenant, $dateTime);
  951. //                /** @var RDV $rdv */
  952. //                foreach ($rdvs as $rdv) {
  953. //                    $rdv->setIntervenant($intervenant);
  954. //                    $entityManager->persist($rdv);
  955. //                }
  956.                 if ($intervenant) {
  957.                     $sessionSalon->setIntervenant($intervenant);
  958.                 }
  959.             }
  960.             $entityManager->persist($sessionSalon);
  961.             $entityManager->flush();
  962.         }
  963.         return $this->redirectToRoute('app_planning_calendrier');
  964.     }
  965.     /**
  966.      * @Route("/dragdrop", methods={"GET","POST"})
  967.      */
  968.     public function dragdrop(Request  $request,
  969.                              SessionSalonRepository $sessionSalonRepository,
  970.                              EntityManagerInterface  $entityManager,
  971.     RDVRepository $RDVRepository,
  972.     IntervenantRepository  $intervenantRepository
  973.     ) {
  974.         $event $request->request->get('event');
  975.         $resource $request->request->get('resource');
  976.         $start $request->request->get('start');
  977.         if (strlen($start) === 13) {
  978.             $start $start 1000// Convert milliseconds to seconds
  979.         }
  980.         /** @var SessionSalon $sessionSalon */
  981.         $sessionSalon $sessionSalonRepository->find($event);
  982.         $updated false;
  983.         if($sessionSalon){
  984.             $updated true;
  985.             $intervenant $intervenantRepository->find($resource);
  986.             // prends les rdv de l'ancienne intervenannte sur l'ancienne date et on les passe à la nouvelle date
  987.             $rdvs $RDVRepository->replanifierDate($sessionSalon->getIntervenant(), $sessionSalon->getSalon(), $sessionSalon->getStart());
  988.             /** @var RDV $rdv */
  989.             foreach ($rdvs as $rdv){
  990.                 $dateTimeStart \DateTime::createFromFormat('U'$start);
  991.                 $dateTimeEnd \DateTime::createFromFormat('U'$start);
  992.                 $dateTimeStart->setTime(
  993.                     $rdv->getStart()->format('H'),    // Hours
  994.                     $rdv->getStart()->format('i'),    // Minutes
  995.                     $rdv->getStart()->format('s')     // Seconds
  996.                 );
  997.                 $dateTimeEnd->setTime(
  998.                     $rdv->getEnd()->format('H'),    // Hours
  999.                     $rdv->getEnd()->format('i'),    // Minutes
  1000.                     $rdv->getEnd()->format('s')     // Seconds
  1001.                 );
  1002.                 $rdv->setStart($dateTimeStart);
  1003.                 $rdv->setEnd($dateTimeEnd);
  1004.                 $rdv->setIntervenant($intervenant);
  1005.                 $entityManager->persist($rdv);
  1006.             }
  1007.             // replanification
  1008.             // $rdvs = $RDVRepository->replanifierIntervenant($sessionSalon->getIntervenant(), $dateTime);
  1009.             // /** @var RDV $rdv */
  1010.             // foreach ($rdvs as $rdv){
  1011.             //     $entityManager->persist($rdv);
  1012.             // }
  1013.             if($intervenant){
  1014.                 $sessionSalon->setIntervenant($intervenant);
  1015.             }
  1016.             $dateTime \DateTime::createFromFormat('U'$start);
  1017.             $dateTime->setTime(100000);
  1018.             $endTime \DateTime::createFromFormat('U'$start);
  1019.             $endTime->setTime(180000);
  1020.             $sessionSalon->setStart($dateTime);
  1021.             $sessionSalon->setEnd($endTime);
  1022.             $entityManager->persist($sessionSalon);
  1023.             $entityManager->flush();
  1024.         }
  1025.         return new JsonResponse(['status' => $updated]);
  1026.     }
  1027.     /**
  1028.      * @Route("/export-calendrier", methods={"GET","POST"})
  1029.      */
  1030.     public function exportCalendrier(Request  $requestSessionSalonRepository  $sessionSalonRepository){
  1031.         $salonQuery $request->query->get('salon');
  1032.         $intervenantQuery $request->query->get('intervenant');
  1033.         $dateDebut $request->query->get('date_debut');
  1034.         $dateFin $request->query->get('date_fin');
  1035.         $user $this->getUser();
  1036.         $sessions $sessionSalonRepository->findAllMax($salonQuery$intervenantQuery$dateDebut$dateFin$user);
  1037.         // Create a new PhpSpreadsheet spreadsheet
  1038.         $spreadsheet = new Spreadsheet();
  1039.         // Create a new worksheet
  1040.         $worksheet $spreadsheet->getActiveSheet();
  1041.         // Add headers to the worksheet (customize this part as needed)
  1042.         $worksheet->setCellValue('A1''Session Start');
  1043.         $worksheet->setCellValue('B1''Session End');
  1044.         $worksheet->setCellValue('C1''Session Title');
  1045.         $worksheet->setCellValue('D1''Intervenant Name');
  1046.         $row 2// Start from row 2
  1047.         // Add data to the worksheet
  1048.         /** @var SessionSalon $session */
  1049.         foreach ($sessions as $session) {
  1050.             $worksheet->setCellValue('A' $row$session->getStart()->format('Y-m-d\TH:i'));
  1051.             $worksheet->setCellValue('B' $row$session->getEnd() ? $session->getEnd()->format('Y-m-d\TH:i') : $session->getStart()->format('Y-m-d\T23:59'));
  1052.             $worksheet->setCellValue('C' $rowhtmlspecialchars($session->getSalon()->getName(), ENT_QUOTES'UTF-8'));
  1053.             $worksheet->setCellValue('D' $row$session->getIntervenant()->getLastname() . " " $session->getIntervenant()->getFirstname());
  1054.             $row++;
  1055.         }
  1056.         // Create a response for the Excel file
  1057.         // Create a temporary file to store the Excel data
  1058.         $filePath $this->getParameter('kernel.project_dir') . '/public/exported_excel.xlsx';
  1059.         $writer = new Xlsx($spreadsheet);
  1060.         $writer->save($filePath);
  1061.         // Create a BinaryFileResponse for the temporary file
  1062.         $response = new Response();
  1063.         $response->headers->set('Content-Type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  1064.         $response->headers->set('Content-Disposition''attachment;filename="exported_excel.xlsx"');
  1065.         // Read the file and set its content
  1066.         $response->setContent(file_get_contents($filePath));
  1067.         return $response;
  1068.     }
  1069.     /**
  1070.      * @Route("/{id}/delete", name="planning_delete", methods={"DELETE"})
  1071.      */
  1072.     public function deletePlanning(Request $requestSessionSalon $sessionSalon): Response
  1073.     {
  1074.         if ($this->isCsrfTokenValid('delete' $sessionSalon->getId(), $request->request->get('_token'))) {
  1075.             $entityManager $this->getDoctrine()->getManager();
  1076.             $entityManager->remove($sessionSalon);
  1077.             $entityManager->flush();
  1078.         }
  1079.         return $this->redirectToRoute('app_planning_pilotage');
  1080.     }
  1081.     /**
  1082.      * @Route("/{id}/sessionSalon", methods={"GET","POST"})
  1083.      */
  1084.     public function sessionSalon(Request $request,int $idSessionSalon $sessionSalonEntityManagerInterface $em,
  1085.                                 RDVRepository $RDVRepositoryIntervenantRepository  $intervenantRepository,
  1086.                                 SessionSalonRepository  $sessionSalonRepository): Response
  1087.     {
  1088.         $form $this->createForm(SessionSalonType::class, $sessionSalon, [
  1089.             'salon' => $sessionSalon->getSalon()
  1090.         ]);
  1091.         $form->handleRequest($request);
  1092.         if ($form->isSubmitted() && $form->isValid()) {
  1093.             $oldInfo $sessionSalonRepository->getOldInInfos($id);
  1094.             // Make a copy of the old intervenant
  1095.             $oldIntervenant $intervenantRepository->find($oldInfo["id"]);
  1096.             $rdvs $RDVRepository->replanifierDate($oldIntervenant$sessionSalon->getSalon(), $oldInfo["start"]);
  1097.             // Retrieve the new intervenant entity
  1098.             $intervenantRequest $request->request->get('session_salon')["intervenant"];
  1099.             $intervenant $intervenantRepository->find($intervenantRequest);
  1100.             // Retrieve the start date information
  1101.             $dateStart $request->request->get('session_salon')["start"];
  1102.             $year $dateStart["date"]["year"];
  1103.             $month $dateStart["date"]["month"];
  1104.             $day $dateStart["date"]["day"];
  1105.             foreach ($rdvs as $rdv){
  1106.                 $start $rdv->getStart();
  1107.                 $end $rdv->getEnd();
  1108.                 // Create new start and end DateTime objects
  1109.                 $newStart = new DateTime("$year-$month-$day " $start->format('H:i:s'));
  1110.                 $newEnd = new DateTime("$year-$month-$day " $end->format('H:i:s'));
  1111.                 // Update RDV properties
  1112.                 $rdv->setStart($newStart);
  1113.                 $rdv->setEnd($newEnd);
  1114.                 $rdv->setIntervenant($intervenant);
  1115.                 $em->persist($rdv);
  1116.             }
  1117.             $em->persist($sessionSalon);
  1118.             $em->flush();
  1119.         }
  1120.         return $this->render('planning/session_salon.html.twig', [
  1121.             'session' => $sessionSalon,
  1122.             'form' => $form->createView()
  1123.         ]);
  1124.     }
  1125.     /**
  1126.      * @Route("/fusion", methods={"GET","POST"})
  1127.      */
  1128.     public function fusion(Request $requestRDVRepository $RDVRepositoryEntityManagerInterface $entityManager)
  1129.     {
  1130.         // do handle consumer
  1131.         //        //TODO : filter by auto author
  1132.         //        $rdvs = $RDVRepository->findForFusion();
  1133.         //
  1134.         //        foreach ($rdvs as $rdv) {
  1135.         //
  1136.         //            if(!$rdv->getClient()){
  1137.         //                continue;
  1138.         //            }
  1139.         //
  1140.         //            foreach ($rdvs as $key => $rdv2) {
  1141.         //
  1142.         //                if(!$rdv2->getClient()){
  1143.         //                    continue;
  1144.         //                }
  1145.         //
  1146.         //                if ($rdv->getId() != $rdv2->getId() &&
  1147.         //                    $rdv->getClient()->getId() == $rdv2->getClient()->getId() &&
  1148.         //                    $rdv->getStart() == $rdv2->getStart() &&
  1149.         //                    $rdv->getSalon()->getId() == $rdv2->getSalon()->getId()
  1150.         //
  1151.         //                ) {
  1152.         //
  1153.         //                    $gridA = $rdv->getSalon()->getGridPrice()->getId();
  1154.         //                    $gridB = $rdv2->getSalon()->getGridPrice()->getId();
  1155.         //                    $total1 = 0;
  1156.         //                    $total2 = 0;
  1157.         //                    foreach ($rdv->getRdvProducts() as $rdvProduct) {
  1158.         //                        $total1 += $rdvProduct->getProduct()->getPriceSellTTCByGrid($gridA);
  1159.         //                    }
  1160.         //
  1161.         //                    foreach ($rdv2->getRdvProducts() as $rdvProduct) {
  1162.         //                        $total2 += $rdvProduct->getProduct()->getPriceSellTTCByGrid($gridB);
  1163.         //                    }
  1164.         //
  1165.         //                    if ($total1 >= $total2) {
  1166.         //                        // delete 2
  1167.         //                        $entityManager->remove($rdv2);
  1168.         //                    } else {
  1169.         //                        $entityManager->remove($rdv);
  1170.         //                    }
  1171.         //                    $entityManager->flush();
  1172.         //
  1173.         //                }
  1174.         //
  1175.         //
  1176.         //            }
  1177.         //        }
  1178.         return $this->redirectToRoute('app_planning_site');
  1179.     }
  1180.     /**
  1181.      * @Route("/downloadExcel")
  1182.      */
  1183.     public function downloadExcel(Request  $requestRDVRepository $repository)
  1184.     {
  1185.         $date_debut $request->request->get('date_debut') ?? null;
  1186.         $date_fin $request->request->get('date_fin') ?? null;
  1187.         $entities = new ArrayCollection($repository->findForExport($date_debut$date_fin));
  1188.         $response = new StreamedResponse();
  1189.         $columns $this->getColumnsForEntity(RDV::class);
  1190.         $response->setCallback(function () use ($entities$columns) {
  1191.             $handle fopen('php://output''w+');
  1192.             // Add header
  1193.             fputcsv($handlearray_keys($columns));
  1194.             while ($entity $entities->current()) {
  1195.                 $values = [];
  1196.                 foreach ($columns as $column => $callback) {
  1197.                     $value $callback;
  1198.                     if (is_callable($callback)) {
  1199.                         $value $callback($entity);
  1200.                     }
  1201.                     $values[] = $value;
  1202.                 }
  1203.                 fputcsv($handle$values);
  1204.                 $entities->next();
  1205.             }
  1206.             fclose($handle);
  1207.         });
  1208.         $filename 'rdv_export.csv';
  1209.         $response->headers->set('Content-Type''text/csv; charset=utf-8');
  1210.         $response->headers->set('Content-Disposition''attachment; filename="' $filename '"');
  1211.         return $response;
  1212.     }
  1213.     /**
  1214.      * @Route("/addRdv", methods={"POST"}, condition="request.isXmlHttpRequest()")
  1215.      */
  1216.     public function addRdvAjax(
  1217.         Request $request,
  1218.         SerializerInterface $serializer,
  1219.         ProductRepository $productRepository,
  1220.         SalonRepository $salonRepository,
  1221.         SessionSalonRepository $sessionSalonRepository
  1222.     ) {
  1223.         $rdv = new RDV();
  1224.         $em $this->getDoctrine()->getManager();
  1225.         $form $this->createForm(RDVType::class, $rdv, [
  1226.             'action' => $this->generateUrl($request->get('_route'))
  1227.         ])->handleRequest($request);
  1228.         if ($form->isSubmitted()) {
  1229.             $products $form->get('products')->getViewData();
  1230.             foreach ($products as $product) {
  1231.                 $obj $productRepository->find($product);
  1232.                 $rdvProduct = new RDVProduct();
  1233.                 $rdvProduct->setRdv($rdv);
  1234.                 $rdvProduct->setProduct($obj);
  1235.                 $em->persist($rdvProduct);
  1236.             }
  1237.             $params $request->request->get('rdv');
  1238.             $salon $salonRepository->find((int)$params['salon']);
  1239.             $start = new \DateTime($params['start']);
  1240.             $end = clone $start;
  1241.             $sessionLength $salon->getSite()->getType() === Site::TYPE_EHPAD '+15 minutes' '+30 minutes';
  1242.             $end->modify($sessionLength);
  1243.             $rdv->setStart($start);
  1244.             $rdv->setEnd($end);
  1245.             $sessionSalon $sessionSalonRepository->findSessionBySalonAndDate($salon$start);
  1246.             $rdv->setIntervenant($sessionSalon[0]->getIntervenant());
  1247.             $rdv->setAuthor($this->getUser());
  1248.             $this->getDoctrine()->getManager()->persist($rdv);
  1249.             $this->getDoctrine()->getManager()->flush();
  1250.             $rdv_json $serializer->serialize($rdv'json', [
  1251.                 'groups' => 'rdv',
  1252.                 'circular_reference_handler' => function ($object) {
  1253.                     return $object->getId();
  1254.                 }
  1255.             ]);
  1256.             return new JsonResponse($rdv_jsonResponse::HTTP_OK, [], true);
  1257.         }
  1258.         return new JsonResponse(nullResponse::HTTP_BAD_REQUEST);
  1259.     }
  1260.     /**
  1261.      * @Route("/getPlannings", methods={"GET"}, condition="request.isXmlHttpRequest()")
  1262.      */
  1263.     public function ajaxFilter(Request $requestRDVRepository $repositorySerializerInterface $serializer)
  1264.     {
  1265.         $company $request->get('company');
  1266.         $intervenant $request->get('intervenant');
  1267.         $site $request->get('site');
  1268.         $result null;
  1269.         if ($site) {
  1270.             $result $repository->findBySite($site);
  1271.         }
  1272.         if ($company) {
  1273.             $result $repository->findByCompany($company);
  1274.         }
  1275.         if ($intervenant) {
  1276.             $result $repository->findBy(['intervenant' => $intervenant]);
  1277.         }
  1278.         if (!$site && !$company && !$intervenant) {
  1279.             $result $repository->findAll();
  1280.         }
  1281.         $result $serializer->serialize($result'json', [
  1282.             'groups' => 'rdv',
  1283.             'circular_reference_handler' => function ($object) {
  1284.                 return $object->getId();
  1285.             }
  1286.         ]);
  1287.         return new JsonResponse($resultResponse::HTTP_OK, [], true);
  1288.     }
  1289.     /**
  1290.      * @Route("/getSalons/{id}", methods={"GET"}, condition="request.isXmlHttpRequest()")
  1291.      */
  1292.     public function ajaxGetSalons(Client $clientSerializerInterface $serializer)
  1293.     {
  1294.         // dump('d'. $client->getSite()->getId());die;
  1295.         $salons $client->getSite()->getSalons();
  1296.         $result $serializer->serialize($salons'json', [
  1297.             'groups' => 'rdv',
  1298.             'circular_reference_handler' => function ($object) {
  1299.                 return $object->getId();
  1300.             }
  1301.         ]);
  1302.         return new JsonResponse($resultResponse::HTTP_OK, [], true);
  1303.     }
  1304.     /**
  1305.      * @Route("/getIntervenants/{id}/{date}", methods={"GET"}, condition="request.isXmlHttpRequest()")
  1306.      */
  1307.     public function ajaxGetIntervenants(
  1308.         Salon                  $salon,
  1309.         SerializerInterface    $serializer,
  1310.         SessionSalonRepository $sessionSalonRepository,
  1311.         $date
  1312.     ) {
  1313.         // dump('d'. $client->getSite()->getId());die;
  1314.         //        $intervenants = $salon->getIntervenantSalons()->filter(function ($e){
  1315.         //            return $e->getIntervenant()->getStatus() == 1;
  1316.         //        });
  1317.         $date date_create_from_format('Y-m-d H:i'$date);
  1318.         $intervenants = [];
  1319.         $sessionsSalons $sessionSalonRepository->findBy(['salon' => $salon]);
  1320.         /** @var SessionSalon $sessionSalon */
  1321.         foreach ($sessionsSalons as $sessionSalon) {
  1322.             $dateSalon $sessionSalon->getStart();
  1323.             if ($sessionSalon->getIntervenant() && $sessionSalon->getIntervenant()->getStatus() == && $dateSalon->format('Y-m-d') == $date->format('Y-m-d')) {
  1324.                 $intervenants[$sessionSalon->getIntervenant()->getId()] = $sessionSalon->getIntervenant();
  1325.             }
  1326.         }
  1327.         $result $serializer->serialize(array_values($intervenants), 'json', [
  1328.             'groups' => 'rdv',
  1329.             'circular_reference_handler' => function ($object) {
  1330.                 return $object->getId();
  1331.             }
  1332.         ]);
  1333.         return new JsonResponse($resultResponse::HTTP_OK, [], true);
  1334.     }
  1335.     /**
  1336.      * @Route("/getProducts/{id}", methods={"GET"}, condition="request.isXmlHttpRequest()")
  1337.      */
  1338.     public function ajaxGetProducts(Salon $salonSerializerInterface $serializerProductRepository $productRepository)
  1339.     {
  1340.         $tag $salon->getService();
  1341.         $products $productRepository->findBy([
  1342.             'type' => strtolower($tag),
  1343.             'indisponibleVente' => 0
  1344.         ]);
  1345.         $result $serializer->serialize($products'json', [
  1346.             'groups' => 'planning',
  1347.             'circular_reference_handler' => function ($object) {
  1348.                 return $object->getId();
  1349.             }
  1350.         ]);
  1351.         return new JsonResponse($resultResponse::HTTP_OK, [], true);
  1352.     }
  1353.     /**
  1354.      * @Route("/{id}", methods={"GET"})
  1355.      */
  1356.     public function show(RDV $company): Response
  1357.     {
  1358.         return $this->render('company/show.html.twig', [
  1359.             'company' => $company,
  1360.         ]);
  1361.     }
  1362.     /**
  1363.      * @Route("/{id}/edit", methods={"GET","POST"})
  1364.      */
  1365.     public function edit(
  1366.         Request                $request,
  1367.         RDV $rdv,
  1368.         ProductRepository      $productRepository,
  1369.         RDVProductRepository   $RDVProductRepository,
  1370.         SessionSalonRepository $sessionSalonRepository,
  1371.         RDVRepository          $RDVRepository,
  1372.         PaytweakService $paytweakService,
  1373.         LoggerInterface $logger,
  1374.         ReglementManager  $reglementManager,
  1375.         ClientRepository  $clientRepository,
  1376.         CsrfTokenManagerInterface  $csrfTokenManager
  1377.     ): Response {
  1378.         //        if (!$rdv->getClient()) {
  1379.         //            return $this->redirectToRoute('app_planning_liste');
  1380.         //        }
  1381.         $now = new \DateTime();
  1382.         $em $this->getDoctrine()->getManager();
  1383.         /** @var User $user */
  1384.         $user $this->getUser();
  1385.         $canBill true;
  1386.         $canvalidate true;
  1387.         $total 0;
  1388.         if ($user->hasRole('ROLE_COIFFEUR')) {
  1389.             if (!$rdv->getIntervenant() || !$rdv->getIntervenant()->getUser() || ($rdv->getIntervenant()->getUser() && $rdv->getIntervenant()->getUser() != $user)) {
  1390.                 $canBill false;
  1391.             }
  1392.             $interval $now->diff($rdv->getStart());
  1393.             if ($interval->days && $rdv->getStart() > $now) {
  1394.                 $canBill false;
  1395.             }
  1396.         }
  1397.         // on désactiver l'option facturer
  1398.         if ($user->hasRole('ROLE_COIFFEUR')) {
  1399.             $canvalidate false;
  1400.         }
  1401.         // on désativer le fait de changer de stratus
  1402.         $canChangeStatus true;
  1403.         if ($user->hasRole('ROLE_COIFFEUR') && $rdv->getStatus() === RDV::STATUS_FACTURER) {
  1404.             $canChangeStatus false;
  1405.         }
  1406.         $disabled false;
  1407.         if ($rdv->getValidated()) {
  1408.             $dif time() - $rdv->getValidated()->getTimestamp();
  1409.             // $user->hasRole(User::ROLE_COIFFEUR) &&
  1410.             if ($rdv->getStatus() == RDV::STATUS_VALIDATED && $dif 86400) {
  1411.                 $disabled true;
  1412.             }
  1413.         }
  1414.         if ($user->hasRole(User::ROLE_COIFFEUR && $rdv->getStatus() === RDV::STATUS_ANNULER)) {
  1415.             $disabled true;
  1416.         }
  1417.         if ($user->hasRole(User::ROLE_ADMIN) ||  $user->hasRole(User::ROLE_BO) ||  $user->hasRole(User::ROLE_ADMINISTRATIVE)) {
  1418.             $disabled false;
  1419.         }
  1420.         if ($rdv->isPlatform()) {
  1421.             $createdFrom 'Plateforme';
  1422.         } else {
  1423.             $createdFrom $rdv->getAuthor() ?: 'auto';
  1424.         }
  1425.         $oldStatus $rdv->getStatus();
  1426.         $now = new \DateTime();
  1427.         $form $this->createForm(
  1428.             RDVType::class,
  1429.             $rdv,
  1430.             [
  1431.                 'edition' => true,
  1432.                 'disabled' => $disabled,
  1433.                 'salon' => $rdv->getSalon(),
  1434.                 'hideFacture' => $user->hasRole(User::ROLE_COIFFEUR),
  1435.                 'canValidate' => $user->hasRole(User::ROLE_ADMIN)
  1436.                     ||  $user->hasRole(User::ROLE_BO)
  1437.                     ||  $user->hasRole(User::ROLE_ADMINISTRATIVE),
  1438.                 'createdFrom' => $createdFrom,
  1439.                 'csrf_protection' => true,
  1440.                 'csrf_field_name' => '_token',
  1441.                 // important part; unique key
  1442.                 'csrf_token_id'   => 'form_intention',
  1443.                 'canChangeStatus' => $canChangeStatus
  1444.             ]
  1445.         );
  1446.         if($rdv->getClient()){
  1447.             if ($rdv->getClient()->getConsignesClient()){
  1448.                 $form->get('consignesClient')->setData($rdv->getClient()->getConsignesClient());
  1449.             }
  1450.             if ($rdv->getClient()->getRoomNumber()){
  1451.                 $form->get('roomNumber')->setData($rdv->getClient()->getRoomNumber());
  1452.             }
  1453.         }
  1454.         $form->handleRequest($request);
  1455.         if (!$form->isSubmitted()) {
  1456.             $total 0;
  1457.             $products $productRepository->getProductsByRDV($rdv);
  1458.             foreach ($products as $product) {
  1459.                 $grid $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
  1460.                 $productObj $productRepository->find($product);
  1461.                 $total += $productObj->getPriceSellTTCByGrid($grid);
  1462.             }
  1463.             $form->get(
  1464.                 'products'
  1465.             )->setData($products);
  1466.         }
  1467.         else if ($form->isSubmitted() && $form->isValid()) {
  1468.             $roomNumber $form->get('roomNumber')->getData();
  1469.             $comment $form->get('consignesClient')->getData();
  1470.             $client$rdv->getClient();
  1471.             if($client) {
  1472.                 $client->setConsignesClient($comment);
  1473.                 $client->setRoomNumber($roomNumber);
  1474.                 $em->persist($client);
  1475.             }
  1476.             $products $form->get('products')->getViewData();
  1477.             $csrfTokenManager->refreshToken('form_intention');
  1478.             // START: Si on change la date d’un RDV créé par une récurrence de contrat, les RDV de la même récurrence => décalage des autres RDV
  1479.             $uow $em->getUnitOfWork();
  1480.             /** @var RDV $oldRDV */
  1481.             $oldRDV $uow->getOriginalEntityData($rdv);
  1482.             if ($oldRDV['start'] != $rdv->getStart() && $rdv->getContract()) {
  1483.                 $diff $oldRDV['start']->diff($rdv->getStart());
  1484.                 $diff2 $oldRDV['start']->diff($rdv->getStart());
  1485.                 $rdvs = [];
  1486.                 if ($rdv->getContract()) {
  1487.                     $rdvs $RDVRepository->findForReplanificationByContract([$rdv->getContract()], $rdv->getStart(), $rdv->getSalon());
  1488.                 }
  1489.                 /** @var RDV $item */
  1490.                 foreach ($rdvs as $item) {
  1491.                     if ($item->getId() === $rdv->getId()) {
  1492.                         continue;
  1493.                     }
  1494.                     $date = clone $item->getStart();
  1495.                     $endDate = clone $item->getEnd();
  1496.                     $date->add($diff);
  1497.                     $endDate->add($diff2);
  1498.                     $item->setStart($date);
  1499.                     $item->setEnd($endDate);
  1500.                     $em->persist($item);
  1501.                     $em->flush();
  1502.                 }
  1503.                 $em->flush();
  1504.             }
  1505.             // END
  1506.             $productRdv $RDVProductRepository->findBy([
  1507.                 'rdv' => $rdv
  1508.             ]);
  1509.             /*
  1510.              * On duplique le RDV à la prochaine date d’ouverture du salon,
  1511.              * Seule la date et le statut sont différents du RDV d’origine. Le statut = « Replanifié »
  1512.              * Le RDV d’origine est lui conservé en statut annulé
  1513.              */
  1514.             if (
  1515.                 $oldStatus != RDV::STATUS_ANNULER
  1516.                 && $rdv->getStatus() === RDV::STATUS_ANNULER
  1517.                 && $rdv->getCancelReason()->getLabel() != 'Décès'
  1518.                 && $rdv->getCancelReason()->getLabel() != 'Client parti du site'
  1519.                 && $rdv->getCancelReason()->getLabel() != 'RDV supprimé'
  1520.             ) {
  1521.                 $sessionSalons null;
  1522.                 $salon $rdv->getSalon();
  1523.                 $dateStart = clone $rdv->getStart();
  1524.                 //$dateStart->setTime(0, 0, 0, 0);
  1525.                 $dateStart->modify('+1 day');
  1526.                 $dateStart->setTime(
  1527.                     $rdv->getStart()->format('H'),    // Hours
  1528.                     $rdv->getStart()->format('i'),    // Minutes
  1529.                     $rdv->getStart()->format('s')     // Seconds
  1530.                 );
  1531.                 if ($salon) {
  1532.                     $sessionSalons $sessionSalonRepository->findFirstBySalon($salon$dateStart);
  1533.                 }
  1534.                 //1 . create new RDV  to next "JOS"
  1535.                 if ($sessionSalons) {
  1536.                     /** @var \DateTime $josStart */
  1537.                     // keep the rdv hour
  1538.                     $josStart $sessionSalons->getStart();
  1539.                     /** @var \DateTime $josEnd */
  1540.                     $josEnd $sessionSalons->getEnd();
  1541.                     $josStart->setTime(
  1542.                         $rdv->getStart()->format('H'),    // Hours
  1543.                         $rdv->getStart()->format('i'),    // Minutes
  1544.                         $rdv->getStart()->format('s')     // Seconds
  1545.                     );
  1546.                     $josEnd->setTime(
  1547.                         $rdv->getEnd()->format('H'),    // Hours
  1548.                         $rdv->getEnd()->format('i'),    // Minutes
  1549.                         $rdv->getEnd()->format('s')     // Seconds
  1550.                     );
  1551.                     //  CREATE NEW RDV because we cancel the previous one
  1552.                     $rdv2 = new RDV();
  1553.                     $rdv2->setStatus(RDV::STATUS_REPLANIFIER);
  1554.                     $rdv2->setStart($josStart);
  1555.                     $rdv2->setEnd($josStart);
  1556.                     $rdv2->setAuthor($rdv->getAuthor());
  1557.                     $rdv2->setPriorite($rdv->getPriorite());
  1558.                     $rdv2->setRdvProducts($rdv->getRdvProducts());
  1559.                     if($rdv->getRecurrenceRdvs()) {
  1560.                         $rdv2->setRecurrenceRdvs($rdv->getRecurrenceRdvs());
  1561.                     }
  1562.                     foreach ($rdv->getRdvProducts() as $rdvProductOld) {
  1563.                         $rdvProduct = new RDVProduct();
  1564.                         $rdvProduct->setRdv($rdv2);
  1565.                         $rdvProduct->setProduct($rdvProductOld->getProduct());
  1566.                         $em->persist($rdvProduct);
  1567.                     }
  1568.                     $rdv2->setBillings($rdv->getBillings());
  1569.                     $logRDV = new LogCancel();
  1570.                     $rdv2->setSalon($rdv->getSalon());
  1571.                     $rdv2->setRDVBillings($rdv->getRDVBillings()); // to fix ??
  1572.                     $logRDV->setIntervenantOld($rdv->getIntervenant());
  1573.                     if ($sessionSalons->getIntervenant()) {
  1574.                         $rdv2->setIntervenant($sessionSalons->getIntervenant());
  1575.                         $logRDV->setNewIntervenant($sessionSalons->getIntervenant());
  1576.                     } else {
  1577.                         $rdv2->setIntervenant($rdv->getIntervenant());
  1578.                         $logRDV->setNewIntervenant($rdv->getIntervenant());
  1579.                     }
  1580.                     $logRDV->setSessionSalon($sessionSalons);
  1581.                     $em->persist($logRDV);
  1582.                     if ($rdv->getContract()) {
  1583.                         $rdv2->setContract($rdv->getContract());
  1584.                     }
  1585.                     $rdv2->setComment($rdv->getComment());
  1586.                     $rdv2->setClient($rdv->getClient());
  1587.                     $rdv2->setValidated($rdv->getValidated());
  1588.                     $rdv2->setCommentForfait($rdv->getCommentForfait());
  1589.                     $em->persist($rdv2);
  1590.                     ///// END CREATE NEW RDV
  1591.                 }
  1592.                 // 2. get all contracts of the clients
  1593. //                $clientContrats = [];
  1594. //                foreach ($rdv->getClient()->getContract() as $contract) {
  1595. //                    $clientContrats[] = $contract->getId();
  1596. //                }
  1597. //
  1598. //                // 3. get theirs RDV, we exclude the new RDV with the status
  1599. //                $rdvs = $RDVRepository->findForReplanificationByContract($clientContrats, $rdv->getStart(), $rdv->getSalon());
  1600. //
  1601. //                /** @var RDV $item */
  1602. //                foreach ($rdvs as $item) {
  1603. //                    // do not report current RDV
  1604. //                    if ($item->getId() === $rdv->getId()) {
  1605. //                        continue;
  1606. //                    }
  1607. //                    $dateStart = clone $item->getStart();
  1608. //                    $dateStart->setTime(0, 0, 0, 0);
  1609. //                    $dateStart->modify('+1 day');
  1610. //                    // find next jos
  1611. //                    $sessionSalons = $sessionSalonRepository->findFirstBySalon($item->getSalon(), $dateStart);
  1612. //                    if ($sessionSalons) {
  1613. //                        $item->setStart($sessionSalons->getStart());
  1614. //                        $item->setEnd($sessionSalons->getStart());
  1615. //                        $em->persist($item);
  1616. //                    }
  1617. //                }
  1618.                 $rdvs $RDVRepository->findForReplanificationNewRecurence($rdv->getClient(), $rdv->getStart(), $rdv->getSalon());
  1619.                 /** @var RDV $item */
  1620.                 foreach ($rdvs as $item) {
  1621.                     // do not report current RDV
  1622.                     if ($item->getId() === $rdv->getId()) {
  1623.                         continue;
  1624.                     }
  1625.                     $dateStart = clone $item->getStart();
  1626.                     //$dateStart->setTime(0, 0, 0, 0);
  1627.                     $dateStart->modify('+1 day');
  1628.                     $dateStart->setTime(
  1629.                         $item->getStart()->format('H'),    // Hours
  1630.                         $item->getStart()->format('i'),    // Minutes
  1631.                         $item->getStart()->format('s')     // Seconds
  1632.                     );
  1633.                     // find next jos
  1634.                     $sessionSalons $sessionSalonRepository->findFirstBySalon($item->getSalon(), $dateStart);
  1635.                     if ($sessionSalons) {
  1636.                         $startSessionSalon $sessionSalons->getStart();
  1637.                         $startSessionSalon->setTime(
  1638.                             $item->getStart()->format('H'),    // Hours
  1639.                             $item->getStart()->format('i'),    // Minutes
  1640.                             $item->getStart()->format('s')     // Seconds
  1641.                         );
  1642.                         $item->setStart($startSessionSalon);
  1643.                         $item->setEnd($startSessionSalon);
  1644.                         $em->persist($item);
  1645.                     }
  1646.                 }
  1647.                 $em->flush();
  1648.             }
  1649.             if (
  1650.                 $rdv->getStatus() === RDV::STATUS_ANNULER
  1651.                 && ($rdv->getCancelReason()->getLabel() == 'Décès'
  1652.                 || $rdv->getCancelReason()->getLabel() == 'Client parti du site')
  1653.             ) {
  1654.                 $rdvsTodelete $this->RDVManager->findFromTodayByStatusPlan($client);
  1655.                 // supprimer la recurrence TODO:
  1656.                 $recurrence $rdv->getRecurrence();
  1657.                 foreach ($rdvsTodelete as $rdvDelete) {
  1658.                     if($rdvDelete->getId() === $rdv->getId()){
  1659.                         continue;
  1660.                     }
  1661.                     $em->remove($rdvDelete);
  1662.                 }
  1663.                 if($client->getSolde() <= 0){
  1664.                     $client->setStatusProspect(Client::STATUS_INACTIF);
  1665.                 }
  1666.                 else {
  1667.                     if($rdv->getCancelReason()->getLabel() == 'Client parti du site'){
  1668.                         $client->setStatusProspect(Client::STATUS_PARTI);
  1669.                     }
  1670.                     if($rdv->getCancelReason()->getLabel() == 'Décès'){
  1671.                         $client->setStatusProspect(Client::STATUS_DECES);
  1672.                     }
  1673.                 }
  1674.                 $em->flush();
  1675.             }
  1676.             foreach ($productRdv as $product) {
  1677.                 $em->remove($product);
  1678.             }
  1679.             $em->flush();
  1680.             $total 0;
  1681.             foreach ($products as $product) {
  1682.                 $grid $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
  1683.                 $productObj $productRepository->find($product);
  1684.                 $total += $productObj->getPriceSellTTCByGrid($grid);
  1685.                 // if rdvproduct already exists
  1686.                 $rdvProduct $RDVProductRepository->findOneBy([
  1687.                     'product' => $product,
  1688.                     'rdv' => $rdv
  1689.                 ]);
  1690.                 //
  1691.                 if (!$rdvProduct) {
  1692.                     $rdvProduct = new RDVProduct();
  1693.                     $rdvProduct->setRdv($rdv);
  1694.                     $rdvProduct->setProduct($productObj);
  1695.                     $rdv->addRdvProduct($rdvProduct);
  1696.                     $em->persist($rdvProduct);
  1697.                     $em->persist($rdv);
  1698.                 }
  1699.             }
  1700.             if ($oldStatus != RDV::STATUS_VALIDATED && $rdv->getStatus() === RDV::STATUS_VALIDATED) {
  1701.                 $rdv->setValidated(new \DateTime());
  1702.                 if($rdv->isPlatform()){
  1703.                     $clientExist $clientRepository->findOneBy([
  1704.                         'lastname' => $rdv->getClient()->getLastname(),
  1705.                         'firstname' => $rdv->getClient()->getFirstname(),
  1706.                         'civilite' => $rdv->getClient()->getCivilite(),
  1707.                         'site' => $rdv->getSalon()->getSite(),
  1708.                     ]);
  1709.                     $paymentLink $rdv->getPaymentLink();
  1710.                     if($clientExist){
  1711.                         /** @var RDV $lastRDV */
  1712.                         $lastRDV $this->RDVManager->getRepository()->findOneByClientAndToken($clientExist);
  1713.                         if($lastRDV){
  1714.                             $paymentLink $lastRDV->getPaymentLink();
  1715.                             //$path = parse_url($paymentLink, PHP_URL_PATH);
  1716.                             //$orderIdPaytweak = basename($path);
  1717.                         }
  1718.                     }
  1719.                     $billing $this->billingManager->createFromRDV($rdv$this->getUser());
  1720.                     $response $paytweakService->triggerPayment($paymentLink$billing->getTtc(), $billing->getCode());
  1721.                     if ($response['code'] !== 'OK') {
  1722.                         $this->mailService->sentErrorPaytweakResa($rdv$response['code'], $response['message']);
  1723.                         $logger->error('An error occurred for RDV ID ' $rdv->getId() . ': ' $response['message']);
  1724.                     }
  1725.                 }
  1726.             }
  1727.             // set the form product agains
  1728.             $em->flush();
  1729.         }
  1730.         return $this->render('planning/edit.html.twig', [
  1731.             'rdv' => $rdv,
  1732.             'canvalidate' => $canvalidate,
  1733.             'canBill' => $canBill,
  1734.             'total' => $total,
  1735.             'rdvProducts' => $rdv->getRdvProducts(),
  1736.             'form' => $form->createView(),
  1737.             'minuteIncrement' => $rdv->getSalon() && $rdv->getSalon()->getSite() ?  ($rdv->getSalon()->getSite()->getType() === Site::TYPE_EHPAD 15 30) : 15,
  1738.         ]);
  1739.     }
  1740.     /**
  1741.      * @Route("/{id}", methods={"DELETE"})
  1742.      */
  1743.     public function delete(Request $requestRDV $RDV): Response
  1744.     {
  1745.         if ($this->isCsrfTokenValid('delete' $RDV->getId(), $request->request->get('_token'))) {
  1746.             $entityManager $this->getDoctrine()->getManager();
  1747.             $entityManager->remove($RDV);
  1748.             $entityManager->flush();
  1749.         }
  1750.         return $this->redirectToRoute('app_planning_liste');
  1751.     }
  1752.     /**
  1753.      * @param $class
  1754.      * @return \Closure[]|mixed
  1755.      */
  1756.     private function getColumnsForEntity($class)
  1757.     {
  1758.         $columns[RDV::class] = [
  1759.             'Id' => function (RDV $RDV) {
  1760.                 return $RDV->getId();
  1761.             },
  1762.             'Client' => function (RDV $RDV) {
  1763.                 return (string)$RDV->getClient();
  1764.             },
  1765.             'Début' => function (RDV $RDV) {
  1766.                 return $RDV->getStart() ?  $RDV->getStart()->format('d-m-Y H:i:s') ? $RDV->getStart()->format('d-m-Y H:i:s') : '' '';
  1767.             },
  1768.             'Fin' => function (RDV $RDV) {
  1769.                 return $RDV->getEnd() ? $RDV->getEnd()->format('d-m-Y H:i:s') ? $RDV->getEnd()->format('d-m-Y H:i:s') : '' '';
  1770.             },
  1771.             'Intervenant' => function (RDV $RDV) {
  1772.                 return (string)$RDV->getIntervenant();
  1773.             },
  1774.             'Salon' => function (RDV $RDV) {
  1775.                 return $RDV->getSalon() ? $RDV->getSalon()->getName() : '';
  1776.             },
  1777.             'Status' => function (RDV $RDV) {
  1778.                 return $RDV->getStatus();
  1779.             },
  1780.             'Raison annulation' => function (RDV $RDV) {
  1781.                 return $RDV->getCancelReason();
  1782.             },
  1783.             'Commentaires' => function (RDV $RDV) {
  1784.                 return $RDV->getComment();
  1785.             },
  1786.             'Prise de RDV' => function (RDV $RDV) {
  1787.                 if ($RDV->isPlatform()) {
  1788.                     $createdFrom 'Plateforme';
  1789.                 } else {
  1790.                     $createdFrom $RDV->getAuthor() ? $RDV->getAuthor() : 'auto';
  1791.                 }
  1792.                 return $createdFrom;
  1793.             },
  1794.             'Priorite' => function (RDV $RDV) {
  1795.                 return $RDV->getPriorite();
  1796.             },
  1797.             'Récurrence' => function (RDV $RDV) {
  1798.                 return $RDV->getRecurrence();
  1799.             },
  1800.             'Email de facturation' => function (RDV $RDV) {
  1801.                 $billingEmail "";
  1802.                 $client $RDV->getClient();
  1803.                 if ($client && $client->getBillingInfos()) {
  1804.                     $billingEmail $client->getBillingInfos()->getEmail();
  1805.                 }
  1806.                 return $billingEmail;
  1807.             },
  1808.             'Montant TTC' => function (RDV $RDV) {
  1809.                 return $RDV->ttc();
  1810.             },
  1811.             'Products' => function (RDV $RDV) {
  1812.                 $products =[];
  1813.                 $productsRDV $RDV->getRdvProducts();
  1814.                 foreach($productsRDV as $productRdv)
  1815.                 {$products []= $productRdv->getProduct()->getName(); }
  1816.                 return implode(","$products);
  1817.             },
  1818.             'Factures' => function (RDV $RDV) {
  1819.                 $billingCodes = [];
  1820.                 if($RDV->getBillings() && $RDV->getRDVBillings()->count() > 0){
  1821.                     foreach ($RDV->getRDVBillings() as $billing) {
  1822.                         $billingCodes[] = $billing->getBilling()->getCode();
  1823.                     }
  1824.                 }
  1825.                 return implode(","$billingCodes);
  1826.             },
  1827.         ];
  1828.         if (array_key_exists($class$columns)) {
  1829.             return $columns[$class];
  1830.         }
  1831.         throw new \InvalidArgumentException(sprintf(
  1832.             'No columns set for "%s" entity',
  1833.             $class
  1834.         ));
  1835.     }
  1836.     /**
  1837.      * @Route("/rdv/auto-save", name="rdv_auto_save", methods={"POST"})
  1838.      */
  1839.     public function autoSave(Request $requestEntityManagerInterface $emRdvRepository $rdvRepository): JsonResponse
  1840.     {
  1841.         $data json_decode($request->getContent(), true);
  1842.         $field $data['field'];
  1843.         $value $data['value'];
  1844.         $rdvId $data['rdvId'];
  1845.         $rdv $rdvRepository->find($rdvId);
  1846.         if (!$rdv) {
  1847.             return new JsonResponse(['success' => false'message' => 'RDV not found'], 404);
  1848.         }
  1849.         // Update the appropriate field
  1850.         if ($field === 'chequeReception') {
  1851.             $rdv->setChequeReception($value);
  1852.         } elseif ($field === 'infoCheque') {
  1853.             $rdv->setInfoCheque($value);
  1854.         } else {
  1855.             return new JsonResponse(['success' => false'message' => 'Invalid field'], 400);
  1856.         }
  1857.         $em->persist($rdv);
  1858.         $em->flush();
  1859.         return new JsonResponse(['success' => true]);
  1860.     }
  1861. }