diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index 8d1960dda..0dc66e81e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -13,21 +13,23 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; use Chill\MainBundle\Export\AggregatorInterface; use Chill\PersonBundle\Export\Declarations; +use DateTimeImmutable; use Doctrine\ORM\QueryBuilder; +use LogicException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; final class DurationAggregator implements AggregatorInterface { - private TranslatorInterface $translator; - private const CHOICES = [ 'month', 'week', - 'day' + 'day', ]; + private TranslatorInterface $translator; + public function __construct(TranslatorInterface $translator) { $this->translator = $translator; @@ -42,23 +44,29 @@ final class DurationAggregator implements AggregatorInterface { switch ($data['precision']) { case 'day': - $qb->addSelect('(COALESCE(acp.closingDate, NOW()) - acp.openingDate) AS duration_aggregator'); + $qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) AS duration_aggregator'); + break; + case 'week': - $qb->addSelect('EXTRACT (YEAR FROM AGE(COALESCE(acp.closingDate, NOW()), acp.openingDate) * 52 + - EXTRACT (WEEK FROM AGE(COALESCE(acp.closingDate, NOW()'); + $qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7 AS duration_aggregator'); + break; + case 'month': + $qb->addSelect('(EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 + + EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate))) AS duration_aggregator'); + break; + + default: + throw new LogicException('precision not supported: ' . $data['precision']); } - // TODO Pour avoir un interval plus précis (nécessaire ?): - // adapter la fonction extract pour pouvoir l'utiliser avec des intervals: extract(month from interval) - // et ajouter une fonction custom qui calcule plus précisément les intervals, comme doctrineum/date-interval - // https://packagist.org/packages/doctrineum/date-interval#3.1.0 (mais composer fait un conflit de dépendance) - - $qb->addGroupBy('duration_aggregator'); - $qb->addOrderBy('duration_aggregator'); + $qb + ->setParameter('now', new DateTimeImmutable('now')) + ->addGroupBy('duration_aggregator') + ->addOrderBy('duration_aggregator'); } public function applyOn(): string @@ -71,7 +79,7 @@ final class DurationAggregator implements AggregatorInterface $builder->add('precision', ChoiceType::class, [ 'choices' => array_combine(self::CHOICES, self::CHOICES), 'label' => 'export.aggregator.course.duration.Precision', - 'choice_label' => fn (string $c) => 'export.aggregator.course.duration.'.$c, + 'choice_label' => static fn (string $c) => 'export.aggregator.course.duration.' . $c, 'multiple' => false, 'expanded' => true, ]); @@ -79,20 +87,16 @@ final class DurationAggregator implements AggregatorInterface public function getLabels($key, array $values, $data) { - return function ($value): ?string { + return static function ($value) use ($data) { if ('_header' === $value) { - return 'Rounded month duration'; + return 'export.aggregator.course.duration.' . $data['precision']; } if (null === $value) { - return $this->translator->trans('current duration'); // when closingDate is null + return 0; } - if (0 === $value) { - return $this->translator->trans('duration 0 month'); - } - - return $value . $this->translator->trans(' months'); + return $value; }; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 55014637a..7e9fbfeaa 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -951,3 +951,8 @@ export: Group course by referrer's scope: Grouper les parcours par service du référent Computation date for referrer: Date à laquelle le référent était actif Referrer's scope: Service du référent de parcours + duration: + day: Durée du parcours en jours + week: Durée du parcours en semaines + month: Durée du parcours en mois + Precision: Unité de la durée