From 298065bd416c96508d25c435e9d157fe8d765e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 26 Feb 2026 16:28:46 +0100 Subject: [PATCH] Add audit functionality for `HouseholdComposition` actions - Introduced `HouseholdCompositionDisplayer` and `HouseholdCompositionSubjectConverter` to handle audit display and conversion logic. - Integrated audit triggers for create, view, and delete actions in `HouseholdCompositionController`. - Added French translations for audit-related messages and household composition labels. --- .../HouseholdCompositionDisplayer.php | 56 +++++++++++++++++++ .../HouseholdCompositionSubjectConverter.php | 44 +++++++++++++++ .../HouseholdCompositionController.php | 9 +++ .../translations/messages+intl-icu.fr.yaml | 9 +++ .../translations/messages.fr.yml | 1 + 5 files changed, 119 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Audit/Displayer/HouseholdCompositionDisplayer.php create mode 100644 src/Bundle/ChillPersonBundle/Audit/SubjectConverter/HouseholdCompositionSubjectConverter.php diff --git a/src/Bundle/ChillPersonBundle/Audit/Displayer/HouseholdCompositionDisplayer.php b/src/Bundle/ChillPersonBundle/Audit/Displayer/HouseholdCompositionDisplayer.php new file mode 100644 index 000000000..e6592a8f5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Audit/Displayer/HouseholdCompositionDisplayer.php @@ -0,0 +1,56 @@ +type; + } + + public function display(Subject $subject, string $format = 'html', array $options = []): string + { + $composition = $this->compositionRepository->find($subject->identifiers['id']); + + if (null === $composition) { + $message = $this->translator->trans('audit.household_composition.unknown_composition', [ + 'id' => $subject->identifiers['id'], + ]); + } else { + $message = match (is_null($composition->getEndDate())) { + true => $this->translator->trans('audit.household_composition.display_active', [ + 'id' => $subject->identifiers['id'], + 'from' => $composition->getStartDate(), + ]), + false => $this->translator->trans('audit.household_composition.display', [ + 'id' => $subject->identifiers['id'], + 'from' => $composition->getStartDate(), + 'to' => $composition->getEndDate(), + ]), + }; + } + + if ('html' === $format) { + return ''.$message.''; + } + + return $message; + } +} diff --git a/src/Bundle/ChillPersonBundle/Audit/SubjectConverter/HouseholdCompositionSubjectConverter.php b/src/Bundle/ChillPersonBundle/Audit/SubjectConverter/HouseholdCompositionSubjectConverter.php new file mode 100644 index 000000000..3bb00675e --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Audit/SubjectConverter/HouseholdCompositionSubjectConverter.php @@ -0,0 +1,44 @@ + $subject->getId()])); + + $bag->append($this->subjectConverterManager->getSubjectsForEntity($subject->getHousehold())); + + return $bag; + } + + public function supportsConvert(mixed $subject): bool + { + return $subject instanceof HouseholdComposition; + } + + public static function getDefaultPriority(): int + { + return 0; + } +} diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionController.php index 789adf471..98bef6352 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionController.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; +use Chill\MainBundle\Audit\TriggerAuditInterface; +use Chill\MainBundle\Entity\AuditTrail; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\HouseholdComposition; @@ -30,6 +32,7 @@ use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Translation\TranslatableMessage; use Symfony\Contracts\Translation\TranslatorInterface; class HouseholdCompositionController extends AbstractController @@ -44,6 +47,7 @@ class HouseholdCompositionController extends AbstractController private readonly TranslatorInterface $translator, private readonly \Twig\Environment $engine, private readonly UrlGeneratorInterface $urlGenerator, + private readonly TriggerAuditInterface $triggerAudit, ) {} #[Route(path: '/{_locale}/person/household/{household_id}/composition/{composition_id}/delete', name: 'chill_person_household_composition_delete')] @@ -70,6 +74,7 @@ class HouseholdCompositionController extends AbstractController $form->handleRequest($request); if ($form->isValid()) { + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_DELETE, $composition); $this->entityManager->remove($composition); $this->entityManager->flush(); @@ -99,6 +104,8 @@ class HouseholdCompositionController extends AbstractController throw new AccessDeniedException('not allowed to edit a household'); } + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_VIEW, $household, description: new TranslatableMessage('audit.household.list_composition')); + $count = $this->householdCompositionRepository->countByHousehold($household); $paginator = $this->paginatorFactory->create($count); $compositions = $this->householdCompositionRepository->findByHousehold( @@ -146,6 +153,8 @@ class HouseholdCompositionController extends AbstractController $this->entityManager->flush(); + $this->triggerAudit->triggerAudit(AuditTrail::AUDIT_CREATE, $householdComposition); + $request->getSession()->getFlashBag()->add( 'success', $this->translator->trans('household_composition.Composition added') diff --git a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml index 201157214..5cd84b305 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml +++ b/src/Bundle/ChillPersonBundle/translations/messages+intl-icu.fr.yaml @@ -209,3 +209,12 @@ accompanying_course_evaluation_document: accompanying_period_work: title: Action d'accompagnement (n°{id}) - {action_title} + +audit: + household_composition: + display: >- + Composition n°{id} du {from, date, long} à {to, date, long} + display_active: >- + Composition n°{id} du {from, date, long} (toujours active) + unknown_composition: >- + Composition inconnue avec identifiant {id} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index fe6757ebd..2620e6563 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1597,6 +1597,7 @@ audit: list_person_file: Liste des ménages d'un usager edit_participation: "Modification d'une participation au ménage" household_not_found_with_id: 'Ménage non trouvé avec identifiant {id}' + list_composition: 'Liste des compositions de ménage' household_member: not_found_with_id: 'Membre du ménage non trouvé avec identifiant {id}' member_in_household: 'membre du ménage'