From cb718a80dece206e020c4cac7e86aa2e0b735172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 31 May 2023 12:23:34 +0200 Subject: [PATCH] Add accompanying period work evaluation documents to the list of documents for person --- ...anyingCourseDocumentGenericDocProvider.php | 2 +- ...PeriodWorkEvaluationGenericDocProvider.php | 136 +++++++++++++----- 2 files changed, 99 insertions(+), 39 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php index 054e6a6d8..fd36f7976 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php @@ -99,7 +99,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen return $query; } - $query->addWhereClause(implode(' OR ', $or), $orParams, $orTypes); + $query->addWhereClause('(' . implode(' OR ', $or) . ')', $orParams, $orTypes); return $this->addWhereClause($query, $startDate, $endDate, $content); } diff --git a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php index 883836547..f8b99a048 100644 --- a/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php +++ b/src/Bundle/ChillPersonBundle/Service/GenericDoc/Providers/AccompanyingPeriodWorkEvaluationGenericDocProvider.php @@ -15,13 +15,16 @@ use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface { public const KEY = 'accompanying_period_work_evaluation_document'; @@ -32,6 +35,100 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen } public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $accompanyingPeriodWorkMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWork::class); + $query = $this->buildBaseQuery(); + + $query->addWhereClause( + sprintf('action.%s = ?', $accompanyingPeriodWorkMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), + [$accompanyingPeriod->getId()], + [Types::INTEGER] + ); + + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $accompanyingPeriod); + } + + private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument::class); + $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); + + if (null !== $startDate) { + $query->addWhereClause( + sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), + [$startDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $endDate) { + $query->addWhereClause( + sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), + [$endDate], + [Types::DATE_IMMUTABLE] + ); + } + + if (null !== $content) { + $query->addWhereClause( + sprintf('apwed.%s ilike ?', $classMetadata->getColumnName('title')), + ['%' . $content . '%'], + [Types::STRING] + ); + } + + return $query; + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); + $accompanyingPeriodWorkMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWork::class); + $query = $this->buildBaseQuery(); + + // we loop over each accompanying period participation, to check of the user is allowed to see them + $or = []; + $orParams = []; + $orTypes = []; + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $or[] = sprintf( + '(action.%s = ? AND apwed.%s BETWEEN ?::date AND COALESCE(?::date, \'infinity\'::date))', + $accompanyingPeriodWorkMetadata->getSingleAssociationJoinColumnName('accompanyingPeriod'), + $storedObjectMetadata->getColumnName('createdAt') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), + DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; + } + + if ([] === $or) { + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + + $query->addWhereClause(sprintf('(%s)', implode(' OR ', $or)), $orParams, $orTypes); + + return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); + } + + public function isAllowedForPerson(Person $person): bool + { + // this will be filtered during query + return true; + } + + private function buildBaseQuery(): FetchQuery { $classMetadata = $this->entityManager->getClassMetadata(AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument::class); $storedObjectMetadata = $this->entityManager->getClassMetadata(StoredObject::class); @@ -63,43 +160,6 @@ final readonly class AccompanyingPeriodWorkEvaluationGenericDocProvider implemen $accompanyingPeriodWorkMetadata->getColumnName('id') )); - $query->addWhereClause( - sprintf('action.%s = ?', $accompanyingPeriodWorkMetadata->getAssociationMapping('accompanyingPeriod')['joinColumns'][0]['name']), - [$accompanyingPeriod->getId()], - [Types::INTEGER] - ); - - if (null !== $startDate) { - $query->addWhereClause( - sprintf('doc_store.%s >= ?', $storedObjectMetadata->getColumnName('createdAt')), - [$startDate], - [Types::DATE_IMMUTABLE] - ); - } - - if (null !== $endDate) { - $query->addWhereClause( - sprintf('doc_store.%s < ?', $storedObjectMetadata->getColumnName('createdAt')), - [$endDate], - [Types::DATE_IMMUTABLE] - ); - } - - if (null !== $content) { - $query->addWhereClause( - sprintf('apwed.%s ilike ?', $classMetadata->getColumnName('title')), - ['%' . $content . '%'], - [Types::STRING] - ); - } - return $query; } - - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $accompanyingPeriod); - } - - }