From 094a912e427b13ebb05356234dce2c88b1139528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 13:14:48 +0100 Subject: [PATCH 01/15] Fixed: fix date's type in DateType input, and prevent collision on parameter name --- .../AccompanyingCourseFilters/HasNoReferrerFilter.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php index b18bcd1de..303c789af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php @@ -15,7 +15,7 @@ use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory; use Chill\PersonBundle\Export\Declarations; -use DateTime; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -33,15 +33,15 @@ class HasNoReferrerFilter implements FilterInterface ->andWhere(' NOT EXISTS ( SELECT 1 FROM ' . UserHistory::class . ' uh - WHERE uh.startDate < :date + WHERE uh.startDate <= :has_no_referrer_filter_date AND ( uh.endDate IS NULL - or uh.endDate > :date + or uh.endDate > :has_no_referrer_filter_date ) AND uh.accompanyingPeriod = acp ) ') - ->setParameter('date', $data['calc_date'], Types::DATE_IMMUTABLE); + ->setParameter('has_no_referrer_filter_date', $data['calc_date'], Types::DATE_IMMUTABLE); } public function applyOn(): string @@ -54,7 +54,8 @@ class HasNoReferrerFilter implements FilterInterface $builder ->add('calc_date', ChillDateType::class, [ 'label' => 'Has no referrer on this date', - 'data' => new DateTime(), + 'data' => new DateTimeImmutable(), + 'input' => 'datetime_immutable', ]); } From 84e5be6a600f0a549a866c0f7273c0523f671521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 13:21:26 +0100 Subject: [PATCH 02/15] DX: review for hasNoActivityFilter --- .../Export/Filter/ACPFilters/HasNoActivityFilter.php | 10 +--------- .../ChillActivityBundle/translations/messages.fr.yml | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php index 508644a07..570f42ae0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php @@ -14,10 +14,8 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters; use Chill\ActivityBundle\Entity\Activity; use Chill\MainBundle\Export\FilterInterface; use Chill\PersonBundle\Export\Declarations; -use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class HasNoActivityFilter implements FilterInterface { @@ -28,13 +26,7 @@ class HasNoActivityFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('activity', $qb->getAllAliases(), true)) { - $qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp'); - } - $qb - //->andWhere('COUNT(acp.activities) IS NULL') - //TODO check this: ->andWhere(' NOT EXISTS ( SELECT 1 FROM ' . Activity::class . ' activity @@ -55,7 +47,7 @@ class HasNoActivityFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { - return ['Filtered acp which has no activities']; + return ['Filtered acp which has no activities', []]; } public function getTitle(): string diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index e3fcfd2b2..1d5e7f1f2 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -278,7 +278,7 @@ Filter activity by userscope: Filtrer les activités par service du créateur Accepted userscope: Services Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’activité -Filtered acp which has no activities: Filtrés les parcours qui n'ont pas d'activités +Filtered acp which has no activities: Filtrer les parcours sans activité associée Group acp by activity number: Grouper les parcours par nombre d’activité Group activity by sentreceived: Grouper les activités par envoyé / reçu From 24873f0cc29092ff7a8f7f35145c85ac6cc9bfa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 13:33:33 +0100 Subject: [PATCH 03/15] Feature: [export] add aggregator by "number of activity" for acp --- .../ByActivityNumberAggregator.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index de35f75cc..5c6656009 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; +use Chill\ActivityBundle\Entity\Activity; use Chill\MainBundle\Export\AggregatorInterface; use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; @@ -23,9 +24,10 @@ class ByActivityNumberAggregator implements AggregatorInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { - $qb->addSelect('AS activity_by_number_aggregator') + $qb + ->addSelect('(SELECT COUNT(activity.id) FROM ' . Activity::class . ' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator') ->addGroupBy('activity_by_number_aggregator'); } @@ -34,17 +36,23 @@ class ByActivityNumberAggregator implements AggregatorInterface return Declarations::ACP_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { // No form needed } public function getLabels($key, array $values, $data) { - return static function ($value): string { + return static function ($value) { if ('_header' === $value) { return ''; } + + if (null === $value) { + return ''; + } + + return $value; }; } From 51ac4e0938038acf775e10de292438700a5eba10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 13:44:04 +0100 Subject: [PATCH 04/15] Feature: [export] filter accompanying period which has no action - work --- .../AccompanyingCourseFilters/HasNoActionFilter.php | 12 ++++-------- .../ChillPersonBundle/translations/messages.fr.yml | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php index 771b8d063..54c28d027 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoActionFilter.php @@ -12,10 +12,10 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Export\FilterInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class HasNoActionFilter implements FilterInterface { @@ -24,13 +24,9 @@ class HasNoActionFilter implements FilterInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { - if (!in_array('acpw', $qb->getAllAliases(), true)) { - $qb->join('acp.works', 'acpw'); - } - - $qb->andWhere('COUNT(acp.works) IS NULL'); + $qb->andWhere('NOT EXISTS (SELECT 1 FROM ' . AccompanyingPeriodWork::class . ' work WHERE work.accompanyingPeriod = acp)'); } public function applyOn(): string @@ -38,7 +34,7 @@ class HasNoActionFilter implements FilterInterface return Declarations::ACP_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { // no form } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 3821253ed..4b1919f8d 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -569,7 +569,7 @@ Filter by which has no referrer: Filtrer les parcours sans référent "Filtered acp which has no referrer on date: %date%": "Filtré les parcours sans référent à cette date: %date%" Has no referrer on this date: N'a pas de référent à cette date Filter by which has no action: Filtrer les parcours qui n’ont pas d’actions -Filtered acp which has no actions: Filtré les parcours qui n'ont pas d'actions +Filtered acp which has no actions: 'Filtré: uniquement les parcours qui n''ont pas d''actions' Group by number of actions: Grouper les parcours par nombre d’actions Filter by creator: Filtrer les parcours par créateur Filter by creator job: Filtrer les parcours par métier du créateur From c872ca7204805cd0462790f71eb9944b09a1add4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:05:16 +0100 Subject: [PATCH 05/15] Feature: [export] group accompanying period by number of actions --- .../ByActionNumberAggregator.php | 15 +++++++++++---- .../translations/messages.fr.yml | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php index 0f51b6feb..2dffccbbb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ByActionNumberAggregator.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; use Chill\MainBundle\Export\AggregatorInterface; +use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -23,9 +24,9 @@ class ByActionNumberAggregator implements AggregatorInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { - $qb->addSelect('AS acp_by_action_number_aggregator') + $qb->addSelect('(SELECT COUNT(acp_by_action_action.id) FROM ' . AccompanyingPeriodWork::class . ' acp_by_action_action WHERE acp_by_action_action.accompanyingPeriod = acp) AS acp_by_action_number_aggregator') ->addGroupBy('acp_by_action_number_aggregator'); } @@ -34,17 +35,23 @@ class ByActionNumberAggregator implements AggregatorInterface return Declarations::ACP_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { // No form needed } public function getLabels($key, array $values, $data) { - return static function ($value): string { + return static function ($value) { if ('_header' === $value) { + return 'export.aggregator.course.by_number_of_action.Number of actions'; + } + + if (null === $value) { return ''; } + + return $value; }; } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 4b1919f8d..8d5e055cd 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -1013,6 +1013,8 @@ export: Household composition: Composition du ménage Group course by household composition: Grouper les parcours par composition familiale des ménages des usagers concernés Calc date: Date de calcul de la composition du ménage + by_number_of_action: + Number of actions: Nombre d'actions filter: course: by_user_scope: From 60f93f7f12ae2522c6a567b7aaa2e7d2c27f988a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:06:10 +0100 Subject: [PATCH 06/15] DX: more code style fixes --- .../Controller/ActivityControllerTest.php | 8 ++- .../Tests/Form/ActivityTypeTest.php | 4 +- .../Config/ConfigRepository.php | 16 ++++-- .../Service/Summary/SummaryBudget.php | 4 +- .../ParticipationControllerTest.php | 12 +++-- .../Export/Helper/ExportAddressHelper.php | 4 +- .../EntityToJsonTransformer.php | 4 +- .../Form/Type/ScopePickerType.php | 4 +- .../Tests/Entity/NotificationTest.php | 4 +- .../Tests/Form/Type/ScopePickerTypeTest.php | 4 +- .../Authorization/AuthorizationHelperTest.php | 4 +- .../Resolver/DefaultScopeResolverTest.php | 4 +- .../Resolver/ScopeResolverDispatcherTest.php | 4 +- .../NotificationOnTransition.php | 4 +- ...cialIssueConsistencyEntityListenerTest.php | 2 +- .../AccompanyingCourseApiControllerTest.php | 4 +- .../Controller/PersonControllerUpdateTest.php | 52 ++++++++++++++----- ...onControllerUpdateWithHiddenFieldsTest.php | 24 ++++++--- .../Tests/Household/MembersEditorTest.php | 8 ++- .../RelationshipDocGenNormalizerTest.php | 4 +- .../Tests/Timeline/TimelineProviderTest.php | 4 +- 21 files changed, 131 insertions(+), 47 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php index 55a1442f1..8a30a6c9b 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php @@ -369,8 +369,12 @@ final class ActivityControllerTest extends WebTestCase $center ); $reachableScopesId = array_intersect( - array_map(static function ($s) { return $s->getId(); }, $reachableScopesDelete), - array_map(static function ($s) { return $s->getId(); }, $reachableScopesUpdate) + array_map(static function ($s) { + return $s->getId(); + }, $reachableScopesDelete), + array_map(static function ($s) { + return $s->getId(); + }, $reachableScopesUpdate) ); if (count($reachableScopesId) === 0) { diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php index d0b4b5bb2..b6cb6fc7b 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php @@ -188,7 +188,9 @@ final class ActivityTypeTest extends KernelTestCase // map all the values in an array $values = array_map( - static function ($choice) { return $choice->value; }, + static function ($choice) { + return $choice->value; + }, $view['activity']['durationTime']->vars['choices'] ); diff --git a/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php b/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php index 2497bcf21..f28a83a4d 100644 --- a/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php +++ b/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php @@ -31,7 +31,9 @@ class ConfigRepository public function getChargesKeys(bool $onlyActive = false): array { - return array_map(static function ($element) { return $element['key']; }, $this->getCharges($onlyActive)); + return array_map(static function ($element) { + return $element['key']; + }, $this->getCharges($onlyActive)); } /** @@ -50,7 +52,9 @@ class ConfigRepository public function getResourcesKeys(bool $onlyActive = false): array { - return array_map(static function ($element) { return $element['key']; }, $this->getResources($onlyActive)); + return array_map(static function ($element) { + return $element['key']; + }, $this->getResources($onlyActive)); } /** @@ -70,14 +74,18 @@ class ConfigRepository private function getCharges(bool $onlyActive = false): array { return $onlyActive ? - array_filter($this->charges, static function ($el) { return $el['active']; }) + array_filter($this->charges, static function ($el) { + return $el['active']; + }) : $this->charges; } private function getResources(bool $onlyActive = false): array { return $onlyActive ? - array_filter($this->resources, static function ($el) { return $el['active']; }) + array_filter($this->resources, static function ($el) { + return $el['active']; + }) : $this->resources; } diff --git a/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php b/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php index 6ae7e049b..f02d2e64a 100644 --- a/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php +++ b/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php @@ -61,7 +61,9 @@ class SummaryBudget implements SummaryBudgetInterface ]; } - $personIds = $household->getCurrentPersons()->map(static function (Person $p) { return $p->getId(); }); + $personIds = $household->getCurrentPersons()->map(static function (Person $p) { + return $p->getId(); + }); $ids = implode(', ', array_fill(0, count($personIds), '?')); $parameters = [...$personIds, $household->getId()]; diff --git a/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php b/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php index dfb782a7d..fa1ecabbe 100644 --- a/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php +++ b/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php @@ -239,7 +239,9 @@ final class ParticipationControllerTest extends WebTestCase $this->personsIdsCache = array_merge( $this->personsIdsCache, $event->getParticipations()->map( - static function ($p) { return $p->getPerson()->getId(); } + static function ($p) { + return $p->getPerson()->getId(); + } ) ->toArray() ); @@ -303,7 +305,9 @@ final class ParticipationControllerTest extends WebTestCase $event = $this->getRandomEventWithMultipleParticipations(); $persons_id = implode(',', $event->getParticipations()->map( - static function ($p) { return $p->getPerson()->getId(); } + static function ($p) { + return $p->getPerson()->getId(); + } )->toArray()); $crawler = $this->client->request( @@ -329,7 +333,9 @@ final class ParticipationControllerTest extends WebTestCase $nbParticipations = $event->getParticipations()->count(); // get the persons_id participating on this event $persons_id = $event->getParticipations()->map( - static function ($p) { return $p->getPerson()->getId(); } + static function ($p) { + return $p->getPerson()->getId(); + } )->toArray(); // exclude the existing persons_ids from the new person $this->personsIdsCache = array_merge($this->personsIdsCache, $persons_id); diff --git a/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php index 2f9a270ff..7d4245aa6 100644 --- a/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php +++ b/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php @@ -177,7 +177,9 @@ class ExportAddressHelper $prefixes = array_merge( $prefixes, array_map( - static function ($item) use ($prefix) { return $prefix . $item; }, + static function ($item) use ($prefix) { + return $prefix . $item; + }, self::COLUMN_MAPPING[$key] ) ); diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php index ecd668d2b..46fa8799f 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php @@ -51,7 +51,9 @@ class EntityToJsonTransformer implements DataTransformerInterface } return array_map( - function ($item) { return $this->denormalizeOne($item); }, + function ($item) { + return $this->denormalizeOne($item); + }, $denormalized ); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php b/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php index 1cba1ba58..f65677dc7 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php @@ -66,7 +66,9 @@ class ScopePickerType extends AbstractType $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'], $options['center'] ), - static function (Scope $s) { return $s->isActive(); } + static function (Scope $s) { + return $s->isActive(); + } ); if (0 === count($items)) { diff --git a/src/Bundle/ChillMainBundle/Tests/Entity/NotificationTest.php b/src/Bundle/ChillMainBundle/Tests/Entity/NotificationTest.php index f5e203f78..9246cf1e6 100644 --- a/src/Bundle/ChillMainBundle/Tests/Entity/NotificationTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Entity/NotificationTest.php @@ -134,7 +134,9 @@ final class NotificationTest extends KernelTestCase $this->assertEquals($senderId, $notification->getSender()->getId()); $this->assertCount(count($addressesIds), $notification->getUnreadBy()); - $unreadIds = $notification->getUnreadBy()->map(static function (User $u) { return $u->getId(); }); + $unreadIds = $notification->getUnreadBy()->map(static function (User $u) { + return $u->getId(); + }); foreach ($addressesIds as $addresseeId) { $this->assertContains($addresseeId, $unreadIds); diff --git a/src/Bundle/ChillMainBundle/Tests/Form/Type/ScopePickerTypeTest.php b/src/Bundle/ChillMainBundle/Tests/Form/Type/ScopePickerTypeTest.php index d64f68951..ce41c9a21 100644 --- a/src/Bundle/ChillMainBundle/Tests/Form/Type/ScopePickerTypeTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Form/Type/ScopePickerTypeTest.php @@ -96,7 +96,9 @@ final class ScopePickerTypeTest extends TypeTestCase $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class); $translatableStringHelper->localize(Argument::type('array'))->will( - static function ($args) { return $args[0]['fr']; } + static function ($args) { + return $args[0]['fr']; + } ); $type = new ScopePickerType( diff --git a/src/Bundle/ChillMainBundle/Tests/Security/Authorization/AuthorizationHelperTest.php b/src/Bundle/ChillMainBundle/Tests/Security/Authorization/AuthorizationHelperTest.php index 02d319042..cc5a49096 100644 --- a/src/Bundle/ChillMainBundle/Tests/Security/Authorization/AuthorizationHelperTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Security/Authorization/AuthorizationHelperTest.php @@ -211,7 +211,9 @@ final class AuthorizationHelperTest extends KernelTestCase $centerA ); - $usernames = array_map(static function (User $u) { return $u->getUsername(); }, $users); + $usernames = array_map(static function (User $u) { + return $u->getUsername(); + }, $users); $this->assertContains('center a_social', $usernames); } diff --git a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php index 7e6710a20..30d50fca5 100644 --- a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php @@ -33,7 +33,7 @@ final class DefaultScopeResolverTest extends TestCase public function testHasScopeInterface() { $scope = new Scope(); - $entity = new class($scope) implements HasScopeInterface { + $entity = new class ($scope) implements HasScopeInterface { public function __construct(Scope $scope) { $this->scope = $scope; @@ -52,7 +52,7 @@ final class DefaultScopeResolverTest extends TestCase public function testHasScopesInterface() { - $entity = new class($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { + $entity = new class ($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { public function __construct(Scope $scopeA, Scope $scopeB) { $this->scopes = [$scopeA, $scopeB]; diff --git a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php index e2c5d3879..31e5229bb 100644 --- a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php @@ -34,7 +34,7 @@ final class ScopeResolverDispatcherTest extends TestCase public function testHasScopeInterface() { $scope = new Scope(); - $entity = new class($scope) implements HasScopeInterface { + $entity = new class ($scope) implements HasScopeInterface { public function __construct(Scope $scope) { $this->scope = $scope; @@ -52,7 +52,7 @@ final class ScopeResolverDispatcherTest extends TestCase public function testHasScopesInterface() { - $entity = new class($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { + $entity = new class ($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { public function __construct(Scope $scopeA, Scope $scopeB) { $this->scopes = [$scopeA, $scopeB]; diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php index 608ae6fa1..7d2cadc37 100644 --- a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php +++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php @@ -107,7 +107,9 @@ class NotificationOnTransition implements EventSubscriberInterface 'dest' => $subscriber, 'place' => $place, 'workflow' => $workflow, - 'is_dest' => in_array($subscriber->getId(), array_map(static function (User $u) { return $u->getId(); }, $entityWorkflow->futureDestUsers), true), + 'is_dest' => in_array($subscriber->getId(), array_map(static function (User $u) { + return $u->getId(); + }, $entityWorkflow->futureDestUsers), true), ]; $notification = new Notification(); diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php index 0c8c3e0c3..8ac092647 100644 --- a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php @@ -114,7 +114,7 @@ final class AccompanyingPeriodSocialIssueConsistencyEntityListenerTest extends T protected function generateClass(AccompanyingPeriod $period, Collection $socialIssues): AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { - return new class($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { + return new class ($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { public Collection $socialIssues; public AccompanyingPeriod $period; diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php index 30c8e2a4c..154dbd884 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingCourseApiControllerTest.php @@ -342,7 +342,9 @@ final class AccompanyingCourseApiControllerTest extends WebTestCase // check that the person id is contained $participationsPersonsIds = array_map( - static function ($participation) { return $participation->person->id; }, + static function ($participation) { + return $participation->person->id; + }, $data->participations ); diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php index 8b2f4c141..bb70866e2 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateTest.php @@ -294,23 +294,49 @@ final class PersonControllerUpdateTest extends WebTestCase public function validTextFieldsProvider() { return [ - ['firstName', 'random Value', static function (Person $person) { return $person->getFirstName(); }], - ['lastName', 'random Value', static function (Person $person) { return $person->getLastName(); }], + ['firstName', 'random Value', static function (Person $person) { + return $person->getFirstName(); + }], + ['lastName', 'random Value', static function (Person $person) { + return $person->getLastName(); + }], // reminder: this value is capitalized - ['placeOfBirth', 'A PLACE', static function (Person $person) { return $person->getPlaceOfBirth(); }], - ['birthdate', '1980-12-15', static function (Person $person) { return $person->getBirthdate()->format('Y-m-d'); }], + ['placeOfBirth', 'A PLACE', static function (Person $person) { + return $person->getPlaceOfBirth(); + }], + ['birthdate', '1980-12-15', static function (Person $person) { + return $person->getBirthdate()->format('Y-m-d'); + }], // TODO test on phonenumber update // ['phonenumber', '+32123456789', static function (Person $person) { return $person->getPhonenumber(); }], - ['memo', 'jfkdlmq jkfldmsq jkmfdsq', static function (Person $person) { return $person->getMemo(); }], - ['countryOfBirth', 'BE', static function (Person $person) { return $person->getCountryOfBirth()->getCountryCode(); }], - ['nationality', 'FR', static function (Person $person) { return $person->getNationality()->getCountryCode(); }], - ['placeOfBirth', '', static function (Person $person) { return $person->getPlaceOfBirth(); }], - ['birthdate', '', static function (Person $person) { return $person->getBirthdate(); }], + ['memo', 'jfkdlmq jkfldmsq jkmfdsq', static function (Person $person) { + return $person->getMemo(); + }], + ['countryOfBirth', 'BE', static function (Person $person) { + return $person->getCountryOfBirth()->getCountryCode(); + }], + ['nationality', 'FR', static function (Person $person) { + return $person->getNationality()->getCountryCode(); + }], + ['placeOfBirth', '', static function (Person $person) { + return $person->getPlaceOfBirth(); + }], + ['birthdate', '', static function (Person $person) { + return $person->getBirthdate(); + }], //['phonenumber', '', static function (Person $person) { return $person->getPhonenumber(); }], - ['memo', '', static function (Person $person) { return $person->getMemo(); }], - ['countryOfBirth', null, static function (Person $person) { return $person->getCountryOfBirth(); }], - ['nationality', null, static function (Person $person) { return $person->getNationality(); }], - ['gender', Person::FEMALE_GENDER, static function (Person $person) { return $person->getGender(); }], + ['memo', '', static function (Person $person) { + return $person->getMemo(); + }], + ['countryOfBirth', null, static function (Person $person) { + return $person->getCountryOfBirth(); + }], + ['nationality', null, static function (Person $person) { + return $person->getNationality(); + }], + ['gender', Person::FEMALE_GENDER, static function (Person $person) { + return $person->getGender(); + }], ]; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php index 7423b5388..403f89dd4 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php @@ -197,12 +197,24 @@ final class PersonControllerUpdateWithHiddenFieldsTest extends WebTestCase public function validTextFieldsProvider() { return [ - ['firstName', 'random Value', static function (Person $person) { return $person->getFirstName(); }], - ['lastName', 'random Value', static function (Person $person) { return $person->getLastName(); }], - ['birthdate', '15-12-1980', static function (Person $person) { return $person->getBirthdate()->format('d-m-Y'); }], - ['memo', 'jfkdlmq jkfldmsq jkmfdsq', static function (Person $person) { return $person->getMemo(); }], - ['birthdate', '', static function (Person $person) { return $person->getBirthdate(); }], - ['gender', Person::FEMALE_GENDER, static function (Person $person) { return $person->getGender(); }], + ['firstName', 'random Value', static function (Person $person) { + return $person->getFirstName(); + }], + ['lastName', 'random Value', static function (Person $person) { + return $person->getLastName(); + }], + ['birthdate', '15-12-1980', static function (Person $person) { + return $person->getBirthdate()->format('d-m-Y'); + }], + ['memo', 'jfkdlmq jkfldmsq jkmfdsq', static function (Person $person) { + return $person->getMemo(); + }], + ['birthdate', '', static function (Person $person) { + return $person->getBirthdate(); + }], + ['gender', Person::FEMALE_GENDER, static function (Person $person) { + return $person->getGender(); + }], ]; } diff --git a/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php b/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php index 9c0e884a5..a58560bdd 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php @@ -111,7 +111,9 @@ final class MembersEditorTest extends TestCase $this->assertCount(1, $notSharing); $this->assertCount(1, $sharings); - $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); }; + $getPerson = static function (HouseholdMember $m) { + return $m->getPerson(); + }; $this->assertContains($person, $notSharing->map($getPerson)); } @@ -151,7 +153,9 @@ final class MembersEditorTest extends TestCase $this->assertCount(1, $notSharing); $this->assertCount(0, $sharings); - $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); }; + $getPerson = static function (HouseholdMember $m) { + return $m->getPerson(); + }; $this->assertContains($person, $notSharing->map($getPerson)); } diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/RelationshipDocGenNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/RelationshipDocGenNormalizerTest.php index a6bab133a..05d2eace1 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/RelationshipDocGenNormalizerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/RelationshipDocGenNormalizerTest.php @@ -118,7 +118,9 @@ final class RelationshipDocGenNormalizerTest extends TestCase { $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class); $translatableStringHelper->localize(Argument::type('array'))->will( - static function ($args) { return $args[0][array_keys($args[0])[0]]; } + static function ($args) { + return $args[0][array_keys($args[0])[0]]; + } ); $normalizer = new RelationshipDocGenNormalizer( diff --git a/src/Bundle/ChillReportBundle/Tests/Timeline/TimelineProviderTest.php b/src/Bundle/ChillReportBundle/Tests/Timeline/TimelineProviderTest.php index e76688357..6091c51a8 100644 --- a/src/Bundle/ChillReportBundle/Tests/Timeline/TimelineProviderTest.php +++ b/src/Bundle/ChillReportBundle/Tests/Timeline/TimelineProviderTest.php @@ -67,7 +67,9 @@ final class TimelineProviderTest extends WebTestCase self::$em ->getRepository(\Chill\MainBundle\Entity\Scope::class) ->findAll(), - static function (Scope $scope) { return $scope->getName()['en'] === 'social'; } + static function (Scope $scope) { + return $scope->getName()['en'] === 'social'; + } ); $report = (new Report()) From 9cf06c147fdbc7138bd173f0d58cfd19b4231925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:25:52 +0100 Subject: [PATCH 07/15] Feature: [export][activity] Add an aggregator to group by sent / received --- .../Aggregator/SentReceivedAggregator.php | 28 +++++++++++++------ .../translations/messages.fr.yml | 10 +++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index 24000096f..3396faa80 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -16,15 +16,27 @@ use Chill\MainBundle\Export\AggregatorInterface; use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class SentReceivedAggregator implements AggregatorInterface { + private TranslatorInterface $translator; + + /** + * @param TranslatorInterface $translator + */ + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + } + + public function addRole(): ?string { return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { $qb->addSelect('activity.sentReceived AS activity_sentreceived_aggregator') ->addGroupBy('activity_sentreceived_aggregator'); @@ -35,16 +47,16 @@ class SentReceivedAggregator implements AggregatorInterface return Declarations::ACTIVITY; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { // No form needed } - public function getLabels($key, array $values, $data) + public function getLabels($key, array $values, $data): callable { - return static function ($value): string { + return function (?string $value): string { if ('_header' === $value) { - return ''; + return 'export.aggregator.activity.by_sent_received.Sent or received'; } switch ($value) { @@ -52,10 +64,10 @@ class SentReceivedAggregator implements AggregatorInterface return ''; case 'sent': - return 'is sent'; + return $this->translator->trans('export.aggregator.activity.by_sent_received.is sent'); case 'received': - return 'is received'; + return $this->translator->trans('export.aggregator.activity.by_sent_received.is received'); default: throw new LogicException(sprintf('The value %s is not valid', $value)); @@ -70,6 +82,6 @@ class SentReceivedAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group activity by sentreceived'; + return 'export.aggregator.activity.by_sent_received.Group activity by sentreceived'; } } diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 1d5e7f1f2..c3d56185a 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -260,8 +260,6 @@ activity is not emergency: l'activité n'est pas urgente Filter activity by sentreceived: Filtrer les activités par envoyé/reçu 'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%" Accepted sentreceived: '' -is sent: envoyé -is received: reçu Filter activity by linked socialaction: Filtrer les activités 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 activités par problématique liée @@ -280,7 +278,6 @@ Accepted userscope: Services Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’activité Filtered acp which has no activities: Filtrer les parcours sans activité associée Group acp by activity number: Grouper les parcours par nombre d’activité -Group activity by sentreceived: Grouper les activités par envoyé / reçu #aggregators Activity type: Type d'activité @@ -337,3 +334,10 @@ export: by_usersscope: Filter by users scope: Filtrer les activités 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%' + aggregator: + activity: + by_sent_received: + Sent or received: Envoyé ou reçu + is sent: envoyé + is received: reçu + Group activity by sentreceived: Grouper les activités par envoyé / reçu From 1bf7f9945cac5bbbcbe3f5b73fabe02ff0ea36dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:39:36 +0100 Subject: [PATCH 08/15] Feature: [export][action] Filter 'active' action: which does not have an end date --- .../Export/Filter/SocialWorkFilters/CurrentActionFilter.php | 6 +++--- .../config/services/exports_social_actions.yaml | 6 +++++- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php index cbf958182..cbdb64d8d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CurrentActionFilter.php @@ -23,9 +23,9 @@ class CurrentActionFilter implements FilterInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { - $qb->andWhere('acpw.startDate IS NULL'); + $qb->andWhere('acpw.endDate IS NULL'); } public function applyOn(): string @@ -33,7 +33,7 @@ class CurrentActionFilter implements FilterInterface return Declarations::SOCIAL_WORK_ACTION_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { //no form } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index 28401c3b3..8b2d9d2b8 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -38,6 +38,10 @@ services: - { 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 } ## AGGREGATORS chill.person.export.aggregator_action_type: @@ -89,4 +93,4 @@ services: tags: - { name: chill.export_aggregator, alias: social_work_actions_goal_result_aggregator } - Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator: \ No newline at end of file + Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators\CurrentActionAggregator: diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 8d5e055cd..df4b0fab2 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -576,7 +576,7 @@ Filter by creator job: Filtrer les parcours par métier du créateur Group by creator job: Grouper les parcours par métier du créateur Filter by current actions: Filtrer les actions en cours -Filtered by current action: Filtré les actions en cours +Filtered by current action: 'Filtré: uniquement les actions en cours (sans date de fin)' Group by current actions: Grouper les actions en cours Current action: Actions en cours Not current action: Actions terminées From cda25d3459d05d5f7dccead62a22f9c26416e5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:40:17 +0100 Subject: [PATCH 09/15] DX: more cs --- .../Export/Aggregator/SentReceivedAggregator.php | 4 ---- .../Tests/Security/Resolver/DefaultScopeResolverTest.php | 4 ++-- .../Tests/Security/Resolver/ScopeResolverDispatcherTest.php | 4 ++-- ...mpanyingPeriodSocialIssueConsistencyEntityListenerTest.php | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index 3396faa80..7d77a7c69 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -22,15 +22,11 @@ class SentReceivedAggregator implements AggregatorInterface { private TranslatorInterface $translator; - /** - * @param TranslatorInterface $translator - */ public function __construct(TranslatorInterface $translator) { $this->translator = $translator; } - public function addRole(): ?string { return null; diff --git a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php index 30d50fca5..7e6710a20 100644 --- a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/DefaultScopeResolverTest.php @@ -33,7 +33,7 @@ final class DefaultScopeResolverTest extends TestCase public function testHasScopeInterface() { $scope = new Scope(); - $entity = new class ($scope) implements HasScopeInterface { + $entity = new class($scope) implements HasScopeInterface { public function __construct(Scope $scope) { $this->scope = $scope; @@ -52,7 +52,7 @@ final class DefaultScopeResolverTest extends TestCase public function testHasScopesInterface() { - $entity = new class ($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { + $entity = new class($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { public function __construct(Scope $scopeA, Scope $scopeB) { $this->scopes = [$scopeA, $scopeB]; diff --git a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php index 31e5229bb..e2c5d3879 100644 --- a/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Security/Resolver/ScopeResolverDispatcherTest.php @@ -34,7 +34,7 @@ final class ScopeResolverDispatcherTest extends TestCase public function testHasScopeInterface() { $scope = new Scope(); - $entity = new class ($scope) implements HasScopeInterface { + $entity = new class($scope) implements HasScopeInterface { public function __construct(Scope $scope) { $this->scope = $scope; @@ -52,7 +52,7 @@ final class ScopeResolverDispatcherTest extends TestCase public function testHasScopesInterface() { - $entity = new class ($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { + $entity = new class($scopeA = new Scope(), $scopeB = new Scope()) implements HasScopesInterface { public function __construct(Scope $scopeA, Scope $scopeB) { $this->scopes = [$scopeA, $scopeB]; diff --git a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php index 8ac092647..0c8c3e0c3 100644 --- a/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/AccompanyingPeriod/SocialIssueConsistency/AccompanyingPeriodSocialIssueConsistencyEntityListenerTest.php @@ -114,7 +114,7 @@ final class AccompanyingPeriodSocialIssueConsistencyEntityListenerTest extends T protected function generateClass(AccompanyingPeriod $period, Collection $socialIssues): AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { - return new class ($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { + return new class($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface { public Collection $socialIssues; public AccompanyingPeriod $period; From 63d38e35f729d1646b93ed141a2bff7d257872e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 14:55:12 +0100 Subject: [PATCH 10/15] Feature: [export][work] Group by current action --- .../CurrentActionAggregator.php | 24 ++++++++++++------- .../services/exports_social_actions.yaml | 4 ++++ .../translations/messages.fr.yml | 9 ++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php index a77838167..58fcb2874 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CurrentActionAggregator.php @@ -16,19 +16,27 @@ use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class CurrentActionAggregator implements AggregatorInterface { + private TranslatorInterface $translator; + + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + } + public function addRole(): ?string { return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { $qb ->addSelect(' - (CASE true WHEN acpw.startDate IS NULL ELSE false END) + (CASE WHEN acpw.endDate IS NULL THEN true ELSE false END) AS acpw_current_action_aggregator ') ->addGroupBy('acpw_current_action_aggregator'); @@ -39,24 +47,24 @@ class CurrentActionAggregator implements AggregatorInterface return Declarations::SOCIAL_WORK_ACTION_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { // No form needed } public function getLabels($key, array $values, $data) { - return static function ($value): string { + return function ($value): string { if ('_header' === $value) { - return ''; + return 'export.aggregator.course_work.by_current_action.Current action ?'; } switch ($value) { case true: - return 'Current action'; + return $this->translator->trans('export.aggregator.course_work.by_current_action.Current action'); case false: - return 'Not current action'; + return $this->translator->trans('export.aggregator.course_work.by_current_action.Not current action'); default: throw new LogicException(sprintf('The value %s is not valid', $value)); @@ -71,6 +79,6 @@ class CurrentActionAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group by current actions'; + return 'export.aggregator.course_work.by_current_action.Group by current actions'; } } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index 8b2d9d2b8..13c51762f 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -94,3 +94,7 @@ services: - { 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 } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index df4b0fab2..0833f57e3 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -577,9 +577,6 @@ Group by creator job: Grouper les parcours par métier du créateur Filter by current actions: Filtrer les actions en cours Filtered by current action: 'Filtré: uniquement les actions en cours (sans date de fin)' -Group by current actions: Grouper les actions en cours -Current action: Actions en cours -Not current action: Actions terminées Filter by start date evaluations: Filtrer les évaluations par date de début Filter by end date evaluations: Filtrer les évaluations par date de fin start period date: Date de début de la période @@ -1015,6 +1012,12 @@ export: Calc date: Date de calcul de la composition du ménage by_number_of_action: Number of actions: Nombre d'actions + course_work: + by_current_action: + Current action ?: Action en cours ? + Group by current actions: Grouper les actions en cours + Current action: Action en cours + Not current action: Action terminée filter: course: by_user_scope: From d8104c4443b948d0433ff438f88279c3ebe33c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 15:08:04 +0100 Subject: [PATCH 11/15] DX: prevent collision in parameter name in evaluation / by start date filter --- .../EvaluationFilters/ByStartDateFilter.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php index e21a1ea68..f12b5e805 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByStartDateFilter.php @@ -14,7 +14,7 @@ namespace Chill\PersonBundle\Export\Filter\EvaluationFilters; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\PersonBundle\Export\Declarations; -use DateTime; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -26,12 +26,12 @@ class ByStartDateFilter implements FilterInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { $qb - ->andWhere('workeval.startDate IS BETWEEN :start_date and :end_date') - ->setParameter('start_date', $data['start_date'], Types::DATE_IMMUTABLE) - ->setParameter('end_date', $data['end_date'], Types::DATE_IMMUTABLE); + ->andWhere('workeval.startDate BETWEEN :work_eval_by_start_date_start_date and :work_eval_by_start_date_end_date') + ->setParameter('work_eval_by_start_date_start_date', $data['start_date'], Types::DATE_IMMUTABLE) + ->setParameter('work_eval_by_start_date_end_date', $data['end_date'], Types::DATE_IMMUTABLE); } public function applyOn(): string @@ -39,16 +39,18 @@ class ByStartDateFilter implements FilterInterface return Declarations::EVAL_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { $builder ->add('start_date', ChillDateType::class, [ 'label' => 'start period date', - 'data' => new DateTime(), + 'data' => new DateTimeImmutable('1 year ago'), + 'input' => 'datetime_immutable', ]) ->add('end_date', ChillDateType::class, [ 'label' => 'end period date', - 'data' => new DateTime(), + 'data' => new DateTimeImmutable(), + 'input' => 'datetime_immutable', ]); } From 2d40c38c88fed58648f713bbd47a2dac1ca22784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 15:56:48 +0100 Subject: [PATCH 12/15] Feature: [export][evaluation] add by end date filter --- .../EvaluationFilters/ByEndDateFilter.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php index 5c509d50c..f828da109 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/ByEndDateFilter.php @@ -14,7 +14,7 @@ namespace Chill\PersonBundle\Export\Filter\EvaluationFilters; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\PersonBundle\Export\Declarations; -use DateTime; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -26,12 +26,12 @@ class ByEndDateFilter implements FilterInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { $qb - ->andWhere('workeval.endDate IS BETWEEN :start_date and :end_date') - ->setParameter('start_date', $data['start_date'], Types::DATE_IMMUTABLE) - ->setParameter('end_date', $data['end_date'], Types::DATE_IMMUTABLE); + ->andWhere('workeval.endDate BETWEEN :work_eval_by_end_date_start_date and :work_eval_by_end_date_end_date') + ->setParameter('work_eval_by_end_date_start_date', $data['start_date'], Types::DATE_IMMUTABLE) + ->setParameter('work_eval_by_end_date_end_date', $data['end_date'], Types::DATE_IMMUTABLE); } public function applyOn(): string @@ -39,16 +39,18 @@ class ByEndDateFilter implements FilterInterface return Declarations::EVAL_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { $builder ->add('start_date', ChillDateType::class, [ 'label' => 'start period date', - 'data' => new DateTime(), + 'data' => new DateTimeImmutable('1 year ago'), + 'input' => 'datetime_immutable', ]) ->add('end_date', ChillDateType::class, [ 'label' => 'end period date', - 'data' => new DateTime(), + 'data' => new DateTimeImmutable(), + 'input' => 'datetime_immutable', ]); } From f0b2ec13486f971ec4e62b0fc3418380a547b85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 16:17:10 +0100 Subject: [PATCH 13/15] Feature: [export][evaluation] filter by current evaluation (without any end date) --- .../Filter/EvaluationFilters/CurrentEvaluationsFilter.php | 4 ++-- src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php index 50c95600e..140f6c3cb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/CurrentEvaluationsFilter.php @@ -23,7 +23,7 @@ class CurrentEvaluationsFilter implements FilterInterface return null; } - public function alterQuery(QueryBuilder $qb, $data) + public function alterQuery(QueryBuilder $qb, $data): void { $qb->andWhere('workeval.endDate IS NULL'); } @@ -33,7 +33,7 @@ class CurrentEvaluationsFilter implements FilterInterface return Declarations::EVAL_TYPE; } - public function buildForm(FormBuilderInterface $builder) + public function buildForm(FormBuilderInterface $builder): void { //no form needed } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 0833f57e3..3764325af 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -584,7 +584,7 @@ end period date: Date de fin de la période "Filtered by start date: between %start_date% and %end_date%": "Filtré par la date de début: comprise entre %start_date% et %end_date%" "Filtered by end date: between %start_date% and %end_date%": "Filtré par la date de fin: comprise entre %start_date% et %end_date%" Filter by current evaluations: Filtrer les évaluations en cours -"Filtered by current evaluations": "Filtré selon les évaluations en cours" +"Filtered by current evaluations": "Filtré: uniquement les évaluations en cours" Group by start date evaluations: Grouper les évaluations par semaine/mois/année de la date de début Group by end date evaluations: Grouper les évaluations par semaine/mois/année de la date de fin Group by max date evaluations: Grouper les évaluations par semaine/mois/année de la date d'échéance From 4ca10ce38d11f991a0d80e7d264253fbe2374097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 16:26:56 +0100 Subject: [PATCH 14/15] Feature: [export][evaluation] Adding group by evaluation having end date --- .../HavingEndDateAggregator.php | 23 +++++++++++-------- .../config/services/exports_evaluation.yaml | 7 ++++++ .../translations/messages.fr.yml | 9 +++++--- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php index af801b74d..e33bb326f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php @@ -16,9 +16,17 @@ use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; use LogicException; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class HavingEndDateAggregator implements AggregatorInterface { + private TranslatorInterface $translator; + + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + } + public function addRole(): ?string { return null; @@ -27,10 +35,7 @@ class HavingEndDateAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb - ->addSelect(' - CASE true WHEN workeval.endDAte IS NULL ELSE false END - AS eval_enddate_aggregator - ') + ->addSelect('CASE WHEN workeval.endDate IS NULL THEN true ELSE false END AS eval_enddate_aggregator') ->addGroupBy('eval_enddate_aggregator'); } @@ -46,17 +51,17 @@ class HavingEndDateAggregator implements AggregatorInterface public function getLabels($key, array $values, $data) { - return static function ($value): string { + return function ($value): string { if ('_header' === $value) { - return ''; + return 'export.aggregator.eval.by_end_date.Has end date ?'; } switch ($value) { case true: - return 'enddate is specified'; + return $this->translator->trans('export.aggregator.eval.by_end_date.enddate is specified'); case false: - return 'enddate is not specified'; + return $this->translator->trans('export.aggregator.eval.by_end_date.enddate is not specified'); default: throw new LogicException(sprintf('The value %s is not valid', $value)); @@ -71,6 +76,6 @@ class HavingEndDateAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group evaluations having end date'; + return 'export.aggregator.eval.by_end_date.Group evaluations having end date'; } } diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml index a389c1f80..f58b7112b 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_evaluation.yaml @@ -73,3 +73,10 @@ services: autoconfigure: true tags: - { name: chill.export_aggregator, alias: evaluation_bymaxdate_aggregator } + + Chill\PersonBundle\Export\Aggregator\EvaluationAggregators\HavingEndDateAggregator: + autowire: true + autoconfigure: true + tags: + - { name: chill.export_aggregator, alias: evaluation_byend_date_aggregator } + diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 3764325af..89808d900 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -626,9 +626,6 @@ maxdate is specified: la date d'échéance est spécifiée maxdate is not specified: la date d'échéance n'est pas spécifiée "Filtered by maxdate: only %choice%": "Filtré par date d'échéance: uniquement si %choice%" -Group evaluations having end date: Grouper les évaluations qui ont une date de fin -enddate is specified: la date de fin est spécifiée -enddate is not specified: la date de fin n'est pas spécifiée ## household filters/aggr Filter by composition: Filtrer les ménages par composition familiale @@ -1018,6 +1015,12 @@ export: Group by current actions: Grouper les actions en cours Current action: Action en cours Not current action: Action terminée + eval: + by_end_date: + Has end date ?: Évaluation en cours ? + Group evaluations having end date: Grouper les évaluations en cours (avec ou sans date de fin) + enddate is specified: la date de fin est spécifiée + enddate is not specified: la date de fin n'est pas spécifiée filter: course: by_user_scope: From 0255f12fa913c39ce5efbd4da9a63b23d5cf7061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Nov 2022 16:42:23 +0100 Subject: [PATCH 15/15] Feature: [export][evaluation] Group evaluation by start date --- .../ByStartDateAggregator.php | 54 +++++++++++++++++-- .../translations/messages.fr.yml | 4 +- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php index e64245d53..a41fe2451 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php @@ -14,10 +14,23 @@ namespace Chill\PersonBundle\Export\Aggregator\EvaluationAggregators; use Chill\MainBundle\Export\AggregatorInterface; use Chill\PersonBundle\Export\Declarations; use Doctrine\ORM\QueryBuilder; +use LogicException; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class ByStartDateAggregator implements AggregatorInterface { + private const CHOICES = [ + 'by month' => 'month', + 'by week' => 'week', + 'by year' => 'year', + ]; + + private const DEFAULT_CHOICE = 'year'; + + private TranslatorInterface $translator; + public function addRole(): ?string { return null; @@ -25,8 +38,29 @@ class ByStartDateAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->addSelect('AS eval_by_start_date_aggregator') - ->addGroupBy('eval_by_start_date_aggregator'); + switch ($data['frequency']) { + case 'month': + $fmt = 'YYYY-MM'; + + break; + + case 'week': + $fmt = 'YYYY-IW'; + + break; + + case 'year': + $fmt = 'YYYY'; + + break; + + default: + throw new LogicException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); + } + + $qb->addSelect(sprintf("TO_CHAR(workeval.startDate, '%s') AS eval_by_start_date_aggregator", $fmt)); + $qb->addGroupBy(' eval_by_start_date_aggregator'); + $qb->addOrderBy(' eval_by_start_date_aggregator', 'ASC'); } public function applyOn(): string @@ -36,15 +70,27 @@ class ByStartDateAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { - // No form needed + $builder->add('frequency', ChoiceType::class, [ + 'choices' => self::CHOICES, + 'multiple' => false, + 'expanded' => true, + 'empty_data' => self::DEFAULT_CHOICE, + 'data' => self::DEFAULT_CHOICE, + ]); } public function getLabels($key, array $values, $data) { return static function ($value): string { if ('_header' === $value) { + return 'export.aggregator.eval.by_start_date_period.Start date period'; + } + + if (null === $value) { return ''; } + + return $value; }; } @@ -55,6 +101,6 @@ class ByStartDateAggregator implements AggregatorInterface public function getTitle(): string { - return 'Group by start date evaluations'; + return 'export.aggregator.eval.by_start_date_period.Group by start date evaluations'; } } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 89808d900..9f6eda592 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -585,7 +585,6 @@ end period date: Date de fin de la période "Filtered by end date: between %start_date% and %end_date%": "Filtré par la date de fin: comprise entre %start_date% et %end_date%" Filter by current evaluations: Filtrer les évaluations en cours "Filtered by current evaluations": "Filtré: uniquement les évaluations en cours" -Group by start date evaluations: Grouper les évaluations par semaine/mois/année de la date de début Group by end date evaluations: Grouper les évaluations par semaine/mois/année de la date de fin Group by max date evaluations: Grouper les évaluations par semaine/mois/année de la date d'échéance @@ -1021,6 +1020,9 @@ export: Group evaluations having end date: Grouper les évaluations en cours (avec ou sans date de fin) enddate is specified: la date de fin est spécifiée enddate is not specified: la date de fin n'est pas spécifiée + by_start_date_period: + Start date period: Début (par periode) + Group by start date evaluations: Grouper les évaluations par semaine/mois/année de la date de début filter: course: by_user_scope: