Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #9 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
109 lines
4.2 KiB
PHP
109 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\State;
|
|
|
|
use ApiPlatform\Metadata\Operation;
|
|
use ApiPlatform\State\ProcessorInterface;
|
|
use App\Entity\Notification;
|
|
use App\Entity\User;
|
|
use App\Entity\WorkHour;
|
|
use App\Repository\UserRepository;
|
|
use App\Repository\WorkHourRepository;
|
|
use App\Security\EmployeeScopeService;
|
|
use App\Service\AuditLogger;
|
|
use DateTimeImmutable;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\SecurityBundle\Security;
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
|
|
final readonly class WorkHourSiteValidationProcessor implements ProcessorInterface
|
|
{
|
|
public function __construct(
|
|
private Security $security,
|
|
private EmployeeScopeService $employeeScopeService,
|
|
private WorkHourRepository $workHourRepository,
|
|
private UserRepository $userRepository,
|
|
private EntityManagerInterface $entityManager,
|
|
private AuditLogger $auditLogger,
|
|
) {}
|
|
|
|
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): WorkHour
|
|
{
|
|
if (!$data instanceof WorkHour) {
|
|
throw new AccessDeniedHttpException('Invalid payload.');
|
|
}
|
|
|
|
$user = $this->security->getUser();
|
|
if (!$user instanceof User) {
|
|
throw new AccessDeniedHttpException('Authentication required.');
|
|
}
|
|
|
|
// Réservé aux profils "Sites" (ni admin, ni self).
|
|
if (in_array('ROLE_ADMIN', $user->getRoles(), true) || in_array('ROLE_SELF', $user->getRoles(), true)) {
|
|
throw new AccessDeniedHttpException('Only site managers can update site validation.');
|
|
}
|
|
|
|
$siteId = $data->getEmployee()?->getSite()?->getId();
|
|
if (!$siteId) {
|
|
throw new AccessDeniedHttpException('Employee site is required.');
|
|
}
|
|
|
|
$allowedSiteIds = $this->employeeScopeService->getAllowedSiteIds($user);
|
|
if (!in_array($siteId, $allowedSiteIds, true)) {
|
|
throw new AccessDeniedHttpException('Employee is outside your site scope.');
|
|
}
|
|
|
|
$uow = $this->entityManager->getUnitOfWork();
|
|
$uow->computeChangeSets();
|
|
$changeSet = $uow->getEntityChangeSet($data);
|
|
$isSiteValidationChangedToTrue = isset($changeSet['isSiteValid'])
|
|
&& false === $changeSet['isSiteValid'][0]
|
|
&& true === $changeSet['isSiteValid'][1];
|
|
|
|
if (isset($changeSet['isSiteValid'])) {
|
|
$employee = $data->getEmployee();
|
|
$empName = $employee ? trim(($employee->getLastName() ?? '').' '.($employee->getFirstName() ?? '')) : '';
|
|
$workDate = $data->getWorkDate();
|
|
$newVal = $changeSet['isSiteValid'][1] ? 'validé' : 'dévalidé';
|
|
|
|
$this->auditLogger->log(
|
|
$employee,
|
|
'site_validate',
|
|
'work_hour',
|
|
$data->getId(),
|
|
sprintf('Validation site %s pour %s le %s', $newVal, $empName, $workDate->format('d/m/Y')),
|
|
['old' => ['isSiteValid' => $changeSet['isSiteValid'][0]], 'new' => ['isSiteValid' => $changeSet['isSiteValid'][1]]],
|
|
$workDate instanceof DateTimeImmutable ? $workDate : DateTimeImmutable::createFromInterface($workDate),
|
|
);
|
|
}
|
|
|
|
$this->entityManager->flush();
|
|
|
|
// Notification uniquement quand la dernière ligne du site est validée pour la date.
|
|
if ($isSiteValidationChangedToTrue) {
|
|
$workDate = $data->getWorkDate();
|
|
$hasPending = $this->workHourRepository->hasPendingSiteValidationForSiteAndDate($siteId, $workDate);
|
|
if (!$hasPending) {
|
|
$message = 'a validé les heures';
|
|
|
|
foreach ($this->userRepository->findAllAdmins() as $admin) {
|
|
$notification = new Notification();
|
|
$notification->setRecipient($admin)
|
|
->setActor($user)
|
|
->setMessage($message)
|
|
->setCategory('Heures')
|
|
->setTarget('/hours')
|
|
;
|
|
$this->entityManager->persist($notification);
|
|
}
|
|
|
|
$this->entityManager->flush();
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
}
|