<?php
namespace App\EventSubscriber\CoordinationHour;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Declaration\Staff\DeclarationMonth;
use App\Entity\Declaration\Staff\DeclarationTrimester;
use App\Entity\Declaration\Staff\Line\DeclarationStaffLine;
use App\Entity\Declaration\Staff\Line\DeclarationStaffLineMonth;
use App\Entity\Declaration\Staff\Line\DeclarationStaffLineWeek;
use App\Entity\Diploma\DiplomaLevel;
use App\Entity\Establishment\Establishment;
use App\Entity\Establishment\EstablishmentCoordinationMailed;
use App\Entity\Establishment\EstablishmentDataYear;
use App\Entity\Establishment\EstablishmentStaff;
use App\Entity\Forecast\HourType;
use App\Entity\Staff\Role;
use App\Entity\Staff\StaffPosition;
use App\MailBundle\Entity\Mail;
use App\MailBundle\EventListener\MailListener;
use App\MailBundle\EventListener\ValidationRequest\ValidationRequestEventListener;
use App\MailBundle\MailBundle;
use App\MailBundle\Service\MailSender;
use App\Repository\DeclarationStaffLineRepository;
use App\Repository\DiplomaLevelRepository;
use App\Repository\DiplomaRepository;
use App\Repository\EstablishmentDataYearRepository;
use App\Repository\EstablishmentDiplomaRepository;
use App\Repository\EstablishmentStaffRepository;
use App\Repository\ForecastOnEstablishmentRepository;
use App\Repository\ForecastStaffLineRepository;
use App\Repository\HourTypeRepository;
use App\Repository\StaffRepository;
use App\Security\Voter\Staff\PseudoRoleVoter;
use App\Service\Tools;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
class CoordinationHour90PercentSubscriber extends MailListener implements EventSubscriberInterface
{
public function __construct(
MailSender $mailSender,
Tools $tools,Private EstablishmentStaffRepository $establishmentStaffRepository,
private DeclarationStaffLineRepository $declarationStaffLineRepository,
private EstablishmentDataYearRepository $establishmentDataYearRepository,
private EstablishmentDiplomaRepository $establishmentDiplomaRepository,
private StaffRepository $repositoryStaff,
private EntityManagerInterface $entityManager,
private DiplomaRepository $diplomaRepository,
private DiplomaLevelRepository $diplomaLevelRepository,
)
{
$this->mailSender = $mailSender;
$this->tools = $tools;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['updateCoordination', EventPriorities::POST_WRITE]
];
}
public function updateCoordination(ViewEvent $event)
{
$entity = $event->getControllerResult();
if ($entity instanceof DeclarationStaffLine) {
$request = $event->getRequest();
$method = $request->getMethod();
$hourTypeId = $entity->getForecastStaffLine()->getHourType()->getId();
if ($method != Request::METHOD_PATCH || $hourTypeId != HourType::HEURE_COORDINATION) {
return;
}
else {
$establishmentDiplomaEntity = $entity->getEstablishmentDiploma();
$establishment = $establishmentDiplomaEntity->getEstablishment();
$schoolYear = $entity->getSchoolYear();
$schoolYearId = $schoolYear->getId();
// Nombre d'heures de coordination autorisée par établissement
$establishmentDataYear = $this->establishmentDataYearRepository->findBy(['establishment' => $establishment, 'schoolYear' => $schoolYear]);
$establishmentDataYear = $establishmentDataYear[0];
$nbHourAllowedByEstablishment = $establishmentDataYear->getNbCoordinationHourAuthorized()->getHourAuthorized();
$coordinationMailed = $establishmentDataYear->getCoordinationMailed();
// On récupère tout les diplomes de l'établissement
$allDiplomaByEstablishmentAndSchoolYear = $this->establishmentDiplomaRepository->findBy(['establishment' => $establishment, 'schoolYear' => $schoolYear]);
$allDeclarationEstablishment = 0;
foreach($allDiplomaByEstablishmentAndSchoolYear as $establishmentDiploma){
//somme de toute les declaration de type heure de coordination pour un diplome
$totalHourCoordinationByDiploma = (float)$this->declarationStaffLineRepository->getTotalOfCoordinationHourWorkedByEstablishment($establishmentDiploma);
$allDeclarationEstablishment = $allDeclarationEstablishment + $totalHourCoordinationByDiploma;
}
//On récupère 90% de la prévison
$ninetyPercentForecastHourCoordination = $nbHourAllowedByEstablishment * 0.90;
if ($coordinationMailed !== null){
/* Si une l'établissement à déja été notifié par mail et que sa valeur de l'époque est égale ou supérieur à celle d'aujourd'hui
et que la valeur à deja atteint les 100% on ne fait rien*/
if ($coordinationMailed->getForecastLimit() >= $nbHourAllowedByEstablishment && $coordinationMailed->isHundredPercent())
{
return;
}
/*Si une l'établissement à déja été notifié par mail et que sa valeur de l'époque est égale ou supérieur à celle d'aujourd'hui
mais que les 100% n'ont pas été atteint alors check pour l'envoie de mail des heures totales atteintes*/
elseif ($coordinationMailed->getForecastLimit() >= $nbHourAllowedByEstablishment && !$coordinationMailed->isHundredPercent())
{
if ($allDeclarationEstablishment < $nbHourAllowedByEstablishment)
{
return;
}
else
{
$template = Mail::COORDINATION_HOUR_EXCEEDED_TEMPLATE;
$this->sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request);
$coordinationMailed->setIsHundredPercent(true);
}
}
elseif ($coordinationMailed->getForecastLimit() <= $nbHourAllowedByEstablishment && !$coordinationMailed->isHundredPercent())
{
if ($allDeclarationEstablishment < $nbHourAllowedByEstablishment && $allDeclarationEstablishment > $ninetyPercentForecastHourCoordination)
{
$template = Mail::COORDINATION_90_PERCENT_TEMPLATE;
$this->sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request);
$coordinationMailed->setForecastLimit($nbHourAllowedByEstablishment);
}
if ($allDeclarationEstablishment > $nbHourAllowedByEstablishment)
{
$template = Mail::COORDINATION_HOUR_EXCEEDED_TEMPLATE;
$this->sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request);
$coordinationMailed->setIsHundredPercent(true);
}
return;
}
}
else
{
if($allDeclarationEstablishment >= $ninetyPercentForecastHourCoordination && $allDeclarationEstablishment <= $nbHourAllowedByEstablishment)
{
$template = Mail::COORDINATION_90_PERCENT_TEMPLATE;
$this->sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request);
$establishmentCoordinationMailedEntity = New EstablishmentCoordinationMailed();
$establishmentCoordinationMailedEntity->setEstablishment($establishmentDataYear);
$establishmentCoordinationMailedEntity->setForecastLimit($nbHourAllowedByEstablishment);
$establishmentCoordinationMailedEntity->setIsHundredPercent(false);
$this->entityManager->persist($establishmentCoordinationMailedEntity);
$this->entityManager->flush();
$establishmentDataYear->setCoordinationMailed($establishmentCoordinationMailedEntity);
$this->entityManager->flush();
}
if ($allDeclarationEstablishment >= $ninetyPercentForecastHourCoordination && $allDeclarationEstablishment > $nbHourAllowedByEstablishment)
{
$template = Mail::COORDINATION_HOUR_EXCEEDED_TEMPLATE;
$this->sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request);
$establishmentCoordinationMailedEntity = New EstablishmentCoordinationMailed();
$establishmentCoordinationMailedEntity->setEstablishment($establishmentDataYear);
$establishmentCoordinationMailedEntity->setForecastLimit($nbHourAllowedByEstablishment);
$establishmentCoordinationMailedEntity->setIsHundredPercent(true);
$this->entityManager->persist($establishmentCoordinationMailedEntity);
$this->entityManager->flush();
$establishmentDataYear->setCoordinationMailed($establishmentCoordinationMailedEntity);
$this->entityManager->flush();
}
return;
}
}
}
}
public function getAdminEmails(): array
{
return $this->repositoryStaff->getUserEmailWithRole([Role::ROLE_ADMIN, Role::ROLE_SUPER_ADMIN]);
}
public function getDdfptEmails($establishment): array
{
return $this->repositoryStaff->getUserEmailWithPosition([StaffPosition::DDFPT], $establishment);
}
private function sendMailForCoordination($entity, $template, $establishment, $schoolYear, $request)
{
$querryGetEstablishmentDirectorArray = $this->establishmentStaffRepository->getDirectorEstablishment($establishment, $schoolYear);
$querryGetEstablishmentDirectorCollection = $querryGetEstablishmentDirectorArray[0];
// On récupére les emails des administrateurs et du directeur
if ($querryGetEstablishmentDirectorCollection instanceof EstablishmentStaff) {
$director = $querryGetEstablishmentDirectorCollection->getStaff();
$directorEmail = $director->getEmail();
$adminMailCollection = $this->getAdminEmails();
$ddfptMailCollection = $this->getDdfptEmails($establishment);
$samiraMail = 'service-paie.cfa.academique@ac-besancon.fr';
$data = $this->getBaseTemplateData();
$declarationStaffLineWeek = $request->attributes->get('data');
$declaration = $declarationStaffLineWeek->getDeclaration();
$establishmentDiploma = $declaration->getEstablishmentDiploma();
$diplomaId = $establishmentDiploma->getDiploma()->getid();
$diploma = $this->diplomaRepository->findBy(['id' => $diplomaId]);
$type = $diploma[0]->getLevel()->getLabel();
if ($declaration instanceof DeclarationMonth) {
$declarationType = "declaration-mensuelle";
}
else if ($declaration instanceof DeclarationTrimester) {
$declarationType = "declaration-trimestrielle";
}
else{
return throw new HttpException(500, 'La déclaration doit être de type mensuel ou trimestriel');
}
//email du directeur
$email = [
$directorEmail,
];
foreach ($adminMailCollection as $adminMail) {
array_push($email, $adminMail);
}
foreach ($ddfptMailCollection as $ddfptMail) {
array_push($email, $ddfptMail);
}
array_push($email, $samiraMail);
//informations pour la template du mail
$data['typeOfDiploma'] = $entity->getEstablishmentDiploma()->getDiploma()->getLevel()->getLabel();
$data["diploma"] = $entity->getEstablishmentDiploma()->getDiploma()->getDataOfYear($schoolYear)->getName();
$data["establishment"] = $establishment->getName();
$data['type'] = $type;
// Ajout du l'url pour le bouton
$button_url_root = '/gestion-des-heures/diplomes/' . $establishmentDiploma->getId() . '/' . $declarationType . '/' . $declaration->getId();
$data['button_url'] = $button_url_root;
// envoie du mail pour les utilisateurs concerné
$mail = new Mail(
$template,
$email,
$data,
);
$this->mailSender->sendEmail($mail);
}
}
}