mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch '172-missing-exports' into 'master'
[Export]: add missing grouping and filters and fix some issues Closes #177 and #172 See merge request Chill-Projet/chill-bundles!598
This commit is contained in:
commit
f8ee2903b2
6
.changes/unreleased/Feature-20231018-113825.yaml
Normal file
6
.changes/unreleased/Feature-20231018-113825.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
kind: Feature
|
||||
body: '[export] Add a filter "grouping accompanying period by opening date" and "trouping
|
||||
accompanying period by closing date"'
|
||||
time: 2023-10-18T11:38:25.80362952+02:00
|
||||
custom:
|
||||
Issue: "172"
|
6
.changes/unreleased/Feature-20231018-133203.yaml
Normal file
6
.changes/unreleased/Feature-20231018-133203.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
kind: Feature
|
||||
body: '[export] add a filter and aggregator on accompanying period work: group/filter
|
||||
by handling third party'
|
||||
time: 2023-10-18T13:32:03.565201495+02:00
|
||||
custom:
|
||||
Issue: "172"
|
6
.changes/unreleased/Feature-20231018-160235.yaml
Normal file
6
.changes/unreleased/Feature-20231018-160235.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
kind: Feature
|
||||
body: '[export] add a filter and aggregator on activites: group/filter activities
|
||||
by people participating to the exchange'
|
||||
time: 2023-10-18T16:02:35.99265091+02:00
|
||||
custom:
|
||||
Issue: "172"
|
6
.changes/unreleased/Feature-20231018-164927.yaml
Normal file
6
.changes/unreleased/Feature-20231018-164927.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
kind: Feature
|
||||
body: '[export] add a grouping on accompanying period export: group by activity type
|
||||
associated to at least one activity within the accompanying period'
|
||||
time: 2023-10-18T16:49:27.567166953+02:00
|
||||
custom:
|
||||
Issue: "172"
|
5
.changes/unreleased/Feature-20231019-140357.yaml
Normal file
5
.changes/unreleased/Feature-20231019-140357.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
kind: Feature
|
||||
body: '[export] sort filters and aggregators by title'
|
||||
time: 2023-10-19T14:03:57.435338127+02:00
|
||||
custom:
|
||||
Issue: ""
|
6
.changes/unreleased/Fixed-20231019-114350.yaml
Normal file
6
.changes/unreleased/Fixed-20231019-114350.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
kind: Fixed
|
||||
body: '[export] fix date range selection on filter and grouping "by status of the
|
||||
course at date", on accompanying periods'
|
||||
time: 2023-10-19T11:43:50.455829748+02:00
|
||||
custom:
|
||||
Issue: "177"
|
@ -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;
|
||||
}
|
||||
}
|
@ -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';
|
||||
}
|
||||
}
|
@ -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'),
|
||||
];
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -200,3 +200,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 }
|
||||
|
@ -362,7 +362,7 @@ export:
|
||||
Filter by users scope: Filtrer les échanges par services 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,23 @@ 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
|
||||
|
||||
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 +410,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:
|
||||
|
@ -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
|
||||
|
@ -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: ~
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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';
|
||||
}
|
@ -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)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -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'),
|
||||
];
|
||||
}
|
||||
}
|
@ -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 }
|
||||
|
||||
Chill\PersonBundle\Export\Export\ListAccompanyingPeriodWork:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
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 }
|
||||
|
||||
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_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_treatingagent:
|
||||
class: Chill\PersonBundle\Export\Filter\SocialWorkFilters\ReferrerFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
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\AccompanyingPeriodWorkStartDateBetweenDateFilter:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
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 }
|
||||
|
||||
## 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 }
|
||||
|
||||
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_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\PersonBundle\Export\Aggregator\SocialWorkAggregators\ReferrerAggregator:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
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_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_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\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\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
|
||||
@ -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:
|
||||
|
@ -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 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 usagers qui ont une addresse de résidence chez un tiers de catégorie %thirdparty_type% et valide sur la date %date_calc%"
|
||||
|
Loading…
x
Reference in New Issue
Block a user