From 7173e4be4a998eeec46f5fcb26436b1904b9cb5e Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Wed, 24 Aug 2022 15:44:18 +0200 Subject: [PATCH] exports: fix activity DateAggregator; add customs DQL Date/Time functions --- .../ACPAggregators/DateAggregator.php | 62 +++++++++++++++---- .../translations/messages.fr.yml | 8 ++- .../ChillMainExtension.php | 6 ++ .../ChillMainBundle/Doctrine/DQL/Extract.php | 47 ++++++++++++++ .../ChillMainBundle/Doctrine/DQL/ToChar.php | 38 ++++++++++++ 5 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php create mode 100644 src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index 11e508b88..6dda268e2 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -8,6 +8,7 @@ use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Closure; use Doctrine\ORM\QueryBuilder; +use RuntimeException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -16,7 +17,7 @@ class DateAggregator implements AggregatorInterface { private const CHOICES = [ 'by month' => 'month', - 'by week' => 'week', // numéro de la semaine + 'by week' => 'week', 'by year' => 'year', ]; @@ -32,22 +33,32 @@ class DateAggregator implements AggregatorInterface public function getLabels($key, array $values, $data) { - return function ($value): string { - switch ($value) { - case '_header': - return 'By date'; - + return function ($value) use ($data): string { + switch ($data['frequency']) { case 'month': - return $this->translator->trans('by month'); + if ($value === '_header') { + return 'by month'; + } + $month = \DateTime::createFromFormat('!m', $value); + return + sprintf("%02d", $value) .'/'. + $month->format('F') // TODO translation ?!? + ; case 'week': - return $this->translator->trans('by week'); + if ($value === '_header') { + return 'by week'; + } + return $this->translator->trans('for week') .' '. $value ; case 'year': - return $this->translator->trans('by year'); + if ($value === '_header') { + return 'by year'; + } + return $this->translator->trans('in year') .' '. $value ; default: - throw new LogicException(sprintf('The value %s is not valid', $value)); + throw new RuntimeException(sprintf('The value %s is not valid', $value)); } }; } @@ -59,8 +70,7 @@ class DateAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('by_date', ChoiceType::class, [ - 'label' => 'Frequency', + $builder->add('frequency', ChoiceType::class, [ 'choices' => self::CHOICES, 'multiple' => false, 'expanded' => true, @@ -81,7 +91,33 @@ class DateAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->addSelect('activity.date AS date_aggregator'); + switch ($data['frequency']) { + case 'month': + $qb + //->addSelect("TO_CHAR(activity.date,'Mon') AS MON") + ->addSelect('EXTRACT(month FROM activity.date) AS date_aggregator') + //->orderBy('date_aggregator') + ; + break; + + case 'week': + $qb + ->addSelect("TO_CHAR(activity.date, 'IW') AS date_aggregator") + //->orderBy('date_aggregator') + ; + break; + + case 'year': + $qb + //->addSelect("TO_CHAR(activity.date, 'YYYY') AS date_aggregator") + ->addSelect('EXTRACT(year FROM activity.date) AS date_aggregator') + //->orderBy('date_aggregator', 'ASC') + ; + break; + + default: + throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); + } $groupBy = $qb->getDQLPart('groupBy'); diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 4041b97dc..9f8ed3d7c 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -289,9 +289,11 @@ Aggregate by activity reason: Grouper les activités par sujet Group activity by locationtype: Grouper les activités par type de localisation Group activity by date: Grouper les activités par date Frequency: Fréquence -by month: par mois -by week: par semaine -by year: par année +by month: Par mois +by week: Par semaine +for week: Semaine +by year: Par année +in year: En Group activity by linked users: Grouper les activités par TMS impliqué Group activity by linked thirdparties: Grouper les activités par tiers impliqué Accepted thirdparty: Tiers impliqué diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index df0affa86..30bda0ab6 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -22,6 +22,7 @@ use Chill\MainBundle\Controller\UserController; use Chill\MainBundle\Controller\UserJobApiController; use Chill\MainBundle\Controller\UserJobController; use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface; +use Chill\MainBundle\Doctrine\DQL\Extract; use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey; use Chill\MainBundle\Doctrine\DQL\JsonAggregate; use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength; @@ -31,6 +32,7 @@ use Chill\MainBundle\Doctrine\DQL\Replace; use Chill\MainBundle\Doctrine\DQL\Similarity; use Chill\MainBundle\Doctrine\DQL\STContains; use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS; +use Chill\MainBundle\Doctrine\DQL\ToChar; use Chill\MainBundle\Doctrine\DQL\Unaccent; use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator; use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType; @@ -238,6 +240,10 @@ class ChillMainExtension extends Extension implements 'ST_CONTAINS' => STContains::class, 'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class, ], + 'datetime_functions' => [ + 'EXTRACT' => Extract::class, + 'TO_CHAR' => ToChar::class, + ], ], 'hydrators' => [ 'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class, diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php new file mode 100644 index 000000000..44d20724b --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php @@ -0,0 +1,47 @@ +field, + $this->value->dispatch($sqlWalker) + ); + } + + public function parse(Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $parser->match(Lexer::T_IDENTIFIER); + $this->field = $parser->getLexer()->token['value']; + + $parser->match(Lexer::T_FROM); + + $this->value = $parser->ScalarExpression(); + + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } + +} \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php new file mode 100644 index 000000000..c634555dc --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php @@ -0,0 +1,38 @@ +walkArithmeticPrimary($this->datetime), + $sqlWalker->walkArithmeticPrimary($this->fmt) + ); + } + + public function parse(Parser $parser) + { + $parser->match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $this->datetime = $parser->ArithmeticExpression(); + $parser->match(Lexer::T_COMMA); + $this->fmt = $parser->StringExpression(); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } + +} \ No newline at end of file