From 2b57807565a335e6d81a761bd11d490cc9fa7de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 30 May 2023 22:14:13 +0200 Subject: [PATCH] show generic doc accompanying course document in person generic doc list --- ...anyingCourseDocumentGenericDocProvider.php | 75 +++++++++++++++++-- ...anyingCourseDocumentGenericDocRenderer.php | 10 +-- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php index 439f6a511..054e6a6d8 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProvider.php @@ -15,13 +15,17 @@ use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; +use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; +use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; -final readonly class AccompanyingCourseDocumentGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface +final readonly class AccompanyingCourseDocumentGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface { public const KEY = 'accompanying_course_document'; @@ -38,7 +42,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen $query = new FetchQuery( self::KEY, sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), - sprintf($classMetadata->getColumnName('date')), + $classMetadata->getColumnName('date'), $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() ); @@ -48,6 +52,67 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen [Types::INTEGER] ); + return $this->addWhereClause($query, $startDate, $endDate, $content); + } + + public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool + { + return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); + } + + public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); + + $query = new FetchQuery( + self::KEY, + sprintf('jsonb_build_object(\'id\', %s)', $classMetadata->getIdentifierColumnNames()[0]), + $classMetadata->getColumnName('date'), + $classMetadata->getSchemaName() . '.' . $classMetadata->getTableName() . ' AS acc_course_document' + ); + + $atLeastOne = false; + $or = []; + $orParams = []; + $orTypes = []; + + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (!$this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $participation->getAccompanyingPeriod())) { + continue; + } + + $atLeastOne = true; + + $or[] = sprintf( + "(acc_course_document.%s = ? AND acc_course_document.%s BETWEEN ? AND COALESCE(?, 'infinity'::date))", + $classMetadata->getSingleAssociationJoinColumnName('course'), + $classMetadata->getColumnName('date') + ); + $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), $participation->getStartDate(), $participation->getEndDate()]; + $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_MUTABLE, Types::DATE_MUTABLE]; + } + + if (!$atLeastOne) { + // there aren't any period allowed to be seen. Add an unreachable condition + $query->addWhereClause('TRUE = FALSE'); + + return $query; + } + + $query->addWhereClause(implode(' OR ', $or), $orParams, $orTypes); + + return $this->addWhereClause($query, $startDate, $endDate, $content); + } + + public function isAllowedForPerson(Person $person): bool + { + return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); + } + + private function addWhereClause(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + { + $classMetadata = $this->entityManager->getClassMetadata(AccompanyingCourseDocument::class); + if (null !== $startDate) { $query->addWhereClause( sprintf('? <= %s', $classMetadata->getColumnName('date')), @@ -64,7 +129,7 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen ); } - if (null !== $content) { + if (null !== $content and '' !== $content) { $query->addWhereClause( sprintf( '(%s ilike ? OR %s ilike ?)', @@ -79,8 +144,4 @@ final readonly class AccompanyingCourseDocumentGenericDocProvider implements Gen return $query; } - public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool - { - return $this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $accompanyingPeriod); - } } diff --git a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php index ffa158aca..052153be8 100644 --- a/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php +++ b/src/Bundle/ChillDocStoreBundle/GenericDoc/Renderer/AccompanyingCourseDocumentGenericDocRenderer.php @@ -40,18 +40,18 @@ final readonly class AccompanyingCourseDocumentGenericDocRenderer implements Gen public function getTemplateData(GenericDocDTO $genericDocDTO, $options = []): array { - if ($genericDocDTO->linked instanceof AccompanyingPeriod) { + if (AccompanyingCourseDocumentGenericDocProvider::KEY === $genericDocDTO->key) { return [ - 'document' => $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), - 'accompanyingCourse' => $genericDocDTO->linked, + 'document' => $doc = $this->accompanyingCourseDocumentRepository->find($genericDocDTO->identifiers['id']), + 'accompanyingCourse' => $doc->getCourse(), 'options' => $options, ]; } // this is a person return [ - 'document' => $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), - 'person' => $genericDocDTO->linked, + 'document' => $doc = $this->personDocumentRepository->find($genericDocDTO->identifiers['id']), + 'person' => $doc->getPerson(), 'options' => $options, ]; }