diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php index 98467a302..315c83cce 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php @@ -11,24 +11,46 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; +use Chill\MainBundle\Audit\TriggerAuditInterface; use Chill\MainBundle\CRUD\Controller\ApiController; +use Chill\MainBundle\Entity\AuditTrail; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Counter; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Validator\ConstraintViolationListInterface; class AccompanyingCourseWorkApiController extends ApiController { public function __construct( private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository, private readonly Security $security, + private readonly TriggerAuditInterface $triggerAudit, ) {} + protected function onAfterFlush(string $action, Request $request, string $_format, $entity, ConstraintViolationListInterface $errors, array $more = []): ?Response + { + if (Request::METHOD_GET === $request->getMethod()) { + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_VIEW, $entity); + } elseif (Request::METHOD_PUT === $request->getMethod() || Request::METHOD_PATCH === $request->getMethod()) { + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_UPDATE, $entity); + } elseif (Request::METHOD_POST === $request->getMethod()) { + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_CREATE, $entity); + } elseif (Request::METHOD_DELETE === $request->getMethod()) { + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_DELETE, $entity); + } else { + throw new \RuntimeException(sprintf('Unsupported HTTP method "%s" for audit trail.', $action)); + } + + return parent::onAfterFlush($action, $request, $_format, $entity, $errors, $more); + } + #[Route(path: '/api/1.0/person/accompanying-period/work/my-near-end')] public function myWorksNearEndDate(Request $request): JsonResponse { diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php index c7d5ecbf9..79dbe53e8 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; -use Chill\MainBundle\Audit\AuditEvent; +use Chill\MainBundle\Audit\TriggerAuditInterface; use Chill\MainBundle\Entity\AuditTrail; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; @@ -23,7 +23,6 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; -use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -46,7 +45,7 @@ final class AccompanyingCourseWorkController extends AbstractController private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, - private readonly EventDispatcherInterface $eventDispatcher, + private readonly TriggerAuditInterface $triggerAudit, ) {} #[Route(path: '{_locale}/person/accompanying-period/{id}/work/new', name: 'chill_person_accompanying_period_work_new', methods: ['GET'])] @@ -70,6 +69,12 @@ final class AccompanyingCourseWorkController extends AbstractController $json = $this->serializer->normalize($period, 'json', ['groups' => ['read']]); + $this->triggerAudit->triggerAudit( + AuditTrail::AUDIT_CREATE, + $period, + metadata: ['action' => 'create_form'] + ); + return $this->render('@ChillPerson/AccompanyingCourseWork/create.html.twig', [ 'accompanyingCourse' => $period, 'json' => $json, @@ -95,6 +100,11 @@ final class AccompanyingCourseWorkController extends AbstractController 'accompanying_period_id' => $work->getAccompanyingPeriod()->getId(), ]); + $this->triggerAudit->triggerAudit( + AuditTrail::AUDIT_DELETE, + $work, + ); + $em->remove($work); $em->flush(); @@ -117,12 +127,18 @@ final class AccompanyingCourseWorkController extends AbstractController } #[Route(path: '{_locale}/person/accompanying-period/work/{id}/edit', name: 'chill_person_accompanying_period_work_edit', methods: ['GET'])] - public function editWork(AccompanyingPeriodWork $work): Response + public function editWork(AccompanyingPeriodWork $work, Request $request): Response { $this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::UPDATE, $work); + $previousVersion = $work->getVersion(); $json = $this->serializer->normalize($work, 'json', ['groups' => ['read']]); + $this->triggerAudit->triggerAudit( + AuditTrail::AUDIT_VIEW, + $work, + ); + return $this->render('@ChillPerson/AccompanyingCourseWork/edit.html.twig', [ 'accompanyingCourse' => $work->getAccompanyingPeriod(), 'work' => $work, @@ -159,13 +175,10 @@ final class AccompanyingCourseWorkController extends AbstractController $paginator->getCurrentPageFirstItemNumber() ); - $this->eventDispatcher->dispatch( - new AuditEvent( - AuditTrail::AUDIT_VIEW, - $period, - description: new TranslatableMessage('accompanying_period.audit.show_list_work'), - metadata: ['action' => 'show_list_work'] - ) + $this->triggerAudit->triggerAudit( + AuditTrail::AUDIT_LIST, + $period, + description: new TranslatableMessage('audit.accompanying_period_work.list'), ); return $this->render('@ChillPerson/AccompanyingCourseWork/index.html.twig', [ @@ -185,11 +198,9 @@ final class AccompanyingCourseWorkController extends AbstractController $this->denyAccessUnlessGranted(AccompanyingPeriodWorkVoter::SEE, $work); - $this->eventDispatcher->dispatch( - new AuditEvent( - AuditTrail::AUDIT_VIEW, - $work, - ) + $this->triggerAudit->triggerAudit( + AuditTrail::AUDIT_VIEW, + $work, ); return $this->render('@ChillPerson/AccompanyingCourseWork/show.html.twig', [ diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 8423f101b..656a7d991 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1588,6 +1588,7 @@ audit: remove_confidential: 'Indique parcours comme non-confidentiel' accompanying_period_work: accompanying_period_work_number: "Action d'accompagnement n°{id}" + list: Liste des actions d'accompagnement d'un parcours person_resource: list: Liste des personnes ressources person_resource_number: "Personne ressource n°{id}: {name}"