Loading module/Oscar/src/Oscar/Command/OscarNotificationsPurgeCommand.php 0 → 100644 +46 −0 Original line number Diff line number Diff line <?php namespace Oscar\Command; use Oscar\Service\NotificationService; use Oscar\Service\OscarUserContext; use Oscar\Service\PersonService; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; class OscarNotificationsPurgeCommand extends OscarCommandAbstract { protected static $defaultName = 'notifications:purge'; protected function configure() { $this ->setDescription("Purge les notifications obsolétes") ; } protected function execute(InputInterface $input, OutputInterface $output): int { $this->addOutputStyle($output); $io = new SymfonyStyle($input, $output); /** @var NotificationService $notificationService */ $notificationService = $this->getServicemanager()->get(NotificationService::class); try { $notificationService->purgeNotificationsObsoletes($io); $notificationService->purgeNotificationsPersonsInactive($io); $notificationService->purgeNotificationsNoPersons($io); } catch (\Exception $e) { $io->error($e->getMessage()); return self::FAILURE; } return self::SUCCESS; } } No newline at end of file module/Oscar/src/Oscar/Entity/Activity.php +27 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,19 @@ class Activity implements ResourceInterface { use TraitTrackable; public static function getStatusInactive() :array { return [ self::STATUS_ABORDED, self::STATUS_CLOSED, self::STATUS_FENCED, self::STATUS_REFUSED, self::STATUS_REFUSED_2, self::STATUS_REORIENTED, self::STATUS_TERMINATED, self::STATUS_TRANSFERED, ]; } public static function getStatusSelect() { static $statusSelect; Loading Loading @@ -1994,6 +2007,18 @@ class Activity implements ResourceInterface return $json; } public function getPersonsDeeper( bool $active = true) { $affectations = $this->getPersonsDeep(); /** @var ActivityOrganization $activityOrganization */ foreach ($this->getOrganizationsDeep() as $activityOrganization) { foreach ($activityOrganization->getOrganization()->getPersons() as $person) { $affectations[] = $person; } } return $affectations; } public function getPersonsDeep($ignoreMain = false) { $persons = []; Loading Loading @@ -2027,6 +2052,8 @@ class Activity implements ResourceInterface return $partners; } protected function deepParent(Organization $organization, &$out = []): array { if ($organization->getParent()) { Loading module/Oscar/src/Oscar/Entity/NotificationRepository.php +41 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ namespace Oscar\Entity; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\Expr\Join; class NotificationRepository extends EntityRepository { Loading Loading @@ -135,6 +136,46 @@ class NotificationRepository extends EntityRepository $this->getEntityManager()->createQuery($dql)->getResult(); } public function getNotificationsObsoletes(array $params) { $qb = $this->createQueryBuilder("n") ->leftJoin(Activity::class, 'a', Join::WITH, "n.objectId = a.id") ->where("n.object = :object") ->andWhere("a.status IN(:status)") ->orderBy('n.dateEffective', 'ASC'); $parameters = [ 'object' => 'activity', 'status' => $params['status'] ]; $qb->setParameters($parameters); return $qb->getQuery()->getResult(); } public function getNotificationsPersonsInactive(string $date) { $qb = $this->getEntityManager()->getRepository(NotificationPerson::class, 'np') ->createQueryBuilder('np') ->innerJoin('np.person', 'p') ->where('p.ldapFinInscription < :date') ->setParameters( [ 'date' => $date, ] ); return $qb->getQuery()->execute(); } public function getNotificationsEmpty() { $qb = $this->createQueryBuilder("n") ->where("n.persons IS EMPTY"); return $qb->getQuery()->getResult(); } protected function getQueryBuilderDeleteBase() { return $this->getBaseQueryBuilder() Loading module/Oscar/src/Oscar/Entity/PersonRepository.php +68 −1 Original line number Diff line number Diff line Loading @@ -251,7 +251,7 @@ class PersonRepository extends EntityRepository implements IConnectedRepository ) ->innerJoin(NotificationPerson::class, 'n', Join::WITH, $qb->expr()->eq('p.id', 'n.person')) ->innerJoin('n.notification', 'nt') ->where('n.read IS NULL AND nt.dateEffective <= :now') ->where('n.read IS NULL AND nt.dateEffective <= :now AND p.ldapFinInscription < :now') ->orderBy('p.lastname', 'ASC') ->setParameter('now', date('Y-m-d')) ->getQuery() Loading Loading @@ -672,4 +672,71 @@ class PersonRepository extends EntityRepository implements IConnectedRepository ; return $qb->getQuery()->getResult(); } public function getPersonsWithPaymentsLate():array { $sql = <<<SQL with -- IDS des activités ayant des versement prévisionnel en retard activity_ids as ( select distinct ap.activity_id as id from activitypayment ap join activity a on ap.activity_id = a.id where ap.datepredicted < now() and ap.status = 1 and a.status not in(200,201) ), -- IDs des rôles ayant le privilège de gérer les versements role_payment as ( select distinct ur.id as id from user_role ur join role_privilege rp on ur.id = rp.role_id join privilege p2 on p2.id = rp.privilege_id where p2.code = 'PAYMENT_MANAGE' ) SELECT DISTINCT p.* FROM person p WHERE -- Le compte de la personne est active (p.ldapfininscription is null or p.ldapfininscription <> '' or p.ldapfininscription::date > now()::date ) -- La personne est impliquée dans le versement and p.id IN ( SELECT ap.person_id FROM activityperson ap WHERE ap.activity_id IN(select id from activity_ids) and ap.roleobj_id IN(select id from role_payment) UNION SELECT pp.person_id FROM projectmember pp JOIN activity a ON a.project_id = pp.project_id WHERE a.id IN(select id from activity_ids) and pp.roleobj_id IN(select id from role_payment) UNION -- 3️⃣ Person via une organization liée à l’activité SELECT po.person_id FROM organizationperson po JOIN activityorganization ao ON ao.organization_id = po.organization_id WHERE ao.activity_id IN(select id from activity_ids) and po.roleobj_id IN(select id from role_payment) UNION -- 4️⃣ Person via une organization liée au projet de l’activité SELECT po.person_id FROM organizationperson po JOIN projectpartner oproj ON oproj.organization_id = po.organization_id JOIN activity a ON a.project_id = oproj.project_id WHERE a.id IN(select id from activity_ids) and po.roleobj_id IN(select id from role_payment) ) ; SQL; return $this->getEntityManager() ->getConnection() ->executeQuery($sql) ->fetchAllAssociative(); } } module/Oscar/src/Oscar/Service/NotificationService.php +37 −0 Original line number Diff line number Diff line Loading @@ -988,4 +988,41 @@ class NotificationService implements UseServiceContainer // // die("Calcule"); } public function purgeNotificationsObsoletes(\Symfony\Component\Console\Style\SymfonyStyle $io) { $params = [ 'status' => Activity::getStatusInactive() ]; $notifications = $this->getNotificationRepository()->getNotificationsObsoletes($params); $total = count($notifications); foreach ($notifications as $notification) { $this->getEntityManager()->remove($notification); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Activités terminées"); } public function purgeNotificationsPersonsInactive(\Symfony\Component\Console\Style\SymfonyStyle $io) { $date = new \DateTime('-6 month'); $notifications = $this->getNotificationRepository()->getNotificationsPersonsInactive($date->format('Y-m-d')); $total = count($notifications); foreach ($notifications as $notificationPerson) { $this->getEntityManager()->remove($notificationPerson); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Personnes désactivées depuis plus de 6 mois"); } public function purgeNotificationsNoPersons(\Symfony\Component\Console\Style\SymfonyStyle $io) { $notifications = $this->getNotificationRepository()->getNotificationsEmpty(); $total = count($notifications); foreach ($notifications as $notification) { $this->getEntityManager()->remove($notification); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Aucune personnes associées"); } } Loading
module/Oscar/src/Oscar/Command/OscarNotificationsPurgeCommand.php 0 → 100644 +46 −0 Original line number Diff line number Diff line <?php namespace Oscar\Command; use Oscar\Service\NotificationService; use Oscar\Service\OscarUserContext; use Oscar\Service\PersonService; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; class OscarNotificationsPurgeCommand extends OscarCommandAbstract { protected static $defaultName = 'notifications:purge'; protected function configure() { $this ->setDescription("Purge les notifications obsolétes") ; } protected function execute(InputInterface $input, OutputInterface $output): int { $this->addOutputStyle($output); $io = new SymfonyStyle($input, $output); /** @var NotificationService $notificationService */ $notificationService = $this->getServicemanager()->get(NotificationService::class); try { $notificationService->purgeNotificationsObsoletes($io); $notificationService->purgeNotificationsPersonsInactive($io); $notificationService->purgeNotificationsNoPersons($io); } catch (\Exception $e) { $io->error($e->getMessage()); return self::FAILURE; } return self::SUCCESS; } } No newline at end of file
module/Oscar/src/Oscar/Entity/Activity.php +27 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,19 @@ class Activity implements ResourceInterface { use TraitTrackable; public static function getStatusInactive() :array { return [ self::STATUS_ABORDED, self::STATUS_CLOSED, self::STATUS_FENCED, self::STATUS_REFUSED, self::STATUS_REFUSED_2, self::STATUS_REORIENTED, self::STATUS_TERMINATED, self::STATUS_TRANSFERED, ]; } public static function getStatusSelect() { static $statusSelect; Loading Loading @@ -1994,6 +2007,18 @@ class Activity implements ResourceInterface return $json; } public function getPersonsDeeper( bool $active = true) { $affectations = $this->getPersonsDeep(); /** @var ActivityOrganization $activityOrganization */ foreach ($this->getOrganizationsDeep() as $activityOrganization) { foreach ($activityOrganization->getOrganization()->getPersons() as $person) { $affectations[] = $person; } } return $affectations; } public function getPersonsDeep($ignoreMain = false) { $persons = []; Loading Loading @@ -2027,6 +2052,8 @@ class Activity implements ResourceInterface return $partners; } protected function deepParent(Organization $organization, &$out = []): array { if ($organization->getParent()) { Loading
module/Oscar/src/Oscar/Entity/NotificationRepository.php +41 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ namespace Oscar\Entity; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\Expr\Join; class NotificationRepository extends EntityRepository { Loading Loading @@ -135,6 +136,46 @@ class NotificationRepository extends EntityRepository $this->getEntityManager()->createQuery($dql)->getResult(); } public function getNotificationsObsoletes(array $params) { $qb = $this->createQueryBuilder("n") ->leftJoin(Activity::class, 'a', Join::WITH, "n.objectId = a.id") ->where("n.object = :object") ->andWhere("a.status IN(:status)") ->orderBy('n.dateEffective', 'ASC'); $parameters = [ 'object' => 'activity', 'status' => $params['status'] ]; $qb->setParameters($parameters); return $qb->getQuery()->getResult(); } public function getNotificationsPersonsInactive(string $date) { $qb = $this->getEntityManager()->getRepository(NotificationPerson::class, 'np') ->createQueryBuilder('np') ->innerJoin('np.person', 'p') ->where('p.ldapFinInscription < :date') ->setParameters( [ 'date' => $date, ] ); return $qb->getQuery()->execute(); } public function getNotificationsEmpty() { $qb = $this->createQueryBuilder("n") ->where("n.persons IS EMPTY"); return $qb->getQuery()->getResult(); } protected function getQueryBuilderDeleteBase() { return $this->getBaseQueryBuilder() Loading
module/Oscar/src/Oscar/Entity/PersonRepository.php +68 −1 Original line number Diff line number Diff line Loading @@ -251,7 +251,7 @@ class PersonRepository extends EntityRepository implements IConnectedRepository ) ->innerJoin(NotificationPerson::class, 'n', Join::WITH, $qb->expr()->eq('p.id', 'n.person')) ->innerJoin('n.notification', 'nt') ->where('n.read IS NULL AND nt.dateEffective <= :now') ->where('n.read IS NULL AND nt.dateEffective <= :now AND p.ldapFinInscription < :now') ->orderBy('p.lastname', 'ASC') ->setParameter('now', date('Y-m-d')) ->getQuery() Loading Loading @@ -672,4 +672,71 @@ class PersonRepository extends EntityRepository implements IConnectedRepository ; return $qb->getQuery()->getResult(); } public function getPersonsWithPaymentsLate():array { $sql = <<<SQL with -- IDS des activités ayant des versement prévisionnel en retard activity_ids as ( select distinct ap.activity_id as id from activitypayment ap join activity a on ap.activity_id = a.id where ap.datepredicted < now() and ap.status = 1 and a.status not in(200,201) ), -- IDs des rôles ayant le privilège de gérer les versements role_payment as ( select distinct ur.id as id from user_role ur join role_privilege rp on ur.id = rp.role_id join privilege p2 on p2.id = rp.privilege_id where p2.code = 'PAYMENT_MANAGE' ) SELECT DISTINCT p.* FROM person p WHERE -- Le compte de la personne est active (p.ldapfininscription is null or p.ldapfininscription <> '' or p.ldapfininscription::date > now()::date ) -- La personne est impliquée dans le versement and p.id IN ( SELECT ap.person_id FROM activityperson ap WHERE ap.activity_id IN(select id from activity_ids) and ap.roleobj_id IN(select id from role_payment) UNION SELECT pp.person_id FROM projectmember pp JOIN activity a ON a.project_id = pp.project_id WHERE a.id IN(select id from activity_ids) and pp.roleobj_id IN(select id from role_payment) UNION -- 3️⃣ Person via une organization liée à l’activité SELECT po.person_id FROM organizationperson po JOIN activityorganization ao ON ao.organization_id = po.organization_id WHERE ao.activity_id IN(select id from activity_ids) and po.roleobj_id IN(select id from role_payment) UNION -- 4️⃣ Person via une organization liée au projet de l’activité SELECT po.person_id FROM organizationperson po JOIN projectpartner oproj ON oproj.organization_id = po.organization_id JOIN activity a ON a.project_id = oproj.project_id WHERE a.id IN(select id from activity_ids) and po.roleobj_id IN(select id from role_payment) ) ; SQL; return $this->getEntityManager() ->getConnection() ->executeQuery($sql) ->fetchAllAssociative(); } }
module/Oscar/src/Oscar/Service/NotificationService.php +37 −0 Original line number Diff line number Diff line Loading @@ -988,4 +988,41 @@ class NotificationService implements UseServiceContainer // // die("Calcule"); } public function purgeNotificationsObsoletes(\Symfony\Component\Console\Style\SymfonyStyle $io) { $params = [ 'status' => Activity::getStatusInactive() ]; $notifications = $this->getNotificationRepository()->getNotificationsObsoletes($params); $total = count($notifications); foreach ($notifications as $notification) { $this->getEntityManager()->remove($notification); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Activités terminées"); } public function purgeNotificationsPersonsInactive(\Symfony\Component\Console\Style\SymfonyStyle $io) { $date = new \DateTime('-6 month'); $notifications = $this->getNotificationRepository()->getNotificationsPersonsInactive($date->format('Y-m-d')); $total = count($notifications); foreach ($notifications as $notificationPerson) { $this->getEntityManager()->remove($notificationPerson); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Personnes désactivées depuis plus de 6 mois"); } public function purgeNotificationsNoPersons(\Symfony\Component\Console\Style\SymfonyStyle $io) { $notifications = $this->getNotificationRepository()->getNotificationsEmpty(); $total = count($notifications); foreach ($notifications as $notification) { $this->getEntityManager()->remove($notification); } $this->getEntityManager()->flush(); $this->getLoggerService()->info("$total notification(s) purgées - Aucune personnes associées"); } }