diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php index 581614832..5841cb20f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php @@ -12,16 +12,26 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\AggregatorInterface; +use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Repository\ScopeRepository; +use Chill\MainBundle\Service\RollingDate\RollingDate; +use Chill\MainBundle\Service\RollingDate\RollingDateConverter; use Chill\MainBundle\Templating\TranslatableStringHelper; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class CreatorScopeAggregator implements AggregatorInterface { - public function __construct(private readonly ScopeRepository $scopeRepository, private readonly TranslatableStringHelper $translatableStringHelper) {} + private const PREFIX = 'acp_agg_creator_scope'; + + public function __construct( + private readonly RollingDateConverter $rollingDateConverter, + private readonly ScopeRepository $scopeRepository, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -30,12 +40,30 @@ class CreatorScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actcreator', $qb->getAllAliases(), true)) { - $qb->leftJoin('activity.createdBy', 'actcreator'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(actcreator.mainScope) AS creatorscope_aggregator'); - $qb->addGroupBy('creatorscope_aggregator'); + $qb + ->leftJoin("activity.createdBy", "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Expr\Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", ":{$p}_at"), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", ":{$p}_at") + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select") + ->setParameter( + "{$p}_at", $this->rollingDateConverter->convert($data['scope_at']) + ) + ->addGroupBy("{$p}_select"); } public function applyOn(): string @@ -45,11 +73,14 @@ class CreatorScopeAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - // no form + $builder->add('scope_at', PickRollingDateType::class, [ + 'label' => 'export.aggregator.activity.by_creator_scope.Calc date', + 'required' => true, + ]); } public function getFormDefaultData(): array { - return []; + return ['scope_at' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) @@ -73,11 +104,11 @@ class CreatorScopeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['creatorscope_aggregator']; + return ['_select']; } public function getTitle(): string { - return 'Group activity by creator scope'; + return 'export.aggregator.activity.by_creator_scope.Group activity by creator scope'; } } diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index b824b7a56..ef9a1b45e 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -316,7 +316,6 @@ for week: Semaine by year: Par année in year: En Group activity by creator: Grouper les échanges par créateur de l'échange -Group activity by creator scope: Grouper les échanges par service du créateur de l'échange Group activity by linked thirdparties: Grouper les échanges par tiers impliqué Accepted thirdparty: Tiers impliqué Group activity by linked socialaction: Grouper les échanges par action liée @@ -395,6 +394,9 @@ export: Users 's scope: Service principal des utilisateurs participants à l'échange Aggregate by users scope: Grouper les échanges par service principal de l'utilisateur Calc date: Date de calcul du service principal de l'utilisateur + by_creator_scope: + Group activity by creator scope: Grouper les échanges par service du créateur de l'échange + Calc date: Date de calcul du service du créateur de l'échange generic_doc: diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php index b07da6871..c9d8cbde8 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php @@ -11,17 +11,27 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Export\AggregatorInterface; +use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Repository\UserJobRepository; +use Chill\MainBundle\Service\RollingDate\RollingDate; +use Chill\MainBundle\Service\RollingDate\RollingDateConverter; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class CreatorJobAggregator implements AggregatorInterface { - public function __construct(private readonly UserJobRepository $jobRepository, private readonly TranslatableStringHelper $translatableStringHelper) {} + private const PREFIX = 'acp_agg_creator_job'; + + public function __construct( + private readonly RollingDateConverter $rollingDateConverter, + private readonly UserJobRepository $jobRepository, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -30,12 +40,30 @@ class CreatorJobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acp_creator', $qb->getAllAliases(), true)) { - $qb->leftJoin('acp.createdBy', 'acp_creator'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(acp_creator.userJob) AS acp_creator_job_aggregator') - ->addGroupBy('acp_creator_job_aggregator'); + $qb + ->leftJoin("acp.createdBy", "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Expr\Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", ":{$p}_at"), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", ":{$p}_at") + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.job) AS {$p}_select") + ->setParameter( + "{$p}_at", $this->rollingDateConverter->convert($data['job_at']) + ) + ->addGroupBy("{$p}_select"); } public function applyOn(): string @@ -45,11 +73,14 @@ class CreatorJobAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - // No form needed + $builder->add('job_at', PickRollingDateType::class, [ + 'label' => 'export.aggregator.course.by_creator_job.Calc date', + 'required' => true + ]); } public function getFormDefaultData(): array { - return []; + return ['job_at' => new RollingDate(RollingDate::T_TODAY)]; } public function getLabels($key, array $values, $data) @@ -71,11 +102,11 @@ class CreatorJobAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['acp_creator_job_aggregator']; + return [self::PREFIX . '_select']; } public function getTitle(): string { - return 'Group by creator job'; + return 'export.aggregator.course.by_creator_job.Group by creator job'; } } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index bfecd6559..1a240422b 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -573,7 +573,6 @@ Filter by creator: Filtrer les parcours par créateur 'Filtered by creator: only %creators%': 'Filtré par créateur: uniquement %creators%' Filter by creator job: Filtrer les parcours par métier du créateur 'Filtered by creator job: only %jobs%': 'Filtré par métier du créateur: uniquement %jobs%' -Group by creator job: Grouper les parcours par métier du créateur Filter actions without end date: Filtre les actions sans date de fin (ouvertes) Filtered actions without end date: 'Filtré: uniquement les actions sans date de fin (ouvertes)' @@ -1029,6 +1028,8 @@ export: Number of actions: Nombre d'actions by_creator_job: Creator's job: Métier du créateur + Group by creator job: Grouper les parcours par métier du créateur + Calc date: Date de calcul du métier du créateur by_user_working: title: Grouper les parcours par intervenant user: Intervenant