mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Feature: [export][acp] aggregator by course's duration
This commit is contained in:
parent
3a8640db43
commit
d5efbd505c
@ -13,21 +13,23 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
|
|||||||
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
|
use DateTimeImmutable;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use LogicException;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
final class DurationAggregator implements AggregatorInterface
|
final class DurationAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
private TranslatorInterface $translator;
|
|
||||||
|
|
||||||
private const CHOICES = [
|
private const CHOICES = [
|
||||||
'month',
|
'month',
|
||||||
'week',
|
'week',
|
||||||
'day'
|
'day',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
public function __construct(TranslatorInterface $translator)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
@ -42,23 +44,29 @@ final class DurationAggregator implements AggregatorInterface
|
|||||||
{
|
{
|
||||||
switch ($data['precision']) {
|
switch ($data['precision']) {
|
||||||
case 'day':
|
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;
|
break;
|
||||||
|
|
||||||
case 'week':
|
case 'week':
|
||||||
$qb->addSelect('EXTRACT (YEAR FROM AGE(COALESCE(acp.closingDate, NOW()), acp.openingDate) * 52 +
|
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7 AS duration_aggregator');
|
||||||
EXTRACT (WEEK FROM AGE(COALESCE(acp.closingDate, NOW()');
|
|
||||||
break;
|
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 ?):
|
$qb
|
||||||
// adapter la fonction extract pour pouvoir l'utiliser avec des intervals: extract(month from interval)
|
->setParameter('now', new DateTimeImmutable('now'))
|
||||||
// et ajouter une fonction custom qui calcule plus précisément les intervals, comme doctrineum/date-interval
|
->addGroupBy('duration_aggregator')
|
||||||
// https://packagist.org/packages/doctrineum/date-interval#3.1.0 (mais composer fait un conflit de dépendance)
|
->addOrderBy('duration_aggregator');
|
||||||
|
|
||||||
$qb->addGroupBy('duration_aggregator');
|
|
||||||
$qb->addOrderBy('duration_aggregator');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -71,7 +79,7 @@ final class DurationAggregator implements AggregatorInterface
|
|||||||
$builder->add('precision', ChoiceType::class, [
|
$builder->add('precision', ChoiceType::class, [
|
||||||
'choices' => array_combine(self::CHOICES, self::CHOICES),
|
'choices' => array_combine(self::CHOICES, self::CHOICES),
|
||||||
'label' => 'export.aggregator.course.duration.Precision',
|
'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,
|
'multiple' => false,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
]);
|
]);
|
||||||
@ -79,20 +87,16 @@ final class DurationAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data)
|
||||||
{
|
{
|
||||||
return function ($value): ?string {
|
return static function ($value) use ($data) {
|
||||||
if ('_header' === $value) {
|
if ('_header' === $value) {
|
||||||
return 'Rounded month duration';
|
return 'export.aggregator.course.duration.' . $data['precision'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $value) {
|
if (null === $value) {
|
||||||
return $this->translator->trans('current duration'); // when closingDate is null
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 === $value) {
|
return $value;
|
||||||
return $this->translator->trans('duration 0 month');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value . $this->translator->trans(' months');
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,3 +951,8 @@ export:
|
|||||||
Group course by referrer's scope: Grouper les parcours par service du référent
|
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
|
Computation date for referrer: Date à laquelle le référent était actif
|
||||||
Referrer's scope: Service du référent de parcours
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user