diff --git a/config/domain/notification/translations/messages.fr.yaml b/config/domain/notification/translations/messages.fr.yaml index ac9aebaf424a5e810d5769eea70f777481f4ca91..f151f087cd0da778a6fdfa2fa428e9b38df6a79c 100644 --- a/config/domain/notification/translations/messages.fr.yaml +++ b/config/domain/notification/translations/messages.fr.yaml @@ -8,6 +8,7 @@ notifications: proof: Preuves document: Espace documentaire action: Actions de protection + action_plan: Plan d'actions protect_action: Actions de protection request: Demandes user: Utilisateurs @@ -17,13 +18,13 @@ notifications: delete: Suppression create: Création update: Modification - late_action: En retard - late_request: En retard - late_survey: En retard + late_action: Rappel automatique + late_request: Rappel automatique + late_survey: Rappel automatique no_login: Inactif validation: Validation treatment_needs_aipd: Nécéssité de faire une AIPD - state_change: Changement d'état + state_change: Changement d'étape subject: no_login: Aucune connexion depuis la création du compte late_request: Demande non traitée depuis au moins %days% jours depuis la date de la dernière modification @@ -44,9 +45,10 @@ notification: subcontractor: Sous-traitants violation: Violations proof: Preuves - document: Document + document: Espace documentaire action: Actions de protection protect_action: Actions de protection + action_plan: Plan d'actions request: Demandes user: Utilisateurs documentation: Documentation @@ -56,13 +58,13 @@ notification: delete: Suppression create: Création update: Modification - late_action: En retard - late_request: En retard - late_survey: En retard + late_action: Rappel automatique + late_request: Rappel automatique + late_survey: Rappel automatique no_login: Inactif validation: Validation treatment_needs_aipd: Nécéssité de faire une AIPD - state_change: Changement d'état + state_change: Changement d'étape email: subject: Nouvelles notifications Madis madis: Accéder à madis diff --git a/config/services.yaml b/config/services.yaml index 3ce290969b44b0df0d5566f78fce2d6576f036a2..d497034f071861a120332e41a6714b24193ed36d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -66,8 +66,22 @@ services: $normalizer: '@App\Domain\Notification\Serializer\NotificationNormalizer' $userRepository: '@App\Domain\User\Repository\User' $security: '@Symfony\Component\Security\Core\Security' + $translator: '@Symfony\Contracts\Translation\TranslatorInterface' + $requestDays: '%env(APP_REQUEST_NOTIFICATION_DELAY_DAYS)%' + $surveyDays: '%env(APP_SURVEY_NOTIFICATION_DELAY_DAYS)%' tags: [ { name: doctrine.event_subscriber } ] + App\Domain\Notification\Subscriber\NotificationEventSubscriber: + arguments: + $notificationRepository: '@App\Infrastructure\ORM\Notification\Repository\Notification' + $notificationUserRepository: '@App\Infrastructure\ORM\Notification\Repository\NotificationUser' + $normalizer: '@App\Domain\Notification\Serializer\NotificationNormalizer' + $userRepository: '@App\Domain\User\Repository\User' + $translator: '@Symfony\Contracts\Translation\TranslatorInterface' + $requestDays: '%env(APP_REQUEST_NOTIFICATION_DELAY_DAYS)%' + $surveyDays: '%env(APP_SURVEY_NOTIFICATION_DELAY_DAYS)%' + tags: [ { name: event_subscriber } ] + App\Domain\Notification\Twig\Extension\NotificationExtension: arguments: $translator: '@translator' diff --git a/migrations/Version20230406121754.php b/migrations/Version20230406121754.php new file mode 100644 index 0000000000000000000000000000000000000000..2164af56be449ed561a35cbb1d496903a25c9e4b --- /dev/null +++ b/migrations/Version20230406121754.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20230406121754 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + $this->addSql('ALTER TABLE notification ADD subject LONGTEXT DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + $this->addSql('ALTER TABLE notification DROP subject'); + } +} diff --git a/src/Application/Controller/CRUDController.php b/src/Application/Controller/CRUDController.php index 213b121b14fd515dff09fda12477ad1f97f7f099..1c70b3197744ff35f451582ac541e89c84276c77 100644 --- a/src/Application/Controller/CRUDController.php +++ b/src/Application/Controller/CRUDController.php @@ -247,7 +247,7 @@ abstract class CRUDController extends AbstractController */ public function editAction(Request $request, string $id): Response { -// /** @var CollectivityRelated $object */ + // /** @var CollectivityRelated $object */ $object = $this->repository->findOneById($id); if (!$object) { throw new NotFoundHttpException("No object found with ID '{$id}'"); diff --git a/src/Domain/AIPD/Converter/ModeleToAnalyseConverter.php b/src/Domain/AIPD/Converter/ModeleToAnalyseConverter.php index 99b23f6f9be2af858cc22cdb3e6df8b1eb5b7d59..c9c1de0a02c65f51be458f2684f7b3567e03738e 100644 --- a/src/Domain/AIPD/Converter/ModeleToAnalyseConverter.php +++ b/src/Domain/AIPD/Converter/ModeleToAnalyseConverter.php @@ -102,7 +102,7 @@ class ModeleToAnalyseConverter } } } -// $scenario->setMesuresProtections(self::convertMesuresProtections($scenarioModele, $scenario, $analyseImpact)); + // $scenario->setMesuresProtections(self::convertMesuresProtections($scenarioModele, $scenario, $analyseImpact)); if ($scenarioModele->isDisponibilite() || $scenarioModele->isIntegrite() || $scenarioModele->isConfidentialite()) { $scenario->setCanDicBeModified(false); } else { @@ -127,7 +127,7 @@ class ModeleToAnalyseConverter $analyseMesure->setPoidsVraisemblance($mesureProtection->getPoidsVraisemblance()); $analyseMesure->setPoidsGravite($mesureProtection->getPoidsGravite()); -// $analyseMesure->setScenarioMenace($analyseScenarioMenace); + // $analyseMesure->setScenarioMenace($analyseScenarioMenace); $analyseMesure->setOriginId($mesureProtection->getId()->toString()); $analyseMesure->setAnalyseImpact($analyseImpact); diff --git a/src/Domain/Notification/Command/NotificationsGenerateCommand.php b/src/Domain/Notification/Command/NotificationsGenerateCommand.php index 42bbbc0271282d0011cea785e5d44f48f442b9a4..ec167b7b2f8dafd2acd773b7b9ad6f44a6650dba 100644 --- a/src/Domain/Notification/Command/NotificationsGenerateCommand.php +++ b/src/Domain/Notification/Command/NotificationsGenerateCommand.php @@ -103,7 +103,7 @@ class NotificationsGenerateCommand extends Command if ($action->getPlanificationDate() && $action->getPlanificationDate() < $now) { $this->dispatcher->dispatch(new LateActionEvent($action)); ++$cnt; -// $this->io->writeln('late action count so far: ' . $cnt); + // $this->io->writeln('late action count so far: ' . $cnt); } } @@ -117,7 +117,7 @@ class NotificationsGenerateCommand extends Command foreach ($requests as $request) { $this->dispatcher->dispatch(new LateRequestEvent($request)); ++$cnt; -// $this->io->writeln('late request count so far: ' . $cnt); + // $this->io->writeln('late request count so far: ' . $cnt); } return $cnt; @@ -132,7 +132,7 @@ class NotificationsGenerateCommand extends Command foreach ($surveys as $survey) { $this->dispatcher->dispatch(new LateSurveyEvent($survey)); ++$cnt; -// $this->io->writeln('late survey count so far: ' . $cnt); + // $this->io->writeln('late survey count so far: ' . $cnt); } return $cnt; @@ -146,7 +146,7 @@ class NotificationsGenerateCommand extends Command foreach ($users as $user) { ++$cnt; $this->dispatcher->dispatch(new NoLoginEvent($user)); -// $this->io->writeln('No login count so far: ' . $cnt); + // $this->io->writeln('No login count so far: ' . $cnt); } return $cnt; @@ -163,7 +163,7 @@ class NotificationsGenerateCommand extends Command && null === $conformite->getLastAnalyseImpact() && $this->getCritereValid($conformite)) { ++$cnt; $this->dispatcher->dispatch(new ConformiteTraitementNeedsAIPDEvent($conformite)); -// $this->io->writeln('treatment needs AIPD count so far: ' . $cnt); + // $this->io->writeln('treatment needs AIPD count so far: ' . $cnt); } } diff --git a/src/Domain/Notification/Controller/NotificationController.php b/src/Domain/Notification/Controller/NotificationController.php index 9fcea3fe53d435c61ab974a562b80bc5b510da07..f7bd7eb6a6c303ba5cd0f4e8b2a853d2b296d40d 100644 --- a/src/Domain/Notification/Controller/NotificationController.php +++ b/src/Domain/Notification/Controller/NotificationController.php @@ -30,10 +30,9 @@ use App\Application\Traits\ServersideDatatablesTrait; use App\Domain\Notification\Model; use App\Domain\Notification\Model\Notification; use App\Domain\Notification\Repository; -use App\Domain\Registry\Dictionary\ProofTypeDictionary; -use App\Domain\Registry\Dictionary\ViolationNatureDictionary; use App\Domain\User\Dictionary\UserMoreInfoDictionary; use App\Domain\User\Dictionary\UserRoleDictionary; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\Pagination\Paginator; use Knp\Snappy\Pdf; @@ -152,8 +151,8 @@ class NotificationController extends CRUDController $criteria = []; - if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) { - $criteria['collectivity'] = $user->getCollectivity(); + if (!$this->authorizationChecker->isGranted('ROLE_REFERENT')) { + $criteria['collectivity'] = new ArrayCollection([$user->getCollectivity(), null]); } if ($user) { @@ -176,7 +175,7 @@ class NotificationController extends CRUDController $nameHtml = '<span>' . $notification->getName() . '</span> '; - if ($link && 'notification.actions.delete' !== $notification->getAction()) { + if ($link && 'notification.actions.delete' !== $notification->getAction() && $this->repository->objectExists($notification)) { $nameHtml = '<a href="' . $link . '">' . $notification->getName() . '</a>' ; } @@ -187,7 +186,7 @@ class NotificationController extends CRUDController 'module' => $this->translator->trans($notification->getModule()), 'action' => $this->translator->trans($notification->getAction()), 'name' => $nameHtml, - 'object' => $this->getSubjectForNotification($notification), + 'object' => $notification->getSubject(), 'collectivity' => $this->authorizationChecker->isGranted('ROLE_REFERENT') && $notification->getCollectivity() ? $notification->getCollectivity()->getName() : '', 'date' => date_format($notification->getCreatedAt(), 'd-m-Y H:i:s'), 'user' => $notification->getCreatedBy() ? $notification->getCreatedBy()->__toString() : '', @@ -205,7 +204,7 @@ class NotificationController extends CRUDController 'module' => $this->translator->trans($notification->getModule()), 'action' => $this->translator->trans($notification->getAction()), 'name' => $nameHtml, - 'object' => $this->getSubjectForNotification($notification), + 'object' => $notification->getSubject(), 'date' => date_format($notification->getCreatedAt(), 'd-m-Y H:i:s'), 'user' => $notification->getCreatedBy() ? $notification->getCreatedBy()->__toString() : '', 'actions' => $this->generateActionCellContent($notification), @@ -216,69 +215,6 @@ class NotificationController extends CRUDController return new JsonResponse($reponse); } - private function getSubjectForNotification(Notification $notification): string - { - if ( - 'notification.modules.violation' === $notification->getModule() - ) { - $ob = $notification->getObject(); - if (isset($ob->violationNatures) && is_array($ob->violationNatures) && count($ob->violationNatures) > 0) { - return join(', ', array_map(function ($v) { - return ViolationNatureDictionary::getNatures()[$v] ?? ''; - }, $ob->violationNatures)); - } elseif (isset($ob->violationNature)) { - return ViolationNatureDictionary::getNatures()[$ob->violationNature] ?? ''; - } - - return ''; - } - - if ( - 'notification.modules.proof' === $notification->getModule() - ) { - $type = $notification->getObject()->type; - - return $type && isset(ProofTypeDictionary::getTypes()[$type]) ? ProofTypeDictionary::getTypes()[$type] : ''; - } - - if ('notifications.actions.no_login' === $notification->getAction()) { - return $this->translator->trans('notifications.subject.no_login'); - } - - if ('notifications.actions.state_change' === $notification->getAction()) { - return $notification->getObject()->state; - } - - if ('notifications.actions.late_survey' === $notification->getAction()) { - $days = $this->getParameter('APP_SURVEY_NOTIFICATION_DELAY_DAYS'); - - return $this->translator->trans('notifications.subject.late_survey', ['%days%' => $days]); - } - - if ('notifications.actions.protect_action' === $notification->getAction()) { - return $notification->getObject()->getStatus(); - } - - if ('notifications.actions.late_action' === $notification->getAction()) { - $ob = $notification->getObject(); - $date = \DateTime::createFromFormat(DATE_ATOM, $ob->planificationDate)->format('d/m/Y'); - - return $this->translator->trans('notifications.subject.late_action', ['%date%' => $date]); - } - - if ('notifications.actions.validation' === $notification->getAction()) { - return $this->translator->trans('notifications.subject.validation'); - } - - if ('notifications.actions.late_request' === $notification->getAction()) { - $days = $this->getParameter('APP_REQUEST_NOTIFICATION_DELAY_DAYS'); - - return $this->translator->trans('notifications.subject.late_request', ['%days%' => $days]); - } - - return ''; - } - private function generateActionCellContent(Model\Notification $notification) { $id = $notification->getId(); @@ -465,6 +401,19 @@ class NotificationController extends CRUDController private function getObjectLink(Notification $notification): string { try { + if ('notification.modules.aipd' === $notification->getModule() && 'notification.actions.validation' === $notification->getAction()) { + return $this->router->generate('aipd_analyse_impact_validation', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + if ('notification.modules.aipd' === $notification->getModule() && 'notification.actions.state_change' === $notification->getAction()) { + return $this->router->generate('aipd_analyse_impact_evaluation', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + if ('notification.modules.document' === $notification->getModule() && 'notification.actions.delete' !== $notification->getAction()) { + return $notification->getObject()->url; + } + if ('notification.modules.action_plan' === $notification->getModule()) { + return $this->router->generate('registry_mesurement_show', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + return $this->router->generate($this->getRouteForModule($notification->getModule()), ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); } catch (\Exception $e) { return ''; @@ -518,7 +467,7 @@ class NotificationController extends CRUDController return 'user_user_edit'; case 'notification.modules.documentation': case 'notification.modules.document': - return 'documentation_document_edit'; + return 'documentation_document_download'; case 'notification.modules.maturity': return 'maturity_survey_edit'; } diff --git a/src/Domain/Notification/Dictionary/NotificationActionDictionary.php b/src/Domain/Notification/Dictionary/NotificationActionDictionary.php index fd85dc1b1fae643aa5acde68ce92c31afdc82d6d..62fc203362c7e53e41b94011305505337b147e86 100644 --- a/src/Domain/Notification/Dictionary/NotificationActionDictionary.php +++ b/src/Domain/Notification/Dictionary/NotificationActionDictionary.php @@ -33,7 +33,7 @@ class NotificationActionDictionary extends SimpleDictionary public const EDIT = 'edit'; public const DELETE = 'delete'; public const LATE = 'late'; - public const LATE_ACTION = 'late_action'; + public const AUTOMATIC = 'automatic'; public const LATE_SURVEY = 'late_survey'; public const NO_LOGIN = 'no_login'; public const VALIDATION = 'validation'; @@ -53,15 +53,14 @@ class NotificationActionDictionary extends SimpleDictionary public static function getActions() { return [ - self::CREATE => 'Création', self::ADD => 'Ajout', + self::CREATE => 'Création', self::EDIT => 'Modification', + self::STATE_CHANGE => 'Changement d\'étape', + self::TREATMENT_NEEDS_AIPD => 'AIPD nécéssaire', + self::VALIDATION => 'Validation nécéssaire', self::DELETE => 'Suppression', - self::LATE_ACTION => 'Action de protection en retard (automatique)', - self::LATE_SURVEY => 'Indice de maturité en retard (automatique)', - self::TREATMENT_NEEDS_AIPD => 'Nécéssité de faire une AIPD', - self::NO_LOGIN => 'Utilisateur inactif', - self::STATE_CHANGE => 'Changement d\'état', + self::AUTOMATIC => 'Rappel automatique', ]; } diff --git a/src/Domain/Notification/Dictionary/NotificationActionUserDictionary.php b/src/Domain/Notification/Dictionary/NotificationActionUserDictionary.php new file mode 100644 index 0000000000000000000000000000000000000000..ac338faa5d2200c7ef0c07dbd1b065a4bc6dc170 --- /dev/null +++ b/src/Domain/Notification/Dictionary/NotificationActionUserDictionary.php @@ -0,0 +1,67 @@ +<?php + +/** + * This file is part of the MADIS - RGPD Management application. + * + * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes + * @author Donovan Bourlard <donovan@awkan.fr> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace App\Domain\Notification\Dictionary; + +use App\Application\Dictionary\SimpleDictionary; + +class NotificationActionUserDictionary extends SimpleDictionary +{ + public const ADD = 'add'; + public const AUTOMATIC = 'automatic'; + public const LATE_SURVEY = 'late_survey'; + public const NO_LOGIN = 'no_login'; + public const VALIDATION = 'validation'; + public const TREATMENT_NEEDS_AIPD = 'treatment_needs_aipd'; + + public function __construct() + { + parent::__construct('notificationActionUser', self::getActions()); + } + + /** + * Get an array of Roles. + * + * @return array + */ + public static function getActions() + { + return [ + self::ADD => 'Ajout', + self::TREATMENT_NEEDS_AIPD => 'AIPD nécéssaire', + self::VALIDATION => 'Validation nécéssaire', + self::AUTOMATIC => 'Rappel automatique', + ]; + } + + /** + * Get keys of the Roles array. + * + * @return array + */ + public static function getFrequenciesKeys() + { + return \array_keys(self::getActions()); + } +} diff --git a/src/Domain/Notification/Dictionary/NotificationModuleDictionary.php b/src/Domain/Notification/Dictionary/NotificationModuleDictionary.php index 04af083c7ead7861eec4ba8cf2971380fcf0ff18..5aa1595f04e784164322e457e3e2b73ff95b2c1b 100644 --- a/src/Domain/Notification/Dictionary/NotificationModuleDictionary.php +++ b/src/Domain/Notification/Dictionary/NotificationModuleDictionary.php @@ -37,9 +37,12 @@ use App\Domain\Registry\Model\Proof; use App\Domain\Registry\Model\Request; use App\Domain\Registry\Model\Treatment; use App\Domain\Registry\Model\Violation; +use App\Domain\User\Model\User; class NotificationModuleDictionary extends SimpleDictionary { + public const ACTION_PLAN = 'action_plan'; + public function __construct() { parent::__construct('notificationModule', self::getModules()); @@ -53,18 +56,19 @@ class NotificationModuleDictionary extends SimpleDictionary public static function getModules() { return [ - Notification::MODULES[Treatment::class] => 'Traitement', - Notification::MODULES[Contractor::class] => 'Sous-traitant', - Notification::MODULES[Request::class] => 'Demande', - Notification::MODULES[Violation::class] => 'Violation', - Notification::MODULES[Proof::class] => 'Preuve', - Notification::MODULES[Mesurement::class] => 'Action de protection', - Notification::MODULES[Maturity::class] => 'Indice de maturité', - Notification::MODULES[ConformiteTraitement::class] => 'Conformité du traitement', - Notification::MODULES[Conformite::class] => 'Conformité de la structure', - Notification::MODULES[AnalyseImpact::class] => 'Analyse d\'impact', - Notification::MODULES[Document::class] => 'Espace Documentaire', - 'user' => 'Utilisateurs', + Notification::MODULES[Treatment::class] => 'Traitements', + Notification::MODULES[Contractor::class] => 'Sous-traitants', + Notification::MODULES[Request::class] => 'Demandes', + Notification::MODULES[Violation::class] => 'Violations', + Notification::MODULES[Proof::class] => 'Preuves', + Notification::MODULES[Mesurement::class] => 'Actions de protection', + self::ACTION_PLAN => 'Plan d\'actions', +// Notification::MODULES[ConformiteTraitement::class] => 'Conformité du traitement', +// Notification::MODULES[Conformite::class] => 'Conformité de la structure', + Notification::MODULES[AnalyseImpact::class] => 'AIPD', +// Notification::MODULES[Document::class] => 'Espace Documentaire', + Notification::MODULES[Maturity::class] => 'Indice de maturité', + Notification::MODULES[User::class] => 'Utilisateurs', ]; } diff --git a/src/Domain/Notification/Dictionary/NotificationModuleUserDictionary.php b/src/Domain/Notification/Dictionary/NotificationModuleUserDictionary.php new file mode 100644 index 0000000000000000000000000000000000000000..5430930e79a3332a87550a94746dcdae8f4f7a20 --- /dev/null +++ b/src/Domain/Notification/Dictionary/NotificationModuleUserDictionary.php @@ -0,0 +1,68 @@ +<?php + +/** + * This file is part of the MADIS - RGPD Management application. + * + * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes + * @author Donovan Bourlard <donovan@awkan.fr> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace App\Domain\Notification\Dictionary; + +use App\Application\Dictionary\SimpleDictionary; +use App\Domain\AIPD\Model\AnalyseImpact; +use App\Domain\Documentation\Model\Document; +use App\Domain\Maturity\Model\Maturity; +use App\Domain\Notification\Model\Notification; +use App\Domain\Registry\Model\Request; + +class NotificationModuleUserDictionary extends SimpleDictionary +{ + public const ACTION_PLAN = 'action_plan'; + + public function __construct() + { + parent::__construct('notificationUserModule', self::getModules()); + } + + /** + * Get an array of Roles. + * + * @return array + */ + public static function getModules() + { + return [ + Notification::MODULES[Request::class] => 'Demandes', + self::ACTION_PLAN => 'Plan d\'actions', + Notification::MODULES[AnalyseImpact::class] => 'AIPD', + Notification::MODULES[Maturity::class] => 'Indice de maturité', + Notification::MODULES[Document::class] => 'Espace Documentaire', + ]; + } + + /** + * Get keys of the Roles array. + * + * @return array + */ + public static function getModulesKeys() + { + return \array_keys(self::getModules()); + } +} diff --git a/src/Domain/Notification/Model/Notification.php b/src/Domain/Notification/Model/Notification.php index 13baa79445e58368642cc6ac3375733f48cf1dff..a5fc02b952d7d77d25e5f92a113118988834d843 100644 --- a/src/Domain/Notification/Model/Notification.php +++ b/src/Domain/Notification/Model/Notification.php @@ -67,6 +67,7 @@ class Notification Conformite::class => 'organization_conformity', AnalyseImpact::class => 'aipd', Document::class => 'document', + User::class => 'user', ]; /** @@ -96,6 +97,10 @@ class Notification * @var string|null */ private $module; + /** + * @ORM\Column(type="text", nullable=true) + */ + private ?string $subject; /** * @ORM\Column(type="string") @@ -273,4 +278,14 @@ class Notification { $this->dpo = $dpo; } + + public function getSubject(): ?string + { + return $this->subject; + } + + public function setSubject(?string $subject): void + { + $this->subject = $subject; + } } diff --git a/src/Domain/Notification/Repository/Notification.php b/src/Domain/Notification/Repository/Notification.php index f3f5bdcbc54e89079900d9669ff9c05963c2fba4..33bd1e65ea98b36d00048e63b7166a4bf1fe0519 100644 --- a/src/Domain/Notification/Repository/Notification.php +++ b/src/Domain/Notification/Repository/Notification.php @@ -30,4 +30,6 @@ use App\Application\Doctrine\Repository\DataTablesRepository; interface Notification extends CRUDRepositoryInterface, DataTablesRepository { public function findOneBy(array $criteria); + + public function objectExists(\App\Domain\Notification\Model\Notification $notification); } diff --git a/src/Domain/Notification/Serializer/NotificationNormalizer.php b/src/Domain/Notification/Serializer/NotificationNormalizer.php index f1d2eacd0c01fb46109421fea3e82d5bea46eb4f..14833434250edcc5e09e5601c51f6af20187d2c2 100644 --- a/src/Domain/Notification/Serializer/NotificationNormalizer.php +++ b/src/Domain/Notification/Serializer/NotificationNormalizer.php @@ -88,9 +88,9 @@ class NotificationNormalizer extends ObjectNormalizer } foreach ($stack as $attribute => $attributeValue) { -// if (!$this->serializer instanceof NormalizerInterface) { -// throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer.', $attribute)); -// } + // if (!$this->serializer instanceof NormalizerInterface) { + // throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer.', $attribute)); + // } $data = $this->updateData($data, $attribute, $this->getObjectSimpleValue($attributeValue), $class, $format, $context); } diff --git a/src/Domain/Notification/Subscriber/NotificationEventSubscriber.php b/src/Domain/Notification/Subscriber/NotificationEventSubscriber.php index 800fcae09e067da2d1557e82ebdd92b8ddb20ef3..044b8def70e5b2f4042761659c1850f2f5ed4d5a 100644 --- a/src/Domain/Notification/Subscriber/NotificationEventSubscriber.php +++ b/src/Domain/Notification/Subscriber/NotificationEventSubscriber.php @@ -3,6 +3,7 @@ namespace App\Domain\Notification\Subscriber; use App\Application\Interfaces\CollectivityRelated; +use App\Domain\Notification\Dictionary\NotificationModuleDictionary; use App\Domain\Notification\Event\ConformiteTraitementNeedsAIPDEvent; use App\Domain\Notification\Event\LateActionEvent; use App\Domain\Notification\Event\LateRequestEvent; @@ -12,16 +13,14 @@ use App\Domain\Notification\Model\Notification; use App\Domain\Notification\Model\NotificationUser; use App\Domain\Notification\Serializer\NotificationNormalizer; use App\Domain\Registry\Model\ConformiteTraitement\ConformiteTraitement; -use App\Domain\Registry\Model\Mesurement; use App\Domain\User\Dictionary\UserMoreInfoDictionary; use App\Domain\User\Model\User; use App\Domain\User\Repository\User as UserRepository; use App\Infrastructure\ORM\Notification\Repository\Notification as NotificationRepository; use App\Infrastructure\ORM\Notification\Repository\NotificationUser as NotificationUserRepository; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; +use Symfony\Contracts\Translation\TranslatorInterface; /** * This event subscriber creates notification for things that are trigerred by a cron job. @@ -32,19 +31,26 @@ class NotificationEventSubscriber implements EventSubscriberInterface protected NotificationUserRepository $notificationUserRepository; protected NotificationNormalizer $normalizer; protected UserRepository $userRepository; - protected EventDispatcherInterface $dispatcher; - protected MailerInterface $mailer; + protected TranslatorInterface $translator; + protected string $requestDays; + protected string $surveyDays; public function __construct( NotificationRepository $notificationRepository, NotificationUserRepository $notificationUserRepository, NotificationNormalizer $normalizer, UserRepository $userRepository, + TranslatorInterface $translator, + string $requestDays, + string $surveyDays, ) { $this->notificationRepository = $notificationRepository; $this->notificationUserRepository = $notificationUserRepository; $this->normalizer = $normalizer; $this->userRepository = $userRepository; + $this->translator = $translator; + $this->requestDays = $requestDays; + $this->surveyDays = $surveyDays; } public static function getSubscribedEvents() @@ -84,6 +90,7 @@ class NotificationEventSubscriber implements EventSubscriberInterface $notification->setName($conformite->__toString()); $notification->setObject((object) $norm); $notification->setDpo(true); + $notification->setSubject(''); $this->notificationRepository->insert($notification); $nus = $this->notificationUserRepository->saveUsers($notification, $users); @@ -121,6 +128,7 @@ class NotificationEventSubscriber implements EventSubscriberInterface $notification->setName($survey->__toString()); $notification->setObject((object) $norm); $notification->setDpo(true); + $notification->setSubject($this->translator->trans('notifications.subject.late_survey', ['%days%' => $this->surveyDays])); $this->notificationRepository->insert($notification); $nus = $this->notificationUserRepository->saveUsers($notification, $users); @@ -137,7 +145,7 @@ class NotificationEventSubscriber implements EventSubscriberInterface { $action = $event->getMesurement(); $existing = $this->notificationRepository->findBy([ - 'module' => 'notification.modules.' . Notification::MODULES[Mesurement::class], + 'module' => 'notification.modules.' . NotificationModuleDictionary::ACTION_PLAN, 'collectivity' => $action->getCollectivity(), 'action' => 'notifications.actions.late_action', 'name' => $action->getName(), @@ -150,12 +158,16 @@ class NotificationEventSubscriber implements EventSubscriberInterface $users = $this->userRepository->findNonDpoUsersForCollectivity($action->getCollectivity()); $notification = new Notification(); - $notification->setModule('notification.modules.' . Notification::MODULES[Mesurement::class]); + $notification->setModule('notification.modules.' . NotificationModuleDictionary::ACTION_PLAN); $notification->setCollectivity($action->getCollectivity()); $notification->setAction('notifications.actions.late_action'); $notification->setName($action->getName()); $notification->setObject((object) $norm); $notification->setDpo(true); + $ob = $notification->getObject(); + $date = \DateTime::createFromFormat(DATE_ATOM, $ob->planificationDate)->format('d/m/Y'); + + $notification->setSubject($this->translator->trans('notifications.subject.late_action', ['%date%' => $date])); $this->notificationRepository->insert($notification); $nus = $this->notificationUserRepository->saveUsers($notification, $users); @@ -191,6 +203,7 @@ class NotificationEventSubscriber implements EventSubscriberInterface $notification->setName($request->__toString()); $notification->setObject((object) $norm); $notification->setDpo(true); + $notification->setSubject($this->translator->trans('notifications.subject.late_request', ['%days%' => $this->requestDays])); $this->notificationRepository->insert($notification); $nus = $this->notificationUserRepository->saveUsers($notification, $users); @@ -222,9 +235,10 @@ class NotificationEventSubscriber implements EventSubscriberInterface $notification->setCollectivity($user->getCollectivity()); $notification->setAction('notifications.actions.no_login'); $notification->setName($user->getFullName()); - $notification->setCreatedBy($user); + //$notification->setCreatedBy($user); $notification->setObject((object) $this->normalizer->normalize($user, null, self::normalizerOptions())); $notification->setDpo(true); + $notification->setSubject($this->translator->trans('notifications.subject.no_login')); $this->notificationRepository->insert($notification); $this->saveEmailNotificationForRefOp($notification, $user); diff --git a/src/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationEventSubscriber.php b/src/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationEventSubscriber.php index 55d1f00ca2f2bb71f4e7b946edaba13cfbdf9812..c3a3043b9dcff4e07aa64ef71bd4f8bfa892ea04 100644 --- a/src/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationEventSubscriber.php +++ b/src/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationEventSubscriber.php @@ -10,6 +10,9 @@ use App\Domain\Documentation\Model\Document; use App\Domain\Notification\Model\Notification; use App\Domain\Notification\Model\NotificationUser; use App\Domain\Notification\Serializer\NotificationNormalizer; +use App\Domain\Registry\Dictionary\MesurementStatusDictionary; +use App\Domain\Registry\Dictionary\ProofTypeDictionary; +use App\Domain\Registry\Dictionary\ViolationNatureDictionary; use App\Domain\Registry\Model\Contractor; use App\Domain\Registry\Model\Mesurement; use App\Domain\Registry\Model\Proof; @@ -28,6 +31,7 @@ use Doctrine\ORM\Events; use Symfony\Component\Security\Core\Security; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * This subscriber handles events that are generated by doctrine, and creates notifications from them if necessary. @@ -61,6 +65,9 @@ class NotificationEventSubscriber implements EventSubscriber protected UserRepository $userRepository; protected Security $security; protected NormalizerInterface $normalizer; + protected TranslatorInterface $translator; + protected string $requestDays; + protected string $surveyDays; public function __construct( NotificationRepository $notificationRepository, @@ -68,12 +75,18 @@ class NotificationEventSubscriber implements EventSubscriber UserRepository $userRepository, NotificationUserRepository $notificationUserRepository, Security $security, + TranslatorInterface $translator, + string $requestDays, + string $surveyDays, ) { $this->notificationRepository = $notificationRepository; $this->normalizer = $normalizer; $this->userRepository = $userRepository; $this->notificationUserRepository = $notificationUserRepository; $this->security = $security; + $this->translator = $translator; + $this->requestDays = $requestDays; + $this->surveyDays = $surveyDays; } public function getSubscribedEvents(): array @@ -106,6 +119,7 @@ class NotificationEventSubscriber implements EventSubscriber foreach ($uow->getScheduledEntityUpdates() as $entity) { $class = get_class($entity); + if (!in_array($class, $this->classes) || Document::class === $class) { continue; } @@ -125,6 +139,7 @@ class NotificationEventSubscriber implements EventSubscriber if (!isset($ch['statut']) && !isset($ch['isReadyForValidation'])) { continue; } + if (isset($ch['statut'])) { $action = 'state_change'; } elseif (isset($ch['isReadyForValidation'])) { @@ -134,7 +149,6 @@ class NotificationEventSubscriber implements EventSubscriber $this->createNotifications($entity, $action, $em); } - foreach ($uow->getScheduledEntityDeletions() as $entity) { $class = get_class($entity); if (!in_array($class, $this->classes) || Request::class == $class || Document::class === $class || AnalyseImpact::class === $class) { @@ -208,6 +222,7 @@ class NotificationEventSubscriber implements EventSubscriber $meta2 = $em->getClassMetadata(NotificationUser::class); foreach ($notifications as $notif) { + $notif->setSubject($this->getSubjectForNotification($notif)); $em->persist($notif); /** * @var Notification $notif @@ -369,7 +384,7 @@ class NotificationEventSubscriber implements EventSubscriber $nu->setActive(false); $nu->setSent(false); $nus[] = $nu; -// $this->notificationUserRepository->persist($nu); + // $this->notificationUserRepository->persist($nu); } return $nus; @@ -395,4 +410,51 @@ class NotificationEventSubscriber implements EventSubscriber return $object; } + + private function getSubjectForNotification(Notification $notification): string + { + if ( + 'notification.modules.violation' === $notification->getModule() + ) { + $ob = $notification->getObject(); + if (isset($ob->violationNatures)) { + $vn = explode(',', $ob->violationNatures); + if (is_array($vn) && count($vn) > 0) { + return join(', ', array_map(function ($v) { + return ViolationNatureDictionary::getNatures()[trim($v)] ?? ''; + }, $vn)); + } + } elseif (isset($ob->violationNature)) { + return ViolationNatureDictionary::getNatures()[$ob->violationNature] ?? ''; + } + + return ''; + } + + if ( + 'notification.modules.proof' === $notification->getModule() + ) { + $type = $notification->getObject()->type; + + return $type && isset(ProofTypeDictionary::getTypes()[$type]) ? ProofTypeDictionary::getTypes()[$type] : ''; + } + + if ('notification.modules.protect_action' === $notification->getModule()) { + return MesurementStatusDictionary::getStatus()[$notification->getObject()->status] ?? ''; + } + + if ('notification.modules.request' === $notification->getModule() && ('notifications.actions.state_change' === $notification->getAction() || 'notification.actions.state_change' === $notification->getAction())) { + return $notification->getObject()->state; + } + + if ('notification.modules.aipd' === $notification->getModule() && ('notifications.actions.state_change' === $notification->getAction() || 'notification.actions.state_change' === $notification->getAction())) { + return $notification->getObject()->statut; + } + + if ('notifications.actions.validation' === $notification->getAction() || 'notification.actions.validation' === $notification->getAction()) { + return $this->translator->trans('notifications.subject.validation'); + } + + return ''; + } } diff --git a/src/Domain/Notification/Twig/Extension/NotificationExtension.php b/src/Domain/Notification/Twig/Extension/NotificationExtension.php index 27b6e02dbf51f8c2df9124962e4188d90792d0a1..c130a9742ba6b6732c7a6212b8512da32a79a479 100644 --- a/src/Domain/Notification/Twig/Extension/NotificationExtension.php +++ b/src/Domain/Notification/Twig/Extension/NotificationExtension.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Domain\Notification\Twig\Extension; +use App\Domain\Documentation\Model\Document; use App\Domain\Notification\Model\Notification; use App\Domain\Notification\Model\Notification as NotificationModel; use App\Domain\Registry\Dictionary\ProofTypeDictionary; @@ -20,14 +21,16 @@ class NotificationExtension extends AbstractExtension { protected TranslatorInterface $translator; protected RouterInterface $router; + protected \App\Domain\Notification\Repository\Notification $repository; protected string $requestDays; protected string $surveyDays; - public function __construct(TranslatorInterface $translator, RouterInterface $router, string $requestDays, string $surveyDays) + public function __construct(TranslatorInterface $translator, RouterInterface $router, \App\Domain\Notification\Repository\Notification $repository, string $requestDays, string $surveyDays) { $this->translator = $translator; $this->router = $router; + $this->repository = $repository; $this->requestDays = $requestDays; $this->surveyDays = $surveyDays; } @@ -44,31 +47,46 @@ class NotificationExtension extends AbstractExtension { $sentence = '<strong>[' . $this->translator->trans($notification->getModule()) . ']</strong> '; + if ($notification->getModule() === 'notification.modules.' . NotificationModel::MODULES[Document::class]) { + $sentence .= ' Nouveau document déposé par le DPD '; + } + switch ($notification->getAction()) { case 'notifications.actions.late_request': + case 'notification.actions.late_request': $link = $this->getObjectLink($notification); $sentence .= $this->translator->trans('notifications.sentence.late_request', [ '%name%' => '<a href="' . $link . '">' . $notification->getName() . '</a> ', '%days%' => $this->requestDays, ]) . ' '; break; - case 'notifications.sentence.late_request': + case 'notifications.actions.late_survey': + case 'notification.actions.late_survey': $sentence .= $this->translator->trans('notifications.sentence.late_survey', [ '%days%' => $this->surveyDays, ]) . ' '; break; case 'notifications.actions.delete': + case 'notification.actions.delete': $sentence .= $this->translator->trans($notification->getAction()) . ' '; $sentence .= ' : ' . '<span>' . $notification->getName() . '</span> ' ; break; default: - $sentence .= $this->translator->trans($notification->getAction()) . ' '; + if ($notification->getModule() !== 'notification.modules.' . NotificationModel::MODULES[Document::class]) { + $sentence .= $this->translator->trans($notification->getAction()) . ' '; + } $link = $this->getObjectLink($notification); - $sentence .= ' : ' . - '<a href="' . $link . '">' . $notification->getName() . '</a> ' - ; + if ($this->repository->objectExists($notification)) { + $sentence .= ' : ' . + '<a href="' . $link . '">' . $notification->getName() . '</a> ' + ; + } else { + $sentence .= ' : ' . + '<span>' . $notification->getName() . '</span> ' + ; + } } if ($notification->getModule() === 'notification.modules.' . NotificationModel::MODULES[Violation::class]) { @@ -86,6 +104,7 @@ class NotificationExtension extends AbstractExtension if ($notification->getModule() === 'notification.modules.' . NotificationModel::MODULES[Proof::class]) { $sentence .= '<strong>(' . ProofTypeDictionary::getTypes()[$notification->getObject()->type] . ')</strong> '; } + if ($notification->getCollectivity()) { $sentence .= $this->translator->trans('label.par') . ' <strong>' . $notification->getCollectivity()->getName() . '</strong>'; } @@ -96,6 +115,19 @@ class NotificationExtension extends AbstractExtension public function getObjectLink(Notification $notification): string { try { + if ('notification.modules.aipd' === $notification->getModule() && 'notification.actions.validation' === $notification->getAction()) { + return $this->router->generate('aipd_analyse_impact_validation', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + if ('notification.modules.aipd' === $notification->getModule() && 'notification.actions.state_change' === $notification->getAction()) { + return $this->router->generate('aipd_analyse_impact_evaluation', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + if ('notification.modules.document' === $notification->getModule() && 'notification.actions.delete' !== $notification->getAction()) { + return $notification->getObject()->url; + } + if ('notification.modules.action_plan' === $notification->getModule()) { + return $this->router->generate('registry_mesurement_show', ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); + } + return $this->router->generate($this->getRouteForModule($notification->getModule()), ['id' => $notification->getObject()->id], UrlGeneratorInterface::ABSOLUTE_URL); } catch (\Exception $e) { return ''; @@ -116,6 +148,8 @@ class NotificationExtension extends AbstractExtension return 'registry_proof_edit'; case 'notification.modules.protect_action': return 'registry_mesurement_show'; + case 'notification.modules.aipd': + return 'aipd_analyse_impact_edit'; case 'notification.modules.request': return 'registry_request_show'; case 'notification.modules.user': diff --git a/src/Infrastructure/ORM/Notification/Repository/Notification.php b/src/Infrastructure/ORM/Notification/Repository/Notification.php index c8e534b2b6ae5955f12918ebcba35d000058bbcb..e0a449cd61f651b5302f3424e5918d37e6303bea 100644 --- a/src/Infrastructure/ORM/Notification/Repository/Notification.php +++ b/src/Infrastructure/ORM/Notification/Repository/Notification.php @@ -28,6 +28,7 @@ use App\Application\Doctrine\Repository\CRUDRepository; use App\Application\Traits\RepositoryUtils; use App\Domain\Notification\Model; use App\Domain\Notification\Repository; +use App\Domain\Registry\Model\Mesurement; use App\Domain\User\Dictionary\UserMoreInfoDictionary; use App\Domain\User\Dictionary\UserRoleDictionary; use App\Domain\User\Model\Collectivity; @@ -60,7 +61,7 @@ class Notification extends CRUDRepository implements Repository\Notification return Model\Notification::class; } - public function findAll(array $order = ['createdAt' => 'DESC']): array + private function getQueryBuilder(array $order = ['createdAt' => 'DESC']): QueryBuilder { /** * @var User $user @@ -75,11 +76,10 @@ class Notification extends CRUDRepository implements Repository\Notification $allNotifs = true; } - $qb = $this->createQueryBuilder(); - - foreach ($order as $field => $direction) { - $qb->addOrderBy(new OrderBy('o.' . $field, $direction)); - } + $qb = $this->createQueryBuilder() + ->addSelect('collectivity') + ->leftJoin('o.collectivity', 'collectivity') + ; if ($allNotifs) { $qb->where('o.dpo = 1'); @@ -88,12 +88,12 @@ class Notification extends CRUDRepository implements Repository\Notification if (in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) { $cf = $user->getCollectivitesReferees(); $cf = new ArrayCollection([...$cf]); -// if (!is_object($cf) || ArrayCollection::class !== get_class($cf)) { -// $cf = new ArrayCollection([...$cf]); -// } + // if (!is_object($cf) || ArrayCollection::class !== get_class($cf)) { + // $cf = new ArrayCollection([...$cf]); + // } $collectivityIds = $cf->map(function (Collectivity $c) {return $c->getId()->__toString(); })->toArray(); } else { - $collectivityIds = [$user->getCollectivity()->getId()->__toString()]; + $collectivityIds = [$user->getCollectivity()->getId()->__toString(), null]; } $qb->innerJoin('o.collectivity', 'c'); $qb->andWhere( @@ -103,11 +103,21 @@ class Notification extends CRUDRepository implements Repository\Notification } } else { $qb->leftJoin('o.notificationUsers', 'u') - ->andWhere('u.active = 1') - ->andWhere('u.user = :user') + ->where('u.active = 1') + ->where('u.user = :user') ->setParameter('user', $user) ; - $qb->addSelect('u.readAt as userReadAt'); + } + + return $qb; + } + + public function findAll(array $order = ['createdAt' => 'DESC']): array + { + $qb = $this->getQueryBuilder($order); + + foreach ($order as $field => $direction) { + $qb->addOrderBy(new OrderBy('o.' . $field, $direction)); } return $qb->getQuery()->getResult(); @@ -132,62 +142,23 @@ class Notification extends CRUDRepository implements Repository\Notification public function count(array $criteria = []) { - /** - * @var User $user - */ - $user = $this->security->getUser(); - - $allNotifs = false; - - $allowedRoles = [UserRoleDictionary::ROLE_REFERENT, UserRoleDictionary::ROLE_ADMIN]; - if ($user && (count($user->getRoles()) && in_array($user->getRoles()[0], $allowedRoles)) || in_array(UserMoreInfoDictionary::MOREINFO_DPD, $user->getMoreInfos())) { - // Find notifications with null user if current user is dpo - $allNotifs = true; - } - - $qb = $this->createQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->select('COUNT(o.id)'); - if ($allNotifs) { - $qb->where('o.dpo = 1'); - if (!in_array(UserRoleDictionary::ROLE_ADMIN, $user->getRoles())) { - // For non admin users - if (in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) { - $cf = $user->getCollectivitesReferees(); - $cf = new ArrayCollection([...$cf]); -// if (!is_object($cf) || ArrayCollection::class !== get_class($cf)) { -// $cf = new ArrayCollection([...$cf]); -// } - $collectivityIds = $cf->map(function (Collectivity $c) {return $c->getId()->__toString(); })->toArray(); - } else { - $collectivityIds = [$user->getCollectivity()->getId()->__toString()]; - } - $qb->innerJoin('o.collectivity', 'c'); - $qb->andWhere( - $qb->expr()->in('c.id', ':ids') - ); - $qb->setParameter('ids', $collectivityIds); - } - } else { - $qb->leftJoin('o.notificationUsers', 'u') - ->where('u.active = 1') - ->where('u.user = :user') - ->setParameter('user', $user) - ; - } - if (isset($criteria['collectivity']) && $criteria['collectivity'] instanceof Collection) { - $qb->innerJoin('o.collectivity', 'collectivite'); + $collectivityIds = $criteria['collectivity']->toArray(); + array_push($collectivityIds, null); + // $qb->innerJoin('o.collectivity', 'collectivite'); $qb->andWhere( - $qb->expr()->in('collectivite', ':collectivities') + $qb->expr()->in('collectivity', ':collectivities') ) - ->setParameter('collectivities', $criteria['collectivity']->toArray()) + ->setParameter('collectivities', $collectivityIds) ; unset($criteria['collectivity']); } -// -// dd($criteria); + // + // dd($criteria); foreach ($criteria as $key => $value) { $this->addWhereClause($qb, $key, $value); @@ -198,60 +169,27 @@ class Notification extends CRUDRepository implements Repository\Notification public function findPaginated($firstResult, $maxResults, $orderColumn, $orderDir, $searches, $criteria = []) { - $qb = $this->createQueryBuilder() - ->addSelect('collectivity') - ->innerJoin('o.collectivity', 'collectivity') - ; - - /** - * @var User $user - */ - $user = $this->security->getUser(); - - $allNotifs = false; - - $allowedRoles = [UserRoleDictionary::ROLE_REFERENT, UserRoleDictionary::ROLE_ADMIN]; - if ($user && (count($user->getRoles()) && in_array($user->getRoles()[0], $allowedRoles)) || in_array(UserMoreInfoDictionary::MOREINFO_DPD, $user->getMoreInfos())) { - // Find notifications with null user if current user is dpo - $allNotifs = true; - } - - if ($allNotifs) { - $qb->where('o.dpo = 1'); - if (!in_array(UserRoleDictionary::ROLE_ADMIN, $user->getRoles())) { - // For non admin users - if (in_array(UserRoleDictionary::ROLE_REFERENT, $user->getRoles())) { - $cf = $user->getCollectivitesReferees(); - $cf = new ArrayCollection([...$cf]); -// if (!is_object($cf) || ArrayCollection::class !== get_class($cf)) { -// $cf = new ArrayCollection([...$cf]); -// } - $collectivityIds = $cf->map(function (Collectivity $c) {return $c->getId()->__toString(); })->toArray(); - } else { - $collectivityIds = [$user->getCollectivity()->getId()->__toString()]; - } - $qb->innerJoin('o.collectivity', 'c'); - $qb->andWhere( - $qb->expr()->in('c.id', ':ids') - ); - $qb->setParameter('ids', $collectivityIds); - } - } else { - $qb->leftJoin('o.notificationUsers', 'u') - ->where('u.active = 1') - ->where('u.user = :user') - ->setParameter('user', $user) - ; - } - - if (isset($criteria['collectivity']) && $criteria['collectivity'] instanceof Collection) { - $qb->andWhere( - $qb->expr()->in('collectivity', ':collectivities') - ) - ->setParameter('collectivities', $criteria['collectivity']->toArray()) - ; - unset($criteria['collectivity']); - } + $qb = $this->getQueryBuilder(); + + // if (isset($criteria['collectivity']) && $criteria['collectivity'] instanceof Collection) { + // $collectivityIds = $criteria['collectivity']->map(function($c) { + // if ($c instanceof Collectivity) { + // return $c->getId()->__toString(); + // } + // return $c; + // })->toArray(); + // //dd($collectivityIds); + // array_push($collectivityIds, null); + // //$qb->innerJoin('o.collectivity', 'collectivite'); + // $qb->andWhere( + // $qb->expr()->in('collectivity', ':collectivities') + // ) + // ->setParameter('collectivities', $collectivityIds) + // ; + // + // //dd($qb->getQuery()->getParameters()); + unset($criteria['collectivity']); + // } foreach ($criteria as $key => $value) { $this->addWhereClause($qb, $key, $value); @@ -303,13 +241,27 @@ class Notification extends CRUDRepository implements Repository\Notification ->setParameter('name', '%' . $search . '%'); break; case 'action': - $queryBuilder->andWhere('o.action LIKE :action') - ->setParameter('action', '%' . $search . '%'); + if ('automatic' === $search) { + $queryBuilder + ->andWhere('o.action LIKE :a1 OR o.action LIKE :a2 OR o.action LIKE :a3') + ->setParameter('a1', '%no_login') + ->setParameter('a2', '%late_survey') + ->setParameter('a3', '%late_action') + ; + } else { + $queryBuilder->andWhere('o.action LIKE :action') + ->setParameter('action', '%' . $search . '%'); + } + break; case 'module': $queryBuilder->andWhere('o.module LIKE :module') ->setParameter('module', '%' . $search . '%'); break; + case 'object': + $queryBuilder->andWhere('o.subject LIKE :object') + ->setParameter('object', '%' . $search . '%'); + break; case 'date': $queryBuilder->andWhere('o.createdAt LIKE :createdAt') ->setParameter('createdAt', date_create_from_format('d/m/Y', $search)->format('Y-m-d') . '%'); @@ -363,6 +315,9 @@ class Notification extends CRUDRepository implements Repository\Notification case 'action': $queryBuilder->addOrderBy('o.action', $orderDir); break; + case 'object': + $queryBuilder->addOrderBy('o.subject', $orderDir); + break; case 'module': $queryBuilder->addOrderBy('o.module', $orderDir); break; @@ -380,4 +335,22 @@ class Notification extends CRUDRepository implements Repository\Notification break; } } + + public function objectExists(\App\Domain\Notification\Model\Notification $notification): bool + { + if (!$notification->getObject()) { + return false; + } + + $object = $notification->getObject(); + $moduleName = str_replace('notification.modules.', '', $notification->getModule()); + + if ('action_plan' === $moduleName) { + $objectClass = Mesurement::class; + } else { + $objectClass = array_flip(\App\Domain\Notification\Model\Notification::MODULES)[$moduleName]; + } + + return (bool) $this->registry->getRepository($objectClass)->find($object->id); + } } diff --git a/templates/Notification/Notification/list.html.twig b/templates/Notification/Notification/list.html.twig index 05725b6f012bdb342bcd4da2b789c0057fa46334..3af6bf5fd77d93a48b8775520b19e79a1cf864f3 100644 --- a/templates/Notification/Notification/list.html.twig +++ b/templates/Notification/Notification/list.html.twig @@ -32,7 +32,7 @@ <table id="table" class="table table-bordered table-hover"> <thead> <tr> - <th> + <th scope="col"> <select class="form-control" id="search_state" style="width: 100%;"> <option value="" selected>{{ 'notification.notification.list.state'|trans }}</option> {% for key, subject in dictionary('notifications_notification_state') %} @@ -40,60 +40,75 @@ {% endfor %} </select> </th> - <th> + <th scope="col"> <select class="form-control" id="search_module" style="width: 100%;"> <option value="" selected>{{ 'notification.notification.list.module'|trans }}</option> - {% for key, subject in dictionary('notificationModule') %} - <option value="{{ key }}">{{ subject }}</option> - {% endfor %} + {% if is_granted('ROLE_REFERENT') or 'MOREINFO_DPD' in app.user.moreInfos %} + {% for key, subject in dictionary('notificationModule') %} + <option value="{{ key }}">{{ subject }}</option> + {% endfor %} + {% else %} + {% for key, subject in dictionary('notificationUserModule') %} + <option value="{{ key }}">{{ subject }}</option> + {% endfor %} + {% endif %} </select> </th> - <th> + <th scope="col"> <select class="form-control" id="search_action" style="width: 100%;"> <option value="" selected>{{ 'notification.notification.list.action'|trans }}</option> - {% for key, subject in dictionary('notificationAction') %} - <option value="{{ key }}">{{ subject }}</option> - {% endfor %} + {% if is_granted('ROLE_REFERENT') or 'MOREINFO_DPD' in app.user.moreInfos %} + {% for key, subject in dictionary('notificationAction') %} + <option value="{{ key }}">{{ subject }}</option> + {% endfor %} + {% else %} + {% for key, subject in dictionary('notificationActionUser') %} + <option value="{{ key }}">{{ subject }}</option> + {% endfor %} + {% endif %} </select> </th> - <th> + <th scope="col"> <input class="form-control" type="text" id="search_name" placeholder="Nom" style="width: 100%;"> </th> - <th> + <th scope="col"> + <input class="form-control" type="text" id="search_object" placeholder="Objet" style="width: 100%;"> </th> {% if is_granted('ROLE_ADMIN') %} - <th> + <th scope="col"> <input class="form-control" type="text" id="search_collectivity" placeholder="Structure" style="width: 100%;"> </th> {% endif %} - <th><input class="datepicker form-control" type="text" id="search_date" placeholder="Date" style="width: 100%;"></th> - <th> + <th scope="col"><input class="datepicker form-control" type="text" id="search_date" placeholder="Date" style="width: 100%;"></th> + {% if is_granted('ROLE_ADMIN') %} + <th scope="col"> <input class="form-control" type="text" id="search_user_name" placeholder="Nom" style="width: 100%;"> </th> - {% if is_granted('ROLE_ADMIN') %} - <th><input class="datepicker form-control" type="text" id="search_read_at" placeholder="Date" style="width: 100%;"></th> - <th> + <th scope="col"> + <input class="datepicker form-control" type="text" id="search_read_at" placeholder="Date" style="width: 100%;"> + </th> + <th scope="col"> <input class="form-control" type="text" id="search_read_by" placeholder="Nom" style="width: 100%;"> </th> {% endif %} </tr> <tr> - <th>{{ 'notification.notification.list.state'|trans }}</th> - <th>{{ 'notification.notification.list.module'|trans }}</th> - <th>{{ 'notification.notification.list.action'|trans }}</th> - <th>{{ 'notification.notification.list.name'|trans }}</th> - <th>{{ 'notification.notification.list.object'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.state'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.module'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.action'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.name'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.object'|trans }}</th> {% if is_granted('ROLE_ADMIN') %} - <th>{{ 'notification.notification.list.collectivity'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.collectivity'|trans }}</th> {% endif %} - <th>{{ 'notification.notification.list.date'|trans }}</th> - <th>{{ 'notification.notification.list.user'|trans }}</th> - {% if is_granted('ROLE_ADMIN') %} - <th>{{ 'notification.notification.list.read_date'|trans }}</th> - <th>{{ 'notification.notification.list.read_by'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.date'|trans }}</th> + {% if is_granted('ROLE_ADMIN') %} + <th scope="col">{{ 'notification.notification.list.user'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.read_date'|trans }}</th> + <th scope="col">{{ 'notification.notification.list.read_by'|trans }}</th> {% endif %} - <th>{{ 'label.actions'|trans }}</th> + <th scope="col">{{ 'label.actions'|trans }}</th> </tr> </thead> @@ -119,7 +134,7 @@ {"data": "module"}, {"data": "action"}, {"data": "name"}, - {"data": "object", "orderable": false}, + {"data": "object"}, {"data": "collectivity"}, {"data": "date"}, {"data": "user"}, @@ -133,12 +148,11 @@ {"data": "module"}, {"data": "action"}, {"data": "name"}, - {"data": "object", "orderable": false}, + {"data": "object"}, {"data": "date"}, - {"data": "user"}, {"data": "actions", "orderable": false, "className": "noVis actions",}, ] %} - {% set order = [[4, 'desc']] %} + {% set order = [[5, 'desc']] %} {% set coldefs = [{ targets: 6, className: 'noVis' @@ -178,8 +192,6 @@ function setEvents() { var oTable = $('#table').DataTable(); - {% if is_granted('ROLE_ADMIN') %} - // NON LU SEULEMENT $('#search_state').off('change'); $('#search_state').change(function(){ oTable.column('0').search($(this).val()).draw(); @@ -200,6 +212,15 @@ oTable.column('3').search($(this).val()).draw(); })); + $('#search_object').off('keyup'); + $('#search_object').keyup($.debounce(250, function(){ + oTable.column('4').search($(this).val()).draw(); + })); + + {% if is_granted('ROLE_ADMIN') %} + // NON LU SEULEMENT + + $('#search_collectivity').off('keyup'); $('#search_collectivity').keyup($.debounce(250, function(){ oTable.column('5').search($(this).val()).draw(); @@ -227,25 +248,7 @@ {% else %} - $('#search_state').off('change'); - $('#search_state').change(function(){ - oTable.column('0').search($(this).val()).draw(); - }); - - $('#search_module').off('change'); - $('#search_module').change(function(){ - oTable.column('1').search($(this).val()).draw(); - }); - $('#search_action').off('change'); - $('#search_action').change(function(){ - oTable.column('2').search($(this).val()).draw(); - }); - - $('#search_name').off('keyup'); - $('#search_name').keyup($.debounce(250, function(){ - oTable.column('3').search($(this).val()).draw(); - })); $('#search_date').off('change'); diff --git a/tests/Domain/Notification/Subscriber/NotificationEventSubscriberTest.php b/tests/Domain/Notification/Subscriber/NotificationEventSubscriberTest.php index 67be13c43e50d7e6c10658f15532d87b3e38719c..81c3c068457f90c4366aa07c61dbd29551535de6 100644 --- a/tests/Domain/Notification/Subscriber/NotificationEventSubscriberTest.php +++ b/tests/Domain/Notification/Subscriber/NotificationEventSubscriberTest.php @@ -3,6 +3,7 @@ namespace App\Tests\Domain\Notification\Subscriber; use App\Domain\Maturity\Model\Survey; +use App\Domain\Notification\Dictionary\NotificationModuleDictionary; use App\Domain\Notification\Event\ConformiteTraitementNeedsAIPDEvent; use App\Domain\Notification\Event\LateActionEvent; use App\Domain\Notification\Event\LateRequestEvent; @@ -25,6 +26,7 @@ use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class NotificationEventSubscriberTest extends TestCase { @@ -34,6 +36,7 @@ class NotificationEventSubscriberTest extends TestCase private ObjectProphecy $userRepository; private ObjectProphecy $notificationUserRepository; private ObjectProphecy $notificationRepository; + private ObjectProphecy $translator; private NotificationEventSubscriber $subscriber; @@ -43,8 +46,17 @@ class NotificationEventSubscriberTest extends TestCase $this->notificationNormalizer = $this->prophesize(NotificationNormalizer::class); $this->userRepository = $this->prophesize(UserRepository::class); $this->notificationUserRepository = $this->prophesize(NotificationUserRepository::class); - - $this->subscriber = new NotificationEventSubscriber($this->notificationRepository->reveal(), $this->notificationUserRepository->reveal(), $this->notificationNormalizer->reveal(), $this->userRepository->reveal()); + $this->translator = $this->prophesize(TranslatorInterface::class); + + $this->subscriber = new NotificationEventSubscriber( + $this->notificationRepository->reveal(), + $this->notificationUserRepository->reveal(), + $this->notificationNormalizer->reveal(), + $this->userRepository->reveal(), + $this->translator->reveal(), + 30, + 30 + ); } public function testInstanceOf() @@ -188,19 +200,21 @@ class NotificationEventSubscriberTest extends TestCase $action = new Mesurement(); $action->setCollectivity($collectivity); $action->setCreatedAt(new \DateTimeImmutable()); + // $action->setPlanificationDate((new \DateTime())->sub(new \DateInterval('P3M'))); $this->notificationRepository->findBy([ - 'module' => 'notification.modules.' . Notification::MODULES[Mesurement::class], + 'module' => 'notification.modules.' . NotificationModuleDictionary::ACTION_PLAN, 'collectivity' => $action->getCollectivity(), 'action' => 'notifications.actions.late_action', 'name' => $action->__toString(), ])->shouldBeCalled()->willReturn([]); $user = new User(); + $user->setCollectivity($collectivity); $notification = new Notification(); - $notification->setModule('notification.modules.' . Notification::MODULES[Mesurement::class]); + $notification->setModule('notification.modules.' . NotificationModuleDictionary::ACTION_PLAN); $notification->setCollectivity($action->getCollectivity()); $notification->setAction('notifications.actions.late_action'); $notification->setName($action->__toString()); @@ -209,21 +223,21 @@ class NotificationEventSubscriberTest extends TestCase 'collectivity' => [ 'name' => 'coll', ], + 'planificationDate' => (new \DateTime())->sub(new \DateInterval('P3M'))->format(DATE_ATOM), ]); - $this->notificationRepository->insert(new NotificationToken($notification))->shouldBeCalled(); + $this->notificationRepository->insert(Argument::any())->shouldBeCalled(); $nu = new NotificationUser(); $nu->setUser($user); $nu->setNotification($notification); + $notification->setNotificationUsers([$nu]); - $notification->setNotificationUsers([$user]); - - $this->notificationRepository->update(new NotificationToken($notification))->shouldBeCalled(); - + $this->notificationRepository->update(Argument::any())->shouldBeCalled(); $this->userRepository->findNonDpoUsersForCollectivity($collectivity)->shouldBeCalled()->willReturn([$user]); - - $this->notificationUserRepository->saveUsers(new NotificationToken($notification), [$user])->shouldBeCalled()->willReturn([$nu]); + $this->notificationUserRepository->saveUsers(Argument::any(), Argument::any()) + ->shouldBeCalled() + ->willReturn([$nu]); $this->notificationNormalizer->normalize(Argument::exact($action), null, Argument::any()) ->shouldBeCalled() @@ -231,6 +245,7 @@ class NotificationEventSubscriberTest extends TestCase 'collectivity' => [ 'name' => 'coll', ], + 'planificationDate' => (new \DateTime())->sub(new \DateInterval('P3M'))->format(DATE_ATOM), ]) ; diff --git a/tests/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationGenerationSubscriberTest.php b/tests/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationGenerationSubscriberTest.php index 24161e6eafb976d6bfb4cbc6fb0c6a96a805d4e0..39022c894f57d831261d6da97a43fda22273b397 100644 --- a/tests/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationGenerationSubscriberTest.php +++ b/tests/Domain/Notification/Symfony/EventSubscriber/Doctrine/NotificationGenerationSubscriberTest.php @@ -5,6 +5,7 @@ namespace App\Tests\Domain\Notification\Symfony\EventSubscriber\Doctrine; use App\Domain\AIPD\Model\AnalyseImpact; use App\Domain\Notification\Serializer\NotificationNormalizer; use App\Domain\Notification\Symfony\EventSubscriber\Doctrine\NotificationEventSubscriber; +use App\Domain\Registry\Dictionary\ProofTypeDictionary; use App\Domain\Registry\Model\ConformiteTraitement\ConformiteTraitement; use App\Domain\Registry\Model\Proof; use App\Domain\Registry\Model\Treatment; @@ -23,6 +24,7 @@ use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; use Symfony\Component\Security\Core\Security; +use Symfony\Contracts\Translation\TranslatorInterface; class NotificationGenerationSubscriberTest extends TestCase { @@ -32,6 +34,7 @@ class NotificationGenerationSubscriberTest extends TestCase private ObjectProphecy $userRepository; private ObjectProphecy $security; private ObjectProphecy $notificationUserRepository; + private ObjectProphecy $translator; private NotificationEventSubscriber $subscriber; @@ -46,9 +49,19 @@ class NotificationGenerationSubscriberTest extends TestCase $this->notificationNormalizer = $this->prophesize(NotificationNormalizer::class); $this->userRepository = $this->prophesize(User::class); $this->notificationUserRepository = $this->prophesize(NotificationUser::class); + $this->translator = $this->prophesize(TranslatorInterface::class); $this->security = $this->prophesize(Security::class); - $this->subscriber = new NotificationEventSubscriber($nr->reveal(), $this->notificationNormalizer->reveal(), $this->userRepository->reveal(), $this->notificationUserRepository->reveal(), $this->security->reveal()); + $this->subscriber = new NotificationEventSubscriber( + $nr->reveal(), + $this->notificationNormalizer->reveal(), + $this->userRepository->reveal(), + $this->notificationUserRepository->reveal(), + $this->security->reveal(), + $this->translator->reveal(), + 30, + 30 + ); $conn = \Doctrine\DBAL\DriverManager::getConnection(['driver' => 'pdo_sqlite', 'memory' => true]); $config = new \Doctrine\ORM\Configuration(); @@ -194,6 +207,7 @@ class NotificationGenerationSubscriberTest extends TestCase public function testCreateProofNotification() { $object = new Proof(); + $object->setType(ProofTypeDictionary::TYPE_POLICY_MANAGEMENT); $om = $this->prophesize(EntityManagerInterface::class); $uow = $this->prophesize(UnitOfWork::class); @@ -208,7 +222,11 @@ class NotificationGenerationSubscriberTest extends TestCase $om->getClassMetadata(\App\Domain\Notification\Model\Notification::class)->shouldBeCalled()->willReturn($this->notificationMetadata); $om->getClassMetadata(\App\Domain\Notification\Model\NotificationUser::class)->shouldBeCalled()->willReturn($this->notificationUserMetadata); - $this->notificationNormalizer->normalize($object, null, Argument::type('array'))->shouldBeCalled(); + $this->notificationNormalizer->normalize($object, null, Argument::type('array')) + ->shouldBeCalled() + ->willReturn((object) [ + 'type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT, + ]); $this->userRepository->findNonDpoUsers()->shouldNotBeCalled(); $this->userRepository->findNonDpoUsersForCollectivity(Argument::any())->shouldNotBeCalled(); $this->lifeCycleEventArgs->getObjectManager()->shouldBeCalled()->willReturn($om); @@ -222,7 +240,7 @@ class NotificationGenerationSubscriberTest extends TestCase $notification->setName($object->getName()); $notification->setAction('notification.actions.create'); $notification->setCreatedBy(null); - $notification->setObject((object) []); + $notification->setObject((object) ['type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT]); $om->persist(new NotificationToken($notification))->shouldHaveBeenCalled(); $om->persist(Argument::type(\App\Domain\Notification\Model\NotificationUser::class))->shouldNotHaveBeenCalled(); @@ -232,6 +250,7 @@ class NotificationGenerationSubscriberTest extends TestCase public function testUpdateProofNotification() { $object = new Proof(); + $object->setType(ProofTypeDictionary::TYPE_POLICY_MANAGEMENT); $om = $this->prophesize(EntityManagerInterface::class); $uow = $this->prophesize(UnitOfWork::class); @@ -247,7 +266,11 @@ class NotificationGenerationSubscriberTest extends TestCase $om->getClassMetadata(\App\Domain\Notification\Model\Notification::class)->shouldBeCalled()->willReturn($this->notificationMetadata); $om->getClassMetadata(\App\Domain\Notification\Model\NotificationUser::class)->shouldBeCalled()->willReturn($this->notificationUserMetadata); - $this->notificationNormalizer->normalize($object, null, Argument::type('array'))->shouldBeCalled(); + $this->notificationNormalizer->normalize($object, null, Argument::type('array')) + ->shouldBeCalled() + ->willReturn((object) [ + 'type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT, + ]); $this->userRepository->findNonDpoUsers()->shouldNotBeCalled(); $this->userRepository->findNonDpoUsersForCollectivity(Argument::any())->shouldNotBeCalled(); $this->lifeCycleEventArgs->getObjectManager()->shouldBeCalled()->willReturn($om); @@ -260,7 +283,7 @@ class NotificationGenerationSubscriberTest extends TestCase $notification->setName($object->getName()); $notification->setAction('notification.actions.update'); $notification->setCreatedBy(null); - $notification->setObject((object) []); + $notification->setObject((object) ['type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT]); $om->persist(new NotificationToken($notification))->shouldHaveBeenCalled(); $om->persist(Argument::type(\App\Domain\Notification\Model\NotificationUser::class))->shouldNotHaveBeenCalled(); @@ -270,6 +293,7 @@ class NotificationGenerationSubscriberTest extends TestCase public function testDeleteProofNotification() { $object = new Proof(); + $object->setType(ProofTypeDictionary::TYPE_POLICY_MANAGEMENT); $om = $this->prophesize(EntityManagerInterface::class); $uow = $this->prophesize(UnitOfWork::class); @@ -282,10 +306,17 @@ class NotificationGenerationSubscriberTest extends TestCase $this->security->getUser()->shouldBeCalled()->willReturn(new \App\Domain\User\Model\User()); - $om->getClassMetadata(\App\Domain\Notification\Model\Notification::class)->shouldBeCalled()->willReturn($this->notificationMetadata); - $om->getClassMetadata(\App\Domain\Notification\Model\NotificationUser::class)->shouldBeCalled()->willReturn($this->notificationUserMetadata); - - $this->notificationNormalizer->normalize($object, null, Argument::type('array'))->shouldBeCalled(); + $om->getClassMetadata(\App\Domain\Notification\Model\Notification::class) + ->shouldBeCalled() + ->willReturn($this->notificationMetadata); + $om->getClassMetadata(\App\Domain\Notification\Model\NotificationUser::class) + ->shouldBeCalled() + ->willReturn($this->notificationUserMetadata); + + $this->notificationNormalizer->normalize($object, null, Argument::type('array')) + ->shouldBeCalled()->willReturn((object) [ + 'type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT, + ]); $this->userRepository->findNonDpoUsers()->shouldNotBeCalled(); $this->userRepository->findNonDpoUsersForCollectivity(Argument::any())->shouldNotBeCalled(); $this->lifeCycleEventArgs->getObjectManager()->shouldBeCalled()->willReturn($om); @@ -298,7 +329,7 @@ class NotificationGenerationSubscriberTest extends TestCase $notification->setName($object->getName()); $notification->setAction('notification.actions.delete'); $notification->setCreatedBy(null); - $notification->setObject((object) []); + $notification->setObject((object) ['type' => ProofTypeDictionary::TYPE_POLICY_MANAGEMENT]); $om->persist(new NotificationToken($notification))->shouldHaveBeenCalled();