diff --git a/Export/Filter/BirthdateFilter.php b/Export/Filter/BirthdateFilter.php new file mode 100644 index 000000000..52afb2ff7 --- /dev/null +++ b/Export/Filter/BirthdateFilter.php @@ -0,0 +1,133 @@ + + * + * 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\PersonBundle\Export\Filter; + +use Chill\MainBundle\Export\FilterInterface; +use Symfony\Component\Form\Extension\Core\Type\DateType; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; +use Doctrine\ORM\Query\Expr; +use Chill\MainBundle\Form\Type\Export\FilterType; +use Symfony\Component\Form\FormError; + +/** + * + * + * @author Julien Fastré + */ +class BirthdateFilter implements FilterInterface +{ + + public function addRole() + { + return null; + } + + public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data) + { + $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->between('person.birthdate', ':date_from', + ':date_to'); + + if ($where instanceof Expr\Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->add('where', $where); + $qb->setParameter('date_from', $data['date_from']); + $qb->setParameter('date_to', $data['date_to']); + } + + public function applyOn() + { + return 'person'; + } + + public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder) + { + $builder->add('date_from', DateType::class, array( + 'label' => "Born after this date", + 'data' => new \DateTime(), + 'attr' => array('class' => 'datepicker'), + 'widget'=> 'single_text', + 'format' => 'dd-MM-yyyy', + )); + + $builder->add('date_to', DateType::class, array( + 'label' => "Born before this date", + 'data' => new \DateTime(), + 'attr' => array('class' => 'datepicker'), + 'widget'=> 'single_text', + 'format' => 'dd-MM-yyyy', + )); + + $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) { + /* @var $filterForm \Symfony\Component\Form\FormInterface */ + $filterForm = $event->getForm()->getParent(); + $enabled = $filterForm->get(FilterType::ENABLED_FIELD)->getData(); + + if ($enabled === true) { + // if the filter is enabled, add some validation + $form = $event->getForm(); + $date_from = $form->get('date_from')->getData(); + $date_to = $form->get('date_to')->getData(); + + // check that fields are not empty + if ($date_from === null) { + $form->get('date_from')->addError(new FormError('This field ' + . 'should not be empty')); + } + if ($date_to === null) { + $form->get('date_to')->addError(new FormError('This field ' + . 'should not be empty')); + } + + // check that date_from is before date_to + if ( + ($date_from !== null && $date_to !== null) + && + $date_from >= $date_to + ) { + $form->get('date_to')->addError(new FormError('This date ' + . 'should be after the date given in "born after" field')); + } + } + }); + } + + public function describeAction($data, $format = 'string') + { + return array('Filtered by person\'s birtdate: ' + . 'between %date_from% and %date_to%', array( + '%date_from%' => $data['date_from']->format('d-m-Y'), + '%date_to%' => $data['date_to']->format('d-m-Y') + )); + } + + public function getTitle() + { + return 'Filter by person\'s birthdate'; + } + +} diff --git a/Resources/config/services/exports.yml b/Resources/config/services/exports.yml index 7416d5cbf..443ed7c3d 100644 --- a/Resources/config/services/exports.yml +++ b/Resources/config/services/exports.yml @@ -19,6 +19,10 @@ services: tags: - { name: chill.export_filter, alias: person_gender_filter } + chill.person.export.filter_birthdate: + class: Chill\PersonBundle\Export\Filter\BirthdateFilter + tags: + - { name: chill.export_filter, alias: person_birthdate_filter } chill.person.export.filter_nationality: class: Chill\PersonBundle\Export\Filter\NationalityFilter diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 8be23ca04..7c25d2886 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -154,6 +154,13 @@ Nationalities: Nationalités Choose countries: Choisir les nationalités 'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%' +Filter by person's birthdate: Filtrer par date de naissance de la personne +Born after this date: Nés après cette date +Born before this date: Nés avant cette date +This field should not be empty: Ce champ ne peut pas être vide +This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le" +"Filtered by person's birtdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%" + ## aggregators Group people by nationality: Aggréger les personnes par nationalités Group by level: Grouper par niveau diff --git a/Resources/translations/validators.fr.yml b/Resources/translations/validators.fr.yml index b6ea52607..d691c8119 100644 --- a/Resources/translations/validators.fr.yml +++ b/Resources/translations/validators.fr.yml @@ -14,4 +14,8 @@ The date of closing is before the date of opening: La période de fermeture est The birthdate must be before %date%: La date de naissance doit être avant le %date% #export list -You must select at least one element: Vous devez sélectionner au moins un élément \ No newline at end of file +You must select at least one element: Vous devez sélectionner au moins un élément + +# filter by person birthdate +This field should not be empty: Ce champ ne peut pas être vide +This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le" diff --git a/Tests/Export/Filter/BirthdayFilterTest.php b/Tests/Export/Filter/BirthdayFilterTest.php new file mode 100644 index 000000000..1bcb040e4 --- /dev/null +++ b/Tests/Export/Filter/BirthdayFilterTest.php @@ -0,0 +1,85 @@ + + * + * 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\PersonBundle\Tests\Export\Filter; + +use Chill\MainBundle\Test\Export\AbstractFilterTest; + +/** + * + * + * @author Julien Fastré + */ +class BirthdayFilterTest extends AbstractFilterTest +{ + /** + * + * @var \Chill\PersonBundle\Export\Filter\BirthdateFilter + */ + private $filter; + + public function setUp() + { + static::bootKernel(); + + $container = static::$kernel->getContainer(); + + $this->filter = $container->get('chill.person.export.filter_birthdate'); + } + + + public function getFilter() + { + return $this->filter; + } + + public function getFormData() + { + return array( + array( + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2000-01-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2010-01-01') + ) + ); + } + + public function getQueryBuilders() + { + if (static::$kernel === null) { + static::bootKernel(); + } + + $em = static::$kernel->getContainer() + ->get('doctrine.orm.entity_manager'); + + return array( + $em->createQueryBuilder() + ->select('p.firstName') + ->from('ChillPersonBundle:Person', 'p'), + $em->createQueryBuilder() + ->select('p.firstName') + ->from('ChillPersonBundle:Person', 'p') + // add a dummy where clause + ->where('p.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('count(IDENTITY(p))') + ->from('ChillPersonBundle:Person', 'p') + // add a dummy where clause + ->where('p.firstname IS NOT NULL') + ); + } +}