diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php index bdfd3326f..5cea8daf2 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php @@ -11,17 +11,28 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators; +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 Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use function in_array; final readonly class ScopeAggregator implements AggregatorInterface { - public function __construct(private ScopeRepository $scopeRepository, private TranslatableStringHelper $translatableStringHelper) {} + private const PREFIX = 'acp_work_action_agg_user_scope'; + + public function __construct( + private RollingDateConverter $rollingDateConverter, + private ScopeRepository $scopeRepository, + private TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -30,12 +41,31 @@ final readonly class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acpwuser', $qb->getAllAliases(), true)) { - $qb->leftJoin('acpw.referrers', 'acpwuser'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(acpwuser.mainScope) as scope_aggregator'); - $qb->addGroupBy('scope_aggregator'); + $qb + ->leftJoin("acpw.referrers", "{$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 +75,14 @@ final readonly class ScopeAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - // no form + $builder->add('scope_at', PickRollingDateType::class, [ + 'label' => 'export.acpw.agent_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) @@ -63,7 +96,9 @@ final readonly class ScopeAggregator implements AggregatorInterface return ''; } - $s = $this->scopeRepository->find($value); + if (null === $s = $this->scopeRepository->find($value)) { + return ''; + } return $this->translatableStringHelper->localize( $s->getName() @@ -73,11 +108,11 @@ final readonly class ScopeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['scope_aggregator']; + return [self::PREFIX . '_select']; } public function getTitle(): string { - return 'Group by treating agent scope'; + return 'export.acpw.agent_scope.Group by treating agent scope'; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php index 9a31d88bc..0bb9fba13 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Aggregator\SocialWorkAggregators; +use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ScopeAggregator; @@ -39,7 +40,9 @@ final class ScopeAggregatorTest extends AbstractAggregatorTest public function getFormData(): array { return [ - [], + [ + 'scope_at' => new RollingDate(RollingDate::T_FIXED_DATE, \DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01')), + ], ]; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index d6f6eef4d..a14ea3ed7 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -598,7 +598,6 @@ Filter by current evaluations: Filtrer les évaluations en cours ## social actions filters/aggr Filter by treating agent scope: Filtrer les actions par service de l'agent traitant "Filtered by treating agent scope: only %scopes%": "Filtré par service de l'agent traitant: uniquement %scopes%" -Group by treating agent scope: Grouper les actions par service de l'agent traitant Filter by scope: Filtrer par service @@ -1007,6 +1006,9 @@ export: agent_job: Group by treating agent job: Grouper les actions par métier de l'agent traitant Calc date: Date de calcul du métier de l'agent traitant + agent_scope: + Group by treating agent scope: Grouper les actions par service de l'agent traitant + Calc date: Date de calcul du service de l'agent traitant export: acp_stats: avg_duration: Moyenne de la durée de participation de chaque usager concerné