From e1ec2dc25c05bdac13226faec200c3a14ff289af Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 25 Aug 2022 12:38:00 +0200 Subject: [PATCH] exports: DurationAggregator: test qb addSelect for compute date interval --- .../ChillMainBundle/Doctrine/DQL/Extract.php | 13 +++-- .../DurationAggregator.php | 51 ++++++++++++++++--- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php index 44d20724b..72ca2b461 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php @@ -2,7 +2,9 @@ namespace Chill\MainBundle\Doctrine\DQL; +use Doctrine\ORM\Query\AST\Functions\DateDiffFunction; use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\AST\Node; use Doctrine\ORM\Query\AST\PathExpression; use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; @@ -12,13 +14,17 @@ use Doctrine\ORM\Query\SqlWalker; * Extract postgresql function * https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT * - * Usage : EXTRACT(field FROM value) + * Usage : EXTRACT(field FROM timestamp) + * TODO allow interval usage -> EXTRACT(field FROM interval) */ class Extract extends FunctionNode { private string $field; - private PathExpression $value; + private $value; + //private PathExpression $value; + //private FunctionNode $value; + //private DateDiffFunction $value; public function getSql(SqlWalker $sqlWalker) { @@ -39,7 +45,8 @@ class Extract extends FunctionNode $parser->match(Lexer::T_FROM); - $this->value = $parser->ScalarExpression(); + //$this->value = $parser->ScalarExpression(); + $this->value = $parser->ArithmeticPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index edf4dc24c..163c318c5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -3,8 +3,12 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; use Chill\MainBundle\Export\AggregatorInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; /** @@ -24,16 +28,17 @@ class DurationAggregator implements AggregatorInterface */ public function getLabels($key, array $values, $data) { - return function ($value): string { - switch ($value) { + dump($key, $values, $data); - case '_header': - return 'Duration'; - - - default: - throw new \LogicException(sprintf('The value %s is not valid', $value)); + return function ($value) use ($data): string { + if ($value === '_header') { + return 'Duration'; } + if ($value === null) { + return 'current'; // when closingDate is null + } + return $value; + //sprintf("%02d", $value) . ' days'; }; } @@ -75,7 +80,37 @@ class DurationAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb + // OUI ->addSelect('(acp.closingDate - acp.openingDate) AS duration_aggregator') + //->addSelect('DATE_DIFF(acp.closingDate, acp.openingDate) AS duration_aggregator') + //->addSelect('EXTRACT(month FROM acp.openingDate) AS duration_aggregator') + //->addSelect("DATE_SUB(acp.openingDate, 6, 'day') AS duration_aggregator") + + // TODO adapter la fonction extract pour l'utiliser avec des intervals: extract(month from interval) + // et ajouter une fonction custom qui calcule les intervals, comme doctrineum/date-interval + // https://packagist.org/packages/doctrineum/date-interval#3.1.0 + // (composer fait un conflit de dépendance) + + //->addSelect(" + // EXTRACT( + // month FROM + // DATE_INTERVAL(acp.closingDate, acp.openingDate) + // ) + // AS duration_aggregator") + + // NON + //->addSelect("BETWEEN acp.openingDate AND acp.closingDate AS duration_aggregator") + //->addSelect("EXTRACT(month FROM DATE_SUB(acp.openingDate, 6, 'day')) AS duration_aggregator") + //->addSelect('EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) AS duration_aggregator') + /* + ->addSelect(' + ( CASE + WHEN EXTRACT(day FROM DATE_DIFF(acp.closingDate, acp.openingDate)) > 15 + THEN EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) +1 + ELSE EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) + END ) AS duration_aggregator + ') + */ ; $groupBy = $qb->getDQLPart('groupBy');