From 722274964c8f8f42cbe3e7e9b7717c388a51823f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 28 Jan 2019 15:21:31 +0100 Subject: [PATCH] api for grouping centers, select centers as group in "pick centers" step for exports --- CHANGELOG.md | 4 + Center/GroupingCenterInterface.php | 27 ++++++ ChillMainBundle.php | 2 + .../GroupingCenterCompilerPass.php | 46 +++++++++ Export/ExportManager.php | 2 +- Form/Type/Export/PickCenterType.php | 93 ++++++++++++++++++- Resources/translations/messages.fr.yml | 1 + .../views/Export/new_centers_step.html.twig | 9 ++ 8 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 Center/GroupingCenterInterface.php create mode 100644 DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d3211bcca..62746ba68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,3 +31,7 @@ Master branch - add margin of 0.5rem beyond buttons ; - add a spreadsheet formatter (format xlsx, ods, csv) for lists +- add possibility to generate DirectExport: exports without formatters, filters and aggregators ; +- add api for grouping centers ; +- select centers as grouped on step "pick centers" in exports ; + diff --git a/Center/GroupingCenterInterface.php b/Center/GroupingCenterInterface.php new file mode 100644 index 000000000..5f10d35c8 --- /dev/null +++ b/Center/GroupingCenterInterface.php @@ -0,0 +1,27 @@ +addCompilerPass(new NotificationCounterCompilerPass()); $container->addCompilerPass(new MenuCompilerPass()); $container->addCompilerPass(new ACLFlagsCompilerPass()); + $container->addCompilerPass(new GroupingCenterCompilerPass()); } } diff --git a/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php b/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php new file mode 100644 index 000000000..3239e7045 --- /dev/null +++ b/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php @@ -0,0 +1,46 @@ + + * + * 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\MainBundle\DependencyInjection\CompilerPass; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; +use Chill\MainBundle\Form\Type\Export\PickCenterType; + +/** + * + * + * + */ +class GroupingCenterCompilerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (FALSE === $container->hasDefinition('chill.main.form.pick_centers_type')) { + throw new \LogicException("The service chill.main.form.pick_centers_type does " + . "not exists in container"); + } + + $pickCenterType = $container->getDefinition('chill.main.form.pick_centers_type'); + + foreach ($container->findTaggedServiceIds('chill.grouping_center') as $serviceId => $tagged) { + $pickCenterType->addMethodCall('addGroupingCenter', + [ new Reference($serviceId) ]); + } + } +} diff --git a/Export/ExportManager.php b/Export/ExportManager.php index 49458b4ec..ea15fea63 100644 --- a/Export/ExportManager.php +++ b/Export/ExportManager.php @@ -563,7 +563,7 @@ class ExportManager */ public function getPickedCenters(array $data) { - return $data[PickCenterType::CENTERS_IDENTIFIERS]; + return $data; } /** diff --git a/Form/Type/Export/PickCenterType.php b/Form/Type/Export/PickCenterType.php index 4f375bc5b..c58237ff2 100644 --- a/Form/Type/Export/PickCenterType.php +++ b/Form/Type/Export/PickCenterType.php @@ -28,12 +28,14 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Doctrine\ORM\EntityRepository; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Center\GroupingCenterInterface; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\CallbackTransformer; +use Doctrine\Common\Collections\Collection; /** * Pick centers amongst available centers for the user * - * @author Julien Fastré - * @author Champs Libres */ class PickCenterType extends AbstractType { @@ -49,6 +51,12 @@ class PickCenterType extends AbstractType */ protected $exportManager; + /** + * + * @var GroupingCenterInterface[] + */ + protected $groupingCenters = []; + const CENTERS_IDENTIFIERS = 'c'; /** @@ -87,10 +95,87 @@ class PickCenterType extends AbstractType return $qb->where($qb->expr()->in('c.id', $ids)); }, 'multiple' => true, - 'expanded' => false, + 'expanded' => true, 'choice_label' => function(Center $c) { return $c->getName(); }, - 'data' => $centers + 'data' => count($this->groupingCenters) > 0 ? null : $centers )); + + if (count($this->groupingCenters) > 0) { + $groupingBuilder = $builder->create('g', null, [ + 'compound' => true + ]); + + foreach ($this->groupingCenters as $key => $gc) { + $choices = $this->buildChoices($centers, $gc); + + if (count($choices) > 0) { + $groupingBuilder->add($key, ChoiceType::class, [ + 'choices' => $choices, + 'multiple' => true, + 'expanded' => true, + 'label' => $gc->getName() + ]); + } + } + + if ($groupingBuilder->count() > 0) { + $builder->add($groupingBuilder); + } + } + $builder->addModelTransformer(new CallbackTransformer( + function($data) use ($centers) { return $this->transform($data, $centers); }, + function($data) use ($centers) { return $this->reverseTransform($data, $centers); } + )); + } + + public function addGroupingCenter(GroupingCenterInterface $grouping) + { + $this->groupingCenters[md5($grouping->getName())] = $grouping; + } + + protected function buildChoices($reachablesCenters, GroupingCenterInterface $gc) + { + $result = []; + + foreach ($gc->getGroups() as $group) { + foreach ($gc->getCentersForGroup($group) as $center) { + if (\in_array($center, $reachablesCenters)) { + $result[$group] = $group; + } + } + } + + return $result; + } + + protected function transform($data, $centers) + { + return $data; + } + + protected function reverseTransform($data, $centers) + { + $picked = $data[self::CENTERS_IDENTIFIERS] + instanceof \Doctrine\Common\Collections\Collection ? + $data[self::CENTERS_IDENTIFIERS]->toArray() + : + $data[self::CENTERS_IDENTIFIERS]; + + if (\array_key_exists('g', $data)) { + foreach($data['g'] as $gcid => $group) { + $picked = + \array_merge( + \array_intersect( + $this->groupingCenters[$gcid] ->getCentersForGroup($group), + $centers + ), + $picked + ) + ; + } + } + + return \array_unique($picked); } } diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index d810fcc41..93cab97d0 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -152,6 +152,7 @@ Pick centers: Choisir les centres The export will contains only data from the picked centers.: L'export ne contiendra que les données des centres choisis. This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis. Go to export options: Vers la préparation de l'export +Pick aggregated centers: Regroupement de centres # export creation step 'export' : choose aggregators, filtering and formatter Formatter: Mise en forme Choose the formatter: Choisissez le format d'export voulu. diff --git a/Resources/views/Export/new_centers_step.html.twig b/Resources/views/Export/new_centers_step.html.twig index 454abf85b..2afc437f2 100644 --- a/Resources/views/Export/new_centers_step.html.twig +++ b/Resources/views/Export/new_centers_step.html.twig @@ -35,6 +35,15 @@ {{ form_widget(form.centers.c) }} + {% if form.centers.children.g is defined %} + +

{{ 'Pick aggregated centers'|trans }}

+ + {% for f in form.centers.children.g.children %} + {{ form_row(f) }} + {% endfor %} + {% endif %} +

{{ form_widget(form.submit, { 'attr' : { 'class' : 'sc-button btn-action bt-create' }, 'label' : 'Go to export options' } ) }}

{{ form_end(form) }}