src/EventSubscriber/CalendarSubscriber.php line 38

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Booking;
  4. use App\Entity\BookingEvent;
  5. use App\Entity\BookingVisitReport;
  6. use App\Repository\BookingEventRepository;
  7. use App\Repository\BookingRepository;
  8. use App\Repository\BookingVisitReportRepository;
  9. use CalendarBundle\CalendarEvents;
  10. use CalendarBundle\Entity\Event;
  11. use CalendarBundle\Event\CalendarEvent;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  14. use Symfony\Component\Security\Core\Security;
  15. class CalendarSubscriber implements EventSubscriberInterface
  16. {
  17.     public function __construct(
  18.         private readonly BookingRepository            $bookingRepository,
  19.         private readonly BookingVisitReportRepository $bookingVisitReportRepository,
  20.         private readonly BookingEventRepository       $bookingEventRepository,
  21.         private readonly UrlGeneratorInterface        $router,
  22.         private readonly Security                     $security
  23.     )
  24.     {
  25.     }
  26.     public static function getSubscribedEvents()
  27.     {
  28.         return [
  29.             CalendarEvents::SET_DATA => 'onCalendarSetData',
  30.         ];
  31.     }
  32.     // Cette méthode est appelée pour configurer les données du calendrier.
  33.     public function onCalendarSetData(CalendarEvent $calendar): void
  34.     {
  35.         $filters $calendar->getFilters();
  36. //        dump($filters['eventTypes']);
  37.         // SI on a les droits de voir les événements et les rapports de visite
  38.         if ($this->security->isGranted('ROLE_VISIT_REPORT')) {
  39.             // Vérifiez si le filtre pour les rapports de visite est activé
  40.             if ($this->security->isGranted('ROLE_COMMERCIAL') || !$filters || in_array('rv'$filters['eventTypes'] ?? [], true)) {
  41.                 $this->getVisitReports($calendar);
  42.             }
  43.         }
  44.         // Vérifiez si le filtre pour les événements et séminaires est activé
  45.         if ($this->security->isGranted('ROLE_COMMERCIAL') || !$filters || in_array('ev'$filters['eventTypes'] ?? [], true)) {
  46.             $this->getBookingEvents($calendar);
  47.         }
  48.     }
  49.     /**
  50.      * @param CalendarEvent $calendar
  51.      * @return void
  52.      */
  53.     protected function getVisitReports(CalendarEvent $calendar): void
  54.     {
  55.         $user $this->security->getUser();
  56.         if (!$user) {
  57.             return;
  58.         }
  59.         $start $calendar->getStart()->format('Y-m-d H:i:s');
  60.         $end   $calendar->getEnd()->format('Y-m-d H:i:s');
  61.         // Récupérer les filtres depuis l'objet CalendarEvent
  62.         $filters $calendar->getFilters();
  63.         $queryBuilder $this->bookingVisitReportRepository
  64.             ->createQueryBuilder('booking')
  65.             ->where('booking.beginAt BETWEEN :start and :end OR booking.endAt BETWEEN :start and :end')
  66.             ->setParameter('start'$start)
  67.             ->setParameter('end'$end)
  68.         ;
  69.         // Comme les commerciaux ont pas (encore) le filtres,
  70.         if (!$user->hasRole('ROLE_COMMERCIAL')) {
  71.             // Vérifier si le filtre commercialIds est défini
  72.             if (isset($filters['commercialIds'])) {
  73.                 // Si le tableau commercialIds est vide, ne retourner aucun événement
  74.                 if (empty($filters['commercialIds'])) {
  75.                     return;
  76.                 }
  77.                 $queryBuilder->andWhere('booking.owner IN (:commercials)')
  78.                              ->setParameter('commercials'$filters['commercialIds'])
  79.                 ;
  80.             }
  81.         }
  82.         // La gestion des rôles doit être explicite et claire.
  83.         if ($user->hasRole('ROLE_EMPLOYEE')) {
  84.             // Si on a un role EMPLOYEE, on renvoie les rapports de visite de tous le monde
  85.             $queryBuilder->leftJoin('booking.visitReport''visitReport');
  86.         } // Si on a un role commercial, on renvoie les rapports de visite qui lui sont liés
  87.         elseif ($user->hasRole('ROLE_COMMERCIAL')) {
  88. //            $queryBuilder->andWhere('booking.owner = :user')
  89.             $queryBuilder->leftJoin('booking.visitReport''visitReport')
  90.                          ->andWhere('booking.owner = :user OR visitReport.visitedBy = :user')
  91.                          ->setParameter('user'$user)
  92.             ;
  93.         }
  94.         // Exécution de la requête et obtention des résultats.
  95.         $bookings $queryBuilder->getQuery()->getResult();
  96.         // Parcours de chaque réservation pour créer et configurer un événement de calendrier correspondant.
  97.         /** @var BookingVisitReport $booking */
  98.         foreach ($bookings as $booking) {
  99.             // Vérification de l'existence d'un rapport de visite pour cette réservation.
  100.             if (null === $visitReport $booking->getVisitReport()) {
  101.                 continue; // Passer à la réservation suivante si aucun rapport de visite n'est associé.
  102.             }
  103.             // Création d'un nouvel événement avec le titre et les dates de début et de fin de la réservation.
  104.             $bookingEvent = new Event(
  105.                 $booking->getTitle(),
  106.                 $booking->getBeginAt(),
  107.                 $booking->getEndAt(), // Si pas de date de fin, un événement sur toute la journée est créé.
  108.                 null,
  109.             );
  110.             // Ajout de la mention "(RDV)" au titre de l'événement.
  111.             // Gestion du titre de l'événement en fonction du rôle.
  112.             $eventTitlePrefix "";
  113.             switch ($booking->getVisitReport()?->getBooking()?->getMethod()?->getSlug()) {
  114.                 case BookingVisitReport::VISIT_TYPE_PHYSICAL:
  115.                     $eventTitlePrefix '(RP) ';
  116.                     break;
  117.                 case BookingVisitReport::VISIT_TYPE_TELEPHONE:
  118.                     $eventTitlePrefix '(RT) ';
  119.                     break;
  120.                 case BookingVisitReport::VISIT_TYPE_VISIO:
  121.                     $eventTitlePrefix '(RV) ';
  122.                     break;
  123.             }
  124.             $bookingEvent->setOptions(
  125.                 [
  126.                     'className'       => 'visitReportEvent',
  127.                     'backgroundColor' => 'white',
  128.                 ]);
  129.             // Gestion du titre de l'événement en fonction du rôle.
  130.             if ($user->hasRole('ROLE_EMPLOYEE')) {
  131.                 $bookingEvent->setTitle($eventTitlePrefix $booking->getVisitReport()->getVisitedBy()?->getFullName());
  132.             } else {
  133.                 $bookingEvent->setTitle($eventTitlePrefix $booking->getVisitReport()->getPrescriber()?->getFullName());
  134.             }
  135.             if (!$visitReport->isApproved()) {
  136.                 if ($visitReport->isIsReadyForValidation()) {
  137.                     // Événements non validés mais prêts pour la validation.
  138.                     $bookingEvent->setOptions(
  139.                         [
  140.                             'className'       => 'visitReportEvent',
  141.                             'backgroundColor' => 'orange',
  142.                         ]);
  143.                 } else {
  144.                     // Événements ni prêts pour la validation ni validés (marqués comme temporaires).
  145.                     $bookingEvent->setOptions(
  146.                         [
  147.                             'className'       => 'visitReportEvent',
  148.                             'backgroundColor' => 'yellow',
  149.                         ]);
  150.                     $bookingEvent->setTitle($bookingEvent->getTitle());
  151.                 }
  152.             } elseif ($visitReport->isIsReadyForValidation() && $visitReport->isApproved()) {
  153.                 // Événements prêts pour la validation et déjà validés.
  154.                 // Aucune option supplémentaire n'est définie, on affiche seulement le titre.
  155.             }
  156.             if ($visitReport->getBooking()?->isIsCancelled()) {
  157.                 // Événements annulés.
  158.                 $bookingEvent->setOptions(
  159.                     [
  160.                         'className'       => 'visitReportEvent cancelled-booking',
  161.                         'backgroundColor' => 'red',
  162.                     ]);
  163.             }
  164.             $bookingEvent->addOption(
  165.                 'url',
  166.                 $this->router->generate('app_booking_visit_report_edit', [
  167.                     'id' => $booking->getId(),
  168.                 ])
  169.             );
  170.             $bookingEvent->addOption(
  171.                 'object'$booking->getTitle(),
  172.             );
  173.             // Ajout de l'événement configuré au calendrier.
  174.             $calendar->addEvent($bookingEvent);
  175.         }
  176.     }
  177.     protected function getBookingEvents(CalendarEvent $calendar): void
  178.     {
  179.         $user $this->security->getUser();
  180.         if (!$user) {
  181.             return;
  182.         }
  183.         $start $calendar->getStart()->format('Y-m-d H:i:s');
  184.         $end   $calendar->getEnd()->format('Y-m-d H:i:s');
  185.         // Récupérer les filtres depuis l'objet CalendarEvent
  186.         $filters $calendar->getFilters();
  187.         $queryBuilder $this->bookingEventRepository
  188.             ->createQueryBuilder('booking')
  189.             ->where('booking.beginAt BETWEEN :start and :end OR booking.endAt BETWEEN :start and :end')
  190.             ->setParameter('start'$start)
  191.             ->setParameter('end'$end)
  192.         ;
  193.         // Exécution de la requête et obtention des résultats.
  194.         $bookings $queryBuilder->getQuery()->getResult();
  195.         // Parcours de chaque réservation pour créer et configurer un événement de calendrier correspondant.
  196.         /** @var BookingEvent $booking */
  197.         foreach ($bookings as $booking) {
  198.             // Vérifier si l'utilisateur courant est le propriétaire ou fait partie des utilisateurs autorisés
  199.             if ($booking->getOwner() === $user ||
  200.                 $booking->getUsers()->contains($user) ||
  201.                 $booking->getAllowedEmployees()->contains($user) ||
  202.                 $booking->getAllowedCommercials()->contains($user)) {
  203.                 // Création d'un nouvel événement avec le titre et les dates de début et de fin de la réservation.
  204.                 $bookingEvent = new Event(
  205.                     $booking->getTitle(),
  206.                     $booking->getBeginAt(),
  207.                     $booking->getEndAt(), // Si pas de date de fin, un événement sur toute la journée est créé.
  208.                     null,
  209.                 );
  210.                 $className $booking->getEventCategory()?->getSlug() ?? '';
  211.                 // Gestion de la pastille en fonction du RAF.
  212.                 $backgroundColor 'orange';
  213.                 if ($booking->isIsClosed()) {
  214.                     $backgroundColor 'green';
  215.                 }
  216.                 // Configuration des options de l'événement...
  217.                 $bookingEvent->setOptions(
  218.                     [
  219.                         'className'       => "booking-event-" $className,
  220.                         'backgroundColor' => $backgroundColor// Couleur de fond de l'événement
  221.                     ]);
  222.                 $bookingEventDb $this->bookingEventRepository->find($booking->getId());
  223.                 if ($bookingEventDb) {
  224.                     if ($bookingEventDb->getCity()) {
  225.                         $bookingEvent->addOption(
  226.                             'city'$bookingEventDb->getCity(),
  227.                         );
  228.                     }
  229.                 }
  230.                 if ($bookingEventDb->isIsCancelled()) {
  231.                     $bookingEvent->setOptions(
  232.                         [
  233.                             'className'       => "cancelled-booking "."booking-event-" $className,
  234.                             'backgroundColor' => 'red'// Couleur de la pastille
  235.                         ]);
  236.                 }
  237.                 $route 'app_booking_event_show';
  238.                 if ($user->hasRole('ROLE_BOOKING_EVENT')) {
  239.                     $route 'app_booking_event_edit';
  240.                 }
  241.                 $bookingEvent->addOption(
  242.                     'url',
  243.                     $this->router->generate($route, [
  244.                         'id' => $booking->getId(),
  245.                     ])
  246.                 );
  247.                 $bookingEvent->addOption(
  248.                     'object'$booking->getTitle(),
  249.                 );
  250.                 // Ajout de l'événement configuré au calendrier.
  251.                 $calendar->addEvent($bookingEvent);
  252.             }
  253.         }
  254.     }
  255. }