mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-04 03:08:25 +00:00 
			
		
		
		
	Compare commits
	
		
			26 Commits
		
	
	
		
			68-feature
			...
			replace_tr
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2927561c02 | |||
| 5188891108 | |||
| c6deb21606 | |||
| cdfb084fe4 | |||
| 5ce21aadce | |||
| b9000a38d3 | |||
| 89a185a34f | |||
| 
						
						
							
						
						bc6c3a1089
	
				 | 
					
					
						|||
| 
						
						
							
						
						2c50f484f0
	
				 | 
					
					
						|||
| 
						
						
							
						
						4bc1de01d6
	
				 | 
					
					
						|||
| 
						
						
							
						
						e21fe70b75
	
				 | 
					
					
						|||
| 461995b56b | |||
| 
						
						
							
						
						e635b73256
	
				 | 
					
					
						|||
| 
						
						
							
						
						54ae17a8d2
	
				 | 
					
					
						|||
| 617d09ab8a | |||
| f8ee2903b2 | |||
| 
						
						
							
						
						36b0844e79
	
				 | 
					
					
						|||
| 
						
						
							
						
						7bff5ce39e
	
				 | 
					
					
						|||
| 
						
						
							
						
						4375ecf49a
	
				 | 
					
					
						|||
| 
						
						
							
						
						a6e930958b
	
				 | 
					
					
						|||
| 
						
						
							
						
						5f805626f7
	
				 | 
					
					
						|||
| 
						
						
							
						
						4c9ea740c8
	
				 | 
					
					
						|||
| 
						
						
							
						
						981dc6a959
	
				 | 
					
					
						|||
| 
						
						
							
						
						11fb9bcd0b
	
				 | 
					
					
						|||
| 
						
						
							
						
						a4edb34668
	
				 | 
					
					
						|||
| 
						
						
							
						
						f799fe0649
	
				 | 
					
					
						
							
								
								
									
										5
									
								
								.changes/unreleased/Fixed-20231026-152205.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.changes/unreleased/Fixed-20231026-152205.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
kind: Fixed
 | 
			
		||||
body: Replace old method of getting translator with injection of translatorInterface
 | 
			
		||||
time: 2023-10-26T15:22:05.134223653+02:00
 | 
			
		||||
custom:
 | 
			
		||||
  Issue: "175"
 | 
			
		||||
							
								
								
									
										20
									
								
								.changes/v2.10.0.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.changes/v2.10.0.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
## v2.10.0 - 2023-10-24
 | 
			
		||||
### Feature
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] Add a filter "grouping accompanying period by opening date" and "grouping accompanying period by closing date"
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a filter and aggregator on accompanying period work: group/filter by handling third party
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a filter and aggregator on activites: group/filter activities by people participating to the activities
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a grouping on accompanying period export: group by activity type associated to at least one activity within the accompanying period
 | 
			
		||||
* [export] sort filters and aggregators by title
 | 
			
		||||
* ([#179](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/179)) [export] create a parameter that will force to skip the filtering by center (ACL) when generating an export
 | 
			
		||||
### Fixed
 | 
			
		||||
* ([#177](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/177)) [export] fix date range selection on filter and grouping "by status of the course at date", on accompanying periods
 | 
			
		||||
 | 
			
		||||
### Résumé francophone des changements
 | 
			
		||||
 | 
			
		||||
- Ajout d'un regroupement sur les parcours: par date de cloture et d'ouverture;
 | 
			
		||||
- Ajouter d'un filtre et regroupement par tiers traitant sur les actions d'accompagnement;
 | 
			
		||||
- ajout d'un filtre et regroupement par usager participant sur les échanges
 | 
			
		||||
- ajout d'un regroupement: par type d'activité associé au parcours;
 | 
			
		||||
- trie les filtre et regroupements par ordre alphabétique dans els exports
 | 
			
		||||
- ajout d'un paramètre qui permet de désactiver le filtre par centre dans les exports
 | 
			
		||||
- correction de l'interface de date dans les filtres et regroupements "par statut du parcours à la date"
 | 
			
		||||
							
								
								
									
										3
									
								
								.changes/v2.10.1.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.changes/v2.10.1.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
## v2.10.1 - 2023-10-24
 | 
			
		||||
### Fixed
 | 
			
		||||
* Fix export controller when generating an export without any data in session 
 | 
			
		||||
							
								
								
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -6,6 +6,35 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
 | 
			
		||||
and is generated by [Changie](https://github.com/miniscruff/changie).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## v2.10.2 - 2023-10-26
 | 
			
		||||
### Fixed
 | 
			
		||||
* ([#175](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/175)) Use injection of translator instead of ->get(). 
 | 
			
		||||
 | 
			
		||||
## v2.10.1 - 2023-10-24
 | 
			
		||||
### Fixed
 | 
			
		||||
* Fix export controller when generating an export without any data in session 
 | 
			
		||||
 | 
			
		||||
## v2.10.0 - 2023-10-24
 | 
			
		||||
### Feature
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] Add a filter "grouping accompanying period by opening date" and "grouping accompanying period by closing date"
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a filter and aggregator on accompanying period work: group/filter by handling third party
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a filter and aggregator on activites: group/filter activities by people participating to the activities
 | 
			
		||||
* ([#172](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/172)) [export] add a grouping on accompanying period export: group by activity type associated to at least one activity within the accompanying period
 | 
			
		||||
* [export] sort filters and aggregators by title
 | 
			
		||||
* ([#179](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/179)) [export] create a parameter that will force to skip the filtering by center (ACL) when generating an export
 | 
			
		||||
### Fixed
 | 
			
		||||
* ([#177](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/177)) [export] fix date range selection on filter and grouping "by status of the course at date", on accompanying periods
 | 
			
		||||
 | 
			
		||||
### Résumé francophone des changements
 | 
			
		||||
 | 
			
		||||
- Ajout d'un regroupement sur les parcours: par date de cloture et d'ouverture;
 | 
			
		||||
- Ajouter d'un filtre et regroupement par tiers traitant sur les actions d'accompagnement;
 | 
			
		||||
- ajout d'un filtre et regroupement par usager participant sur les échanges
 | 
			
		||||
- ajout d'un regroupement: par type d'activité associé au parcours;
 | 
			
		||||
- trie les filtre et regroupements par ordre alphabétique dans els exports
 | 
			
		||||
- ajout d'un paramètre qui permet de désactiver le filtre par centre dans les exports
 | 
			
		||||
- correction de l'interface de date dans les filtres et regroupements "par statut du parcours à la date"
 | 
			
		||||
 | 
			
		||||
## v2.9.2 - 2023-10-17
 | 
			
		||||
### Fixed
 | 
			
		||||
* Fix possible null values in string's entities 
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,122 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\ActivityBundle\Entity\ActivityType;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Doctrine\ORM\Query\Expr\Join;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
final readonly class ByActivityTypeAggregator implements AggregatorInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acp_by_activity_type_agg';
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        private ActivityTypeRepositoryInterface $activityTypeRepository,
 | 
			
		||||
        private TranslatableStringHelperInterface $translatableStringHelper,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
        $builder
 | 
			
		||||
            ->add('after_date', PickRollingDateType::class, [
 | 
			
		||||
                'required' => false,
 | 
			
		||||
                'label' => 'export.aggregator.acp.by_activity_type.after_date',
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('before_date', PickRollingDateType::class, [
 | 
			
		||||
                'required' => false,
 | 
			
		||||
                'label' => 'export.aggregator.acp.by_activity_type.before_date',
 | 
			
		||||
            ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'before_date' => null,
 | 
			
		||||
            'after_date' => null,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        return function (null|int|string $value): string {
 | 
			
		||||
            if ('_header' === $value) {
 | 
			
		||||
                return 'export.aggregator.acp.by_activity_type.activity_type';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ('' === $value || null === $value || null === $activityType = $this->activityTypeRepository->find($value)) {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $this->translatableStringHelper->localize($activityType->getName());
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryKeys($data)
 | 
			
		||||
    {
 | 
			
		||||
        return [self::PREFIX.'_actype_id'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aggregator.acp.by_activity_type.title';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        // we make a left join, with acp having at least one activity of the given type
 | 
			
		||||
        $exists = 'EXISTS (SELECT 1 FROM '.Activity::class." {$p}_activity WHERE {$p}_activity.accompanyingPeriod = acp AND {$p}_activity.activityType = {$p}_activity_type";
 | 
			
		||||
 | 
			
		||||
        if (null !== $data['after_date']) {
 | 
			
		||||
            $exists .= " AND {$p}_activity.date > :{$p}_after_date";
 | 
			
		||||
            $qb->setParameter("{$p}_after_date", $this->rollingDateConverter->convert($data['after_date']));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (null !== $data['before_date']) {
 | 
			
		||||
            $exists .= " AND {$p}_activity.date < :{$p}_before_date";
 | 
			
		||||
            $qb->setParameter("{$p}_before_date", $this->rollingDateConverter->convert($data['before_date']));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $exists .= ')';
 | 
			
		||||
 | 
			
		||||
        $qb->leftJoin(
 | 
			
		||||
            ActivityType::class,
 | 
			
		||||
            "{$p}_activity_type",
 | 
			
		||||
            Join::WITH,
 | 
			
		||||
            $exists
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->addSelect("{$p}_activity_type.id AS {$p}_actype_id")
 | 
			
		||||
            ->addGroupBy("{$p}_actype_id");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ACP_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -73,7 +73,6 @@ class DateAggregator implements AggregatorInterface
 | 
			
		||||
            'choices' => self::CHOICES,
 | 
			
		||||
            'multiple' => false,
 | 
			
		||||
            'expanded' => true,
 | 
			
		||||
            'empty_data' => self::DEFAULT_CHOICE,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Export\Aggregator;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Declarations;
 | 
			
		||||
use Chill\ActivityBundle\Tests\Export\Aggregator\PersonsAggregatorTest;
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see PersonsAggregatorTest
 | 
			
		||||
 */
 | 
			
		||||
final readonly class PersonsAggregator implements AggregatorInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'act_persons_agg';
 | 
			
		||||
 | 
			
		||||
    public function __construct(private LabelPersonHelper $labelPersonHelper) {}
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
        // nothing to add here
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        if ($key !== self::PREFIX.'_pid') {
 | 
			
		||||
            throw new \UnexpectedValueException('this key should not be handled: '.$key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->labelPersonHelper->getLabel($key, $values, 'export.aggregator.activity.by_persons.Persons');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryKeys($data)
 | 
			
		||||
    {
 | 
			
		||||
        return [self::PREFIX.'_pid'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aggregator.activity.by_persons.Group activity by persons';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->leftJoin('activity.persons', "{$p}_p")
 | 
			
		||||
            ->addSelect("{$p}_p.id AS {$p}_pid")
 | 
			
		||||
            ->addGroupBy("{$p}_pid");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ACTIVITY;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,8 +11,8 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\ActivityBundle\Export\Declarations;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityRepository;
 | 
			
		||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
 | 
			
		||||
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
 | 
			
		||||
use Chill\MainBundle\Export\ExportInterface;
 | 
			
		||||
@@ -21,19 +21,19 @@ use Chill\MainBundle\Export\GroupedExportInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class AvgActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        private readonly ActivityRepository $activityRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(Activity::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
@@ -91,23 +91,25 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
    {
 | 
			
		||||
        $centers = array_map(static fn ($el) => $el['center'], $acl);
 | 
			
		||||
 | 
			
		||||
        $qb = $this->repository->createQueryBuilder('activity');
 | 
			
		||||
        $qb = $this->activityRepository->createQueryBuilder('activity');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->join('activity.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->select('AVG(activity.durationTime) as export_avg_activity_duration')
 | 
			
		||||
            ->andWhere($qb->expr()->isNotNull('activity.durationTime'));
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,21 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(Activity::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
@@ -101,16 +106,18 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
 | 
			
		||||
            ->select('AVG(activity.travelTime) as export_avg_activity_visit_duration')
 | 
			
		||||
            ->andWhere($qb->expr()->isNotNull('activity.travelTime'));
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,21 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountActivity implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(Activity::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
@@ -95,16 +100,18 @@ class CountActivity implements ExportInterface, GroupedExportInterface
 | 
			
		||||
            ->createQueryBuilder('activity')
 | 
			
		||||
            ->join('activity.accompanyingPeriod', 'acp');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,21 @@ use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
 | 
			
		||||
use Chill\MainBundle\Export\ListInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class ListActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly ListActivityHelper $helper, private readonly EntityManagerInterface $entityManager, private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ListActivityHelper $helper,
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -107,21 +117,27 @@ class ListActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
            ->join('activity.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->leftJoin('acp.participations', 'acppart')
 | 
			
		||||
            ->leftJoin('acppart.person', 'person')
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL');
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1
 | 
			
		||||
                    FROM '.PersonCenterHistory::class.' acl_count_person_history
 | 
			
		||||
                    WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            // some grouping are necessary
 | 
			
		||||
            ->addGroupBy('acp.id')
 | 
			
		||||
            ->addOrderBy('activity.date')
 | 
			
		||||
            ->addOrderBy('activity.id')
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
            ->addOrderBy('activity.id');
 | 
			
		||||
 | 
			
		||||
        $this->helper->addSelect($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,20 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class SumActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(Activity::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
@@ -101,16 +105,18 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
        $qb->select('SUM(activity.durationTime) as export_sum_activity_duration')
 | 
			
		||||
            ->andWhere($qb->expr()->isNotNull('activity.durationTime'));
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,20 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class SumActivityVisitDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(Activity::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
@@ -101,16 +105,18 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
 | 
			
		||||
        $qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration')
 | 
			
		||||
            ->andWhere($qb->expr()->isNotNull('activity.travelTime'));
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,19 @@ use Chill\MainBundle\Export\FormatterInterface;
 | 
			
		||||
use Chill\MainBundle\Export\GroupedExportInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountActivity implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(protected ActivityRepository $activityRepository) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ActivityRepository $activityRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
 | 
			
		||||
@@ -82,23 +90,25 @@ class CountActivity implements ExportInterface, GroupedExportInterface
 | 
			
		||||
 | 
			
		||||
        $qb = $this->activityRepository
 | 
			
		||||
            ->createQueryBuilder('activity')
 | 
			
		||||
            ->join('activity.person', 'person')
 | 
			
		||||
            ->join('person.centerHistory', 'centerHistory');
 | 
			
		||||
            ->join('activity.person', 'person');
 | 
			
		||||
 | 
			
		||||
        $qb->select('COUNT(activity.id) as export_count_activity');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->where(
 | 
			
		||||
                $qb->expr()->andX(
 | 
			
		||||
                    $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                    $qb->expr()->orX(
 | 
			
		||||
                        $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                        $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->join('person.centerHistory', 'centerHistory')
 | 
			
		||||
                ->where(
 | 
			
		||||
                    $qb->expr()->andX(
 | 
			
		||||
                        $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                        $qb->expr()->orX(
 | 
			
		||||
                            $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                            $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
            ->setParameter('centers', $centers);
 | 
			
		||||
                ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
                ->setParameter('centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $qb;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\DBAL\Exception\InvalidArgumentException;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
use Symfony\Component\Validator\Constraints\Callback;
 | 
			
		||||
@@ -44,8 +45,17 @@ class ListActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
        'person_lastname',
 | 
			
		||||
        'person_id',
 | 
			
		||||
    ];
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(protected EntityManagerInterface $entityManager, protected TranslatorInterface $translator, protected TranslatableStringHelperInterface $translatableStringHelper, private readonly ActivityRepository $activityRepository) {}
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected EntityManagerInterface $entityManager,
 | 
			
		||||
        protected TranslatorInterface $translator,
 | 
			
		||||
        protected TranslatableStringHelperInterface $translatableStringHelper,
 | 
			
		||||
        private readonly ActivityRepository $activityRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -188,20 +198,22 @@ class ListActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->from('ChillActivityBundle:Activity', 'activity')
 | 
			
		||||
            ->join('activity.person', 'actperson')
 | 
			
		||||
            ->join('actperson.centerHistory', 'centerHistory');
 | 
			
		||||
            ->join('activity.person', 'actperson');
 | 
			
		||||
 | 
			
		||||
        $qb->where(
 | 
			
		||||
            $qb->expr()->andX(
 | 
			
		||||
                $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                $qb->expr()->orX(
 | 
			
		||||
                    $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                    $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb->join('actperson.centerHistory', 'centerHistory');
 | 
			
		||||
            $qb->where(
 | 
			
		||||
                $qb->expr()->andX(
 | 
			
		||||
                    $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                    $qb->expr()->orX(
 | 
			
		||||
                        $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                        $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
            ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
            ->setParameter('centers', $centers);
 | 
			
		||||
                ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
                ->setParameter('centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($this->fields as $f) {
 | 
			
		||||
            if (\in_array($f, $data['fields'], true)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ use Chill\MainBundle\Export\FormatterInterface;
 | 
			
		||||
use Chill\MainBundle\Export\GroupedExportInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -30,17 +31,21 @@ use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
class StatActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    final public const SUM = 'sum';
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $action the stat to perform
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ActivityRepository $activityRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
        /**
 | 
			
		||||
         * The action for this report.
 | 
			
		||||
         */
 | 
			
		||||
        protected string $action = 'sum'
 | 
			
		||||
    ) {}
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
 | 
			
		||||
@@ -119,21 +124,23 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb->select($select)
 | 
			
		||||
            ->join('activity.person', 'person')
 | 
			
		||||
            ->join('person.centerHistory', 'centerHistory');
 | 
			
		||||
            ->join('activity.person', 'person');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->where(
 | 
			
		||||
                $qb->expr()->andX(
 | 
			
		||||
                    $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                    $qb->expr()->orX(
 | 
			
		||||
                        $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                        $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->join('person.centerHistory', 'centerHistory')
 | 
			
		||||
                ->where(
 | 
			
		||||
                    $qb->expr()->andX(
 | 
			
		||||
                        $qb->expr()->lte('centerHistory.startDate', 'activity.date'),
 | 
			
		||||
                        $qb->expr()->orX(
 | 
			
		||||
                            $qb->expr()->isNull('centerHistory.endDate'),
 | 
			
		||||
                            $qb->expr()->gt('centerHistory.endDate', 'activity.date')
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
            ->setParameter('centers', $centers);
 | 
			
		||||
                ->andWhere($qb->expr()->in('centerHistory.center', ':centers'))
 | 
			
		||||
                ->setParameter('centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $qb;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,9 @@ use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class UserScopeFilter implements FilterInterface
 | 
			
		||||
class CreatorScopeFilter implements FilterInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acp_act_filter_user_scope';  // creator ? cfr translation
 | 
			
		||||
    private const PREFIX = 'acp_act_filter_creator_scope';
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly TranslatableStringHelper $translatableStringHelper
 | 
			
		||||
@@ -39,7 +39,7 @@ class UserScopeFilter implements FilterInterface
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->leftJoin('activity.user', "{$p}_user")  // createdBy ? cfr translation
 | 
			
		||||
            ->leftJoin('activity.createdBy', "{$p}_user")
 | 
			
		||||
            ->leftJoin(
 | 
			
		||||
                UserScopeHistory::class,
 | 
			
		||||
                "{$p}_history",
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Export\Filter;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Declarations;
 | 
			
		||||
use Chill\ActivityBundle\Tests\Export\Filter\PersonsFilterTest;
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see PersonsFilterTest
 | 
			
		||||
 */
 | 
			
		||||
final readonly class PersonsFilter implements FilterInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'act_persons_filter';
 | 
			
		||||
 | 
			
		||||
    public function __construct(private PersonRenderInterface $personRender) {}
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $orX = $qb->expr()->orX();
 | 
			
		||||
 | 
			
		||||
        foreach (array_values($data['accepted_persons']) as $key => $person) {
 | 
			
		||||
            $orX->add($qb->expr()->isMemberOf(":{$p}_p_{$key}", 'activity.persons'));
 | 
			
		||||
            $qb->setParameter(":{$p}_p_{$key}", $person);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb->andWhere($orX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ACTIVITY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('accepted_persons', PickPersonDynamicType::class, [
 | 
			
		||||
            'multiple' => true,
 | 
			
		||||
            'label' => 'export.filter.activity.by_persons.persons taking part on the activity',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'accepted_persons' => [],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function describeAction($data, $format = 'string')
 | 
			
		||||
    {
 | 
			
		||||
        $users = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($data['accepted_persons'] as $u) {
 | 
			
		||||
            $users[] = $this->personRender->renderString($u, []);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ['export.filter.activity.by_persons.Filtered activity by persons: only %persons%', [
 | 
			
		||||
            '%persons%' => implode(', ', $users),
 | 
			
		||||
        ]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.filter.activity.by_persons.Filter activity by persons';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,8 +23,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
class SentReceivedFilter implements FilterInterface
 | 
			
		||||
{
 | 
			
		||||
    private const CHOICES = [
 | 
			
		||||
        'is sent' => Activity::SENTRECEIVED_SENT,
 | 
			
		||||
        'is received' => Activity::SENTRECEIVED_RECEIVED,
 | 
			
		||||
        'export.filter.activity.by_sent_received.is sent' => Activity::SENTRECEIVED_SENT,
 | 
			
		||||
        'export.filter.activity.by_sent_received.is received' => Activity::SENTRECEIVED_RECEIVED,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    private const DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT;
 | 
			
		||||
@@ -64,6 +64,7 @@ class SentReceivedFilter implements FilterInterface
 | 
			
		||||
            'multiple' => false,
 | 
			
		||||
            'expanded' => true,
 | 
			
		||||
            'empty_data' => self::DEFAULT_CHOICE,
 | 
			
		||||
            'label' => 'export.filter.activity.by_sent_received.Sent or received',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByActivityTypeAggregator;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ByActivityTypeAggregatorTest extends AbstractAggregatorTest
 | 
			
		||||
{
 | 
			
		||||
    private RollingDateConverterInterface $rollingDateConverter;
 | 
			
		||||
    private ActivityTypeRepositoryInterface $activityTypeRepository;
 | 
			
		||||
    private TranslatableStringHelperInterface $translatableStringHelper;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $this->rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
        $this->activityTypeRepository = self::$container->get(ActivityTypeRepositoryInterface::class);
 | 
			
		||||
        $this->translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAggregator()
 | 
			
		||||
    {
 | 
			
		||||
        return new ByActivityTypeAggregator(
 | 
			
		||||
            $this->rollingDateConverter,
 | 
			
		||||
            $this->activityTypeRepository,
 | 
			
		||||
            $this->translatableStringHelper,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [
 | 
			
		||||
                'after_date' => null,
 | 
			
		||||
                'before_date' => null,
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'after_date' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START),
 | 
			
		||||
                'before_date' => null,
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'after_date' => null,
 | 
			
		||||
                'before_date' => new RollingDate(RollingDate::T_TODAY),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'after_date' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START),
 | 
			
		||||
                'before_date' => new RollingDate(RollingDate::T_TODAY),
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            $em->createQueryBuilder()
 | 
			
		||||
                ->select('count(distinct acp.id)')
 | 
			
		||||
                ->from(AccompanyingPeriod::class, 'acp'),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,60 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\ActivityBundle\Export\Aggregator\PersonsAggregator;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class PersonsAggregatorTest extends AbstractAggregatorTest
 | 
			
		||||
{
 | 
			
		||||
    private LabelPersonHelper $labelPersonHelper;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $this->labelPersonHelper = self::$container->get(LabelPersonHelper::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAggregator()
 | 
			
		||||
    {
 | 
			
		||||
        return new PersonsAggregator($this->labelPersonHelper);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            $em->createQueryBuilder()
 | 
			
		||||
                ->select('count(activity.id)')
 | 
			
		||||
                ->from(Activity::class, 'activity'),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityDuration;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityRepository;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -21,18 +22,17 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class AvgActivityDurationTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private AvgActivityDuration $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.avg_activity_duration_linked_to_acp');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $activityRepository = self::$container->get(ActivityRepository::class);
 | 
			
		||||
 | 
			
		||||
        yield new AvgActivityDuration($activityRepository, $this->getParameters(true));
 | 
			
		||||
        yield new AvgActivityDuration($activityRepository, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityVisitDuration;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -21,18 +22,17 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class AvgActivityVisitDurationTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private AvgActivityVisitDuration $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.avg_activity_visit_duration_linked_to_acp');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new AvgActivityVisitDuration($em, $this->getParameters(true));
 | 
			
		||||
        yield new AvgActivityVisitDuration($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToACP\CountActivity;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -21,18 +22,17 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class CountActivityTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private CountActivity $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.count_activity_linked_to_acp');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountActivity($em, $this->getParameters(true));
 | 
			
		||||
        yield new CountActivity($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityDuration;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -21,18 +22,17 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class SumActivityDurationTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private SumActivityDuration $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.sum_activity_duration_linked_to_acp');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new SumActivityDuration($em, $this->getParameters(true));
 | 
			
		||||
        yield new SumActivityDuration($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToACP;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityVisitDuration;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -32,7 +33,10 @@ final class SumActivityVisitDurationTest extends AbstractExportTest
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new SumActivityVisitDuration($em, $this->getParameters(true));
 | 
			
		||||
        yield new SumActivityVisitDuration($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityRepository;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -21,18 +22,17 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class CountActivityTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private CountActivity $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.count_activity_linked_to_person');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $activityRepository = self::$container->get(ActivityRepository::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountActivity($activityRepository, $this->getParameters(true));
 | 
			
		||||
        yield new CountActivity($activityRepository, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,12 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityRepository;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Prophecy\PhpUnit\ProphecyTrait;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -24,14 +28,12 @@ final class ListActivityTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    use ProphecyTrait;
 | 
			
		||||
 | 
			
		||||
    private ListActivity $export;
 | 
			
		||||
    private readonly ListActivity $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.list_activity_linked_to_person');
 | 
			
		||||
 | 
			
		||||
        $request = $this->prophesize()
 | 
			
		||||
            ->willExtend(\Symfony\Component\HttpFoundation\Request::class);
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +45,26 @@ final class ListActivityTest extends AbstractExportTest
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $translator = self::$container->get(TranslatorInterface::class);
 | 
			
		||||
        $translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class);
 | 
			
		||||
        $activityRepository = self::$container->get(ActivityRepository::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListActivity(
 | 
			
		||||
            $em,
 | 
			
		||||
            $translator,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $activityRepository,
 | 
			
		||||
            $this->getParameters(true)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListActivity(
 | 
			
		||||
            $em,
 | 
			
		||||
            $translator,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $activityRepository,
 | 
			
		||||
            $this->getParameters(false)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Export\LinkedToPerson;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration;
 | 
			
		||||
use Chill\ActivityBundle\Repository\ActivityRepository;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -23,18 +24,18 @@ use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
 */
 | 
			
		||||
final class StatActivityDurationTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private StatActivityDuration $export;
 | 
			
		||||
    private readonly StatActivityDuration $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.activity.export.sum_activity_duration_linked_to_person');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $activityRepository = self::$container->get(ActivityRepository::class);
 | 
			
		||||
        yield new StatActivityDuration($activityRepository, $this->getParameters(true), 'sum');
 | 
			
		||||
        yield new StatActivityDuration($activityRepository, $this->getParameters(false), 'sum');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Filter;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\ActivityBundle\Export\Filter\UserScopeFilter;
 | 
			
		||||
use Chill\ActivityBundle\Export\Filter\CreatorScopeFilter;
 | 
			
		||||
use Chill\MainBundle\Entity\Scope;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
@@ -22,15 +22,15 @@ use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
final class UserScopeFilterTest extends AbstractFilterTest
 | 
			
		||||
final class CreatorScopeFilterTest extends AbstractFilterTest
 | 
			
		||||
{
 | 
			
		||||
    private UserScopeFilter $filter;
 | 
			
		||||
    private CreatorScopeFilter $filter;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->filter = self::$container->get(UserScopeFilter::class);
 | 
			
		||||
        $this->filter = self::$container->get(CreatorScopeFilter::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFilter()
 | 
			
		||||
@@ -0,0 +1,72 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\ActivityBundle\Tests\Export\Filter;
 | 
			
		||||
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\ActivityBundle\Export\Filter\PersonsFilter;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class PersonsFilterTest extends AbstractFilterTest
 | 
			
		||||
{
 | 
			
		||||
    private PersonRenderInterface $personRender;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $this->personRender = self::$container->get(PersonRenderInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFilter()
 | 
			
		||||
    {
 | 
			
		||||
        return new PersonsFilter($this->personRender);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        $persons = $em->createQuery('SELECT p FROM '.Person::class.' p ')
 | 
			
		||||
            ->setMaxResults(2)
 | 
			
		||||
            ->getResult();
 | 
			
		||||
 | 
			
		||||
        self::ensureKernelShutdown();
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            [
 | 
			
		||||
                'accepted_persons' => $persons,
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield $em->createQueryBuilder()
 | 
			
		||||
            ->select('count(activity.id)')
 | 
			
		||||
            ->from(Activity::class, 'activity');
 | 
			
		||||
 | 
			
		||||
        self::ensureKernelShutdown();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -109,8 +109,10 @@ services:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: 'activity_user_filter' }
 | 
			
		||||
 | 
			
		||||
    Chill\ActivityBundle\Export\Filter\UserScopeFilter:
 | 
			
		||||
    Chill\ActivityBundle\Export\Filter\CreatorScopeFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            # WARNING: for backward compatibility reason, the alias is named with userscope. Changing this will
 | 
			
		||||
            # affect all saved exports (unless we write a migration for that)
 | 
			
		||||
            - { name: chill.export_filter, alias: 'activity_userscope_filter' }
 | 
			
		||||
 | 
			
		||||
    Chill\ActivityBundle\Export\Filter\UsersJobFilter:
 | 
			
		||||
@@ -200,3 +202,15 @@ services:
 | 
			
		||||
    Chill\ActivityBundle\Export\Aggregator\SentReceivedAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: activity_sentreceived_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\ActivityBundle\Export\Filter\PersonsFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: activity_by_persons_filter }
 | 
			
		||||
 | 
			
		||||
    Chill\ActivityBundle\Export\Aggregator\PersonsAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: activity_by_persons_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByActivityTypeAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: acp_by_activity_type_aggregator }
 | 
			
		||||
 
 | 
			
		||||
@@ -275,7 +275,7 @@ Filter activity by linked socialaction: Filtrer les échanges par action liée
 | 
			
		||||
'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%"
 | 
			
		||||
Filter activity by linked socialissue: Filtrer les échanges par problématique liée
 | 
			
		||||
'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%"
 | 
			
		||||
Filter activity by user: Filtrer les échanges par créateur
 | 
			
		||||
Filter activity by user: Filtrer les échanges par utilisateur principal
 | 
			
		||||
Filter activity by users: Filtrer les échanges par utilisateur participant
 | 
			
		||||
Filter activity by creator: Filtrer les échanges par créateur de l'échange
 | 
			
		||||
'Filtered activity by user: only %users%': "Filtré par référent: uniquement %users%"
 | 
			
		||||
@@ -359,10 +359,10 @@ export:
 | 
			
		||||
                Filter by users job: Filtrer les échanges par métier d'au moins un utilisateur participant
 | 
			
		||||
                'Filtered activity by users job: only %jobs%': 'Filtré par métier d''au moins un utilisateur participant: seulement %jobs%'
 | 
			
		||||
            by_users_scope:
 | 
			
		||||
                Filter by users scope: Filtrer les échanges par services d'au moins un utilisateur participant
 | 
			
		||||
                Filter by users scope: Filtrer les échanges par service d'au moins un utilisateur participant
 | 
			
		||||
                'Filtered activity by users scope: only %scopes%': 'Filtré par service d''au moins un utilisateur participant: seulement %scopes%'
 | 
			
		||||
            course_having_activity_between_date:
 | 
			
		||||
                Title: Filtre les parcours ayant reçu un échange entre deux dates
 | 
			
		||||
                Title: Filtrer les parcours ayant reçu un échange entre deux dates
 | 
			
		||||
                Receiving an activity after: Ayant reçu un échange après le
 | 
			
		||||
                Receiving an activity before: Ayant reçu un échange avant le
 | 
			
		||||
            acp_by_activity_type:
 | 
			
		||||
@@ -372,13 +372,27 @@ export:
 | 
			
		||||
                Implied in an activity before this date: Impliqué dans un échange avant cette date
 | 
			
		||||
                Activity reasons for those activities: Sujets de ces échanges
 | 
			
		||||
                if no reasons: Si aucun sujet n'est coché, tous les sujets seront pris en compte
 | 
			
		||||
                title: Filtrer les personnes ayant été associés à un échange au cours de la période
 | 
			
		||||
                title: Filtrer les usagers ayant été associés à un échange au cours de la période
 | 
			
		||||
                date mismatch: La date de fin de la période doit être supérieure à la date du début
 | 
			
		||||
            by_creator_scope:
 | 
			
		||||
                Filter activity by user scope: Filtrer les échanges par service du créateur de l'échange
 | 
			
		||||
                'Filtered activity by user scope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%"
 | 
			
		||||
            by_persons:
 | 
			
		||||
                Filter activity by persons: Filtrer les échanges par usager participant
 | 
			
		||||
                'Filtered activity by persons: only %persons%': 'Échanges filtrés par usagers participants: seulement %persons%'
 | 
			
		||||
                persons taking part on the activity: Usagers participants à l'échange
 | 
			
		||||
            by_sent_received:
 | 
			
		||||
                Sent or received: Envoyé ou reçu
 | 
			
		||||
                is sent: envoyé
 | 
			
		||||
                is received: reçu
 | 
			
		||||
 | 
			
		||||
    aggregator:
 | 
			
		||||
        acp:
 | 
			
		||||
            by_activity_type:
 | 
			
		||||
                title: Grouper les parcours par type d'échange
 | 
			
		||||
                after_date: Uniquement échanges après cette date
 | 
			
		||||
                before_date: Uniquement échanges avant cette date
 | 
			
		||||
                activity_type: Types d'échange
 | 
			
		||||
        activity:
 | 
			
		||||
            by_sent_received:
 | 
			
		||||
                Sent or received: Envoyé ou reçu
 | 
			
		||||
@@ -400,6 +414,9 @@ export:
 | 
			
		||||
            by_creator_job:
 | 
			
		||||
                Group activity by creator job: Grouper les échanges par service du créateur de l'échange
 | 
			
		||||
                Calc date: Date de calcul du service du créateur de l'échange
 | 
			
		||||
            by_persons:
 | 
			
		||||
                Group activity by persons: Grouper les échanges par usager participant
 | 
			
		||||
                Persons: Usagers participants
 | 
			
		||||
 | 
			
		||||
generic_doc:
 | 
			
		||||
    filter:
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@ use Symfony\Component\Validator\Exception\LogicException;
 | 
			
		||||
 | 
			
		||||
class CountCalendars implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly CalendarRepository $calendarRepository) {}
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly CalendarRepository $calendarRepository,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,15 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class CustomFieldController.
 | 
			
		||||
 */
 | 
			
		||||
class CustomFieldController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly TranslatorInterface $translator) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new CustomField entity.
 | 
			
		||||
     *
 | 
			
		||||
@@ -40,13 +43,13 @@ class CustomFieldController extends AbstractController
 | 
			
		||||
            $em->persist($entity);
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')
 | 
			
		||||
            $this->addFlash('success', $this->translator
 | 
			
		||||
                ->trans('The custom field has been created'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute('customfieldsgroup_show', ['id' => $entity->getCustomFieldsGroup()->getId()]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->addFlash('error', $this->get('translator')
 | 
			
		||||
        $this->addFlash('error', $this->translator
 | 
			
		||||
            ->trans('The custom field form contains errors'));
 | 
			
		||||
 | 
			
		||||
        return $this->render('@ChillCustomFields/CustomField/new.html.twig', [
 | 
			
		||||
@@ -130,13 +133,13 @@ class CustomFieldController extends AbstractController
 | 
			
		||||
        if ($editForm->isSubmitted() && $editForm->isValid()) {
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')
 | 
			
		||||
            $this->addFlash('success', $this->translator
 | 
			
		||||
                ->trans('The custom field has been updated'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute('customfield_edit', ['id' => $id]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->addFlash('error', $this->get('translator')
 | 
			
		||||
        $this->addFlash('error', $this->translator
 | 
			
		||||
            ->trans('The custom field form contains errors'));
 | 
			
		||||
 | 
			
		||||
        return $this->render('@ChillCustomFields/CustomField/edit.html.twig', [
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,7 @@ class EventController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                $this->addFlash(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')
 | 
			
		||||
                    $this->translator
 | 
			
		||||
                        ->trans('The event has been sucessfully removed')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
@@ -249,7 +249,7 @@ class EventController extends AbstractController
 | 
			
		||||
            $em->persist($entity);
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')
 | 
			
		||||
            $this->addFlash('success', $this->translator
 | 
			
		||||
                ->trans('The event was created'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute('chill_event__event_show', ['event_id' => $entity->getId()]);
 | 
			
		||||
@@ -364,7 +364,7 @@ class EventController extends AbstractController
 | 
			
		||||
        if ($editForm->isValid()) {
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')
 | 
			
		||||
            $this->addFlash('success', $this->translator
 | 
			
		||||
                ->trans('The event was updated'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute('chill_event__event_edit', ['event_id' => $event_id]);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\Form\FormInterface;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ParticipationController.
 | 
			
		||||
@@ -32,7 +33,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
    /**
 | 
			
		||||
     * ParticipationController constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(private readonly LoggerInterface $logger) {}
 | 
			
		||||
    public function __construct(private readonly LoggerInterface $logger, private readonly TranslatorInterface $translator) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/create", name="chill_event_participation_create")
 | 
			
		||||
@@ -177,7 +178,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans(
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans(
 | 
			
		||||
                'The participations were created'
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
@@ -211,7 +212,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
            $em->persist($participation);
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans(
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans(
 | 
			
		||||
                'The participation was created'
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
@@ -260,7 +261,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                $this->addFlash(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')
 | 
			
		||||
                    $this->translator
 | 
			
		||||
                        ->trans('The participation has been sucessfully removed')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
@@ -340,7 +341,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
        switch ($event->getParticipations()->count()) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                // if there aren't any participation, redirect to the 'show' view with an add flash
 | 
			
		||||
                $this->addFlash('warning', $this->get('translator')
 | 
			
		||||
                $this->addFlash('warning', $this->translator
 | 
			
		||||
                    ->trans('There are no participation to edit for this event'));
 | 
			
		||||
 | 
			
		||||
                return $this->redirectToRoute(
 | 
			
		||||
@@ -434,7 +435,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
 | 
			
		||||
            $em->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans(
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans(
 | 
			
		||||
                'The participation was updated'
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
@@ -480,7 +481,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
        if ($form->isSubmitted() && $form->isValid()) {
 | 
			
		||||
            $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans('The participations '
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans('The participations '
 | 
			
		||||
                    .'have been successfully updated.'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute(
 | 
			
		||||
@@ -652,7 +653,7 @@ class ParticipationController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        if ([] === $newParticipations) {
 | 
			
		||||
            // if we do not have nay participants, redirect to event view
 | 
			
		||||
            $this->addFlash('error', $this->get('translator')->trans(
 | 
			
		||||
            $this->addFlash('error', $this->translator->trans(
 | 
			
		||||
                'None of the requested people may participate '
 | 
			
		||||
                    .'the event: they are maybe already participating.'
 | 
			
		||||
            ));
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ use Chill\MainBundle\Security\Authorization\SavedExportVoter;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\Form\FormFactoryInterface;
 | 
			
		||||
@@ -46,6 +47,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 */
 | 
			
		||||
class ExportController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ChillRedis $redis,
 | 
			
		||||
        private readonly ExportManager $exportManager,
 | 
			
		||||
@@ -56,8 +59,11 @@ class ExportController extends AbstractController
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly ExportFormHelper $exportFormHelper,
 | 
			
		||||
        private readonly SavedExportRepositoryInterface $savedExportRepository,
 | 
			
		||||
        private readonly Security $security
 | 
			
		||||
    ) {}
 | 
			
		||||
        private readonly Security $security,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/exports/download/{alias}", name="chill_main_export_download", methods={"GET"})
 | 
			
		||||
@@ -275,7 +281,7 @@ class ExportController extends AbstractController
 | 
			
		||||
        $options = match ($step) {
 | 
			
		||||
            'export', 'generate_export' => [
 | 
			
		||||
                'export_alias' => $alias,
 | 
			
		||||
                'picked_centers' => $exportManager->getPickedCenters($data['centers']),
 | 
			
		||||
                'picked_centers' => $exportManager->getPickedCenters($data['centers'] ?? []),
 | 
			
		||||
            ],
 | 
			
		||||
            'formatter', 'generate_formatter' => [
 | 
			
		||||
                'export_alias' => $alias,
 | 
			
		||||
@@ -333,9 +339,9 @@ class ExportController extends AbstractController
 | 
			
		||||
        $exportManager = $this->exportManager;
 | 
			
		||||
 | 
			
		||||
        // check we have data from the previous step (export step)
 | 
			
		||||
        $data = $this->session->get('centers_step', null);
 | 
			
		||||
        $data = $this->session->get('centers_step', []);
 | 
			
		||||
 | 
			
		||||
        if (null === $data) {
 | 
			
		||||
        if (null === $data && true === $this->filterStatsByCenters) {
 | 
			
		||||
            return $this->redirectToRoute('chill_main_export_new', [
 | 
			
		||||
                'step' => $this->getNextStep('export', $export, true),
 | 
			
		||||
                'alias' => $alias,
 | 
			
		||||
@@ -484,9 +490,13 @@ class ExportController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        $alias = $rawData['alias'];
 | 
			
		||||
 | 
			
		||||
        $formCenters = $this->createCreateFormExport($alias, 'generate_centers', [], $savedExport);
 | 
			
		||||
        $formCenters->submit($rawData['centers']);
 | 
			
		||||
        $dataCenters = $formCenters->getData();
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $formCenters = $this->createCreateFormExport($alias, 'generate_centers', [], $savedExport);
 | 
			
		||||
            $formCenters->submit($rawData['centers']);
 | 
			
		||||
            $dataCenters = $formCenters->getData();
 | 
			
		||||
        } else {
 | 
			
		||||
            $dataCenters = ['centers' => []];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters, $savedExport);
 | 
			
		||||
        $formExport->submit($rawData['export']);
 | 
			
		||||
@@ -513,6 +523,14 @@ class ExportController extends AbstractController
 | 
			
		||||
     */
 | 
			
		||||
    private function selectCentersStep(Request $request, DirectExportInterface|ExportInterface $export, $alias, SavedExport $savedExport = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (!$this->filterStatsByCenters) {
 | 
			
		||||
            return $this->redirectToRoute('chill_main_export_new', [
 | 
			
		||||
                'step' => $this->getNextStep('centers', $export),
 | 
			
		||||
                'alias' => $alias,
 | 
			
		||||
                'from_saved' => $request->get('from_saved', ''),
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /** @var \Chill\MainBundle\Export\ExportManager $exportManager */
 | 
			
		||||
        $exportManager = $this->exportManager;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,12 +32,13 @@ use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
class UserController extends CRUDController
 | 
			
		||||
{
 | 
			
		||||
    final public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter';
 | 
			
		||||
 | 
			
		||||
    public function __construct(private readonly LoggerInterface $logger, private readonly ValidatorInterface $validator, private readonly UserPasswordEncoderInterface $passwordEncoder, private readonly UserRepository $userRepository, protected ParameterBagInterface $parameterBag) {}
 | 
			
		||||
    public function __construct(private readonly LoggerInterface $logger, private readonly ValidatorInterface $validator, private readonly UserPasswordEncoderInterface $passwordEncoder, private readonly UserRepository $userRepository, protected ParameterBagInterface $parameterBag, private readonly TranslatorInterface $translator) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Route("/{_locale}/admin/main/user/{uid}/add_link_groupcenter",
 | 
			
		||||
@@ -65,7 +66,7 @@ class UserController extends CRUDController
 | 
			
		||||
            if (0 === $this->validator->validate($user)->count()) {
 | 
			
		||||
                $em->flush();
 | 
			
		||||
 | 
			
		||||
                $this->addFlash('success', $this->get('translator')->trans('The '
 | 
			
		||||
                $this->addFlash('success', $this->translator->trans('The '
 | 
			
		||||
                    .'permissions have been successfully added to the user'));
 | 
			
		||||
 | 
			
		||||
                $returnPathParams = $request->query->has('returnPath') ?
 | 
			
		||||
@@ -115,14 +116,14 @@ class UserController extends CRUDController
 | 
			
		||||
        try {
 | 
			
		||||
            $user->removeGroupCenter($groupCenter);
 | 
			
		||||
        } catch (\RuntimeException $ex) {
 | 
			
		||||
            $this->addFlash('error', $this->get('translator')->trans($ex->getMessage()));
 | 
			
		||||
            $this->addFlash('error', $this->translator->trans($ex->getMessage()));
 | 
			
		||||
 | 
			
		||||
            return $this->redirectToRoute('chill_crud_admin_user_edit', ['id' => $uid]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $em->flush();
 | 
			
		||||
 | 
			
		||||
        $this->addFlash('success', $this->get('translator')
 | 
			
		||||
        $this->addFlash('success', $this->translator
 | 
			
		||||
            ->trans('The permissions where removed.'));
 | 
			
		||||
 | 
			
		||||
        return $this->redirectToRoute('chill_crud_admin_user_edit', ['id' => $uid]);
 | 
			
		||||
@@ -207,7 +208,7 @@ class UserController extends CRUDController
 | 
			
		||||
            $user->setCurrentLocation($currentLocation);
 | 
			
		||||
 | 
			
		||||
            $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans('Current location successfully updated'));
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans('Current location successfully updated'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirect(
 | 
			
		||||
                $request->query->has('returnPath') ? $request->query->get('returnPath') :
 | 
			
		||||
@@ -243,7 +244,7 @@ class UserController extends CRUDController
 | 
			
		||||
            $user->setPassword($this->passwordEncoder->encodePassword($user, $password));
 | 
			
		||||
 | 
			
		||||
            $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans('Password successfully updated!'));
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans('Password successfully updated!'));
 | 
			
		||||
 | 
			
		||||
            return $this->redirect(
 | 
			
		||||
                $request->query->has('returnPath') ? $request->query->get('returnPath') :
 | 
			
		||||
 
 | 
			
		||||
@@ -116,8 +116,12 @@ class Configuration implements ConfigurationInterface
 | 
			
		||||
            ->booleanNode('form_show_centers')
 | 
			
		||||
            ->defaultTrue()
 | 
			
		||||
            ->end()
 | 
			
		||||
            ->booleanNode('filter_stats_by_center')
 | 
			
		||||
            ->defaultTrue()
 | 
			
		||||
            ->info("if set to false, the exports won't take into account the center of the people")
 | 
			
		||||
            ->end()
 | 
			
		||||
            ->end()
 | 
			
		||||
            ->end() // end of 'acl'
 | 
			
		||||
            ->booleanNode('access_global_history')
 | 
			
		||||
            ->defaultTrue()
 | 
			
		||||
            ->end()
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Chill\MainBundle\Form\Type\Export\ExportType;
 | 
			
		||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
@@ -54,20 +55,17 @@ class ExportManager
 | 
			
		||||
     */
 | 
			
		||||
    private array $formatters = [];
 | 
			
		||||
 | 
			
		||||
    private readonly string|\Stringable|\Symfony\Component\Security\Core\User\UserInterface $user;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly LoggerInterface $logger,
 | 
			
		||||
        private readonly AuthorizationCheckerInterface $authorizationChecker,
 | 
			
		||||
        private readonly AuthorizationHelperInterface $authorizationHelper,
 | 
			
		||||
        TokenStorageInterface $tokenStorage,
 | 
			
		||||
        private readonly TokenStorageInterface $tokenStorage,
 | 
			
		||||
        iterable $exports,
 | 
			
		||||
        iterable $aggregators,
 | 
			
		||||
        iterable $filters
 | 
			
		||||
        // iterable $formatters,
 | 
			
		||||
        // iterable $exportElementProvider
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->user = $tokenStorage->getToken()->getUser();
 | 
			
		||||
        $this->exports = iterator_to_array($exports);
 | 
			
		||||
        $this->aggregators = iterator_to_array($aggregators);
 | 
			
		||||
        $this->filters = iterator_to_array($filters);
 | 
			
		||||
@@ -91,20 +89,24 @@ class ExportManager
 | 
			
		||||
     *
 | 
			
		||||
     * @return FilterInterface[] a \Generator that contains filters. The key is the filter's alias
 | 
			
		||||
     */
 | 
			
		||||
    public function &getFiltersApplyingOn(DirectExportInterface|ExportInterface $export, array $centers = null): iterable
 | 
			
		||||
    public function getFiltersApplyingOn(DirectExportInterface|ExportInterface $export, array $centers = null): array
 | 
			
		||||
    {
 | 
			
		||||
        if ($export instanceof DirectExportInterface) {
 | 
			
		||||
            return;
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $filters = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->filters as $alias => $filter) {
 | 
			
		||||
            if (
 | 
			
		||||
                \in_array($filter->applyOn(), $export->supportsModifiers(), true)
 | 
			
		||||
                    && $this->isGrantedForElement($filter, $export, $centers)
 | 
			
		||||
            ) {
 | 
			
		||||
                yield $alias => $filter;
 | 
			
		||||
                $filters[$alias] = $filter;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $filters;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -112,22 +114,26 @@ class ExportManager
 | 
			
		||||
     *
 | 
			
		||||
     * @internal This class check the interface implemented by export, and, if ´ListInterface´ is used, return an empty array
 | 
			
		||||
     *
 | 
			
		||||
     * @return iterable<string, AggregatorInterface>|null a \Generator that contains aggretagors. The key is the filter's alias
 | 
			
		||||
     * @return array<string, AggregatorInterface> an array that contains aggregators. The key is the filter's alias
 | 
			
		||||
     */
 | 
			
		||||
    public function &getAggregatorsApplyingOn(DirectExportInterface|ExportInterface $export, array $centers = null): ?iterable
 | 
			
		||||
    public function getAggregatorsApplyingOn(DirectExportInterface|ExportInterface $export, array $centers = null): array
 | 
			
		||||
    {
 | 
			
		||||
        if ($export instanceof ListInterface || $export instanceof DirectExportInterface) {
 | 
			
		||||
            return;
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $aggregators = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->aggregators as $alias => $aggregator) {
 | 
			
		||||
            if (
 | 
			
		||||
                \in_array($aggregator->applyOn(), $export->supportsModifiers(), true)
 | 
			
		||||
                    && $this->isGrantedForElement($aggregator, $export, $centers)
 | 
			
		||||
            ) {
 | 
			
		||||
                yield $alias => $aggregator;
 | 
			
		||||
                $aggregators[$alias] = $aggregator;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $aggregators;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addExportElementsProvider(ExportElementsProviderInterface $provider, string $prefix): void
 | 
			
		||||
@@ -347,6 +353,17 @@ class ExportManager
 | 
			
		||||
        return $this->filters[$alias];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAllFilters(): array
 | 
			
		||||
    {
 | 
			
		||||
        $filters = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->filters as $alias => $filter) {
 | 
			
		||||
            $filters[$alias] = $filter;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $filters;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * get all filters.
 | 
			
		||||
     *
 | 
			
		||||
@@ -452,7 +469,7 @@ class ExportManager
 | 
			
		||||
        if (null === $centers || [] === $centers) {
 | 
			
		||||
            // we want to try if at least one center is reachable
 | 
			
		||||
            return [] !== $this->authorizationHelper->getReachableCenters(
 | 
			
		||||
                $this->user,
 | 
			
		||||
                $this->tokenStorage->getToken()->getUser(),
 | 
			
		||||
                $role
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
@@ -484,11 +501,17 @@ class ExportManager
 | 
			
		||||
    {
 | 
			
		||||
        $r = [];
 | 
			
		||||
 | 
			
		||||
        $user = $this->tokenStorage->getToken()->getUser();
 | 
			
		||||
 | 
			
		||||
        if (!$user instanceof User) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($centers as $center) {
 | 
			
		||||
            $r[] = [
 | 
			
		||||
                'center' => $center,
 | 
			
		||||
                'circles' => $this->authorizationHelper->getReachableScopes(
 | 
			
		||||
                    $this->user,
 | 
			
		||||
                    $user,
 | 
			
		||||
                    $element->requiredRole(),
 | 
			
		||||
                    $center
 | 
			
		||||
                ),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								src/Bundle/ChillMainBundle/Export/SortExportElement.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/Bundle/ChillMainBundle/Export/SortExportElement.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Export;
 | 
			
		||||
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
final readonly class SortExportElement
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private TranslatorInterface $translator,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param array<int|string, FilterInterface> $elements
 | 
			
		||||
     */
 | 
			
		||||
    public function sortFilters(array &$elements): void
 | 
			
		||||
    {
 | 
			
		||||
        uasort($elements, fn (FilterInterface $a, FilterInterface $b) => $this->translator->trans($a->getTitle()) <=> $this->translator->trans($b->getTitle()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param array<int|string, AggregatorInterface> $elements
 | 
			
		||||
     */
 | 
			
		||||
    public function sortAggregators(array &$elements): void
 | 
			
		||||
    {
 | 
			
		||||
        uasort($elements, fn (AggregatorInterface $a, AggregatorInterface $b) => $this->translator->trans($a->getTitle()) <=> $this->translator->trans($b->getTitle()));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\MainBundle\Form\Type\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\ExportManager;
 | 
			
		||||
use Chill\MainBundle\Export\SortExportElement;
 | 
			
		||||
use Chill\MainBundle\Validator\Constraints\Export\ExportElementConstraint;
 | 
			
		||||
use Symfony\Component\Form\AbstractType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
 | 
			
		||||
@@ -28,15 +29,7 @@ class ExportType extends AbstractType
 | 
			
		||||
 | 
			
		||||
    final public const PICK_FORMATTER_KEY = 'pick_formatter';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var ExportManager
 | 
			
		||||
     */
 | 
			
		||||
    protected $exportManager;
 | 
			
		||||
 | 
			
		||||
    public function __construct(ExportManager $exportManager)
 | 
			
		||||
    {
 | 
			
		||||
        $this->exportManager = $exportManager;
 | 
			
		||||
    }
 | 
			
		||||
    public function __construct(private readonly ExportManager $exportManager, private readonly SortExportElement $sortExportElement) {}
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder, array $options)
 | 
			
		||||
    {
 | 
			
		||||
@@ -58,12 +51,12 @@ class ExportType extends AbstractType
 | 
			
		||||
        if ($export instanceof \Chill\MainBundle\Export\ExportInterface) {
 | 
			
		||||
            // add filters
 | 
			
		||||
            $filters = $this->exportManager->getFiltersApplyingOn($export, $options['picked_centers']);
 | 
			
		||||
            $this->sortExportElement->sortFilters($filters);
 | 
			
		||||
            $filterBuilder = $builder->create(self::FILTER_KEY, FormType::class, ['compound' => true]);
 | 
			
		||||
 | 
			
		||||
            foreach ($filters as $alias => $filter) {
 | 
			
		||||
                $filterBuilder->add($alias, FilterType::class, [
 | 
			
		||||
                    'filter_alias' => $alias,
 | 
			
		||||
                    'export_manager' => $this->exportManager,
 | 
			
		||||
                    'filter' => $filter,
 | 
			
		||||
                    'label' => $filter->getTitle(),
 | 
			
		||||
                    'constraints' => [
 | 
			
		||||
                        new ExportElementConstraint(['element' => $filter]),
 | 
			
		||||
@@ -76,6 +69,7 @@ class ExportType extends AbstractType
 | 
			
		||||
            // add aggregators
 | 
			
		||||
            $aggregators = $this->exportManager
 | 
			
		||||
                ->getAggregatorsApplyingOn($export, $options['picked_centers']);
 | 
			
		||||
            $this->sortExportElement->sortAggregators($aggregators);
 | 
			
		||||
            $aggregatorBuilder = $builder->create(
 | 
			
		||||
                self::AGGREGATOR_KEY,
 | 
			
		||||
                FormType::class,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Form\Type\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Symfony\Component\Form\AbstractType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
 | 
			
		||||
@@ -25,8 +26,7 @@ class FilterType extends AbstractType
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder, array $options)
 | 
			
		||||
    {
 | 
			
		||||
        $exportManager = $options['export_manager'];
 | 
			
		||||
        $filter = $exportManager->getFilter($options['filter_alias']);
 | 
			
		||||
        $filter = $options['filter'];
 | 
			
		||||
 | 
			
		||||
        $builder
 | 
			
		||||
            ->add(self::ENABLED_FIELD, CheckboxType::class, [
 | 
			
		||||
@@ -46,8 +46,9 @@ class FilterType extends AbstractType
 | 
			
		||||
 | 
			
		||||
    public function configureOptions(OptionsResolver $resolver)
 | 
			
		||||
    {
 | 
			
		||||
        $resolver->setRequired('filter_alias')
 | 
			
		||||
            ->setRequired('export_manager')
 | 
			
		||||
        $resolver
 | 
			
		||||
            ->setRequired('filter')
 | 
			
		||||
            ->setAllowedTypes('filter', [FilterInterface::class])
 | 
			
		||||
            ->setDefault('compound', true)
 | 
			
		||||
            ->setDefault('error_bubbling', false);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ class PickRollingDateType extends AbstractType
 | 
			
		||||
                ),
 | 
			
		||||
                'multiple' => false,
 | 
			
		||||
                'expanded' => false,
 | 
			
		||||
                'required' => $options['required'],
 | 
			
		||||
                'label' => 'rolling_date.roll_movement',
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('fixedDate', ChillDateType::class, [
 | 
			
		||||
@@ -57,7 +58,10 @@ class PickRollingDateType extends AbstractType
 | 
			
		||||
            'constraints' => [
 | 
			
		||||
                new Callback($this->validate(...)),
 | 
			
		||||
            ],
 | 
			
		||||
            'required' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $resolver->setAllowedTypes('required', 'bool');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function validate($data, ExecutionContextInterface $context, $payload): void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{#
 | 
			
		||||
 * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, 
 | 
			
		||||
 * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
 | 
			
		||||
 <info@champs-libres.coop> / <http://www.champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
@@ -36,84 +36,84 @@
 | 
			
		||||
 | 
			
		||||
{% block content  %}
 | 
			
		||||
    <div class="col-md-10">
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
        {{ include('@ChillMain/Export/_breadcrumb.html.twig') }}
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
        <h1>{{ export.title|trans }}</h1>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <p>{{ export.description|trans }}</p>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
        {{ form_start(form) }}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        {% if form.children.export.children.filters is defined %}
 | 
			
		||||
            {% if form.children.export.children.filters is not empty%}
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            <section class="filter mb-4">
 | 
			
		||||
                <h2>{{ 'Filters'| trans }}</h2>
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                {{ form_errors(form.children.export.children.filters) }}
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                <div class="flex-table">
 | 
			
		||||
                {% for filter_form in form.children.export.children.filters %}
 | 
			
		||||
                    <div class="item-bloc no-altern">
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                        {{ form_widget(filter_form.enabled, {
 | 
			
		||||
                            'label': filter_form.vars.label,
 | 
			
		||||
                            'label_attr': { 'class': 'h6' },
 | 
			
		||||
                            'attr': { 'data-display-target': filter_form.vars.id }
 | 
			
		||||
                        }) }}
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                        <div data-display-show-hide="{{ filter_form.vars.id }}">
 | 
			
		||||
                            {{ form_widget(filter_form.form) }}
 | 
			
		||||
                            {{ form_errors(filter_form) }}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
                </div>
 | 
			
		||||
            </section>
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            {% else %}
 | 
			
		||||
                {# render the children, to mark the widget as 'rendered' #}
 | 
			
		||||
                {{ form_widget(form.children.export.children.filters) }}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        {% if form.children.export.children.aggregators is defined %}
 | 
			
		||||
            {% if form.children.export.children.aggregators is not empty %}
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            <section class="aggregator mb-4">
 | 
			
		||||
                <h2>{{ 'Aggregators'| trans }}</h2>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
                <div class="flex-table">
 | 
			
		||||
                {% for aggregator_form in form.children.export.children.aggregators %}
 | 
			
		||||
                    <div class="item-bloc no-altern">
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                        {{ form_widget(aggregator_form.enabled, {
 | 
			
		||||
                            'label': aggregator_form.vars.label,
 | 
			
		||||
                            'label_attr': { 'class': 'h6' },
 | 
			
		||||
                            'attr': { 'data-display-target': aggregator_form.vars.id }
 | 
			
		||||
                        }) }}
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                        <div data-display-show-hide="{{ aggregator_form.vars.id }}">
 | 
			
		||||
                            {{ form_widget(aggregator_form.form) }}
 | 
			
		||||
                            {{ form_errors(aggregator_form) }}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                    </div>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
                </div>
 | 
			
		||||
            </section>
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            {% else %}
 | 
			
		||||
                {# render the children, to mark the widget as 'rendered' #}
 | 
			
		||||
                {{ form_widget(form.children.export.children.aggregators) }}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        {% if form.children.export.children.export.children|length > 0 %}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
            <style>
 | 
			
		||||
                div#export_export_fields { column-count: 2; }
 | 
			
		||||
            </style>
 | 
			
		||||
@@ -123,12 +123,12 @@
 | 
			
		||||
                </h2>
 | 
			
		||||
                {{ form_widget(form.children.export.children.export) }}
 | 
			
		||||
            </section>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        {% else %}
 | 
			
		||||
            {# render the children, to mark the widget as 'rendered' #}
 | 
			
		||||
            {{ form_widget(form.children.export.children.export) }}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        {% if form.children.export.children.pick_formatter is defined %}
 | 
			
		||||
            <section class="formatter mb-4">
 | 
			
		||||
                <h2>
 | 
			
		||||
@@ -140,7 +140,7 @@
 | 
			
		||||
                {{ form_row(form.children.export.children.pick_formatter.children.alias, { 'label' : 'Formatter' }) }}
 | 
			
		||||
            </section>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <p>{{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-create' }, 'label' : 'Go to formatter options' } ) }}</p>
 | 
			
		||||
        {{ form_end(form) }}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,15 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Test\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\DirectExportInterface;
 | 
			
		||||
use Chill\MainBundle\Export\ExportInterface;
 | 
			
		||||
use Chill\MainBundle\Test\PrepareClientTrait;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\NativeQuery;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class provide a set of tests for exports.
 | 
			
		||||
@@ -94,7 +98,7 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an instance of the report to test.
 | 
			
		||||
     *
 | 
			
		||||
     * @return \Chill\MainBundle\Export\ExportInterface an instance of the export to test
 | 
			
		||||
     * @return ExportInterface|DirectExportInterface|iterable<ExportInterface>|iterable<DirectExportInterface> an instance of the export to test
 | 
			
		||||
     */
 | 
			
		||||
    abstract public function getExport();
 | 
			
		||||
 | 
			
		||||
@@ -116,19 +120,40 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    abstract public function getModifiersCombination();
 | 
			
		||||
 | 
			
		||||
    protected function getParameters(bool $filterStatsByCenter): ParameterBagInterface
 | 
			
		||||
    {
 | 
			
		||||
        return new ParameterBag(['chill_main' => ['acl' => ['filter_stats_by_center' => $filterStatsByCenter]]]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * wrap the results of @see{self::getExports()}, which may be an iterable or an export into an iterble.
 | 
			
		||||
     */
 | 
			
		||||
    private function getExports(): iterable
 | 
			
		||||
    {
 | 
			
		||||
        $exports = $this->getExport();
 | 
			
		||||
 | 
			
		||||
        if (is_iterable($exports)) {
 | 
			
		||||
            return $exports;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [$exports];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Test the formatters type are string.
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetAllowedFormattersType()
 | 
			
		||||
    {
 | 
			
		||||
        $formattersTypes = $this->getExport()->getAllowedFormattersTypes();
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $formattersTypes = $export->getAllowedFormattersTypes();
 | 
			
		||||
 | 
			
		||||
        $this->assertContainsOnly(
 | 
			
		||||
            'string',
 | 
			
		||||
            $formattersTypes,
 | 
			
		||||
            true,
 | 
			
		||||
            'Test that the method `getAllowedFormattersTypes` returns an array of string'
 | 
			
		||||
        );
 | 
			
		||||
            $this->assertContainsOnly(
 | 
			
		||||
                'string',
 | 
			
		||||
                $formattersTypes,
 | 
			
		||||
                true,
 | 
			
		||||
                'Test that the method `getAllowedFormattersTypes` returns an array of string'
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -136,17 +161,17 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetDescription()
 | 
			
		||||
    {
 | 
			
		||||
        $export = $this->getExport();
 | 
			
		||||
 | 
			
		||||
        $this->assertIsString(
 | 
			
		||||
            $export->getDescription(),
 | 
			
		||||
            'Assert that the `getDescription` method return a string'
 | 
			
		||||
        );
 | 
			
		||||
        $this->assertNotEmpty(
 | 
			
		||||
            $export->getDescription(),
 | 
			
		||||
            'Assert that the `getDescription` method does not return an empty '
 | 
			
		||||
            .'string.'
 | 
			
		||||
        );
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $this->assertIsString(
 | 
			
		||||
                $export->getDescription(),
 | 
			
		||||
                'Assert that the `getDescription` method return a string'
 | 
			
		||||
            );
 | 
			
		||||
            $this->assertNotEmpty(
 | 
			
		||||
                $export->getDescription(),
 | 
			
		||||
                'Assert that the `getDescription` method does not return an empty '
 | 
			
		||||
                .'string.'
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -156,19 +181,21 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetQueryKeys(array $data)
 | 
			
		||||
    {
 | 
			
		||||
        $queryKeys = $this->getExport()->getQueryKeys($data);
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $queryKeys = $export->getQueryKeys($data);
 | 
			
		||||
 | 
			
		||||
        $this->assertContainsOnly(
 | 
			
		||||
            'string',
 | 
			
		||||
            $queryKeys,
 | 
			
		||||
            true,
 | 
			
		||||
            'test that the query keys returned by `getQueryKeys` are only strings'
 | 
			
		||||
        );
 | 
			
		||||
        $this->assertGreaterThanOrEqual(
 | 
			
		||||
            1,
 | 
			
		||||
            \count($queryKeys),
 | 
			
		||||
            'test that there are at least one query key returned'
 | 
			
		||||
        );
 | 
			
		||||
            $this->assertContainsOnly(
 | 
			
		||||
                'string',
 | 
			
		||||
                $queryKeys,
 | 
			
		||||
                true,
 | 
			
		||||
                'test that the query keys returned by `getQueryKeys` are only strings'
 | 
			
		||||
            );
 | 
			
		||||
            $this->assertGreaterThanOrEqual(
 | 
			
		||||
                1,
 | 
			
		||||
                \count($queryKeys),
 | 
			
		||||
                'test that there are at least one query key returned'
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -187,61 +214,70 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetResultsAndLabels($modifiers, $acl, array $data)
 | 
			
		||||
    {
 | 
			
		||||
        // it is more convenient to  group the `getResult` and `getLabels` test
 | 
			
		||||
        // due to the fact that testing both methods use the same tools.
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            // it is more convenient to  group the `getResult` and `getLabels` test
 | 
			
		||||
            // due to the fact that testing both methods use the same tools.
 | 
			
		||||
 | 
			
		||||
        $queryKeys = $this->getExport()->getQueryKeys($data);
 | 
			
		||||
        $query = $this->getExport()->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
            $queryKeys = $export->getQueryKeys($data);
 | 
			
		||||
            $query = $export->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
 | 
			
		||||
        // limit the result for the query for performance reason (only for QueryBuilder,
 | 
			
		||||
        // not possible in NativeQuery)
 | 
			
		||||
        if ($query instanceof QueryBuilder) {
 | 
			
		||||
            $query->setMaxResults(1);
 | 
			
		||||
        }
 | 
			
		||||
            // limit the result for the query for performance reason (only for QueryBuilder,
 | 
			
		||||
            // not possible in NativeQuery)
 | 
			
		||||
            if ($query instanceof QueryBuilder) {
 | 
			
		||||
                $query->setMaxResults(1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        $results = $this->getExport()->getResult($query, $data);
 | 
			
		||||
            $results = $export->getResult($query, $data);
 | 
			
		||||
 | 
			
		||||
        $this->assertIsArray(
 | 
			
		||||
            $results,
 | 
			
		||||
            'assert that the returned result is an array'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (0 === \count($results)) {
 | 
			
		||||
            $this->markTestIncomplete('The result is empty. We cannot process tests '
 | 
			
		||||
                .'on results');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // testing the result
 | 
			
		||||
        $result = $results[0];
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue(
 | 
			
		||||
            is_iterable($result),
 | 
			
		||||
            'test that each row in the result is traversable or an array'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        foreach ($result as $key => $value) {
 | 
			
		||||
            $this->assertContains(
 | 
			
		||||
                $key,
 | 
			
		||||
                $queryKeys,
 | 
			
		||||
                'test that each key is present in `getQueryKeys`'
 | 
			
		||||
            $this->assertIsArray(
 | 
			
		||||
                $results,
 | 
			
		||||
                'assert that the returned result is an array'
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            $closure = $this->getExport()->getLabels($key, [$value], $data);
 | 
			
		||||
            if (0 === \count($results)) {
 | 
			
		||||
                $this->markTestIncomplete('The result is empty. We cannot process tests '
 | 
			
		||||
                    .'on results');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // testing the result
 | 
			
		||||
            $result = $results[0];
 | 
			
		||||
 | 
			
		||||
            $this->assertTrue(
 | 
			
		||||
                \is_callable($closure, false),
 | 
			
		||||
                'test that the `getLabels` for key is a callable'
 | 
			
		||||
                is_iterable($result),
 | 
			
		||||
                'test that each row in the result is traversable or an array'
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            $this->assertTrue(
 | 
			
		||||
                // conditions
 | 
			
		||||
                \is_string((string) \call_user_func($closure, '_header'))
 | 
			
		||||
                && !empty(\call_user_func($closure, '_header'))
 | 
			
		||||
                && '_header' !== \call_user_func($closure, '_header'),
 | 
			
		||||
                // message
 | 
			
		||||
                sprintf('Test that the callable return by `getLabels` for key %s '
 | 
			
		||||
                .'can provide an header', $key)
 | 
			
		||||
            );
 | 
			
		||||
            $i = 0;
 | 
			
		||||
            foreach ($result as $key => $value) {
 | 
			
		||||
                $this->assertContains(
 | 
			
		||||
                    $key,
 | 
			
		||||
                    $queryKeys,
 | 
			
		||||
                    'test that each key is present in `getQueryKeys`'
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                $closure = $export->getLabels($key, [$value], $data);
 | 
			
		||||
 | 
			
		||||
                $this->assertTrue(
 | 
			
		||||
                    \is_callable($closure, false),
 | 
			
		||||
                    'test that the `getLabels` for key is a callable'
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                $this->assertTrue(
 | 
			
		||||
                    // conditions
 | 
			
		||||
                    \is_string((string) \call_user_func($closure, '_header'))
 | 
			
		||||
                    && !empty(\call_user_func($closure, '_header'))
 | 
			
		||||
                    && '_header' !== \call_user_func($closure, '_header'),
 | 
			
		||||
                    // message
 | 
			
		||||
                    sprintf('Test that the callable return by `getLabels` for key %s '
 | 
			
		||||
                        .'can provide an header', $key)
 | 
			
		||||
                );
 | 
			
		||||
                ++$i;
 | 
			
		||||
 | 
			
		||||
                if ($i > 15) {
 | 
			
		||||
                    // do not iterate on each result
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -250,14 +286,14 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetType()
 | 
			
		||||
    {
 | 
			
		||||
        $export = $this->getExport();
 | 
			
		||||
 | 
			
		||||
        $this->assertIsString(
 | 
			
		||||
            $export->getType(),
 | 
			
		||||
            'Assert that the `getType` method return a string'
 | 
			
		||||
        );
 | 
			
		||||
        $this->assertNotEmpty($export->getType(), 'Assert that the `getType` method'
 | 
			
		||||
            .' does not return an empty string.');
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $this->assertIsString(
 | 
			
		||||
                $export->getType(),
 | 
			
		||||
                'Assert that the `getType` method return a string'
 | 
			
		||||
            );
 | 
			
		||||
            $this->assertNotEmpty($export->getType(), 'Assert that the `getType` method'
 | 
			
		||||
                .' does not return an empty string.');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -272,34 +308,36 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testInitiateQuery(mixed $modifiers, mixed $acl, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        $query = $this->getExport()->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $query = $export->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue(
 | 
			
		||||
            $query instanceof QueryBuilder || $query instanceof NativeQuery,
 | 
			
		||||
            sprintf(
 | 
			
		||||
                'Assert that the returned query is an instance of %s or %s',
 | 
			
		||||
                QueryBuilder::class,
 | 
			
		||||
                Query::class
 | 
			
		||||
            )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if ($query instanceof QueryBuilder) {
 | 
			
		||||
            $this->assertGreaterThanOrEqual(
 | 
			
		||||
                1,
 | 
			
		||||
                \count($query->getDQLPart('select')),
 | 
			
		||||
                "assert there is at least one 'select' part"
 | 
			
		||||
            $this->assertTrue(
 | 
			
		||||
                $query instanceof QueryBuilder || $query instanceof NativeQuery,
 | 
			
		||||
                sprintf(
 | 
			
		||||
                    'Assert that the returned query is an instance of %s or %s',
 | 
			
		||||
                    QueryBuilder::class,
 | 
			
		||||
                    NativeQuery::class
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            $this->assertGreaterThanOrEqual(
 | 
			
		||||
                1,
 | 
			
		||||
                \count($query->getDQLPart('from')),
 | 
			
		||||
                "assert there is at least one 'from' part"
 | 
			
		||||
            );
 | 
			
		||||
        } elseif ($query instanceof NativeQuery) {
 | 
			
		||||
            $this->assertNotEmpty(
 | 
			
		||||
                $query->getSQL(),
 | 
			
		||||
                'check that the SQL query is not empty'
 | 
			
		||||
            );
 | 
			
		||||
            if ($query instanceof QueryBuilder) {
 | 
			
		||||
                $this->assertGreaterThanOrEqual(
 | 
			
		||||
                    1,
 | 
			
		||||
                    \count($query->getDQLPart('select')),
 | 
			
		||||
                    "assert there is at least one 'select' part"
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                $this->assertGreaterThanOrEqual(
 | 
			
		||||
                    1,
 | 
			
		||||
                    \count($query->getDQLPart('from')),
 | 
			
		||||
                    "assert there is at least one 'from' part"
 | 
			
		||||
                );
 | 
			
		||||
            } elseif ($query instanceof NativeQuery) {
 | 
			
		||||
                $this->assertNotEmpty(
 | 
			
		||||
                    $query->getSQL(),
 | 
			
		||||
                    'check that the SQL query is not empty'
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -308,9 +346,11 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testRequiredRole()
 | 
			
		||||
    {
 | 
			
		||||
        $role = $this->getExport()->requiredRole();
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $role = $export->requiredRole();
 | 
			
		||||
 | 
			
		||||
        self::assertIsString($role);
 | 
			
		||||
            self::assertIsString($role);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -323,22 +363,23 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testSupportsModifier(mixed $modifiers, mixed $acl, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        $export = $this->getExport();
 | 
			
		||||
        $query = $export->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
        foreach ($this->getExports() as $export) {
 | 
			
		||||
            $query = $export->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
 | 
			
		||||
        if ($query instanceof QueryBuilder) {
 | 
			
		||||
            $this->assertContainsOnly(
 | 
			
		||||
                'string',
 | 
			
		||||
                $export->supportsModifiers(),
 | 
			
		||||
                true,
 | 
			
		||||
                'Test that the `supportsModifiers` method returns only strings'
 | 
			
		||||
            );
 | 
			
		||||
        } elseif ($query instanceof NativeQuery) {
 | 
			
		||||
            $this->assertTrue(
 | 
			
		||||
                null === $export->supportsModifiers()
 | 
			
		||||
                || 0 === \count($export->supportsModifiers()),
 | 
			
		||||
                'Test that the `supportsModifier` methods returns null or an empty array'
 | 
			
		||||
            );
 | 
			
		||||
            if ($query instanceof QueryBuilder) {
 | 
			
		||||
                $this->assertContainsOnly(
 | 
			
		||||
                    'string',
 | 
			
		||||
                    $export->supportsModifiers(),
 | 
			
		||||
                    true,
 | 
			
		||||
                    'Test that the `supportsModifiers` method returns only strings'
 | 
			
		||||
                );
 | 
			
		||||
            } elseif ($query instanceof NativeQuery) {
 | 
			
		||||
                $this->assertTrue(
 | 
			
		||||
                    null === $export->supportsModifiers()
 | 
			
		||||
                    || 0 === \count($export->supportsModifiers()),
 | 
			
		||||
                    'Test that the `supportsModifier` methods returns null or an empty array'
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,193 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Tests\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\MainBundle\Export\ExportManager;
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Chill\MainBundle\Export\SortExportElement;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class SortExportElementTest extends KernelTestCase
 | 
			
		||||
{
 | 
			
		||||
    private SortExportElement $sortExportElement;
 | 
			
		||||
 | 
			
		||||
    public function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUpBeforeClass();
 | 
			
		||||
        $this->sortExportElement = new SortExportElement($this->makeTranslator());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testSortFilterRealData(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $sorter = self::$container->get(SortExportElement::class);
 | 
			
		||||
        $translator = self::$container->get(TranslatorInterface::class);
 | 
			
		||||
        $exportManager = self::$container->get(ExportManager::class);
 | 
			
		||||
        $filters = $exportManager->getAllFilters();
 | 
			
		||||
 | 
			
		||||
        $sorter->sortFilters($filters);
 | 
			
		||||
 | 
			
		||||
        $previousName = null;
 | 
			
		||||
        foreach ($filters as $filter) {
 | 
			
		||||
            if (null === $previousName) {
 | 
			
		||||
                $previousName = $translator->trans($filter->getTitle());
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $current = $translator->trans($filter->getTitle());
 | 
			
		||||
            if ($current === $previousName) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            self::assertEquals(-1, $previousName <=> $current, sprintf("comparing '%s' and '%s'", $previousName, $current));
 | 
			
		||||
            $previousName = $current;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testSortAggregator(): void
 | 
			
		||||
    {
 | 
			
		||||
        $aggregators = [
 | 
			
		||||
            'foo' => $a = $this->makeAggregator('a'),
 | 
			
		||||
            'zop' => $q = $this->makeAggregator('q'),
 | 
			
		||||
            'bar' => $c = $this->makeAggregator('c'),
 | 
			
		||||
            'baz' => $b = $this->makeAggregator('b'),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        $this->sortExportElement->sortAggregators($aggregators);
 | 
			
		||||
 | 
			
		||||
        self::assertEquals(['foo', 'baz', 'bar', 'zop'], array_keys($aggregators));
 | 
			
		||||
        self::assertSame($a, $aggregators['foo']);
 | 
			
		||||
        self::assertSame($b, $aggregators['baz']);
 | 
			
		||||
        self::assertSame($c, $aggregators['bar']);
 | 
			
		||||
        self::assertSame($q, $aggregators['zop']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testSortFilter(): void
 | 
			
		||||
    {
 | 
			
		||||
        $filters = [
 | 
			
		||||
            'foo' => $a = $this->makeFilter('a'),
 | 
			
		||||
            'zop' => $q = $this->makeFilter('q'),
 | 
			
		||||
            'bar' => $c = $this->makeFilter('c'),
 | 
			
		||||
            'baz' => $b = $this->makeFilter('b'),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        $this->sortExportElement->sortFilters($filters);
 | 
			
		||||
 | 
			
		||||
        self::assertEquals(['foo', 'baz', 'bar', 'zop'], array_keys($filters));
 | 
			
		||||
        self::assertSame($a, $filters['foo']);
 | 
			
		||||
        self::assertSame($b, $filters['baz']);
 | 
			
		||||
        self::assertSame($c, $filters['bar']);
 | 
			
		||||
        self::assertSame($q, $filters['zop']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function makeTranslator(): TranslatorInterface
 | 
			
		||||
    {
 | 
			
		||||
        return new class () implements TranslatorInterface {
 | 
			
		||||
            public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null)
 | 
			
		||||
            {
 | 
			
		||||
                return $id;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function getLocale(): string
 | 
			
		||||
            {
 | 
			
		||||
                return 'en';
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function makeAggregator(string $title): AggregatorInterface
 | 
			
		||||
    {
 | 
			
		||||
        return new class ($title) implements AggregatorInterface {
 | 
			
		||||
            public function __construct(private readonly string $title) {}
 | 
			
		||||
 | 
			
		||||
            public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
 | 
			
		||||
            public function getFormDefaultData(): array
 | 
			
		||||
            {
 | 
			
		||||
                return [];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
            {
 | 
			
		||||
                return fn ($v) => $v;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function getQueryKeys($data)
 | 
			
		||||
            {
 | 
			
		||||
                return [];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function getTitle()
 | 
			
		||||
            {
 | 
			
		||||
                return $this->title;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function addRole(): ?string
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function alterQuery(QueryBuilder $qb, $data) {}
 | 
			
		||||
 | 
			
		||||
            public function applyOn()
 | 
			
		||||
            {
 | 
			
		||||
                return [];
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function makeFilter(string $title): FilterInterface
 | 
			
		||||
    {
 | 
			
		||||
        return new class ($title) implements FilterInterface {
 | 
			
		||||
            public function __construct(private readonly string $title) {}
 | 
			
		||||
 | 
			
		||||
            public function getTitle()
 | 
			
		||||
            {
 | 
			
		||||
                return $this->title;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
 | 
			
		||||
            public function getFormDefaultData(): array
 | 
			
		||||
            {
 | 
			
		||||
                return [];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function describeAction($data, $format = 'string')
 | 
			
		||||
            {
 | 
			
		||||
                return ['a', []];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function addRole(): ?string
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public function alterQuery(QueryBuilder $qb, $data) {}
 | 
			
		||||
 | 
			
		||||
            public function applyOn()
 | 
			
		||||
            {
 | 
			
		||||
                return [];
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -54,3 +54,5 @@ services:
 | 
			
		||||
            - { name: chill.export_formatter, alias: 'csv_pivoted_list' }
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Export\AccompanyingCourseExportHelper: ~
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Export\SortExportElement: ~
 | 
			
		||||
 
 | 
			
		||||
@@ -113,7 +113,7 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr
 | 
			
		||||
                $em->remove($accompanyingCourse);
 | 
			
		||||
                $em->flush();
 | 
			
		||||
 | 
			
		||||
                $this->addFlash('success', $this->get('translator')
 | 
			
		||||
                $this->addFlash('success', $this->translator
 | 
			
		||||
                    ->trans('The accompanying course has been successfully removed.'));
 | 
			
		||||
 | 
			
		||||
                if (null !== $person_id) {
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
use function array_filter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -33,24 +34,12 @@ use function array_filter;
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var EventDispatcherInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $eventDispatcher;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var ValidatorInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $validator;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository,
 | 
			
		||||
        EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        ValidatorInterface $validator
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
        $this->validator = $validator;
 | 
			
		||||
    }
 | 
			
		||||
        private readonly EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        private readonly ValidatorInterface $validator,
 | 
			
		||||
        private readonly TranslatorInterface $translator
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @throws \Exception
 | 
			
		||||
@@ -65,7 +54,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        if (false === $person->isOpen()) {
 | 
			
		||||
            $this->get('session')->getFlashBag()
 | 
			
		||||
                ->add('error', $this->get('translator')
 | 
			
		||||
                ->add('error', $this->translator
 | 
			
		||||
                    ->trans(
 | 
			
		||||
                        'Beware period is closed',
 | 
			
		||||
                        ['%name%' => $person->__toString()]
 | 
			
		||||
@@ -92,7 +81,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                if (0 === \count($errors)) {
 | 
			
		||||
                    $this->get('session')->getFlashBag()
 | 
			
		||||
                        ->add('success', $this->get('translator')
 | 
			
		||||
                        ->add('success', $this->translator
 | 
			
		||||
                            ->trans('An accompanying period has been closed.', [
 | 
			
		||||
                                '%name%' => $person->__toString(),
 | 
			
		||||
                            ]));
 | 
			
		||||
@@ -104,7 +93,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
                $this->get('session')->getFlashBag()
 | 
			
		||||
                    ->add('error', $this->get('translator')
 | 
			
		||||
                    ->add('error', $this->translator
 | 
			
		||||
                        ->trans('Error! Period not closed!'));
 | 
			
		||||
 | 
			
		||||
                foreach ($errors as $error) {
 | 
			
		||||
@@ -115,7 +104,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                $this->get('session')->getFlashBag()
 | 
			
		||||
                    ->add(
 | 
			
		||||
                        'error',
 | 
			
		||||
                        $this->get('translator')
 | 
			
		||||
                        $this->translator
 | 
			
		||||
                            ->trans('Pediod closing form is not valid')
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
@@ -175,7 +164,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                $em->flush();
 | 
			
		||||
                $flashBag->add(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')->trans(
 | 
			
		||||
                    $this->translator->trans(
 | 
			
		||||
                        'A period has been created.'
 | 
			
		||||
                    )
 | 
			
		||||
                );
 | 
			
		||||
@@ -184,7 +173,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                    'person_id' => $person->getId(),
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
            $flashBag->add('error', $this->get('translator')
 | 
			
		||||
            $flashBag->add('error', $this->translator
 | 
			
		||||
                ->trans('Error! Period not created!'));
 | 
			
		||||
 | 
			
		||||
            foreach ($errors as $error) {
 | 
			
		||||
@@ -244,7 +233,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
        // in case the person is already open
 | 
			
		||||
        if ($person->isOpen()) {
 | 
			
		||||
            $this->get('session')->getFlashBag()
 | 
			
		||||
                ->add('error', $this->get('translator')
 | 
			
		||||
                ->add('error', $this->translator
 | 
			
		||||
                    ->trans(
 | 
			
		||||
                        'Error! Period %name% is not closed ; it can be open',
 | 
			
		||||
                        ['%name%' => $person->__toString()]
 | 
			
		||||
@@ -276,7 +265,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                if (\count($errors) <= 0) {
 | 
			
		||||
                    $this->get('session')->getFlashBag()
 | 
			
		||||
                        ->add('success', $this->get('translator')
 | 
			
		||||
                        ->add('success', $this->translator
 | 
			
		||||
                            ->trans(
 | 
			
		||||
                                'An accompanying period has been opened.',
 | 
			
		||||
                                ['%name%' => $person->__toString()]
 | 
			
		||||
@@ -289,7 +278,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                    ]);
 | 
			
		||||
                }
 | 
			
		||||
                $this->get('session')->getFlashBag()
 | 
			
		||||
                    ->add('error', $this->get('translator')
 | 
			
		||||
                    ->add('error', $this->translator
 | 
			
		||||
                        ->trans('Period not opened'));
 | 
			
		||||
 | 
			
		||||
                foreach ($errors as $error) {
 | 
			
		||||
@@ -300,7 +289,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                $this->get('session')->getFlashBag()
 | 
			
		||||
                    ->add(
 | 
			
		||||
                        'error',
 | 
			
		||||
                        $this->get('translator')
 | 
			
		||||
                        $this->translator
 | 
			
		||||
                            ->trans('Period not opened : form is invalid')
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
@@ -340,7 +329,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
 | 
			
		||||
            $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
            $this->addFlash('success', $this->get('translator')->trans(
 | 
			
		||||
            $this->addFlash('success', $this->translator->trans(
 | 
			
		||||
                'The period has been re-opened'
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
@@ -413,7 +402,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                $flashBag->add(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')->trans('An accompanying period has been updated.')
 | 
			
		||||
                    $this->translator->trans('An accompanying period has been updated.')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                return $this->redirectToRoute('chill_person_accompanying_period_list', [
 | 
			
		||||
@@ -421,7 +410,7 @@ class AccompanyingPeriodController extends AbstractController
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $flashBag->add('error', $this->get('translator')
 | 
			
		||||
            $flashBag->add('error', $this->translator
 | 
			
		||||
                ->trans('Error when updating the period'));
 | 
			
		||||
 | 
			
		||||
            foreach ($errors as $error) {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class PersonAddressController
 | 
			
		||||
@@ -25,18 +26,10 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
 */
 | 
			
		||||
class PersonAddressController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var ValidatorInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $validator;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * PersonAddressController constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(ValidatorInterface $validator)
 | 
			
		||||
    {
 | 
			
		||||
        $this->validator = $validator;
 | 
			
		||||
    }
 | 
			
		||||
    public function __construct(private readonly ValidatorInterface $validator, private readonly TranslatorInterface $translator) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/person/{person_id}/address/create", name="chill_person_address_create", methods={"POST"})
 | 
			
		||||
@@ -77,14 +70,14 @@ class PersonAddressController extends AbstractController
 | 
			
		||||
 | 
			
		||||
                $this->addFlash(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')->trans('The new address was created successfully')
 | 
			
		||||
                    $this->translator->trans('The new address was created successfully')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                return $this->redirectToRoute('chill_person_address_list', [
 | 
			
		||||
                    'person_id' => $person->getId(),
 | 
			
		||||
                ]);
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->addFlash('error', $this->get('translator')
 | 
			
		||||
                $this->addFlash('error', $this->translator
 | 
			
		||||
                    ->trans('Error! Address not created!'));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -213,7 +206,7 @@ class PersonAddressController extends AbstractController
 | 
			
		||||
                $this->getDoctrine()->getManager()
 | 
			
		||||
                    ->flush();
 | 
			
		||||
 | 
			
		||||
                $this->addFlash('success', $this->get('translator')->trans(
 | 
			
		||||
                $this->addFlash('success', $this->translator->trans(
 | 
			
		||||
                    'The address has been successfully updated'
 | 
			
		||||
                ));
 | 
			
		||||
 | 
			
		||||
@@ -221,7 +214,7 @@ class PersonAddressController extends AbstractController
 | 
			
		||||
                    'person_id' => $person->getId(),
 | 
			
		||||
                ]);
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->addFlash('error', $this->get('translator')
 | 
			
		||||
                $this->addFlash('error', $this->translator
 | 
			
		||||
                    ->trans('Error when updating the period'));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Enum\DateGroupingChoiceEnum;
 | 
			
		||||
use Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregators\ClosingDateAggregatorTest;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see ClosingDateAggregatorTest
 | 
			
		||||
 */
 | 
			
		||||
final readonly class ClosingDateAggregator implements AggregatorInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acp_closing_date_agg';
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder): void
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('frequency', ChoiceType::class, [
 | 
			
		||||
            'choices' => array_combine(
 | 
			
		||||
                array_map(fn (DateGroupingChoiceEnum $c) => 'export.enum.frequency.'.$c->value, DateGroupingChoiceEnum::cases()),
 | 
			
		||||
                array_map(fn (DateGroupingChoiceEnum $c) => $c->value, DateGroupingChoiceEnum::cases()),
 | 
			
		||||
            ),
 | 
			
		||||
            'label' => 'export.aggregator.course.by_closing_date.frequency',
 | 
			
		||||
            'multiple' => false,
 | 
			
		||||
            'expanded' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'frequency' => 'year',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        return function (null|string $value): string {
 | 
			
		||||
            if ('_header' === $value) {
 | 
			
		||||
                return 'export.aggregator.course.by_closing_date.header';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (string) $value;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryKeys($data)
 | 
			
		||||
    {
 | 
			
		||||
        return [self::PREFIX.'_closing_date'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aggregator.course.by_closing_date.title';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb->addSelect(sprintf("TO_CHAR(acp.closingDate, '%s') AS {$p}_closing_date", $data['frequency']));
 | 
			
		||||
        $qb->addGroupBy("{$p}_closing_date");
 | 
			
		||||
        $qb->addOrderBy("{$p}_closing_date", 'DESC');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ACP_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -38,7 +38,7 @@ final readonly class DurationAggregator implements AggregatorInterface
 | 
			
		||||
        match ($data['precision']) {
 | 
			
		||||
            'day' => $qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate)  AS duration_aggregator'),
 | 
			
		||||
            'week' => $qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7  AS duration_aggregator'),
 | 
			
		||||
            'month' => $qb->addSelect('(EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 +
 | 
			
		||||
            'month' => $qb->addSelect('(EXTRACT (YEAR FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 +
 | 
			
		||||
                    EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate))) AS duration_aggregator'),
 | 
			
		||||
            default => throw new \LogicException('precision not supported: '.$data['precision']),
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Enum\DateGroupingChoiceEnum;
 | 
			
		||||
use Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregators\OpeningDateAggregatorTest;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see OpeningDateAggregatorTest
 | 
			
		||||
 */
 | 
			
		||||
final readonly class OpeningDateAggregator implements AggregatorInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acp_opening_date_agg';
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder): void
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('frequency', ChoiceType::class, [
 | 
			
		||||
            'choices' => array_combine(
 | 
			
		||||
                array_map(fn (DateGroupingChoiceEnum $c) => 'export.enum.frequency.'.$c->value, DateGroupingChoiceEnum::cases()),
 | 
			
		||||
                array_map(fn (DateGroupingChoiceEnum $c) => $c->value, DateGroupingChoiceEnum::cases()),
 | 
			
		||||
            ),
 | 
			
		||||
            'label' => 'export.aggregator.course.by_opening_date.frequency',
 | 
			
		||||
            'multiple' => false,
 | 
			
		||||
            'expanded' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'frequency' => 'year',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        return function (null|string $value): string {
 | 
			
		||||
            if ('_header' === $value) {
 | 
			
		||||
                return 'export.aggregator.course.by_opening_date.header';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (string) $value;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryKeys($data)
 | 
			
		||||
    {
 | 
			
		||||
        return [self::PREFIX.'_opening_date'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aggregator.course.by_opening_date.title';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb->addSelect(sprintf("TO_CHAR(acp.openingDate, '%s') AS {$p}_opening_date", $data['frequency']));
 | 
			
		||||
        $qb->addGroupBy("{$p}_opening_date");
 | 
			
		||||
        $qb->addOrderBy("{$p}_opening_date", 'DESC');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ACP_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -49,7 +49,7 @@ final readonly class StepAggregator implements AggregatorInterface
 | 
			
		||||
                        $qb->expr()->lte(self::A.'.startDate', ':'.self::P),
 | 
			
		||||
                        $qb->expr()->orX(
 | 
			
		||||
                            $qb->expr()->isNull(self::A.'.endDate'),
 | 
			
		||||
                            $qb->expr()->lt(self::A.'.endDate', ':'.self::P)
 | 
			
		||||
                            $qb->expr()->gt(self::A.'.endDate', ':'.self::P)
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\AggregatorInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Tests\Export\Aggregator\SocialWorkAggregators\HandlingThirdPartyAggregatorTest;
 | 
			
		||||
use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see HandlingThirdPartyAggregatorTest
 | 
			
		||||
 */
 | 
			
		||||
final readonly class HandlingThirdPartyAggregator implements AggregatorInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acpw_handling3party_agg';
 | 
			
		||||
 | 
			
		||||
    public function __construct(private LabelThirdPartyHelper $labelThirdPartyHelper) {}
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
        // no form needed here
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabels($key, array $values, mixed $data)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->labelThirdPartyHelper->getLabel($key, $values, 'export.aggregator.course_work.by_handling_third_party.header');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryKeys($data)
 | 
			
		||||
    {
 | 
			
		||||
        return [self::PREFIX.'_h3party'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aggregator.course_work.by_handling_third_party.title';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->addSelect("IDENTITY(acpw.handlingThierParty) AS {$p}_h3party")
 | 
			
		||||
            ->addGroupBy("{$p}_h3party");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::SOCIAL_WORK_ACTION_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Enum;
 | 
			
		||||
 | 
			
		||||
enum DateGroupingChoiceEnum: string
 | 
			
		||||
{
 | 
			
		||||
    case MONTH = 'YYYY-MM';
 | 
			
		||||
    case WEEK = 'YYYY-IW';
 | 
			
		||||
    case YEAR = 'YYYY';
 | 
			
		||||
}
 | 
			
		||||
@@ -23,16 +23,20 @@ use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    protected EntityRepository $repository;
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(AccompanyingPeriod::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder): void
 | 
			
		||||
@@ -102,15 +106,19 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
 | 
			
		||||
            ->andWhere('acp.step != :count_acp_step')
 | 
			
		||||
            ->leftJoin('acp.participations', 'acppart')
 | 
			
		||||
            ->leftJoin('acppart.person', 'person')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT);
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT)
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,19 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(protected EntityManagerInterface $em) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder): void
 | 
			
		||||
    {
 | 
			
		||||
@@ -95,15 +103,19 @@ class CountAccompanyingPeriodWork implements ExportInterface, GroupedExportInter
 | 
			
		||||
            ->from(AccompanyingPeriod\AccompanyingPeriodWork::class, 'acpw')
 | 
			
		||||
            ->join('acpw.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->join('acp.participations', 'acppart')
 | 
			
		||||
            ->join('acppart.person', 'person')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->join('acppart.person', 'person');
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb->select('COUNT(DISTINCT acpw.id) as export_result');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,11 +21,19 @@ use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountEvaluation implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly EntityManagerInterface $entityManager) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder) {}
 | 
			
		||||
 | 
			
		||||
@@ -92,15 +100,19 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
 | 
			
		||||
            ->join('workeval.accompanyingPeriodWork', 'acpw')
 | 
			
		||||
            ->join('acpw.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->join('acp.participations', 'acppart')
 | 
			
		||||
            ->join('acppart.person', 'person')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->join('acppart.person', 'person');
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,13 +23,21 @@ use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountHousehold implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private const TR_PREFIX = 'export.export.nb_household_with_course.';
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(private readonly EntityManagerInterface $entityManager, private readonly RollingDateConverterInterface $rollingDateConverter) {}
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -112,21 +120,25 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
 | 
			
		||||
            ->join('person.accompanyingPeriodParticipations', 'acppart')
 | 
			
		||||
            ->join('acppart.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)')
 | 
			
		||||
            ->setParameter('authorized_centers', $centers)
 | 
			
		||||
            ->setParameter('count_household_at_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->select('COUNT(DISTINCT household.id) AS household_export_result')
 | 
			
		||||
            ->addSelect('COUNT(DISTINCT acp.id) AS acp_export_result');
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
                ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)')
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $qb;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,11 +20,19 @@ use Chill\PersonBundle\Repository\PersonRepository;
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountPerson implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(protected PersonRepository $personRepository) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected PersonRepository $personRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -94,13 +102,17 @@ class CountPerson implements ExportInterface, GroupedExportInterface
 | 
			
		||||
 | 
			
		||||
        $qb = $this->personRepository->createQueryBuilder('person');
 | 
			
		||||
 | 
			
		||||
        $qb->select('COUNT(DISTINCT person.id) AS export_result')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
        $qb->select('COUNT(DISTINCT person.id) AS export_result');
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $qb;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,16 +22,20 @@ use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private readonly EntityRepository $repository;
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(AccompanyingPeriod::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
@@ -105,11 +109,13 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
 | 
			
		||||
            $qb->join('acppart.person', 'person');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb->andWhere(
 | 
			
		||||
            $qb->expr()->exists(
 | 
			
		||||
                'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
            )
 | 
			
		||||
        )->setParameter('authorized_centers', $centers);
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                )
 | 
			
		||||
            )->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,15 +26,21 @@ use Chill\PersonBundle\Export\Helper\ListAccompanyingPeriodHelper;
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
final readonly class ListAccompanyingPeriod implements ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private EntityManagerInterface $entityManager,
 | 
			
		||||
        private RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        private ListAccompanyingPeriodHelper $listAccompanyingPeriodHelper,
 | 
			
		||||
    ) {}
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -102,16 +108,20 @@ final readonly class ListAccompanyingPeriod implements ListInterface, GroupedExp
 | 
			
		||||
        $qb
 | 
			
		||||
            ->from(AccompanyingPeriod::class, 'acp')
 | 
			
		||||
            ->andWhere('acp.step != :list_acp_step')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
            ->setParameter('list_acp_step', AccompanyingPeriod::STEP_DRAFT);
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part
 | 
			
		||||
                    JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person)
 | 
			
		||||
                    WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('list_acp_step', AccompanyingPeriod::STEP_DRAFT)
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,7 @@ use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterface
 | 
			
		||||
@@ -78,6 +79,8 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
 | 
			
		||||
        'updatedBy',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly DateTimeHelper $dateTimeHelper,
 | 
			
		||||
@@ -90,8 +93,11 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
 | 
			
		||||
        private readonly SocialActionRender $socialActionRender,
 | 
			
		||||
        private readonly RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        private readonly AggregateStringHelper $aggregateStringHelper,
 | 
			
		||||
        private readonly SocialActionRepository $socialActionRepository
 | 
			
		||||
    ) {}
 | 
			
		||||
        private readonly SocialActionRepository $socialActionRepository,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -214,15 +220,19 @@ class ListAccompanyingPeriodWork implements ListInterface, GroupedExportInterfac
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            // get participants at the given date
 | 
			
		||||
            ->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers)
 | 
			
		||||
            ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class ListEvaluation implements ListInterface, GroupedExportInterface
 | 
			
		||||
@@ -68,7 +69,24 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
 | 
			
		||||
        'updatedBy',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public function __construct(private readonly EntityManagerInterface $entityManager, private readonly SocialIssueRender $socialIssueRender, private readonly SocialIssueRepository $socialIssueRepository, private readonly SocialActionRender $socialActionRender, private readonly SocialActionRepository $socialActionRepository, private readonly UserHelper $userHelper, private readonly LabelPersonHelper $personHelper, private readonly DateTimeHelper $dateTimeHelper, private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper, private readonly AggregateStringHelper $aggregateStringHelper, private readonly RollingDateConverterInterface $rollingDateConverter) {}
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly SocialIssueRender $socialIssueRender,
 | 
			
		||||
        private readonly SocialIssueRepository $socialIssueRepository,
 | 
			
		||||
        private readonly SocialActionRender $socialActionRender,
 | 
			
		||||
        private readonly SocialActionRepository $socialActionRepository,
 | 
			
		||||
        private readonly UserHelper $userHelper,
 | 
			
		||||
        private readonly LabelPersonHelper $personHelper,
 | 
			
		||||
        private readonly DateTimeHelper $dateTimeHelper,
 | 
			
		||||
        private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper,
 | 
			
		||||
        private readonly AggregateStringHelper $aggregateStringHelper,
 | 
			
		||||
        private readonly RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -190,15 +208,19 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            // get participants at the given date
 | 
			
		||||
            ->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                        AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                        '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers)
 | 
			
		||||
            ->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
 | 
			
		||||
@@ -42,14 +43,18 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
 | 
			
		||||
        'compositionComment',
 | 
			
		||||
        'compositionType',
 | 
			
		||||
    ];
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ExportAddressHelper $addressHelper,
 | 
			
		||||
        private readonly AggregateStringHelper $aggregateStringHelper,
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        private readonly TranslatableStringExportLabelHelper $translatableStringHelper
 | 
			
		||||
    ) {}
 | 
			
		||||
        private readonly TranslatableStringExportLabelHelper $translatableStringHelper,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -138,16 +143,20 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
 | 
			
		||||
            ->join('person.accompanyingPeriodParticipations', 'acppart')
 | 
			
		||||
            ->join('acppart.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)')
 | 
			
		||||
            ->setParameter('count_household_at_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->andWhere('hmember.startDate <= :count_household_at_date AND (hmember.endDate IS NULL OR hmember.endDate > :count_household_at_date)')
 | 
			
		||||
            ->setParameter('authorized_centers', $centers)
 | 
			
		||||
            ->setParameter('count_household_at_date', $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date']));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ use DateTimeImmutable;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
use Symfony\Component\Validator\Constraints\Callback;
 | 
			
		||||
@@ -40,14 +41,18 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
			
		||||
class ListPerson implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private array $slugs = [];
 | 
			
		||||
    private readonly bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly ExportAddressHelper $addressHelper,
 | 
			
		||||
        private readonly CustomFieldProvider $customFieldProvider,
 | 
			
		||||
        private readonly ListPersonHelper $listPersonHelper,
 | 
			
		||||
        private readonly EntityManagerInterface $entityManager,
 | 
			
		||||
        private readonly TranslatableStringHelper $translatableStringHelper
 | 
			
		||||
    ) {}
 | 
			
		||||
        private readonly TranslatableStringHelper $translatableStringHelper,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -184,16 +189,18 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
 | 
			
		||||
            throw new \Doctrine\DBAL\Exception\InvalidArgumentException('any fields have been checked');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb = $this->entityManager->createQueryBuilder();
 | 
			
		||||
        $qb = $this->entityManager->createQueryBuilder()
 | 
			
		||||
            ->from(Person::class, 'person');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->from(Person::class, 'person')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.Person\PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.Person\PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $fields = $data['fields'];
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,9 @@ use Chill\MainBundle\Export\FormatterInterface;
 | 
			
		||||
use Chill\MainBundle\Export\GroupedExportInterface;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
 | 
			
		||||
use Chill\MainBundle\Export\ListInterface;
 | 
			
		||||
use Chill\MainBundle\Form\Type\ChillDateType;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
 | 
			
		||||
@@ -27,6 +29,7 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
 | 
			
		||||
use DateTimeImmutable;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
use Symfony\Component\Validator\Constraints\Callback;
 | 
			
		||||
@@ -37,9 +40,19 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
			
		||||
 *
 | 
			
		||||
 * Details of the accompanying period are not included
 | 
			
		||||
 */
 | 
			
		||||
class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
 | 
			
		||||
final readonly class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterface, ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly ExportAddressHelper $addressHelper, private readonly ListPersonHelper $listPersonHelper, private readonly EntityManagerInterface $entityManager) {}
 | 
			
		||||
    private bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private ExportAddressHelper $addressHelper,
 | 
			
		||||
        private ListPersonHelper $listPersonHelper,
 | 
			
		||||
        private EntityManagerInterface $entityManager,
 | 
			
		||||
        private RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -69,10 +82,9 @@ class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterf
 | 
			
		||||
            ])],
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $builder->add('address_date', ChillDateType::class, [
 | 
			
		||||
        $builder->add('address_date_rolling', PickRollingDateType::class, [
 | 
			
		||||
            'label' => 'Data valid at this date',
 | 
			
		||||
            'help' => 'Data regarding center, addresses, and so on will be computed at this date',
 | 
			
		||||
            'input' => 'datetime_immutable',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +92,7 @@ class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterf
 | 
			
		||||
    {
 | 
			
		||||
        $choices = array_combine(ListPersonHelper::FIELDS, ListPersonHelper::FIELDS);
 | 
			
		||||
 | 
			
		||||
        return ['fields' => array_values($choices), 'address_date' => new \DateTimeImmutable()];
 | 
			
		||||
        return ['fields' => array_values($choices), 'address_date_rolling' => new RollingDate(RollingDate::T_TODAY)];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAllowedFormattersTypes()
 | 
			
		||||
@@ -162,16 +174,20 @@ class ListPersonHavingAccompanyingPeriod implements ExportElementValidatedInterf
 | 
			
		||||
        $qb->from(Person::class, 'person')
 | 
			
		||||
            ->join('person.accompanyingPeriodParticipations', 'acppart')
 | 
			
		||||
            ->join('acppart.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->andWhere($qb->expr()->neq('acp.step', "'".AccompanyingPeriod::STEP_DRAFT."'"))
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                )
 | 
			
		||||
            )->setParameter('authorized_centers', $centers);
 | 
			
		||||
            ->andWhere($qb->expr()->neq('acp.step', "'".AccompanyingPeriod::STEP_DRAFT."'"));
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                    )
 | 
			
		||||
                )->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $fields = $data['fields'];
 | 
			
		||||
 | 
			
		||||
        $this->listPersonHelper->addSelect($qb, $fields, $data['address_date']);
 | 
			
		||||
        $this->listPersonHelper->addSelect($qb, $fields, $this->rollingDateConverter->convert($data['address_date_rolling']));
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
 | 
			
		||||
use DateTimeImmutable;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -35,12 +36,17 @@ use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 */
 | 
			
		||||
final readonly class ListPersonWithAccompanyingPeriodDetails implements ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private ListPersonHelper $listPersonHelper,
 | 
			
		||||
        private ListAccompanyingPeriodHelper $listAccompanyingPeriodHelper,
 | 
			
		||||
        private EntityManagerInterface $entityManager,
 | 
			
		||||
        private RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
    ) {}
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
@@ -114,12 +120,16 @@ final readonly class ListPersonWithAccompanyingPeriodDetails implements ListInte
 | 
			
		||||
        $qb->from(Person::class, 'person')
 | 
			
		||||
            ->join('person.accompanyingPeriodParticipations', 'acppart')
 | 
			
		||||
            ->join('acppart.accompanyingPeriod', 'acp')
 | 
			
		||||
            ->andWhere($qb->expr()->neq('acp.step', "'".AccompanyingPeriod::STEP_DRAFT."'"))
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                )
 | 
			
		||||
            )->setParameter('authorized_centers', $centers);
 | 
			
		||||
            ->andWhere($qb->expr()->neq('acp.step', "'".AccompanyingPeriod::STEP_DRAFT."'"));
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' pch WHERE pch.person = person.id AND pch.center IN (:authorized_centers)'
 | 
			
		||||
                    )
 | 
			
		||||
                )->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->listPersonHelper->addSelect($qb, ListPersonHelper::FIELDS, $this->rollingDateConverter->convert($data['address_date']));
 | 
			
		||||
        $this->listAccompanyingPeriodHelper->addSelectClauses($qb, $this->rollingDateConverter->convert($data['address_date']));
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,9 @@ use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
 | 
			
		||||
use Chill\MainBundle\Export\ExportInterface;
 | 
			
		||||
use Chill\MainBundle\Export\FormatterInterface;
 | 
			
		||||
use Chill\MainBundle\Export\GroupedExportInterface;
 | 
			
		||||
use Chill\MainBundle\Form\Type\ChillDateType;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person\PersonCenterHistory;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
@@ -24,28 +26,34 @@ use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
final readonly class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private readonly EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    private bool $filterStatsByCenters;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        private RollingDateConverterInterface $rollingDateConverter,
 | 
			
		||||
        ParameterBagInterface $parameterBag,
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->repository = $em->getRepository(AccompanyingPeriod::class);
 | 
			
		||||
        $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder): void
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('closingdate', ChillDateType::class, [
 | 
			
		||||
        $builder->add('closingdate_rolling', PickRollingDateType::class, [
 | 
			
		||||
            'label' => 'Closingdate to apply',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return ['closingdate' => new \DateTime('now')];
 | 
			
		||||
        return ['closingdate_rolling' => new RollingDate(RollingDate::T_TODAY)];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAllowedFormattersTypes(): array
 | 
			
		||||
@@ -118,20 +126,24 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
 | 
			
		||||
            ->addSelect('COUNT(DISTINCT acppart.id) AS count_acppart_export_result')
 | 
			
		||||
            ->addSelect('COUNT(DISTINCT person.id) AS count_pers_export_result')
 | 
			
		||||
            ->addSelect('COUNT(DISTINCT acp.id) AS count_acp_export_result')
 | 
			
		||||
            ->setParameter('force_closingDate', $data['closingdate'])
 | 
			
		||||
            ->setParameter('force_closingDate', $this->rollingDateConverter->convert($data['closingdate_rolling']))
 | 
			
		||||
            ->leftJoin('acp.participations', 'acppart')
 | 
			
		||||
            ->leftJoin('acppart.person', 'person')
 | 
			
		||||
            ->andWhere('acp.step != :count_acp_step')
 | 
			
		||||
            ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
 | 
			
		||||
            ->andWhere(
 | 
			
		||||
                $qb->expr()->exists(
 | 
			
		||||
                    'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
            ->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT);
 | 
			
		||||
 | 
			
		||||
        if ($this->filterStatsByCenters) {
 | 
			
		||||
            $qb
 | 
			
		||||
                ->andWhere(
 | 
			
		||||
                    $qb->expr()->exists(
 | 
			
		||||
                        'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
 | 
			
		||||
                    AND acl_count_person_history.center IN (:authorized_centers)
 | 
			
		||||
                    '
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            ->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT)
 | 
			
		||||
            ->setParameter('authorized_centers', $centers);
 | 
			
		||||
                ->setParameter('authorized_centers', $centers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
 | 
			
		||||
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
final readonly class HandlingThirdPartyFilter implements FilterInterface
 | 
			
		||||
{
 | 
			
		||||
    private const PREFIX = 'acpw_handling_3party_filter';
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private ThirdPartyRender $thirdPartyRender,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.filter.work.by_handling3party.title';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function buildForm(FormBuilderInterface $builder)
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('handling_3parties', PickThirdpartyDynamicType::class, [
 | 
			
		||||
            'label' => 'export.filter.work.by_handling3party.pick_3parties',
 | 
			
		||||
            'multiple' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormDefaultData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return ['handling_3parties' => []];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function describeAction($data, $format = 'string')
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'export.filter.work.by_handling3party.Only 3 parties %3parties%',
 | 
			
		||||
            [
 | 
			
		||||
                '%3parties%' => implode(
 | 
			
		||||
                    ', ',
 | 
			
		||||
                    array_map(fn (ThirdParty $thirdParty) => $this->thirdPartyRender->renderString($thirdParty, []), $data['handling_3parties'])
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRole(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $p = self::PREFIX;
 | 
			
		||||
 | 
			
		||||
        $qb->andWhere("acpw.handlingThierParty IN (:{$p}_3ps)");
 | 
			
		||||
        $qb->setParameter("{$p}_3ps", $data['handling_3parties']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function applyOn()
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::SOCIAL_WORK_ACTION_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -61,7 +61,7 @@ class StepFilterOnDate implements FilterInterface
 | 
			
		||||
                    $qb->expr()->lte(self::A.'.startDate', ':'.self::P),
 | 
			
		||||
                    $qb->expr()->orX(
 | 
			
		||||
                        $qb->expr()->isNull(self::A.'.endDate'),
 | 
			
		||||
                        $qb->expr()->lt(self::A.'.endDate', ':'.self::P)
 | 
			
		||||
                        $qb->expr()->gt(self::A.'.endDate', ':'.self::P)
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 *
 | 
			
		||||
 * Makes use of AccompanyingPeriodInfo
 | 
			
		||||
 */
 | 
			
		||||
readonly class UserWorkingOnCourseFilter implements FilterInterface
 | 
			
		||||
final readonly class UserWorkingOnCourseFilter implements FilterInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private UserRender $userRender,
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface
 | 
			
		||||
    {
 | 
			
		||||
        $builder
 | 
			
		||||
            ->add('date_calc', PickRollingDateType::class, [
 | 
			
		||||
                'label' => 'Compute address at date',
 | 
			
		||||
                'label' => 'export.filter.person.by_address_ref_status.Address at date',
 | 
			
		||||
                'required' => true,
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('ref_statuses', ChoiceType::class, [
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,21 @@ class LabelPersonHelper
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(private readonly PersonRepository $personRepository, private readonly PersonRenderInterface $personRender) {}
 | 
			
		||||
 | 
			
		||||
    public function getLabel(string $key, array $values, string $header): callable
 | 
			
		||||
    {
 | 
			
		||||
        return function (null|int|string $value) use ($header): string {
 | 
			
		||||
            if ('_header' === $value) {
 | 
			
		||||
                return $header;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ('' === $value || null === $value || null === $person = $this->personRepository->find($value)) {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $this->personRender->renderString($person, []);
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getLabelMulti(string $key, array $values, string $header): callable
 | 
			
		||||
    {
 | 
			
		||||
        return function ($value) use ($header) {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ClosingDateAggregator;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ClosingDateAggregatorTest extends AbstractAggregatorTest
 | 
			
		||||
{
 | 
			
		||||
    private static ClosingDateAggregator $closingDateAggregator;
 | 
			
		||||
 | 
			
		||||
    private static EntityManagerInterface $entityManager;
 | 
			
		||||
 | 
			
		||||
    public static function setUpBeforeClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUpBeforeClass();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        self::$closingDateAggregator = self::$container->get(ClosingDateAggregator::class);
 | 
			
		||||
        self::$entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAggregator()
 | 
			
		||||
    {
 | 
			
		||||
        return self::$closingDateAggregator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        yield ['frequency' => 'YYYY'];
 | 
			
		||||
        yield ['frequency' => 'YYYY-MM'];
 | 
			
		||||
        yield ['frequency' => 'YYYY-IV'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        self::$entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        $data = [
 | 
			
		||||
            self::$entityManager->createQueryBuilder()
 | 
			
		||||
                ->select('count(acp.id)')
 | 
			
		||||
                ->from(AccompanyingPeriod::class, 'acp'),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        self::ensureKernelShutdown();
 | 
			
		||||
 | 
			
		||||
        return $data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Aggregator\AccompanyingCourseAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\OpeningDateAggregator;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class OpeningDateAggregatorTest extends AbstractAggregatorTest
 | 
			
		||||
{
 | 
			
		||||
    private static OpeningDateAggregator $openingDateAggregator;
 | 
			
		||||
 | 
			
		||||
    private static EntityManagerInterface $entityManager;
 | 
			
		||||
 | 
			
		||||
    public static function setUpBeforeClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUpBeforeClass();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        self::$openingDateAggregator = self::$container->get(OpeningDateAggregator::class);
 | 
			
		||||
        self::$entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAggregator()
 | 
			
		||||
    {
 | 
			
		||||
        return self::$openingDateAggregator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        yield ['frequency' => 'YYYY'];
 | 
			
		||||
        yield ['frequency' => 'YYYY-MM'];
 | 
			
		||||
        yield ['frequency' => 'YYYY-IV'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        self::$entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        $data = [
 | 
			
		||||
            self::$entityManager->createQueryBuilder()
 | 
			
		||||
                ->select('count(acp.id)')
 | 
			
		||||
                ->from(AccompanyingPeriod::class, 'acp'),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        self::ensureKernelShutdown();
 | 
			
		||||
 | 
			
		||||
        return $data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,60 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Aggregator\SocialWorkAggregators;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
 | 
			
		||||
use Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\HandlingThirdPartyAggregator;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class HandlingThirdPartyAggregatorTest extends AbstractAggregatorTest
 | 
			
		||||
{
 | 
			
		||||
    private static HandlingThirdPartyAggregator $handlingThirdPartyAggregator;
 | 
			
		||||
 | 
			
		||||
    public static function setUpBeforeClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUpBeforeClass();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        self::$handlingThirdPartyAggregator = self::$container->get(HandlingThirdPartyAggregator::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getAggregator()
 | 
			
		||||
    {
 | 
			
		||||
        return self::$handlingThirdPartyAggregator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container
 | 
			
		||||
            ->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            $em->createQueryBuilder()
 | 
			
		||||
                ->select('count(acpw.id)')
 | 
			
		||||
                ->from(AccompanyingPeriodWork::class, 'acpw'),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -14,6 +14,7 @@ namespace Export\Export;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\CountAccompanyingCourse;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -22,18 +23,17 @@ use Chill\PersonBundle\Export\Export\CountAccompanyingCourse;
 | 
			
		||||
 */
 | 
			
		||||
final class CountAccompanyingCourseTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private CountAccompanyingCourse $export;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get('chill.person.export.count_accompanyingcourse');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountAccompanyingCourse($em, $this->getParameters(true));
 | 
			
		||||
        yield new CountAccompanyingCourse($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ namespace Export\Export;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -33,7 +34,10 @@ final class CountAccompanyingPeriodWorkTest extends AbstractExportTest
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountAccompanyingPeriodWork($em, $this->getParameters(true));
 | 
			
		||||
        yield new CountAccompanyingPeriodWork($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\CountPerson;
 | 
			
		||||
use Chill\PersonBundle\Repository\PersonRepository;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test CountPerson export.
 | 
			
		||||
@@ -23,18 +24,17 @@ use Chill\PersonBundle\Export\Export\CountPerson;
 | 
			
		||||
 */
 | 
			
		||||
final class CountPersonTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private ?object $export = null;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->export = self::$container->get(CountPerson::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $personRepository = self::$container->get(PersonRepository::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountPerson($personRepository, $this->getParameters(true));
 | 
			
		||||
        yield new CountPerson($personRepository, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,48 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\CountPersonWithAccompanyingCourse;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class CountPersonWithAccompanyingCourseTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new CountPersonWithAccompanyingCourse($em, $this->getParameters(true));
 | 
			
		||||
        yield new CountPersonWithAccompanyingCourse($em, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [[]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::ACP_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,43 +11,51 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\Center;
 | 
			
		||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListAccompanyingPeriod;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\ListAccompanyingPeriodHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListAccompanyingPeriodTest extends KernelTestCase
 | 
			
		||||
class ListAccompanyingPeriodTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private ListAccompanyingPeriod $listAccompanyingPeriod;
 | 
			
		||||
    private readonly ListAccompanyingPeriod $listAccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
    private CenterRepositoryInterface $centerRepository;
 | 
			
		||||
    private readonly CenterRepositoryInterface $centerRepository;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->listAccompanyingPeriod = self::$container->get(ListAccompanyingPeriod::class);
 | 
			
		||||
        $this->centerRepository = self::$container->get(CenterRepositoryInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testQuery(): void
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $centers = $this->centerRepository->findAll();
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
        $listAccompanyingPeriodHelper = self::$container->get(ListAccompanyingPeriodHelper::class);
 | 
			
		||||
 | 
			
		||||
        $query = $this->listAccompanyingPeriod->initiateQuery([], array_map(fn (Center $c) => ['center' => $c], $centers), $exportOpts = ['calc_date' => new RollingDate(RollingDate::T_TODAY)]);
 | 
			
		||||
        yield new ListAccompanyingPeriod($em, $rollingDateConverter, $listAccompanyingPeriodHelper, $this->getParameters(true));
 | 
			
		||||
        yield new ListAccompanyingPeriod($em, $rollingDateConverter, $listAccompanyingPeriodHelper, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        $query->setMaxResults(1);
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            ['calc_date' => new RollingDate(RollingDate::T_TODAY)],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        $actual = $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
 | 
			
		||||
 | 
			
		||||
        self::assertIsArray($actual);
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::ACP_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,40 +11,93 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\Center;
 | 
			
		||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\AggregateStringHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\DateTimeHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\UserHelper;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
 | 
			
		||||
use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListAccompanyingPeriodWorkTest extends KernelTestCase
 | 
			
		||||
class ListAccompanyingPeriodWorkTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private ListAccompanyingPeriodWork $listAccompanyingPeriodWork;
 | 
			
		||||
 | 
			
		||||
    private CenterRepositoryInterface $centerRepository;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $this->listAccompanyingPeriodWork = self::$container->get(ListAccompanyingPeriodWork::class);
 | 
			
		||||
        $this->centerRepository = self::$container->get(CenterRepositoryInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testQuery(): void
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $centers = $this->centerRepository->findAll();
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $dateTimeHelper = self::$container->get(DateTimeHelper::class);
 | 
			
		||||
        $userHelper = self::$container->get(UserHelper::class);
 | 
			
		||||
        $personHelper = self::$container->get(LabelPersonHelper::class);
 | 
			
		||||
        $thirdPartyHelper = self::$container->get(LabelThirdPartyHelper::class);
 | 
			
		||||
        $translatableStringExportLabelHelper = self::$container->get(TranslatableStringExportLabelHelper::class);
 | 
			
		||||
        $socialIssueRender = self::$container->get(SocialIssueRender::class);
 | 
			
		||||
        $socialIssueRepository = self::$container->get(SocialIssueRepository::class);
 | 
			
		||||
        $socialActionRender = self::$container->get(SocialActionRender::class);
 | 
			
		||||
        $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
        $aggregateStringHelper = self::$container->get(AggregateStringHelper::class);
 | 
			
		||||
        $socialActionRepository = self::$container->get(SocialActionRepository::class);
 | 
			
		||||
 | 
			
		||||
        $query = $this->listAccompanyingPeriodWork->initiateQuery([], array_map(fn (Center $c) => ['center' => $c], $centers), ['calc_date' => new RollingDate(RollingDate::T_TODAY)]);
 | 
			
		||||
        $query->setMaxResults(1);
 | 
			
		||||
        yield new ListAccompanyingPeriodWork(
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $dateTimeHelper,
 | 
			
		||||
            $userHelper,
 | 
			
		||||
            $personHelper,
 | 
			
		||||
            $thirdPartyHelper,
 | 
			
		||||
            $translatableStringExportLabelHelper,
 | 
			
		||||
            $socialIssueRender,
 | 
			
		||||
            $socialIssueRepository,
 | 
			
		||||
            $socialActionRender,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $socialActionRepository,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        self::assertIsArray($query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY));
 | 
			
		||||
        yield new ListAccompanyingPeriodWork(
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $dateTimeHelper,
 | 
			
		||||
            $userHelper,
 | 
			
		||||
            $personHelper,
 | 
			
		||||
            $thirdPartyHelper,
 | 
			
		||||
            $translatableStringExportLabelHelper,
 | 
			
		||||
            $socialIssueRender,
 | 
			
		||||
            $socialIssueRepository,
 | 
			
		||||
            $socialActionRender,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $socialActionRepository,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            ['calc_date' => new RollingDate(RollingDate::T_TODAY)],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::ACP_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,18 +12,30 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\Center;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\AggregateStringHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\DateTimeHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\UserHelper;
 | 
			
		||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListEvaluation;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\LabelPersonHelper;
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
 | 
			
		||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListEvaluationTest extends KernelTestCase
 | 
			
		||||
class ListEvaluationTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    private ListEvaluation $listEvaluation;
 | 
			
		||||
 | 
			
		||||
@@ -38,6 +50,61 @@ class ListEvaluationTest extends KernelTestCase
 | 
			
		||||
        $this->centerRepository = self::$container->get(CenterRepositoryInterface::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $dateTimeHelper = self::$container->get(DateTimeHelper::class);
 | 
			
		||||
        $userHelper = self::$container->get(UserHelper::class);
 | 
			
		||||
        $personHelper = self::$container->get(LabelPersonHelper::class);
 | 
			
		||||
        $translatableStringExportLabelHelper = self::$container->get(TranslatableStringExportLabelHelper::class);
 | 
			
		||||
        $socialIssueRender = self::$container->get(SocialIssueRender::class);
 | 
			
		||||
        $socialIssueRepository = self::$container->get(SocialIssueRepository::class);
 | 
			
		||||
        $socialActionRender = self::$container->get(SocialActionRender::class);
 | 
			
		||||
        $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
        $aggregateStringHelper = self::$container->get(AggregateStringHelper::class);
 | 
			
		||||
        $socialActionRepository = self::$container->get(SocialActionRepository::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListEvaluation(
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $socialIssueRender,
 | 
			
		||||
            $socialIssueRepository,
 | 
			
		||||
            $socialActionRender,
 | 
			
		||||
            $socialActionRepository,
 | 
			
		||||
            $userHelper,
 | 
			
		||||
            $personHelper,
 | 
			
		||||
            $dateTimeHelper,
 | 
			
		||||
            $translatableStringExportLabelHelper,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListEvaluation(
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $socialIssueRender,
 | 
			
		||||
            $socialIssueRepository,
 | 
			
		||||
            $socialActionRender,
 | 
			
		||||
            $socialActionRepository,
 | 
			
		||||
            $userHelper,
 | 
			
		||||
            $personHelper,
 | 
			
		||||
            $dateTimeHelper,
 | 
			
		||||
            $translatableStringExportLabelHelper,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [['calc_date' => new RollingDate(RollingDate::T_TODAY)]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::ACP_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testQuery(): void
 | 
			
		||||
    {
 | 
			
		||||
        $centers = $this->centerRepository->findAll();
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,72 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\Helper\AggregateStringHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListHouseholdInPeriod;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListHouseholdInPeriodTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $addressHelper = self::$container->get(ExportAddressHelper::class);
 | 
			
		||||
        $aggregateStringHelper = self::$container->get(AggregateStringHelper::class);
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
        $translatableStringHelper = self::$container->get(TranslatableStringExportLabelHelper::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListHouseholdInPeriod(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListHouseholdInPeriod(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $aggregateStringHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [['calc_date' => new RollingDate(RollingDate::T_TODAY)]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::PERSON_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListPersonHavingAccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListPersonHavingAccompanyingPeriodTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $addressHelper = self::$container->get(ExportAddressHelper::class);
 | 
			
		||||
        $listPersonHelper = self::$container->get(ListPersonHelper::class);
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $rollingDateconverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListPersonHavingAccompanyingPeriod(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateconverter,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListPersonHavingAccompanyingPeriod(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateconverter,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [['address_date_rolling' => new RollingDate(RollingDate::T_TODAY), 'fields' => ListPersonHelper::FIELDS]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [[Declarations::PERSON_TYPE, Declarations::ACP_TYPE]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,8 +11,13 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
 | 
			
		||||
use Chill\MainBundle\Export\Helper\ExportAddressHelper;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListPerson;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Prophecy\PhpUnit\ProphecyTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -45,7 +50,29 @@ final class ListPersonTest extends AbstractExportTest
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $addressHelper = self::$container->get(ExportAddressHelper::class);
 | 
			
		||||
        $customFieldProvider = self::$container->get(CustomFieldProvider::class);
 | 
			
		||||
        $listPersonHelper = self::$container->get(ListPersonHelper::class);
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $translatableStringHelper = self::$container->get(TranslatableStringHelper::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListPerson(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $customFieldProvider,
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListPerson(
 | 
			
		||||
            $addressHelper,
 | 
			
		||||
            $customFieldProvider,
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $translatableStringHelper,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): iterable
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\ListPersonWithAccompanyingPeriodDetails;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\ListAccompanyingPeriodHelper;
 | 
			
		||||
use Chill\PersonBundle\Export\Helper\ListPersonHelper;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class ListPersonWithAccompanyingPeriodDetailsTest extends AbstractExportTest
 | 
			
		||||
{
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        $listPersonHelper = self::$container->get(ListPersonHelper::class);
 | 
			
		||||
        $listAccompanyingPeriodHelper = self::$container->get(ListAccompanyingPeriodHelper::class);
 | 
			
		||||
        $entityManager = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $rollingDateConverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new ListPersonWithAccompanyingPeriodDetails(
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $listAccompanyingPeriodHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $this->getParameters(true),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        yield new ListPersonWithAccompanyingPeriodDetails(
 | 
			
		||||
            $listPersonHelper,
 | 
			
		||||
            $listAccompanyingPeriodHelper,
 | 
			
		||||
            $entityManager,
 | 
			
		||||
            $rollingDateConverter,
 | 
			
		||||
            $this->getParameters(false),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            ['address_date' => new RollingDate(RollingDate::T_TODAY)],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getModifiersCombination()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [Declarations::PERSON_TYPE, Declarations::ACP_TYPE],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,9 +11,12 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
 | 
			
		||||
use Chill\PersonBundle\Export\Declarations;
 | 
			
		||||
use Chill\PersonBundle\Export\Export\StatAccompanyingCourseDuration;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -33,13 +36,17 @@ final class StatAccompanyingCourseDurationTest extends AbstractExportTest
 | 
			
		||||
 | 
			
		||||
    public function getExport()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->export;
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
        $rollingDateconverter = self::$container->get(RollingDateConverterInterface::class);
 | 
			
		||||
 | 
			
		||||
        yield new StatAccompanyingCourseDuration($em, $rollingDateconverter, $this->getParameters(true));
 | 
			
		||||
        yield new StatAccompanyingCourseDuration($em, $rollingDateconverter, $this->getParameters(false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            ['closingdate' => \DateTime::createFromFormat('Y-m-d', '2022-06-30')],
 | 
			
		||||
            ['closingdate_rolling' => new RollingDate(RollingDate::T_TODAY)],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a software for social workers
 | 
			
		||||
 *
 | 
			
		||||
 * For the full copyright and license information, please view
 | 
			
		||||
 * the LICENSE file that was distributed with this source code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Tests\Export\Filter\SocialWorkFilters;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
 | 
			
		||||
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\HandlingThirdPartyFilter;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
class HandlingThirdPartyFilterTest extends AbstractFilterTest
 | 
			
		||||
{
 | 
			
		||||
    private ThirdPartyRender $thirdPartyRender;
 | 
			
		||||
 | 
			
		||||
    protected function setUp(): void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $this->thirdPartyRender = self::$container->get(ThirdPartyRender::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFilter()
 | 
			
		||||
    {
 | 
			
		||||
        return new HandlingThirdPartyFilter($this->thirdPartyRender);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getFormData()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        $thirdParties = $em->createQuery('SELECT tp FROM '.ThirdParty::class.' tp')
 | 
			
		||||
            ->setMaxResults(2)
 | 
			
		||||
            ->getResult();
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            [
 | 
			
		||||
                'handling_3parties' => $thirdParties,
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getQueryBuilders()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class);
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            $em->createQueryBuilder()
 | 
			
		||||
                ->select('acpw.id')
 | 
			
		||||
                ->from(AccompanyingPeriodWork::class, 'acpw'),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -251,3 +251,11 @@ services:
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ScopeWorkingOnCourseAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: accompanyingcourse_scope_working_on_course_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\OpeningDateAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: accompanyingcourse_opening_date_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ClosingDateAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: accompanyingcourse_closing_date_aggregator }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,116 +1,93 @@
 | 
			
		||||
services:
 | 
			
		||||
    _defaults:
 | 
			
		||||
        autowire: true
 | 
			
		||||
        autoconfigure: true
 | 
			
		||||
 | 
			
		||||
  ## Indicators
 | 
			
		||||
  Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export, alias: count_social_work_actions }
 | 
			
		||||
    ## Indicators
 | 
			
		||||
    Chill\PersonBundle\Export\Export\CountAccompanyingPeriodWork:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export, alias: count_social_work_actions }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export, alias: list_social_work_actions }
 | 
			
		||||
    Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export, alias: list_social_work_actions }
 | 
			
		||||
 | 
			
		||||
  ## FILTERS
 | 
			
		||||
  chill.person.export.filter_social_work_type:
 | 
			
		||||
     class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter
 | 
			
		||||
     autowire: true
 | 
			
		||||
     autoconfigure: true
 | 
			
		||||
     tags:
 | 
			
		||||
         - { name: chill.export_filter, alias: social_work_type_filter }
 | 
			
		||||
    ## FILTERS
 | 
			
		||||
    chill.person.export.filter_social_work_type:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\SocialWorkTypeFilter
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_type_filter }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.filter_scope:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ScopeFilter
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_filter, alias: social_work_actions_scope_filter }
 | 
			
		||||
    chill.person.export.filter_scope:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ScopeFilter
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_scope_filter }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.filter_job:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\JobFilter
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_filter, alias: social_work_actions_job_filter }
 | 
			
		||||
    chill.person.export.filter_job:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\JobFilter
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_job_filter }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.filter_treatingagent:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_filter, alias: social_work_actions_treatingagent_filter }
 | 
			
		||||
    chill.person.export.filter_treatingagent:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_treatingagent_filter }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Filter\SocialWorkFilters\CurrentActionFilter:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_filter, alias: social_work_actions_current_filter }
 | 
			
		||||
    Chill\PersonBundle\Export\Filter\SocialWorkFilters\CurrentActionFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_current_filter }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkStartDateBetweenDateFilter:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_filter, alias: social_work_actions_start_btw_dates_filter }
 | 
			
		||||
    Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkStartDateBetweenDateFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_start_btw_dates_filter }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkEndDateBetweenDateFilter:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_filter, alias: social_work_actions_end_btw_dates_filter }
 | 
			
		||||
    Chill\PersonBundle\Export\Filter\SocialWorkFilters\AccompanyingPeriodWorkEndDateBetweenDateFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: social_work_actions_end_btw_dates_filter }
 | 
			
		||||
 | 
			
		||||
      ## AGGREGATORS
 | 
			
		||||
  chill.person.export.aggregator_action_type:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ActionTypeAggregator
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_aggregator, alias: social_work_actions_action_type_aggregator }
 | 
			
		||||
        ## AGGREGATORS
 | 
			
		||||
    chill.person.export.aggregator_action_type:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ActionTypeAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_action_type_aggregator }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.aggregator_treatingagent_scope:
 | 
			
		||||
      class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ScopeAggregator
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_scope_aggregator }
 | 
			
		||||
    chill.person.export.aggregator_treatingagent_scope:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ScopeAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_scope_aggregator }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.aggregator_treatingagent_job:
 | 
			
		||||
      class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\JobAggregator
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_job_aggregator }
 | 
			
		||||
    chill.person.export.aggregator_treatingagent_job:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\JobAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_job_aggregator }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator:
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_aggregator }
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_treatingagent_aggregator }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.aggregator_goal:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalAggregator
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_aggregator, alias: social_work_actions_goal_aggregator }
 | 
			
		||||
    chill.person.export.aggregator_goal:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_goal_aggregator }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.aggregator_result:
 | 
			
		||||
    class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ResultAggregator
 | 
			
		||||
    autowire: true
 | 
			
		||||
    autoconfigure: true
 | 
			
		||||
    tags:
 | 
			
		||||
        - { name: chill.export_aggregator, alias: social_work_actions_result_aggregator }
 | 
			
		||||
    chill.person.export.aggregator_result:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\ResultAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_result_aggregator }
 | 
			
		||||
 | 
			
		||||
  chill.person.export.aggregator_goalresult:
 | 
			
		||||
      class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalResultAggregator
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator }
 | 
			
		||||
    chill.person.export.aggregator_goalresult:
 | 
			
		||||
        class: Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\GoalResultAggregator
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator }
 | 
			
		||||
 | 
			
		||||
  Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator:
 | 
			
		||||
      autowire: true
 | 
			
		||||
      autoconfigure: true
 | 
			
		||||
      tags:
 | 
			
		||||
          - { name: chill.export_aggregator, alias: social_work_actions_current_aggregator }
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: social_work_actions_current_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\HandlingThirdPartyAggregator:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_aggregator, alias: accompanyingcourse_handling3party_aggregator }
 | 
			
		||||
 | 
			
		||||
    Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\HandlingThirdPartyFilter:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: chill.export_filter, alias: 'acpw_handling3party_filter'}
 | 
			
		||||
 
 | 
			
		||||
@@ -480,7 +480,7 @@ acp_geog_agg_unitrefid: Clé de la zone géographique
 | 
			
		||||
Geographical layer: Couche géographique
 | 
			
		||||
Select a geographical layer: Choisir une couche géographique
 | 
			
		||||
Group people by geographical unit based on his address: Grouper les usagers par zone géographique (sur base de l'adresse)
 | 
			
		||||
Filter by person's geographical unit (based on address): Filter les usagers par zone géographique (sur base de l'adresse)
 | 
			
		||||
Filter by person's geographical unit (based on address): Filtrer les usagers par zone géographique (sur base de l'adresse)
 | 
			
		||||
 | 
			
		||||
Filter by socialaction: Filtrer les parcours par action d'accompagnement
 | 
			
		||||
Accepted socialactions: Actions d'accompagnement
 | 
			
		||||
@@ -505,10 +505,10 @@ Accepted origins: Origines
 | 
			
		||||
"Filtered by origins: only %origins%": "Filtré par origine du parcours: uniquement %origins%"
 | 
			
		||||
Group by origin: Grouper les parcours par origine du parcours
 | 
			
		||||
 | 
			
		||||
Filter by closing motive: Filtrer les parcours par motif de fermeture
 | 
			
		||||
Filter by closing motive: Filtrer les parcours par motif de clôture
 | 
			
		||||
Accepted closingmotives: Motifs de clôture
 | 
			
		||||
"Filtered by closingmotive: only %closingmotives%": "Filtré par motif de clôture: uniquement %closingmotives%"
 | 
			
		||||
Group by closing motive: Grouper les parcours par motif de fermeture
 | 
			
		||||
Group by closing motive: Grouper les parcours par motif de clôture
 | 
			
		||||
 | 
			
		||||
Filter by administrative location: Filtrer les parcours par localisation administrative
 | 
			
		||||
Accepted locations: Localisations administratives
 | 
			
		||||
@@ -516,7 +516,7 @@ Administrative location: Localisation administrative
 | 
			
		||||
"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%"
 | 
			
		||||
Group by administrative location: Grouper les parcours par localisation administrative
 | 
			
		||||
 | 
			
		||||
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés
 | 
			
		||||
Filter by requestor: Filtrer les parcours selon la nature du demandeur
 | 
			
		||||
Accepted choices: ''
 | 
			
		||||
is person concerned: Le demandeur est un usager concerné
 | 
			
		||||
is other person: Le demandeur est un usager, mais n'est pas concerné
 | 
			
		||||
@@ -981,6 +981,11 @@ notification:
 | 
			
		||||
personId: Identifiant de l'usager
 | 
			
		||||
 | 
			
		||||
export:
 | 
			
		||||
    enum:
 | 
			
		||||
        frequency:
 | 
			
		||||
            YYYY-IW: par semaine
 | 
			
		||||
            YYYY-MM: par mois
 | 
			
		||||
            YYYY: par année
 | 
			
		||||
    export:
 | 
			
		||||
        acp_stats:
 | 
			
		||||
            avg_duration: Moyenne de la durée de participation de chaque usager concerné
 | 
			
		||||
@@ -1037,6 +1042,14 @@ export:
 | 
			
		||||
                Calc date: Date de calcul du service de l'intervenant
 | 
			
		||||
            by_scope:
 | 
			
		||||
                Group course by scope: Grouper les parcours par service
 | 
			
		||||
            by_opening_date:
 | 
			
		||||
                title: Grouper les parcours par date d'ouverture
 | 
			
		||||
                frequency: Intervalle de regroupement
 | 
			
		||||
                header: Date d'ouverture des parcours (période)
 | 
			
		||||
            by_closing_date:
 | 
			
		||||
                title: Grouper les parcours par date de cloture
 | 
			
		||||
                frequency: Intervalle de regroupement
 | 
			
		||||
                header: Date de cloture des parcours (période)
 | 
			
		||||
 | 
			
		||||
        course_work:
 | 
			
		||||
            by_treating_agent:
 | 
			
		||||
@@ -1053,6 +1066,9 @@ export:
 | 
			
		||||
            by_agent_job:
 | 
			
		||||
                Group by treating agent job: Grouper les actions par métier de l'agent traitant
 | 
			
		||||
                Calc date: Date de calcul du métier de l'agent traitant
 | 
			
		||||
            by_handling_third_party:
 | 
			
		||||
                title: Grouper les actions par tiers traitant
 | 
			
		||||
                header: Tiers traitant
 | 
			
		||||
 | 
			
		||||
        eval:
 | 
			
		||||
            by_end_date:
 | 
			
		||||
@@ -1084,21 +1100,22 @@ export:
 | 
			
		||||
                Persons filtered by no composition at %date%: Uniquement les usagers sans composition de ménage à la date du %date%
 | 
			
		||||
                Date calc: Date de calcul
 | 
			
		||||
            by_address_ref_status:
 | 
			
		||||
                Filter by person's address ref status: Filtrer par comparaison avec l'adresse de référence
 | 
			
		||||
                Filter by person's address ref status: Filtrer les usagers par comparaison avec l'adresse de référence
 | 
			
		||||
                to_review: Diffère de l'adresse de référence
 | 
			
		||||
                reviewed: Diffère de l'adresse de référence mais conservé par l'utilisateur
 | 
			
		||||
                match: Identique à l'adresse de référence
 | 
			
		||||
                Filtered by person\'s address status computed at %datecalc%, only %statuses%: Filtré par comparaison à l'adresse de référence, calculé à %datecalc%, seulement %statuses%
 | 
			
		||||
                Status: Statut
 | 
			
		||||
                Address at date: Adresse à la date
 | 
			
		||||
 | 
			
		||||
        course:
 | 
			
		||||
            having_info_within_interval:
 | 
			
		||||
                title: Filter les parcours ayant reçu une intervention entre deux dates
 | 
			
		||||
                title: Filtrer les parcours ayant reçu une intervention entre deux dates
 | 
			
		||||
                start_date: Début de la période
 | 
			
		||||
                end_date: Fin de la période
 | 
			
		||||
                Only course with events between %startDate% and %endDate%: Seulement les parcours ayant reçu une intervention entre le %startDate% et le %endDate%
 | 
			
		||||
            by_user_working:
 | 
			
		||||
                title: Filter les parcours par intervenant, entre deux dates
 | 
			
		||||
                title: Filtrer les parcours par intervenant, entre deux dates
 | 
			
		||||
                'Filtered by user working on course: only %users%, between %start_date% and %end_date%': 'Filtré par intervenants sur le parcours: seulement %users%, entre le %start_date% et le %end_date%'
 | 
			
		||||
                User working after: Intervention après le
 | 
			
		||||
                User working before: Intervention avant le
 | 
			
		||||
@@ -1168,6 +1185,10 @@ export:
 | 
			
		||||
                Calc date: Date à laquelle l'agent est en situation de désignation sur l'action
 | 
			
		||||
                calc_date_help: Il s'agit de la date à laquelle l'agent est actif comme agent traitant de l'action, et non la date à la quelle l'agent est désigné comme agent traitant.
 | 
			
		||||
                "Filtered by treating agent: only %agents%": "Filtré par agent traitant: uniquement %agents%"
 | 
			
		||||
            by_handling3party:
 | 
			
		||||
                title: Filtrer les actions par tiers traitant
 | 
			
		||||
                Only 3 parties %3parties%: "Seulement les actions d'accompagnement qui ont pour tiers traitant: %3parties%"
 | 
			
		||||
                pick_3parties: Tiers traitants des actions
 | 
			
		||||
 | 
			
		||||
    list:
 | 
			
		||||
        person_with_acp:
 | 
			
		||||
@@ -1205,7 +1226,7 @@ export:
 | 
			
		||||
            referrer: Référent
 | 
			
		||||
            referrerSince: Référent depuis le
 | 
			
		||||
            locationIsPerson: Parcours localisé auprès d'un usager concerné
 | 
			
		||||
            locationIsTemp: Parcours avec une localisation temporaire
 | 
			
		||||
            locationIsTemp: Parcours avec une localisation temporaire ou auprès d'un usager
 | 
			
		||||
            locationPersonName: Usager auprès duquel le parcours est localisé
 | 
			
		||||
            locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé
 | 
			
		||||
            acpaddress_fieldscountry: Pays de l'adresse
 | 
			
		||||
 
 | 
			
		||||
@@ -22,39 +22,22 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ReportController.
 | 
			
		||||
 */
 | 
			
		||||
class ReportController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var AuthorizationHelper
 | 
			
		||||
     */
 | 
			
		||||
    protected $authorizationHelper;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var EventDispatcherInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $eventDispatcher;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var PaginatorFactory
 | 
			
		||||
     */
 | 
			
		||||
    protected $paginator;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ReportController constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        AuthorizationHelper $authorizationHelper,
 | 
			
		||||
        PaginatorFactory $paginator
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
        $this->authorizationHelper = $authorizationHelper;
 | 
			
		||||
        $this->paginator = $paginator;
 | 
			
		||||
    }
 | 
			
		||||
        private readonly EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        private readonly AuthorizationHelper $authorizationHelper,
 | 
			
		||||
        private readonly PaginatorFactory $paginator,
 | 
			
		||||
        private readonly TranslatorInterface $translator
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new report for a given person and of a given type.
 | 
			
		||||
@@ -98,7 +81,7 @@ class ReportController extends AbstractController
 | 
			
		||||
                ->getFlashBag()
 | 
			
		||||
                ->add(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')
 | 
			
		||||
                    $this->translator
 | 
			
		||||
                        ->trans('Success : report created!')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
@@ -108,7 +91,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        $this->get('session')
 | 
			
		||||
            ->getFlashBag()->add(
 | 
			
		||||
                'error',
 | 
			
		||||
                $this->get('translator')
 | 
			
		||||
                $this->translator
 | 
			
		||||
                    ->trans('The form is not valid. The report has not been created !')
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
@@ -135,11 +118,11 @@ class ReportController extends AbstractController
 | 
			
		||||
        $report = $em->getRepository('ChillReportBundle:Report')->find($report_id);
 | 
			
		||||
 | 
			
		||||
        if (!$report) {
 | 
			
		||||
            throw $this->createNotFoundException($this->get('translator')->trans('Unable to find this report.'));
 | 
			
		||||
            throw $this->createNotFoundException($this->translator->trans('Unable to find this report.'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((int) $person_id !== (int) $report->getPerson()->getId()) {
 | 
			
		||||
            throw new \RuntimeException($this->get('translator')->trans('This is not the report of the person.'), 1);
 | 
			
		||||
            throw new \RuntimeException($this->translator->trans('This is not the report of the person.'), 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->denyAccessUnlessGranted('CHILL_REPORT_UPDATE', $report);
 | 
			
		||||
@@ -418,7 +401,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        $report = $em->getRepository('ChillReportBundle:Report')->find($report_id);
 | 
			
		||||
 | 
			
		||||
        if (!$report) {
 | 
			
		||||
            throw $this->createNotFoundException($this->get('translator')->trans('Unable to find this report.'));
 | 
			
		||||
            throw $this->createNotFoundException($this->translator->trans('Unable to find this report.'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->denyAccessUnlessGranted('CHILL_REPORT_UPDATE', $report);
 | 
			
		||||
@@ -433,7 +416,7 @@ class ReportController extends AbstractController
 | 
			
		||||
                ->getFlashBag()
 | 
			
		||||
                ->add(
 | 
			
		||||
                    'success',
 | 
			
		||||
                    $this->get('translator')
 | 
			
		||||
                    $this->translator
 | 
			
		||||
                        ->trans('Success : report updated!')
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
@@ -453,7 +436,7 @@ class ReportController extends AbstractController
 | 
			
		||||
            ->getFlashBag()
 | 
			
		||||
            ->add(
 | 
			
		||||
                'error',
 | 
			
		||||
                $this->get('translator')
 | 
			
		||||
                $this->translator
 | 
			
		||||
                    ->trans('The form is not valid. The report has not been updated !')
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
@@ -480,7 +463,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        $entity = $em->getRepository('ChillReportBundle:Report')->find($report_id);
 | 
			
		||||
 | 
			
		||||
        if (!$entity || !$person) {
 | 
			
		||||
            throw $this->createNotFoundException($this->get('translator')->trans('Unable to find this report.'));
 | 
			
		||||
            throw $this->createNotFoundException($this->translator->trans('Unable to find this report.'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->denyAccessUnlessGranted('CHILL_REPORT_SEE', $entity);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ class LabelThirdPartyHelper
 | 
			
		||||
                return $header;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (null === $value || null === $thirdParty = $this->thirdPartyRepository->find($value)) {
 | 
			
		||||
            if ('' === $value || null === $value || null === $thirdParty = $this->thirdPartyRepository->find($value)) {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -128,8 +128,8 @@ export:
 | 
			
		||||
            thirdParties: Tiers intervenant
 | 
			
		||||
 | 
			
		||||
# exports filters/aggregators
 | 
			
		||||
Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type%
 | 
			
		||||
Filtered by person\'s who have a residential address located at a thirdparty of type %thirparty_type%: Uniquement les usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type%
 | 
			
		||||
is thirdparty: Le demandeur est un tiers
 | 
			
		||||
 | 
			
		||||
Filter by person's who have a residential address located at a thirdparty of type: Filtrer les personnes qui ont une addresse de résidence chez un tiers de catégorie "xxx"
 | 
			
		||||
"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les personnes qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%"
 | 
			
		||||
Filter by person's who have a residential address located at a thirdparty of type: Filtrer les usagers qui ont une addresse de résidence chez un tiers
 | 
			
		||||
"Filtered by person's who have a residential address located at a thirdparty of type %thirdparty_type% and valid on %date_calc%": "Uniquement les usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user