src/EventSubscriber/CheckHolidaysSubscriber.php line 48

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use ApiPlatform\Core\EventListener\EventPriorities;
  4. use App\Entity\Employee;
  5. use App\Entity\Holiday;
  6. use App\Entity\HolidayIncompatibility;
  7. use App\Entity\PublicHoliday;
  8. use App\Entity\Workplace;
  9. use App\Exception\Api\HolidaysAreIncompatibleException;
  10. use App\Service\UserManipulatorService;
  11. use Carbon\Carbon;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Symfony\Component\Config\Definition\Exception\Exception;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpKernel\Event\ViewEvent;
  17. use Symfony\Component\HttpKernel\KernelEvents;
  18. final class CheckHolidaysSubscriber implements EventSubscriberInterface
  19. {
  20.     /**
  21.      * @var EntityManagerInterface
  22.      */
  23.     private $entityManager;
  24.     /**
  25.      * @var UserManipulatorService
  26.      */
  27.     private $generateUserFromEmployeeService;
  28.     public function __construct(EntityManagerInterface $entityManagerUserManipulatorService $generateUserFromEmployeeService)
  29.     {
  30.         $this->entityManager $entityManager;
  31.         $this->generateUserFromEmployeeService $generateUserFromEmployeeService;
  32.     }
  33.     public static function getSubscribedEvents()
  34.     {
  35.         return [
  36.             KernelEvents::VIEW => ['checkHolidays'EventPriorities::PRE_VALIDATE],
  37.         ];
  38.     }
  39.     public function checkHolidays(ViewEvent $viewEvent)
  40.     {
  41.         /** @var Holiday $holiday */
  42.         $holiday $viewEvent->getControllerResult();
  43.         $method $viewEvent->getRequest()->getMethod();
  44.         if (!$holiday instanceof Holiday || Request::METHOD_POST !== $method) {
  45.             return;
  46.         }
  47.         if (Carbon::parse($holiday->getFromDate())->greaterThan(Carbon::parse($holiday->getToDate()))) {
  48.             throw new HolidaysAreIncompatibleException(sprintf('4#Error the fromDate %s greater than toDate: %s'$holiday->getFromDate(), $holiday->getToDate()));
  49.         }
  50.         /* Comprueba que no coja vacaciones dentro del periodo ya cogido */
  51.         $this->checkHolidaysInThisPeriod($holiday$method);
  52.         /* Comprueba si el empleado tiene alguna incompatibilidad con otros usuarios con los que forme un equipo */
  53.         $this->checkHolidayIncompatible($holiday);
  54.         /* Calculo de los dias consumidos, descontando festivos (obtenidos del correspondiente workplace) y fines de semana */
  55.         $workplace $holiday->getEmployee()->getWorkplace();
  56.         /* Compruebo si existen dias festivos en ese rango de fechas */
  57.         if ($workplace) {
  58.             $publicHolidays $this->entityManager->getRepository(PublicHoliday::class)
  59.                 ->findPublicHolidaysByWorkplaceAndBetweenDates($workplace$holiday->getFromDate(), $holiday->getToDate());
  60.         } else {
  61.             // Si no tiene asignado un workcenter, le damos por defecto el primero
  62.             $workplace $this->entityManager->getRepository(Workplace::class)->find(1);
  63.             $publicHolidays $this->entityManager->getRepository(PublicHoliday::class)
  64.                 ->findPublicHolidaysByWorkplaceAndBetweenDates($workplace$holiday->getFromDate(), $holiday->getToDate());
  65.         }
  66.         $daysConsumed $this->calculateDaysConsumed($holiday->getFromDate(), $holiday->getToDate(), $publicHolidays);
  67.         /* Comprueba cuantos dias de vacaciones quedan, si los dias consumidos es mayor al numero de dias permitidos
  68.         para cojer vacaciones 23 dara una excepción */
  69.         $totalDaysConsumed $this->entityManager->getRepository(Holiday::class)->getTotalDaysConsumedInYearExercise($holiday);
  70.         $daysRemain $holiday->getEmployee()->getCurrentDaysOff() - $totalDaysConsumed;
  71.         if ($daysConsumed $daysRemain) {
  72.             throw new HolidaysAreIncompatibleException(sprintf('3#Exceeds the maximum number of vacation days, remains %s and has requested %s'$daysRemain$daysConsumed));
  73.         }
  74.         $holiday->setDaysConsumed($daysConsumed);
  75.         /* TODO que pasa si no tiene teamManager */
  76.     }
  77.     /**
  78.      * Devuelve el número de dias hábiles de vacaciones descontando fines de semana y festivos
  79.      * @param $fromDate
  80.      * @param $toDate
  81.      * @param $publicHolidays
  82.      * @return int
  83.      */
  84.     public function calculateDaysConsumed($fromDate$toDate$publicHolidays)
  85.     {
  86.         $start Carbon::createFromFormat('Y-m-d'$fromDate)->setTime(000);
  87.         $end Carbon::createFromFormat('Y-m-d'$toDate)->setTime(235959);
  88.         $listPublicHolidays = [];
  89.         /** @var PublicHoliday $publicHoliday */
  90.         foreach ($publicHolidays as $publicHoliday) {
  91.             $aPublicHoliday Carbon::createFromFormat('Y-m-d'$publicHoliday->getDate())->setTime(000);
  92.             if ($aPublicHoliday->isSunday()) {
  93.                 $aPublicHoliday->addDay();
  94.             }
  95.             $listPublicHolidays[] = $aPublicHoliday;
  96.         }
  97.         $days $start->diffInDaysFiltered(function (Carbon $date) use ($listPublicHolidays) {
  98.             return $date->isWeekday() && !in_array($date$listPublicHolidays);
  99.         }, $end);
  100.         return $days;
  101.     }
  102.     /**
  103.      * Comprueba si el usuario tiene alguna incompatiblidad para cojer vacaciones con algun miembro de su equipo
  104.      * @param Holiday $holiday
  105.      * @throws HolidaysAreIncompatibleException
  106.      */
  107.     public function checkHolidayIncompatible(Holiday $holiday): void
  108.     {
  109.         /* Si la fecha es Nochebuena o Nochevieja no se comprueba */
  110.         $nochebuena Carbon::createFromDate(null1224);
  111.         if ($nochebuena->isSunday()) {
  112.             $nochebuena->addDay();
  113.         }
  114.         $nochevieja Carbon::createFromDate(null1231);
  115.         if ($nochevieja->isSunday()) {
  116.             $nochevieja->addDay();
  117.         }
  118.         if ($nochebuena->isSameDay(Carbon::createFromFormat('Y-m-d'$holiday->getFromDate())) ||
  119.             $nochevieja->isSameDay(Carbon::createFromFormat('Y-m-d'$holiday->getToDate()))) {
  120.             return;
  121.         }
  122.         /** @var HolidayIncompatibility $holidayIncompatibilities */
  123.         $holidayIncompatibilities $holiday->getEmployee()->getHolidayIncompatibilities();
  124.         if (count($holidayIncompatibilities->getSnapshot()) > 0) {
  125.             $numEmployees 0;
  126.             $totalNumEmployees 0;
  127.             /** @var HolidayIncompatibility $holidayIncompatibility */
  128.             foreach ($holidayIncompatibilities as $holidayIncompatibility) {
  129.                 $employeesIncompatibles $holidayIncompatibility->getEmployees();
  130.                 /** @var Employee $employeeIncompatible */
  131.                 foreach ($employeesIncompatibles as $employeeIncompatible) {
  132. //                    if ($employeeIncompatible->isActive()) {
  133.                         $totalNumEmployees += 1;
  134.                         // comprobar que empleados han cogido vacaciones en ese rango de fechas
  135. //                    $employeeIncompatible->getHolidays();
  136.                         if ($employeeIncompatible->getId() !== $holiday->getEmployee()->getId()) {
  137.                             $holidays $this->entityManager->getRepository(Holiday::class)
  138.                                 ->findHolidaysByEmployeeBetweenDates($employeeIncompatible$holiday->getFromDate(), $holiday->getToDate());
  139.                             if (count($holidays) != 0) {
  140.                                 $numEmployees += 1;
  141.                             }
  142.                         }
  143. //                    }
  144.                 }
  145.             }
  146.             if ($numEmployees >= ($totalNumEmployees $holidayIncompatibility->getMinNumberEmployees())) {
  147.                 throw new HolidaysAreIncompatibleException(sprintf('1#For the employee %s the holidays are incompatibles, there are other employees with this holidays'$holiday->getEmployee()->getId()), '1');
  148.             }
  149.         }
  150.     }
  151.     public function checkHolidaysInThisPeriod(Holiday $holiday$method)
  152.     {
  153.         $from $holiday->getFromDate();
  154.         $toDate $holiday->getToDate();
  155.         $holidays $this->entityManager->getRepository(Holiday::class)
  156.             ->findHolidaysByEmployeeBetweenDatesAndApproved($holiday->getEmployee(), $holiday->getFromDate(), $holiday->getToDate());
  157.         if ($holidays) {
  158.             $message sprintf('2#For the employee %s has holidays between %s and %s'$holiday->getEmployee()->getId(), $holiday->getFromDate(), $holiday->getToDate());
  159.             throw new HolidaysAreIncompatibleException($message);
  160.         }
  161.     }
  162. }