From a63a2f4d9f624186fb1c5849812886512868f4d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?=
Date: Fri, 22 Mar 2024 16:22:01 +0100
Subject: [PATCH 1/4] tag email of user or partner archived #2035
---
migrations/Version20240322123431.php | 30 ++++
.../Back/BackArchivedAccountController.php | 15 +-
.../Back/BackArchivedPartnerController.php | 62 +++++++
src/Controller/Back/PartnerController.php | 7 +-
src/DataFixtures/Files/Partner.yml | 6 +
src/DataFixtures/Files/User.yml | 16 ++
src/DataFixtures/Loader/LoadPartnerData.php | 8 +-
src/DataFixtures/Loader/LoadUserData.php | 8 +-
src/Repository/PartnerRepository.php | 44 +++++
src/Repository/UserRepository.php | 13 ++
src/Service/Sanitizer.php | 5 +
src/Twig/AppExtension.php | 15 ++
templates/back/account/_form.html.twig | 6 +-
templates/back/account/edit.html.twig | 2 +-
templates/back/account/index.html.twig | 4 +-
templates/back/nav_bo.html.twig | 7 +
templates/back/partner/index.html.twig | 2 +-
templates/back/partner/view.html.twig | 2 +-
.../back/partner_archived/index.html.twig | 162 ++++++++++++++++++
.../BackArchivedPartnerControllerTest.php | 63 +++++++
.../BackArchivedAccountControllerTest.php | 55 +++++-
.../Controller/CartographieControllerTest.php | 2 +-
.../Controller/PartnerControllerTest.php | 5 +
.../SignalementListControllerTest.php | 2 +-
.../Token/ActivationTokenGeneratorTest.php | 4 +-
25 files changed, 528 insertions(+), 17 deletions(-)
create mode 100644 migrations/Version20240322123431.php
create mode 100755 src/Controller/Back/BackArchivedPartnerController.php
create mode 100755 templates/back/partner_archived/index.html.twig
create mode 100644 tests/Functional/Controller/Back/BackArchivedPartnerControllerTest.php
diff --git a/migrations/Version20240322123431.php b/migrations/Version20240322123431.php
new file mode 100644
index 000000000..0bb468111
--- /dev/null
+++ b/migrations/Version20240322123431.php
@@ -0,0 +1,30 @@
+addSql(
+ "UPDATE partner SET email = CONCAT(email, '.archived@', DATE_FORMAT(NOW(), '%Y%m%d%H%i')) WHERE is_archive = 1"
+ );
+ $this->addSql(
+ "UPDATE user SET email = CONCAT(email, '.archived@', DATE_FORMAT(NOW(), '%Y%m%d%H%i')) WHERE statut = 2"
+ );
+ }
+
+ public function down(Schema $schema): void
+ {
+ }
+}
diff --git a/src/Controller/Back/BackArchivedAccountController.php b/src/Controller/Back/BackArchivedAccountController.php
index f950a653c..fd5239f91 100755
--- a/src/Controller/Back/BackArchivedAccountController.php
+++ b/src/Controller/Back/BackArchivedAccountController.php
@@ -87,6 +87,7 @@ public function reactiver(
User $user,
TerritoryRepository $territoryRepository,
PartnerRepository $partnerRepository,
+ UserRepository $userRepository,
EntityManagerInterface $entityManager,
NotificationMailerRegistry $notificationMailerRegistry,
): Response {
@@ -101,8 +102,20 @@ public function reactiver(
]);
$form->handleRequest($request);
- if ($form->isSubmitted() && $form->isValid()) {
+ $untaggedEmail = explode('.archived@', $user->getEmail())[0];
+ $userExist = $userRepository->findOneBy(['email' => $untaggedEmail]);
+ if ($userExist && !\in_array('ROLE_USAGER', $userExist->getRoles())) {
+ $this->addFlash('error', 'Un utilisateur existe déjà avec cette adresse e-mail.');
+ }
+
+ $partnerExist = $partnerRepository->findOneBy(['email' => $untaggedEmail]);
+ if ($partnerExist) {
+ $this->addFlash('error', 'Un partenaire existe déjà avec cette adresse e-mail.');
+ }
+
+ if (!$userExist && !$partnerExist && $form->isSubmitted() && $form->isValid()) {
$user->setStatut(User::STATUS_ACTIVE);
+ $user->setEmail($untaggedEmail);
$entityManager->flush();
$this->addFlash('success', 'Réactivation du compte effectuée.');
diff --git a/src/Controller/Back/BackArchivedPartnerController.php b/src/Controller/Back/BackArchivedPartnerController.php
new file mode 100755
index 000000000..5075b2265
--- /dev/null
+++ b/src/Controller/Back/BackArchivedPartnerController.php
@@ -0,0 +1,62 @@
+get('page') ?? 1;
+
+ $isNoneTerritory = 'none' == $request->get('territory');
+ $currentTerritory = $isNoneTerritory ? null : $territoryRepository->find((int) $request->get('territory'));
+ $partnerTerms = $request->get('partnerTerms');
+
+ $paginatedArchivedPartners = $partnerRepository->findAllArchivedOrWithoutTerritory(
+ territory: $currentTerritory,
+ isNoneTerritory: $isNoneTerritory,
+ filterTerms: $partnerTerms,
+ page: (int) $page
+ );
+
+ if ($request->isMethod(Request::METHOD_POST)) {
+ $isNoneTerritory = 'none' == $request->request->get('territory');
+ $currentTerritory = $territoryRepository->find((int) $request->request->get('territory'));
+ $partnerTerms = $request->request->get('bo-filters-partnerterms');
+
+ return $this->redirect($this->generateUrl('back_archived_partner_index', [
+ 'page' => 1,
+ 'territory' => $isNoneTerritory ? 'none' : $currentTerritory?->getId(),
+ 'partnerTerms' => $partnerTerms,
+ ]));
+ }
+
+ $totalArchivedPartners = \count($paginatedArchivedPartners);
+
+ return $this->render('back/partner_archived/index.html.twig', [
+ 'isNoneTerritory' => $isNoneTerritory,
+ 'currentTerritory' => $currentTerritory,
+ 'partnerTerms' => $partnerTerms,
+ 'territories' => $territoryRepository->findAllList(),
+ 'partners' => $paginatedArchivedPartners,
+ 'total' => $totalArchivedPartners,
+ 'page' => $page,
+ 'pages' => (int) ceil($totalArchivedPartners / User::MAX_LIST_PAGINATION),
+ ]);
+ }
+}
diff --git a/src/Controller/Back/PartnerController.php b/src/Controller/Back/PartnerController.php
index 6974f36f6..f4f052817 100755
--- a/src/Controller/Back/PartnerController.php
+++ b/src/Controller/Back/PartnerController.php
@@ -20,6 +20,7 @@
use App\Service\Mailer\NotificationMail;
use App\Service\Mailer\NotificationMailerRegistry;
use App\Service\Mailer\NotificationMailerType;
+use App\Service\Sanitizer;
use App\Service\Signalement\VisiteNotifier;
use Doctrine\ORM\EntityManagerInterface;
use Egulias\EmailValidator\EmailValidator;
@@ -248,8 +249,12 @@ public function delete(
$partner
&& $this->isCsrfTokenValid('partner_delete', $request->request->get('_token'))
) {
+ if (null !== $partner->getEmail()) {
+ $partner->setEmail(Sanitizer::tagArchivedEmail($partner->getEmail()));
+ }
$partner->setIsArchive(true);
foreach ($partner->getUsers() as $user) {
+ $user->setEmail(Sanitizer::tagArchivedEmail($user->getEmail()));
$user->setStatut(User::STATUS_ARCHIVE);
$entityManager->persist($user);
$notificationMailerRegistry->send(
@@ -490,7 +495,7 @@ public function deleteUser(
/** @var User $user */
$user = $userManager->find($userId);
$this->denyAccessUnlessGranted('USER_DELETE', $user);
-
+ $user->setEmail(Sanitizer::tagArchivedEmail($user->getEmail()));
$user->setStatut(User::STATUS_ARCHIVE);
$userManager->save($user);
$notificationMailerRegistry->send(
diff --git a/src/DataFixtures/Files/Partner.yml b/src/DataFixtures/Files/Partner.yml
index 14cdd81fc..9ec6bdef7 100644
--- a/src/DataFixtures/Files/Partner.yml
+++ b/src/DataFixtures/Files/Partner.yml
@@ -50,6 +50,12 @@ partners:
is_esabora_active: 1
type: "ARS"
competence: "VISITES"
+ -
+ nom: "Partenaire 13-07"
+ email: "partenaire-13-07@histologe.fr"
+ is_archive: 1
+ territory: "Bouches-du-Rhône"
+ type: "AUTRE"
-
nom: "Partenaire 01-01"
email: "partenaire-01-01@histologe.fr"
diff --git a/src/DataFixtures/Files/User.yml b/src/DataFixtures/Files/User.yml
index 4cffc31a2..d5c7a3342 100644
--- a/src/DataFixtures/Files/User.yml
+++ b/src/DataFixtures/Files/User.yml
@@ -193,6 +193,14 @@ users:
is_generique: 0
is_mailing_active: 1
territory: "Bouches-du-Rhône"
+ -
+ email: user-13-07@histologe.fr
+ roles: "[\"ROLE_USER_PARTNER\"]"
+ partner: "Partenaire 13-07"
+ statut: 2
+ is_generique: 0
+ is_mailing_active: 1
+ territory: "Bouches-du-Rhône"
-
email: user-2A-01@histologe.fr
roles: "[\"ROLE_USER_PARTNER\"]"
@@ -258,6 +266,14 @@ users:
is_generique: 0
is_mailing_active: 0
territory: "Ain"
+ -
+ email: user-01-06@histologe.fr
+ roles: "[\"ROLE_USER_PARTNER\"]"
+ partner: "Partenaire 01-03-ARCHIVE"
+ statut: 2
+ is_generique: 0
+ is_mailing_active: 0
+ territory: "Ain"
-
email: user-01-07@histologe.fr
roles: "[\"ROLE_USER_PARTNER\"]"
diff --git a/src/DataFixtures/Loader/LoadPartnerData.php b/src/DataFixtures/Loader/LoadPartnerData.php
index 0e44a877b..47c3d392e 100644
--- a/src/DataFixtures/Loader/LoadPartnerData.php
+++ b/src/DataFixtures/Loader/LoadPartnerData.php
@@ -6,6 +6,7 @@
use App\Entity\Enum\Qualification;
use App\Entity\Partner;
use App\Repository\TerritoryRepository;
+use App\Service\Sanitizer;
use App\Service\Token\TokenGeneratorInterface;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
@@ -33,10 +34,15 @@ public function loadPartner(ObjectManager $manager, array $row): void
{
$partner = (new Partner())
->setNom($row['nom'])
- ->setEmail($row['email'] ?? null)
->setIsArchive($row['is_archive'])
->setIsEsaboraActive($row['is_esabora_active'] ?? false);
+ if ($row['is_archive'] && null !== $row['email']) {
+ $partner->setEmail(Sanitizer::tagArchivedEmail($row['email']));
+ } else {
+ $partner->setEmail($row['email'] ?? null);
+ }
+
if (isset($row['insee'])) {
$partner->setInsee(json_decode($row['insee'], true));
}
diff --git a/src/DataFixtures/Loader/LoadUserData.php b/src/DataFixtures/Loader/LoadUserData.php
index 19311c5ce..c44e9988f 100644
--- a/src/DataFixtures/Loader/LoadUserData.php
+++ b/src/DataFixtures/Loader/LoadUserData.php
@@ -7,6 +7,7 @@
use App\Factory\UserFactory;
use App\Repository\PartnerRepository;
use App\Repository\TerritoryRepository;
+use App\Service\Sanitizer;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\ORM\EntityManagerInterface;
@@ -55,10 +56,15 @@ private function loadUsers(ObjectManager $manager, array $row): void
->setRoles(json_decode($row['roles'], true))
->setStatut($row['statut'])
->setIsMailingActive($row['is_mailing_active'])
- ->setEmail($row['email'])
->setPrenom($faker->firstName())
->setNom($faker->lastName());
+ if (User::STATUS_ARCHIVE === $row['statut']) {
+ $user->setEmail(Sanitizer::tagArchivedEmail($row['email']));
+ } else {
+ $user->setEmail($row['email']);
+ }
+
if (isset($row['territory'])) {
$user->setTerritory($this->territoryRepository->findOneBy(['name' => $row['territory']]));
}
diff --git a/src/Repository/PartnerRepository.php b/src/Repository/PartnerRepository.php
index 93fda053b..c2537eab9 100755
--- a/src/Repository/PartnerRepository.php
+++ b/src/Repository/PartnerRepository.php
@@ -99,6 +99,50 @@ public function findAllWithoutTerritory()
->getResult();
}
+ public function findAllArchivedOrWithoutTerritory(
+ Territory|null $territory,
+ bool $isNoneTerritory,
+ ?string $filterTerms,
+ $page
+ ): Paginator {
+ $maxResult = Partner::MAX_LIST_PAGINATION;
+ $firstResult = ($page - 1) * $maxResult;
+ $queryBuilder = $this->createQueryBuilder('p');
+
+ if ($isNoneTerritory) {
+ if ($isNoneTerritory) {
+ $queryBuilder
+ ->where('p.territory IS NULL');
+ }
+ } else {
+ $builtOrCondition = '';
+ if (empty($territory)) {
+ $builtOrCondition .= ' OR p.territory IS NULL';
+ }
+
+ $queryBuilder
+ ->where('p.isArchive = 1'.$builtOrCondition);
+
+ if (!empty($territory)) {
+ $queryBuilder
+ ->andWhere('p.territory = :territory')
+ ->setParameter('territory', $territory);
+ }
+ }
+
+ if (!empty($filterTerms)) {
+ $queryBuilder
+ ->andWhere('LOWER(p.nom) LIKE :usersterms
+ OR LOWER(p.email) LIKE :usersterms');
+ $queryBuilder
+ ->setParameter('usersterms', '%'.strtolower($filterTerms).'%');
+ }
+
+ $queryBuilder->setFirstResult($firstResult)->setMaxResults($maxResult);
+
+ return new Paginator($queryBuilder->getQuery(), false);
+ }
+
public function findAutoAssignable(string $codeInsee, PartnerType $partnerType): ?array
{
if (empty($codeInsee)) {
diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php
index 46108ad64..38896a432 100755
--- a/src/Repository/UserRepository.php
+++ b/src/Repository/UserRepository.php
@@ -55,6 +55,19 @@ public function findActiveAdmins(): ?array
->getResult();
}
+ public function findArchivedUserByEmail(string $email): ?User
+ {
+ $queryBuilder = $this->createQueryBuilder('u');
+
+ return $queryBuilder
+ ->andWhere('u.email LIKE :email')
+ ->setParameter('email', '%'.$email.'%')
+ ->andWhere('u.statut LIKE :archived')
+ ->setParameter('archived', User::STATUS_ARCHIVE)
+ ->getQuery()
+ ->getOneOrNullResult();
+ }
+
public function findActiveTerritoryAdmins(?Territory $territory, ?string $inseeOccupant): ?array
{
if (empty($territory)) {
diff --git a/src/Service/Sanitizer.php b/src/Service/Sanitizer.php
index 77cd7f5d5..358d3c7e6 100644
--- a/src/Service/Sanitizer.php
+++ b/src/Service/Sanitizer.php
@@ -10,4 +10,9 @@ public static function sanitize($text): string
return str_replace('
', '
', $textSanitized); // Replace the end
}
+
+ public static function tagArchivedEmail(string $email): string
+ {
+ return $email.'.archived@'.(new \DateTimeImmutable())->format('YmdHi');
+ }
}
diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php
index 2ff9f9fb4..418788afe 100644
--- a/src/Twig/AppExtension.php
+++ b/src/Twig/AppExtension.php
@@ -22,6 +22,7 @@ public function getFilters(): array
new TwigFilter('signalement_lien_declarant_occupant', [$this, 'getLabelLienDeclarantOccupant']),
new TwigFilter('image64', [ImageBase64Encoder::class, 'encode']),
new TwigFilter('truncate_filename', [$this, 'getTruncatedFilename']),
+ new TwigFilter('clean_tagged_text', [$this, 'cleanTaggedText']),
];
}
@@ -76,4 +77,18 @@ public function getFunctions(): array
new TwigFunction('show_label_facultatif', [AttributeParser::class, 'showLabelAsFacultatif']),
];
}
+
+ public function cleanTaggedText(string $taggedText, string $tag, string $direction): string
+ {
+ $parts = explode($tag, $taggedText);
+
+ switch ($direction) {
+ case 'left':
+ return $parts[0];
+ case 'right':
+ return $parts[1];
+ default:
+ return $taggedText;
+ }
+ }
}
diff --git a/templates/back/account/_form.html.twig b/templates/back/account/_form.html.twig
index e32baa7e0..e268c6d45 100755
--- a/templates/back/account/_form.html.twig
+++ b/templates/back/account/_form.html.twig
@@ -1,13 +1,15 @@
{{ form_start(form,{attr:{'class':'needs-validation','novalidate':true}}) }}