From fad1821c2f34b007a29a45d52722ed69f48b22e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 5 Oct 2018 11:01:00 +0200 Subject: [PATCH 1/2] fix translation in exports / aggregator. The activity type aggregator is shown. --- CHANGELOG.md | 6 +++++ Export/Aggregator/ActivityTypeAggregator.php | 26 -------------------- Export/Export/CountActivity.php | 4 +-- Resources/translations/messages.fr.yml | 5 +++- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88a7e4351..1da0df3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,9 @@ Version 1.5.1 - [report activity count] fix error: do not show centers which are not selected in results. +Master branch +============= + +- [aggregate by activity type] fix translation in aggregate activity type +- fix some translation in export +- fix error when persons not loaded by other aggregators / filters diff --git a/Export/Aggregator/ActivityTypeAggregator.php b/Export/Aggregator/ActivityTypeAggregator.php index 544ae98ac..3dec544ba 100644 --- a/Export/Aggregator/ActivityTypeAggregator.php +++ b/Export/Aggregator/ActivityTypeAggregator.php @@ -63,32 +63,6 @@ class ActivityTypeAggregator implements AggregatorInterface // add select element $qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY)); - // make a jointure only if needed - /*$join = $qb->getDQLPart('join'); - if ( - (array_key_exists('activity', $join) - && - !$this->checkJoinAlreadyDefined($join['activity'], 'reasons') - ) - OR - (! array_key_exists('activity', $join)) - ) { - $qb->add( - 'join', - array('activity' => - new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons') - ), - true); - } - - // join category if necessary - if ($alias === 'activity_categories_id') { - // add join only if needed - if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) { - $qb->join('reasons.category', 'category'); - } - }*/ - // add the "group by" part $groupBy = $qb->addGroupBy(self::KEY); } diff --git a/Export/Export/CountActivity.php b/Export/Export/CountActivity.php index 00f741fce..97a837520 100644 --- a/Export/Export/CountActivity.php +++ b/Export/Export/CountActivity.php @@ -75,9 +75,7 @@ class CountActivity implements ExportInterface ->from('ChillActivityBundle:Activity', 'activity') ; - if (in_array('person', $requiredModifiers)) { - $qb->join('activity.person', 'person'); - } + $qb->join('activity.person', 'person'); $qb->where($qb->expr()->in('person.center', ':centers')) ->setParameter('centers', $centers) diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 63620fb49..55e367d32 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -114,6 +114,7 @@ Count activities by various parameters.: Compte le nombre d'activités enregistr Sum activity duration: Total de la durée des activités Sum activities duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. List activities: Liste les activités +Number of activities: Nombre d'activités #filters Filter by reason: Filtrer par sujet d'activité @@ -137,5 +138,7 @@ Aggregate by activity reason: Aggréger par sujet de l'activité By reason: Par sujet By category of reason: Par catégorie de sujet Reason's level: Niveau du sujet -Aggregate by activity type: Aggréger par date d'activité +Aggregate by activity type: Aggréger par type d'activité +Activity type: Type d'activité +Group by reasons: Sujet d'activité From 5959edb01a4fa406fbda683340bc580d3e867d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 5 Oct 2018 11:21:45 +0200 Subject: [PATCH 2/2] [export] add filter "filter activity by activity type" --- CHANGELOG.md | 2 + Export/Filter/ActivityTypeFilter.php | 148 +++++++++++++++++++++++++ Resources/config/services/export.yml | 8 ++ Resources/translations/messages.fr.yml | 3 +- 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 Export/Filter/ActivityTypeFilter.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 1da0df3a3..16ac704c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,3 +10,5 @@ Master branch - [aggregate by activity type] fix translation in aggregate activity type - fix some translation in export - fix error when persons not loaded by other aggregators / filters +- add "filter by activity type" filter + diff --git a/Export/Filter/ActivityTypeFilter.php b/Export/Filter/ActivityTypeFilter.php new file mode 100644 index 000000000..b3616da10 --- /dev/null +++ b/Export/Filter/ActivityTypeFilter.php @@ -0,0 +1,148 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\ActivityBundle\Export\Filter; + +use Chill\MainBundle\Export\FilterInterface; +use Doctrine\ORM\QueryBuilder; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Chill\MainBundle\Templating\TranslatableStringHelper; +use Doctrine\ORM\Query\Expr; +use Symfony\Component\Security\Core\Role\Role; +use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\Query\Expr\Join; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Chill\MainBundle\Export\ExportElementValidatedInterface; +use Chill\ActivityBundle\Entity\ActivityType; + +/** + * + * + */ +class ActivityTypeFilter implements FilterInterface, + ExportElementValidatedInterface +{ + /** + * + * @var TranslatableStringHelper + */ + protected $translatableStringHelper; + + /** + * The repository for activity reasons + * + * @var EntityRepository + */ + protected $typeRepository; + + public function __construct( + TranslatableStringHelper $helper, + EntityRepository $typeRepository + ) { + $this->translatableStringHelper = $helper; + $this->typeRepository = $typeRepository; + } + + + public function alterQuery(QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->in('activity.type', ':selected_activity_types'); + + if ($where instanceof Expr\Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('selected_activity_types', $data['types']); + } + + /** + * Check if a join between Activity and Reason is already defined + * + * @param Join[] $joins + * @return boolean + */ + private function checkJoinAlreadyDefined(array $joins, $alias) + { + foreach ($joins as $join) { + if ($join->getAlias() === $alias) { + return true; + } + } + + return false; + } + + public function applyOn() + { + return 'activity'; + } + + public function buildForm(FormBuilderInterface $builder) + { + //create a local copy of translatableStringHelper + $helper = $this->translatableStringHelper; + + $builder->add('types', EntityType::class, array( + 'class' => ActivityType::class, + 'choice_label' => function (ActivityType $type) use ($helper) { + return $helper->localize($type->getName()); + }, + 'multiple' => true, + 'expanded' => false + )); + } + + public function validateForm($data, ExecutionContextInterface $context) + { + if ($data['types'] === null || count($data['types']) === 0) { + $context->buildViolation("At least one type must be choosen") + ->addViolation(); + } + } + + public function getTitle() + { + return 'Filter by activity type'; + } + + public function addRole() + { + return new Role(ActivityStatsVoter::STATS); + } + + public function describeAction($data, $format = 'string') + { + // collect all the reasons'name used in this filter in one array + $reasonsNames = array_map( + function(ActivityType $t) { + return "\"".$this->translatableStringHelper->localize($t->getName())."\""; + }, + $this->typeRepository->findBy(array('id' => $data['types']->toArray())) + ); + + return array("Filtered by activity type: only %list%", + ["%list%" => implode(", ", $reasonsNames)]); + } +} diff --git a/Resources/config/services/export.yml b/Resources/config/services/export.yml index cb6ff5f52..61d5cc18b 100644 --- a/Resources/config/services/export.yml +++ b/Resources/config/services/export.yml @@ -31,6 +31,14 @@ services: tags: - { name: chill.export_filter, alias: 'activity_reason_filter' } + chill.activity.export.type_filter: + class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter + arguments: + - "@chill.main.helper.translatable_string" + - "@chill_activity.repository.activity_type" + tags: + - { name: chill.export_filter, alias: 'activity_type_filter' } + chill.activity.export.date_filter: class: Chill\ActivityBundle\Export\Filter\ActivityDateFilter arguments: diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 55e367d32..edbaa0967 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -119,7 +119,7 @@ Number of activities: Nombre d'activités #filters Filter by reason: Filtrer par sujet d'activité 'Filtered by reasons: only %list%': 'Filtré par sujet: seulement %list%' - +'Filtered by activity type: only %list%': "Filtré par type d'activity: seulement %list%" Filtered by date activity: Filtrer par date d'activité Activities after this date: Activités après cette date Activities before this date: Activités avant cette date @@ -132,6 +132,7 @@ Implied in an activity before this date: Impliqué dans une activité avant cett Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par personnes associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name% Activity reasons for those activities: Sujets de ces activités +Filter by activity type: Filtrer par type d'activité #aggregators Aggregate by activity reason: Aggréger par sujet de l'activité