diff --git a/CHANGELOG.md b/CHANGELOG.md index 030b4ba33..df4dab422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to ## Unreleased +* [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person +* [activity][export] Feature: improve label for aliases in "Filter by activity type" +* [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository +* [person][export] Fixed: some inconsistency with date filter on accompanying courses +* [person][export] Fixed: use left join for related entities in accompanying course aggregators ## Test releases diff --git a/exports_alias_conventions.csv b/exports_alias_conventions.csv index 1215479d8..ab32cda8e 100644 --- a/exports_alias_conventions.csv +++ b/exports_alias_conventions.csv @@ -11,10 +11,10 @@ AccompanyingPeriod::class,,,acp ,User::class,acp.user,acpuser AccompanyingPeriodWork::class,,,acpw ,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval -,Goal::class,acpw.goals,goal ,User::class,acpw.referrers,acpwuser -,Result::class,acpw.results,acpwresult ,SocialAction::class,acpw.socialAction,acpwsocialaction +,Goal::class,acpw.goals,goal +,Result::class,acpw.results,result AccompanyingPeriodParticipation::class,,,acppart ,Person::class,acppart.person,partperson AccompanyingPeriodWorkEvaluation::class,,,workeval @@ -23,23 +23,23 @@ Goal::class,,,goal ,Result::class,goal.results,goalresult Person::class,,,person ,Center::class,person.center,center -,HouseholdMember::class,partperson.householdParticipations,member +,HouseholdMember::class,partperson.householdParticipations,householdmember ,MaritalStatus::class,person.maritalStatus,personmarital +,VendeePerson::class,,vp +,VendeePersonMineur::class,,vpm ResidentialAddress::class,,,resaddr -,Person::class,resaddr.person,resaddrperson -,Center::class,resaddrperson.center,resaddrcenter ,ThirdParty::class,resaddr.hostThirdParty,tparty ThirdParty::class,,,tparty ,ThirdPartyCategory::class,tparty.categories,tpartycat -HouseholdMember::class,,,member -,Household::class,member.household,household -,Person::class,member.person,memberperson +HouseholdMember::class,,,householdmember +,Household::class,householdmember.household,household +,Person::class,householdmember.person,memberperson ,,memberperson.center,membercenter Household::class,,,household ,HouseholdComposition::class,household.compositions,composition Activity::class,,,activity ,Person::class,activity.person,actperson -,AccompanyingPeriod::class,activity.accompanyingPeriod,actacp +,AccompanyingPeriod::class,activity.accompanyingPeriod,acp ,Person::class,activity_person_having_activity.person,person_person_having_activity ,ActivityReason::class,activity_person_having_activity.reasons,reasons_person_having_activity ,ActivityType::class,activity.activityType,acttype @@ -58,11 +58,6 @@ Calendar::class,,,cal ,Location::class,cal.location,calloc ,User::class,cal.user,caluser VendeePerson::class,,,vp -,Person::class,vp.person,vpperson -,Center::class,vpperson.center,vpcenter ,SituationProfessionelle::class,vp.situationProfessionelle,vpprof ,StatutLogement::class,vp.statutLogement,vplog ,TempsDeTravail::class,vp.tempsDeTravail,vptt -VendeePersonMineur::class,,,vpm -,Person::class,vpm.person,vpmperson -,Center::class,vpmperson.center,vpmcenter diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index 85973eec1..579d004a5 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -5,72 +5,67 @@ Add condition with distinct alias on each export join clauses (Indicators + Filt These are alias conventions : -| Entity | Join | Attribute | Alias | -| :--- | :--- |:-------------------------------------------|:----------------------------------| -| AccompanyingPeriod::class | | | acp | -| | AccompanyingPeriodWork::class | acp.works | acpw | -| | AccompanyingPeriodParticipation::class | acp.participations | acppart | -| | Location::class | acp.administrativeLocation | acploc | -| | ClosingMotive::class | acp.closingMotive | acpmotive | -| | UserJob::class | acp.job | acpjob | -| | Origin::class | acp.origin | acporigin | -| | Scope::class | acp.scopes | acpscope | -| | SocialIssue::class | acp.socialIssues | acpsocialissue | -| | User::class | acp.user | acpuser | -| AccompanyingPeriodWork::class | | | acpw | -| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | -| | Goal::class | acpw.goals | goal | -| | User::class | acpw.referrers | acpwuser | -| | Result::class | acpw.results | acpwresult | -| | SocialAction::class | acpw.socialAction | acpwsocialaction | -| AccompanyingPeriodParticipation::class | | | acppart | -| | Person::class | acppart.person | partperson | -| AccompanyingPeriodWorkEvaluation::class | | | workeval | -| | Evaluation::class | workeval.evaluation | eval | -| Goal::class | | | goal | -| | Result::class | goal.results | goalresult | -| Person::class | | | person | -| | Center::class | person.center | center | -| | HouseholdMember::class | partperson.householdParticipations | member | -| | MaritalStatus::class | person.maritalStatus | personmarital | -| ResidentialAddress::class | | | resaddr | -| | Person::class | resaddr.person | resaddrperson | -| | Center::class | resaddrperson.center | resaddrcenter | -| | ThirdParty::class | resaddr.hostThirdParty | tparty | -| ThirdParty::class | | | tparty | -| | ThirdPartyCategory::class | tparty.categories | tpartycat | -| HouseholdMember::class | | | member | -| | Household::class | member.household | household | -| | Person::class | member.person | memberperson | -| | | memberperson.center | membercenter | -| Household::class | | | household | -| | HouseholdComposition::class | household.compositions | composition | -| Activity::class | | | activity | -| | Person::class | activity.person | actperson | -| | AccompanyingPeriod::class | activity.accompanyingPeriod | actacp | -| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | -| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | -| | ActivityType::class | activity.activityType | acttype | -| | Location::class | activity.location | actloc | -| | SocialAction::class | activity.socialActions | actsocialaction | -| | SocialIssue::class | activity.socialIssues | actsocialssue | -| | ThirdParty::class | activity.thirdParties | acttparty | -| | User::class | activity.user | actuser | -| | User::class | activity.users | actusers | -| | ActivityReason::class | activity.reasons | actreasons | -| | Center::class | actperson.center | actcenter | -| ActivityReason::class | | | actreasons | -| | ActivityReasonCategory::class | actreason.category | actreasoncat | -| Calendar::class | | | cal | -| | CancelReason::class | cal.cancelReason | calcancel | -| | Location::class | cal.location | calloc | -| | User::class | cal.user | caluser | -| VendeePerson::class | | | vp | -| | Person::class | vp.person | vpperson | -| | Center::class | vpperson.center | vpcenter | -| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | -| | StatutLogement::class | vp.statutLogement | vplog | -| | TempsDeTravail::class | vp.tempsDeTravail | vptt | -| VendeePersonMineur::class | | | vpm | -| | Person::class | vpm.person | vpmperson | -| | Center::class | vpmperson.center | vpmcenter | +| Entity | Join | Attribute | Alias | +|:----------------------------------------|:----------------------------------------|:-------------------------------------------|:----------------------------------| +| AccompanyingPeriod::class | | | acp | +| | AccompanyingPeriodWork::class | acp.works | acpw | +| | AccompanyingPeriodParticipation::class | acp.participations | acppart | +| | Location::class | acp.administrativeLocation | acploc | +| | ClosingMotive::class | acp.closingMotive | acpmotive | +| | UserJob::class | acp.job | acpjob | +| | Origin::class | acp.origin | acporigin | +| | Scope::class | acp.scopes | acpscope | +| | SocialIssue::class | acp.socialIssues | acpsocialissue | +| | User::class | acp.user | acpuser | +| AccompanyingPeriodWork::class | | | acpw | +| | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | +| | User::class | acpw.referrers | acpwuser | +| | SocialAction::class | acpw.socialAction | acpwsocialaction | +| | Goal::class | acpw.goals | goal | +| | Result::class | acpw.results | result | +| AccompanyingPeriodParticipation::class | | | acppart | +| | Person::class | acppart.person | partperson | +| AccompanyingPeriodWorkEvaluation::class | | | workeval | +| | Evaluation::class | workeval.evaluation | eval | +| Goal::class | | | goal | +| | Result::class | goal.results | goalresult | +| Person::class | | | person | +| | Center::class | person.center | center | +| | HouseholdMember::class | partperson.householdParticipations | householdmember | +| | MaritalStatus::class | person.maritalStatus | personmarital | +| | VendeePerson::class | | vp | +| | VendeePersonMineur::class | | vpm | +| ResidentialAddress::class | | | resaddr | +| | ThirdParty::class | resaddr.hostThirdParty | tparty | +| ThirdParty::class | | | tparty | +| | ThirdPartyCategory::class | tparty.categories | tpartycat | +| HouseholdMember::class | | | householdmember | +| | Household::class | householdmember.household | household | +| | Person::class | householdmember.person | memberperson | +| | | memberperson.center | membercenter | +| Household::class | | | household | +| | HouseholdComposition::class | household.compositions | composition | +| Activity::class | | | activity | +| | Person::class | activity.person | actperson | +| | AccompanyingPeriod::class | activity.accompanyingPeriod | acp | +| | Person::class | activity\_person\_having\_activity.person | person\_person\_having\_activity | +| | ActivityReason::class | activity\_person\_having\_activity.reasons | reasons\_person\_having\_activity | +| | ActivityType::class | activity.activityType | acttype | +| | Location::class | activity.location | actloc | +| | SocialAction::class | activity.socialActions | actsocialaction | +| | SocialIssue::class | activity.socialIssues | actsocialssue | +| | ThirdParty::class | activity.thirdParties | acttparty | +| | User::class | activity.user | actuser | +| | User::class | activity.users | actusers | +| | ActivityReason::class | activity.reasons | actreasons | +| | Center::class | actperson.center | actcenter | +| ActivityReason::class | | | actreasons | +| | ActivityReasonCategory::class | actreason.category | actreasoncat | +| Calendar::class | | | cal | +| | CancelReason::class | cal.cancelReason | calcancel | +| | Location::class | cal.location | calloc | +| | User::class | cal.user | caluser | +| VendeePerson::class | | | vp | +| | SituationProfessionelle::class | vp.situationProfessionelle | vpprof | +| | StatutLogement::class | vp.statutLogement | vplog | +| | TempsDeTravail::class | vp.tempsDeTravail | vptt | diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index a147d2e1f..af5cb6272 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -17,7 +17,7 @@ use Chill\ActivityBundle\Form\ActivityType; use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface; use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository; -use Chill\ActivityBundle\Repository\ActivityTypeRepository; +use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Repository\LocationRepository; @@ -56,7 +56,7 @@ final class ActivityController extends AbstractController private ActivityTypeCategoryRepository $activityTypeCategoryRepository; - private ActivityTypeRepository $activityTypeRepository; + private ActivityTypeRepositoryInterface $activityTypeRepository; private CenterResolverManagerInterface $centerResolver; @@ -78,7 +78,7 @@ final class ActivityController extends AbstractController public function __construct( ActivityACLAwareRepositoryInterface $activityACLAwareRepository, - ActivityTypeRepository $activityTypeRepository, + ActivityTypeRepositoryInterface $activityTypeRepository, ActivityTypeCategoryRepository $activityTypeCategoryRepository, PersonRepository $personRepository, ThirdPartyRepository $thirdPartyRepository, @@ -91,7 +91,6 @@ final class ActivityController extends AbstractController SerializerInterface $serializer, UserRepositoryInterface $userRepository, CenterResolverManagerInterface $centerResolver - ) { $this->activityACLAwareRepository = $activityACLAwareRepository; $this->activityTypeRepository = $activityTypeRepository; @@ -107,7 +106,6 @@ final class ActivityController extends AbstractController $this->serializer = $serializer; $this->userRepository = $userRepository; $this->centerResolver = $centerResolver; - } /** diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index 845b31ca2..a2b15ee23 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -516,6 +516,11 @@ class ActivityType return $this->userVisible; } + public function hasCategory(): bool + { + return null !== $this->getCategory(); + } + /** * Is active * return true if the type is active. diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index f35fe6e6b..251f2e9d4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -41,18 +41,11 @@ class BySocialActionAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('actsocialaction', $qb->getAllAliases(), true)) { - $qb->join('activity.socialActions', 'actsocialaction'); + $qb->leftJoin('activity.socialActions', 'actsocialaction'); } $qb->addSelect('actsocialaction.id AS socialaction_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('socialaction_aggregator'); - } else { - $qb->groupBy('socialaction_aggregator'); - } + $qb->addGroupBy('socialaction_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class BySocialActionAggregator implements AggregatorInterface return 'Social action'; } + if (null === $value) { + return ''; + } + $sa = $this->actionRepository->find($value); return $this->actionRender->renderString($sa, []); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index 1126b9373..d7abcfd49 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -41,18 +41,11 @@ class BySocialIssueAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('actsocialissue', $qb->getAllAliases(), true)) { - $qb->join('activity.socialIssues', 'actsocialissue'); + $qb->leftJoin('activity.socialIssues', 'actsocialissue'); } $qb->addSelect('actsocialissue.id AS socialissue_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('socialissue_aggregator'); - } else { - $qb->groupBy('socialissue_aggregator'); - } + $qb->addGroupBy('socialissue_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class BySocialIssueAggregator implements AggregatorInterface return 'Social issues'; } + if (null === $value) { + return ''; + } + $i = $this->issueRepository->find($value); return $this->issueRender->renderString($i, []); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php index 4b56c6fc7..ebd813af4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php @@ -41,18 +41,11 @@ class ByThirdpartyAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acttparty', $qb->getAllAliases(), true)) { - $qb->join('activity.thirdParties', 'acttparty'); + $qb->leftJoin('activity.thirdParties', 'acttparty'); } $qb->addSelect('acttparty.id AS thirdparty_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('thirdparty_aggregator'); - } else { - $qb->groupBy('thirdparty_aggregator'); - } + $qb->addGroupBy('thirdparty_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class ByThirdpartyAggregator implements AggregatorInterface return 'Accepted thirdparty'; } + if (null === $value) { + return ''; + } + $tp = $this->thirdPartyRepository->find($value); return $this->thirdPartyRender->renderString($tp, []); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByUserAggregator.php index 3787e5286..9eb5c307e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByUserAggregator.php @@ -41,18 +41,11 @@ class ByUserAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('actusers', $qb->getAllAliases(), true)) { - $qb->join('activity.users', 'actusers'); + $qb->leftJoin('activity.users', 'actusers'); } $qb->addSelect('actusers.id AS users_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('users_aggregator'); - } else { - $qb->groupBy('users_aggregator'); - } + $qb->addGroupBy('users_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class ByUserAggregator implements AggregatorInterface return 'Accepted users'; } + if (null === $value) { + return ''; + } + $u = $this->userRepository->find($value); return $this->userRender->renderString($u, []); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index 5603b1b78..982f0d6ed 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -49,41 +49,24 @@ class DateAggregator implements AggregatorInterface switch ($data['frequency']) { case 'month': - $fmt = 'MM'; - -break; + $fmt = 'YYYY-MM'; + break; case 'week': - $fmt = 'IW'; - -break; + $fmt = 'YYYY-IW'; + break; case 'year': $fmt = 'YYYY'; $order = 'DESC'; - -break; // order DESC does not works ! + break; // order DESC does not works ! default: throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); } $qb->addSelect(sprintf("TO_CHAR(activity.date, '%s') AS date_aggregator", $fmt)); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('date_aggregator'); - } else { - $qb->groupBy('date_aggregator'); - } - - $orderBy = $qb->getDQLPart('orderBy'); - - if (!empty($orderBy)) { - $qb->addOrderBy('date_aggregator', $order); - } else { - $qb->orderBy('date_aggregator', $order); - } + $qb->addGroupBy('date_aggregator'); + $qb->addOrderBy('date_aggregator', $order); } public function applyOn(): string @@ -109,15 +92,12 @@ break; // order DESC does not works ! return 'by ' . $data['frequency']; } + if (null === $value) { + return ''; + } + switch ($data['frequency']) { case 'month': - $month = DateTime::createFromFormat('!m', $value); - - return sprintf( - '%02d (%s)', - $value, - $month->format('M') - ); case 'week': //return $this->translator->trans('for week') .' '. $value ; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php index d05c0eb41..a4c1087db 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php @@ -41,18 +41,11 @@ class LocationTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('actloc', $qb->getAllAliases(), true)) { - $qb->join('activity.location', 'actloc'); + $qb->leftJoin('activity.location', 'actloc'); } $qb->addSelect('IDENTITY(actloc.locationType) AS locationtype_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('locationtype_aggregator'); - } else { - $qb->groupBy('locationtype_aggregator'); - } + $qb->addGroupBy('locationtype_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class LocationTypeAggregator implements AggregatorInterface return 'Accepted locationtype'; } + if (null === $value) { + return ''; + } + $lt = $this->locationTypeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/UserScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/UserScopeAggregator.php index faaa08b8e..1b7041d9d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/UserScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/UserScopeAggregator.php @@ -41,18 +41,11 @@ class UserScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('actuser', $qb->getAllAliases(), true)) { - $qb->join('activity.user', 'actuser'); + $qb->leftJoin('activity.user', 'actuser'); } $qb->addSelect('IDENTITY(actuser.mainScope) AS userscope_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('userscope_aggregator'); - } else { - $qb->groupBy('userscope_aggregator'); - } + $qb->addGroupBy('userscope_aggregator'); } public function applyOn(): string @@ -72,6 +65,10 @@ class UserScopeAggregator implements AggregatorInterface return 'Scope'; } + if (null === $value) { + return ''; + } + $s = $this->scopeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index 5c285ca3e..74df67d22 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; -use Chill\ActivityBundle\Repository\ActivityTypeRepository; +use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Closure; @@ -25,12 +25,12 @@ class ActivityTypeAggregator implements AggregatorInterface { public const KEY = 'activity_type_aggregator'; - protected ActivityTypeRepository $activityTypeRepository; + protected ActivityTypeRepositoryInterface $activityTypeRepository; protected TranslatableStringHelperInterface $translatableStringHelper; public function __construct( - ActivityTypeRepository $activityTypeRepository, + ActivityTypeRepositoryInterface $activityTypeRepository, TranslatableStringHelperInterface $translatableStringHelper ) { $this->activityTypeRepository = $activityTypeRepository; @@ -49,14 +49,7 @@ class ActivityTypeAggregator implements AggregatorInterface } $qb->addSelect(sprintf('IDENTITY(activity.activityType) AS %s', self::KEY)); - - $groupby = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy(self::KEY); - } else { - $qb->groupBy(self::KEY); - } + $qb->addGroupBy(self::KEY); } public function applyOn(): string @@ -79,6 +72,10 @@ class ActivityTypeAggregator implements AggregatorInterface return 'Activity type'; } + if (null === $value) { + return ''; + } + $t = $this->activityTypeRepository->find($value); return $this->translatableStringHelper->localize($t->getName()); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 39c7c52cb..8e29f9cb0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -61,14 +61,15 @@ class ActivityUserAggregator implements AggregatorInterface public function getLabels($key, $values, $data): Closure { - // preload users at once - $this->userRepository->findBy(['id' => $values]); - - return function ($value) { + return function ($value) { if ('_header' === $value) { return 'Activity user'; } + if (null === $value) { + return ''; + } + $u = $this->userRepository->find($value); return $this->userRender->renderString($u, []); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index 9d7cd3116..f82793e71 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -55,10 +55,10 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali { // add select element if ('reasons' === $data['level']) { - $elem = 'reasons.id'; + $elem = 'actreasons.id'; $alias = 'activity_reasons_id'; } elseif ('categories' === $data['level']) { - $elem = 'category.id'; + $elem = 'actreasoncat.id'; $alias = 'activity_categories_id'; } else { throw new RuntimeException('The data provided are not recognized.'); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index b2346b8fd..3fc975147 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -17,6 +17,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; +use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; @@ -34,7 +35,6 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function buildForm(FormBuilderInterface $builder) { - // TODO: Implement buildForm() method. } public function getAllowedFormattersTypes(): array @@ -55,7 +55,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_avg_activity_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period duration' : $value; @@ -83,10 +83,12 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $qb = $this->repository->createQueryBuilder('activity') - ->join('activity.accompanyingPeriod', 'actacp'); + $qb = $this->repository->createQueryBuilder('activity'); - $qb->select('AVG(activity.durationTime) as export_avg_activity_duration'); + $qb + ->join('activity.accompanyingPeriod', 'acp') + ->select('AVG(activity.durationTime) as export_avg_activity_duration') + ->andWhere($qb->expr()->isNotNull('activity.durationTime')); return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index 0195992fe..69533a09d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -17,6 +17,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; +use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; @@ -55,7 +56,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function getLabels($key, array $values, $data) { if ('export_avg_activity_visit_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period visit duration' : $value; @@ -83,10 +84,13 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $qb = $this->repository->createQueryBuilder('activity') - ->join('activity.accompanyingPeriod', 'actacp'); + $qb = $this->repository->createQueryBuilder('activity'); - $qb->select('AVG(activity.travelTime) as export_avg_activity_visit_duration'); + $qb + ->join('activity.accompanyingPeriod', 'acp') + ->select('AVG(activity.travelTime) as export_avg_activity_visit_duration') + ->andWhere($qb->expr()->isNotNull('activity.travelTime')) + ; return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index e4202c33a..2162b8b58 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -86,11 +86,11 @@ class CountActivity implements ExportInterface, GroupedExportInterface { $qb = $this->repository->createQueryBuilder('activity'); - if (!in_array('actacp', $qb->getAllAliases(), true)) { - $qb->join('activity.accompanyingPeriod', 'actacp'); + if (!in_array('acp', $qb->getAllAliases(), true)) { + $qb->join('activity.accompanyingPeriod', 'acp'); } - $qb->select('COUNT(activity.id) as export_count_activity'); + $qb->select('COUNT(DISTINCT activity.id) as export_count_activity'); return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index 2e87623ef..e9dbaff29 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -17,6 +17,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; +use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; @@ -55,7 +56,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_sum_activity_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period duration' : $value; @@ -85,11 +86,12 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface { $qb = $this->repository->createQueryBuilder('activity'); - if (!in_array('actacp', $qb->getAllAliases(), true)) { - $qb->join('activity.accompanyingPeriod', 'actacp'); + if (!in_array('acp', $qb->getAllAliases(), true)) { + $qb->join('activity.accompanyingPeriod', 'acp'); } - $qb->select('SUM(activity.durationTime) as export_sum_activity_duration'); + $qb->select('SUM(activity.durationTime) as export_sum_activity_duration') + ->andWhere($qb->expr()->isNotNull('activity.durationTime')); return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index 5bb6d542e..d41994562 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -17,6 +17,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; +use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; @@ -55,7 +56,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function getLabels($key, array $values, $data) { if ('export_sum_activity_visit_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period visit duration' : $value; @@ -85,11 +86,12 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac { $qb = $this->repository->createQueryBuilder('activity'); - if (!in_array('actacp', $qb->getAllAliases(), true)) { - $qb->join('activity.accompanyingPeriod', 'actacp'); + if (!in_array('acp', $qb->getAllAliases(), true)) { + $qb->join('activity.accompanyingPeriod', 'acp'); } - $qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration'); + $qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration') + ->andWhere($qb->expr()->isNotNull('activity.travelTime')); return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 398fb14bb..f12507df8 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -86,8 +86,8 @@ class CountActivity implements ExportInterface, GroupedExportInterface $qb = $this->activityRepository->createQueryBuilder('activity'); - if (!in_array('actperson', $qb->getAllAliases(), true)) { - $qb->join('activity.person', 'actperson'); + if (!in_array('person', $qb->getAllAliases(), true)) { + $qb->join('activity.person', 'person'); } $qb->select('COUNT(activity.id) as export_count_activity'); @@ -109,7 +109,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface return [ Declarations::ACTIVITY, Declarations::ACTIVITY_PERSON, - //PersonDeclarations::PERSON_TYPE, + PersonDeclarations::PERSON_TYPE, ]; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index 17b9bd687..78368b0eb 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -210,7 +210,7 @@ class ListActivity implements ListInterface, GroupedExportInterface $qb ->from('ChillActivityBundle:Activity', 'activity') - ->join('activity.person', 'actperson') + ->join('activity.person', 'person') ->join('actperson.center', 'actcenter') ->andWhere('actcenter IN (:authorized_centers)') ->setParameter('authorized_centers', $centers); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php index bcb4da05d..9013b4648 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php @@ -120,7 +120,7 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface } return $qb->select($select) - ->join('activity.person', 'actperson') + ->join('activity.person', 'person') ->join('actperson.center', 'actcenter') ->where($qb->expr()->in('actcenter', ':centers')) ->setParameter(':centers', $centers); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php similarity index 54% rename from src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php rename to src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index f76a00c33..d17a6af99 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -9,26 +9,31 @@ declare(strict_types=1); -namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; +namespace Chill\ActivityBundle\Export\Filter\ACPFilters; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; +use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\FilterInterface; -use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; -/** - * TODO merge with ActivityTypeFilter in ChillActivity (!?). - */ class ActivityTypeFilter implements FilterInterface { - private TranslatableStringHelper $translatableStringHelper; + private ActivityTypeRepositoryInterface $activityTypeRepository; - public function __construct(TranslatableStringHelper $translatableStringHelper) - { + private TranslatableStringHelperInterface $translatableStringHelper; + + public function __construct( + ActivityTypeRepositoryInterface $activityTypeRepository, + TranslatableStringHelperInterface $translatableStringHelper + ) { + $this->activityTypeRepository = $activityTypeRepository; $this->translatableStringHelper = $translatableStringHelper; } @@ -39,31 +44,14 @@ class ActivityTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - // One2many between activity and accompanyingperiod is not reversed ! - // we replace indicator 'from' clause by 'act', and put 'acp' in a join - - $qb->resetDQLPart('from'); - $qb->from('ChillActivityBundle:Activity', 'activity'); - - if (!in_array('actacp', $qb->getAllAliases(), true)) { - $qb->join('activity.accompanyingPeriod', 'actacp'); + if (!in_array('activity', $qb->getAllAliases(), true)) { + $qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp'); } - if (!in_array('acttype', $qb->getAllAliases(), true)) { - $qb->join('activity.activityType', 'acttype'); - } + $clause = $qb->expr()->in('activity.activityType', ':selected_activity_types'); - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('acttype.id', ':activitytypes'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('activitytypes', $data['accepted_activitytypes']); + $qb->andWhere($clause); + $qb->setParameter('selected_activity_types', $data['types']); } public function applyOn() @@ -75,8 +63,12 @@ class ActivityTypeFilter implements FilterInterface { $builder->add('accepted_activitytypes', EntityType::class, [ 'class' => ActivityType::class, + 'choices' => $this->activityTypeRepository->findAllActive(), 'choice_label' => function (ActivityType $aty) { - return $this->translatableStringHelper->localize($aty->getName()); + return + ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + . + $this->translatableStringHelper->localize($aty->getName()); }, 'multiple' => true, 'expanded' => true, @@ -92,7 +84,7 @@ class ActivityTypeFilter implements FilterInterface } return ['Filtered by activity types: only %activitytypes%', [ - '%activitytypes%' => implode(', ou ', $types), + '%activitytypes%' => implode(', ', $types), ]]; } diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index 77d887fdf..7442fabb7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -13,7 +13,7 @@ namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Entity\ActivityType; use Chill\ActivityBundle\Export\Declarations; -use Chill\ActivityBundle\Repository\ActivityTypeRepository; +use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; @@ -28,13 +28,13 @@ use function count; class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInterface { - protected ActivityTypeRepository $activityTypeRepository; + protected ActivityTypeRepositoryInterface $activityTypeRepository; protected TranslatableStringHelperInterface $translatableStringHelper; public function __construct( TranslatableStringHelperInterface $translatableStringHelper, - ActivityTypeRepository $activityTypeRepository + ActivityTypeRepositoryInterface $activityTypeRepository ) { $this->translatableStringHelper = $translatableStringHelper; $this->activityTypeRepository = $activityTypeRepository; @@ -47,16 +47,9 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter public function alterQuery(QueryBuilder $qb, $data) { - $where = $qb->getDQLPart('where'); $clause = $qb->expr()->in('activity.activityType', ':selected_activity_types'); - if ($where instanceof Expr\Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); + $qb->andWhere($clause); $qb->setParameter('selected_activity_types', $data['types']); } @@ -68,11 +61,26 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter public function buildForm(FormBuilderInterface $builder) { $builder->add('types', EntityType::class, [ + 'choices' => $this->activityTypeRepository->findAllActive(), 'class' => ActivityType::class, - 'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()), - 'group_by' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getCategory()->getName()), + 'choice_label' => function (ActivityType $aty) { + return + ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + . + $this->translatableStringHelper->localize($aty->getName()); + }, + 'group_by' => function (ActivityType $type) { + if (!$type->hasCategory()) { + return null; + } + + return $this->translatableStringHelper->localize($type->getCategory()->getName()); + }, 'multiple' => true, 'expanded' => false, + 'attr' => [ + 'class' => 'select2' + ] ]); } diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index 8db312e35..c15411b4e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Filter\PersonFilters; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\MainBundle\Export\ExportElementValidatedInterface; @@ -59,10 +60,10 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt public function alterQuery(QueryBuilder $qb, $data) { - // create a query for activity + // create a subquery for activity $sqb = $qb->getEntityManager()->createQueryBuilder(); $sqb->select('person_person_having_activity.id') - ->from('ChillActivityBundle:Activity', 'activity_person_having_activity') + ->from(Activity::class, 'activity_person_having_activity') ->join('activity_person_having_activity.person', 'person_person_having_activity'); // add clause between date @@ -197,7 +198,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt public function getTitle() { - return 'Filtered by person having an activity in a period'; + return 'Filter by person having an activity in a period'; } public function validateForm($data, ExecutionContextInterface $context) diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php index dc6328709..8140043a4 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Form\Type; use Chill\ActivityBundle\Entity\ActivityType; -use Chill\ActivityBundle\Repository\ActivityTypeRepository; +use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\QueryBuilder; @@ -23,37 +23,25 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class TranslatableActivityType extends AbstractType { - protected ActivityTypeRepository $activityTypeRepository; + protected ActivityTypeRepositoryInterface $activityTypeRepository; protected TranslatableStringHelperInterface $translatableStringHelper; public function __construct( TranslatableStringHelperInterface $helper, - ActivityTypeRepository $activityTypeRepository + ActivityTypeRepositoryInterface $activityTypeRepository ) { $this->translatableStringHelper = $helper; $this->activityTypeRepository = $activityTypeRepository; } - public function buildForm(FormBuilderInterface $builder, array $options) - { - /** @var QueryBuilder $qb */ - $qb = $options['query_builder']; - - if (true === $options['active_only']) { - $qb->where($qb->expr()->eq('at.active', ':active')); - $qb->setParameter('active', true, Types::BOOLEAN); - } - } - public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults( [ 'class' => ActivityType::class, 'active_only' => true, - 'query_builder' => $this->activityTypeRepository - ->createQueryBuilder('at'), + 'choices' => $this->activityTypeRepository->findAllActive(), 'choice_label' => function (ActivityType $type) { return $this->translatableStringHelper->localize($type->getName()); }, diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php index 735b70054..aee3706cf 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php @@ -13,18 +13,58 @@ namespace Chill\ActivityBundle\Repository; use Chill\ActivityBundle\Entity\ActivityType; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Doctrine\Persistence\ManagerRegistry; +use UnexpectedValueException; -/** - * @method ActivityType|null find($id, $lockMode = null, $lockVersion = null) - * @method ActivityType|null findOneBy(array $criteria, array $orderBy = null) - * @method ActivityType[] findAll() - * @method ActivityType[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) - */ -class ActivityTypeRepository extends ServiceEntityRepository +final class ActivityTypeRepository implements ActivityTypeRepositoryInterface { - public function __construct(ManagerRegistry $registry) + private EntityRepository $repository; + + public function __construct(EntityManagerInterface $em) { - parent::__construct($registry, ActivityType::class); + $this->repository = $em->getRepository(ActivityType::class); } + + /** + * @return array|ActivityType[] + */ + public function findAllActive(): array + { + return $this->findBy(['active' => true]); + } + + public function find($id): ?ActivityType + { + return $this->repository->find($id); + } + + /** + * @return array|ActivityType[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array|ActivityType[] + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?ActivityType + { + return $this->repository->findOneBy($criteria); + } + + public function getClassName(): string + { + return ActivityType::class; + } + + } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php new file mode 100644 index 000000000..533798e5e --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php @@ -0,0 +1,15 @@ +helper = $helper; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(Center::class, [self::STATS, self::LISTS]) + ->build(); } public function getRoles(): array @@ -49,30 +49,14 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar return $this->getAttributes(); } - protected function getSupportedClasses() + protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { - return [Center::class]; - } - - protected function isGranted($attribute, $object, $user = null) - { - if (!$user instanceof \Symfony\Component\Security\Core\User\UserInterface) { - return false; - } - - return $this->helper->userHasAccess($user, $object, $attribute); + return $this->helper->voteOnAttribute($attribute, $subject, $token); } protected function supports($attribute, $subject) { - if ( - $subject instanceof Center - && in_array($attribute, $this->getAttributes(), true) - ) { - return true; - } - - return false; + return $this->helper->supports($attribute, $subject); } private function getAttributes() diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php new file mode 100644 index 000000000..d9b3a8cfb --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.bysocialaction_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.socialActions', 'actsocialaction') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php new file mode 100644 index 000000000..87e8462db --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.bysocialissue_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.socialIssues', 'actsocialissue') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByThirdpartyAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByThirdpartyAggregatorTest.php new file mode 100644 index 000000000..c9a824dc3 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByThirdpartyAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.bythirdparty_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.thirdParties', 'acttparty') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByUserAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByUserAggregatorTest.php new file mode 100644 index 000000000..00243ce68 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/ByUserAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.byuser_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.users', 'actusers') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/DateAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/DateAggregatorTest.php new file mode 100644 index 000000000..c5a1b083c --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/DateAggregatorTest.php @@ -0,0 +1,66 @@ +aggregator = self::$container->get('chill.activity.export.date_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'frequency' => 'month', + ], + [ + 'frequency' => 'week', + ], + [ + 'frequency' => 'year', + ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/LocationTypeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/LocationTypeAggregatorTest.php new file mode 100644 index 000000000..69be2c900 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/LocationTypeAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.locationtype_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.location', 'actloc') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/UserScopeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/UserScopeAggregatorTest.php new file mode 100644 index 000000000..73943ce7f --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/UserScopeAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.activity.export.userscope_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.accompanyingPeriod', 'acp') + ->join('activity.user', 'actuser') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityReasonAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityReasonAggregatorTest.php index 436bfc697..79c0924f7 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityReasonAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityReasonAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator; +use Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; /** @@ -21,10 +22,7 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest; */ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator - */ - private $aggregator; + private ActivityReasonAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php index f6efe17a5..bd88a7d3b 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator; +use Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityTypeAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; /** @@ -21,10 +22,7 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest; */ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator - */ - private $aggregator; + private ActivityTypeAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php index 1447f473b..0e620040f 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator; +use Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; /** @@ -21,10 +22,7 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest; */ final class ActivityUserAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator - */ - private $aggregator; + private ActivityUserAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php new file mode 100644 index 000000000..6de364ae7 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php @@ -0,0 +1,65 @@ +aggregator = self::$container->get('chill.activity.export.reason_aggregator'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'level' => 'reasons', + ], + [ + 'level' => 'categories', + ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.person', 'actperson') + ->innerJoin('activity.reasons', 'actreasons') + ->join('actreasons.category', 'actreasoncat') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php new file mode 100644 index 000000000..10f16247e --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php @@ -0,0 +1,85 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.filter_activitytype'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(ActivityType::class, 'at') + ->select('at') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_activitytypes' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp') + ->join('activity.activityType', 'acttype'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php new file mode 100644 index 000000000..1480e3569 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.bysocialaction_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(SocialAction::class, 'sa') + ->select('sa') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_socialactions' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.socialActions', 'actsocialaction'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php new file mode 100644 index 000000000..6af3ea97c --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php @@ -0,0 +1,83 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.bysocialissue_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(SocialIssue::class, 'si') + ->select('si') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_socialissues' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.socialIssues', 'actsocialissue') + , + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByUserFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByUserFilterTest.php new file mode 100644 index 000000000..93810433d --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByUserFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.byuser_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(User::class, 'u') + ->select('u') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_users' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.users', 'actusers'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/EmergencyFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/EmergencyFilterTest.php new file mode 100644 index 000000000..d90523bed --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/EmergencyFilterTest.php @@ -0,0 +1,67 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.emergency_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + ['accepted_emergency' => true ], + ['accepted_emergency' => false ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/LocationTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/LocationTypeFilterTest.php new file mode 100644 index 000000000..dcac884b9 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/LocationTypeFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.locationtype_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(LocationType::class, 'lt') + ->select('lt') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_locationtype' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.location', 'actloc'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/SentReceivedFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/SentReceivedFilterTest.php new file mode 100644 index 000000000..b40443ee4 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/SentReceivedFilterTest.php @@ -0,0 +1,67 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.sentreceived_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + ['accepted_sentreceived' => Activity::SENTRECEIVED_SENT ], + ['accepted_sentreceived' => Activity::SENTRECEIVED_RECEIVED ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserFilterTest.php new file mode 100644 index 000000000..cc1a1b81a --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserFilterTest.php @@ -0,0 +1,81 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.user_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(User::class, 'u') + ->select('u') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_users' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserScopeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserScopeFilterTest.php new file mode 100644 index 000000000..31ff8ca57 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/UserScopeFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.userscope_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(Scope::class, 's') + ->select('s') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_userscope' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.user', 'actuser'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php new file mode 100644 index 000000000..b65d3808d --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php @@ -0,0 +1,69 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.date_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2020-01-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2021-01-01'), + ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php index 5b8ae08c3..72f052f54 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Filter; +use Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; use Doctrine\Common\Collections\ArrayCollection; @@ -20,10 +21,7 @@ use Doctrine\Common\Collections\ArrayCollection; */ final class ActivityReasonFilterTest extends AbstractFilterTest { - /** - * @var \Chill\PersonBundle\Export\Filter\GenderFilter - */ - private $filter; + private ActivityReasonFilter $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php similarity index 72% rename from src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilterTest.php rename to src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php index bce092b6e..12ace7c67 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/ActivityTypeFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php @@ -9,13 +9,13 @@ declare(strict_types=1); -namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters; +namespace Chill\ActivityBundle\Tests\Export\Filter; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; +use Chill\ActivityBundle\Export\Filter\ActivityTypeFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActivityTypeFilter; use Doctrine\ORM\EntityManagerInterface; -use Symfony\Component\HttpFoundation\Request; /** * @internal @@ -27,16 +27,15 @@ final class ActivityTypeFilterTest extends AbstractFilterTest protected function setUp(): void { - //parent::setUp(); self::bootKernel(); // add a fake request with a default locale (used in translatable string) $request = $this->prophesize(); - $request->willExtend(Request::class); + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->getLocale()->willReturn('fr'); - $this->filter = self::$container->get('chill.person.export.filter_activitytype'); + $this->filter = self::$container->get('chill.activity.export.type_filter'); } public function getFilter() @@ -56,8 +55,10 @@ final class ActivityTypeFilterTest extends AbstractFilterTest $data = []; - foreach ($array as $t) { - $data[] = ['accepted_activitytypes' => $t]; + foreach ($array as $a) { + $data[] = [ + 'types' => $a + ]; } return $data; @@ -73,8 +74,8 @@ final class ActivityTypeFilterTest extends AbstractFilterTest return [ $em->createQueryBuilder() - ->from('ChillPersonBundle:AccompanyingPeriod', 'acp') - ->select('acp.id'), + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php new file mode 100644 index 000000000..e6b14b44c --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.reason_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(ActivityReason::class, 'ar') + ->select('ar') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'reasons' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.reasons', 'actreasons'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php new file mode 100644 index 000000000..5cad68da4 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php @@ -0,0 +1,83 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.activity.export.person_having_an_activity_between_date_filter'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(ActivityReason::class, 'ar') + ->select('ar') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2021-07-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2022-07-01'), + 'reasons' => $a + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php index 94d99c2a7..507f03323 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Filter; +use Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; use DateTime; use function array_slice; @@ -21,10 +22,7 @@ use function array_slice; */ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest { - /** - * @var \Chill\PersonBundle\Export\Filter\PersonHavingActivityBetweenDateFilter - */ - private $filter; + private PersonHavingActivityBetweenDateFilter $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index c88046c5f..bdaae8c8a 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -67,6 +67,11 @@ services: name: chill.export_filter alias: 'activity_person_having_ac_bw_date_filter' + chill.activity.export.filter_activitytype: + class: Chill\ActivityBundle\Export\Filter\ACPFilters\ActivityTypeFilter + tags: + - { name: chill.export_filter, alias: 'accompanyingcourse_activitytype_filter' } + chill.activity.export.locationtype_filter: class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter tags: diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php index 013b465d5..beeb055e1 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php @@ -127,7 +127,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface public function setLocation(?Location $location): self { $this->location = $location; - + return $this; } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php index 7e7d55739..402da0b73 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php @@ -143,7 +143,7 @@ class MapCalendarToUser public function writeMetadata(User $user): User { - if (null === $user->getEmail() OR '' === $user->getEmail()) { + if (null === $user->getEmail() || '' === $user->getEmail()) { return $user; } diff --git a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml index 56580dba1..0526ce1dc 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml +++ b/src/Bundle/ChillCalendarBundle/Resources/config/services/exports.yaml @@ -1,104 +1,104 @@ -services: - - ## Indicators - chill.calendar.export.count_appointments: - class: Chill\CalendarBundle\Export\Export\CountAppointments - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: count_appointments } - - chill.calendar.export.average_duration_appointments: - class: Chill\CalendarBundle\Export\Export\StatAppointmentAvgDuration - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: average_duration_appointments } - - chill.calendar.export.sum_duration_appointments: - class: Chill\CalendarBundle\Export\Export\StatAppointmentSumDuration - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: sum_duration_appointments } - - ## Filters - - chill.calendar.export.agent_filter: - class: Chill\CalendarBundle\Export\Filter\AgentFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: agent_filter } - - chill.calendar.export.job_filter: - class: Chill\CalendarBundle\Export\Filter\JobFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: job_filter } - - chill.calendar.export.scope_filter: - class: Chill\CalendarBundle\Export\Filter\ScopeFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: scope_filter } - - chill.calendar.export.between_dates_filter: - class: Chill\CalendarBundle\Export\Filter\BetweenDatesFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: between_dates_filter } - - ## Aggregator - - chill.calendar.export.agent_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\AgentAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: agent_aggregator } - - chill.calendar.export.job_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\JobAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: job_aggregator } - - chill.calendar.export.scope_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\ScopeAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: scope_aggregator } - - chill.calendar.export.location_type_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\LocationTypeAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: location_type_aggregator } - - chill.calendar.export.location_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\LocationAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: location_aggregator } - - chill.calendar.export.cancel_reason_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\CancelReasonAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: cancel_reason_aggregator } - - chill.calendar.export.month_aggregator: - class: Chill\CalendarBundle\Export\Aggregator\MonthYearAggregator - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: month_aggregator } \ No newline at end of file +#services: +# + # Indicators +# chill.calendar.export.count_appointments: +# class: Chill\CalendarBundle\Export\Export\CountAppointments +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export, alias: count_appointments } +# +# chill.calendar.export.average_duration_appointments: +# class: Chill\CalendarBundle\Export\Export\StatAppointmentAvgDuration +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export, alias: average_duration_appointments } +# +# chill.calendar.export.sum_duration_appointments: +# class: Chill\CalendarBundle\Export\Export\StatAppointmentSumDuration +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export, alias: sum_duration_appointments } +# + # Filters +# +# chill.calendar.export.agent_filter: +# class: Chill\CalendarBundle\Export\Filter\AgentFilter +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_filter, alias: agent_filter } +# +# chill.calendar.export.job_filter: +# class: Chill\CalendarBundle\Export\Filter\JobFilter +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_filter, alias: job_filter } +# +# chill.calendar.export.scope_filter: +# class: Chill\CalendarBundle\Export\Filter\ScopeFilter +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_filter, alias: scope_filter } +# +# chill.calendar.export.between_dates_filter: +# class: Chill\CalendarBundle\Export\Filter\BetweenDatesFilter +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_filter, alias: between_dates_filter } +# + # Aggregator +# +# chill.calendar.export.agent_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\AgentAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: agent_aggregator } +# +# chill.calendar.export.job_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\JobAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: job_aggregator } +# +# chill.calendar.export.scope_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\ScopeAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: scope_aggregator } +# +# chill.calendar.export.location_type_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\LocationTypeAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: location_type_aggregator } +# +# chill.calendar.export.location_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\LocationAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: location_aggregator } +# +# chill.calendar.export.cancel_reason_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\CancelReasonAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: cancel_reason_aggregator } +# +# chill.calendar.export.month_aggregator: +# class: Chill\CalendarBundle\Export\Aggregator\MonthYearAggregator +# autowire: true +# autoconfigure: true +# tags: +# - { name: chill.export_aggregator, alias: month_aggregator } diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index 5c95aaebe..b8b1e2e56 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -102,4 +102,3 @@ Job: Métier Location type: Type de localisation Location: Lieu de rendez-vous by month and year: Par mois et année - diff --git a/src/Bundle/ChillEventBundle/migrations/Version20160318111334.php b/src/Bundle/ChillEventBundle/migrations/Version20160318111334.php index e879f1d29..241003abf 100644 --- a/src/Bundle/ChillEventBundle/migrations/Version20160318111334.php +++ b/src/Bundle/ChillEventBundle/migrations/Version20160318111334.php @@ -126,7 +126,7 @@ class Version20160318111334 extends AbstractMigration $this->addSql('ALTER TABLE chill_event_participation ' . 'ADD CONSTRAINT FK_4E7768AC217BBB47 ' . 'FOREIGN KEY (person_id) ' - . 'REFERENCES chill_person_person(id) ' + . 'REFERENCES Person (id) ' . 'NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE chill_event_participation ' . 'ADD CONSTRAINT FK_4E7768ACD60322AC ' diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 3d9760dad..4ced2cacc 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -142,10 +143,8 @@ class ExportController extends AbstractController /** * Render the list of available exports. - * - * @return \Symfony\Component\HttpFoundation\Response */ - public function indexAction(Request $request) + public function indexAction(): Response { $exportManager = $this->exportManager; diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index 671a431ff..ba15d0cc0 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Export; use Chill\MainBundle\Form\Type\Export\ExportType; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Generator; @@ -42,52 +43,38 @@ class ExportManager /** * The collected aggregators, injected by DI. * - * @var AggregatorInterface[] + * @var array|AggregatorInterface[] */ - private $aggregators = []; + private array $aggregators = []; - /** - * @var AuthorizationChecker - */ - private $authorizationChecker; + private AuthorizationCheckerInterface $authorizationChecker; - /** - * @var AuthorizationHelper - */ - private $authorizationHelper; + private AuthorizationHelperInterface $authorizationHelper; - /** - * @var EntityManagerInterface - */ - private $em; + private EntityManagerInterface $em; /** * Collected Exports, injected by DI. * - * @var ExportInterface[] + * @var array|ExportInterface[] */ - private $exports = []; + private array $exports = []; /** * The collected filters, injected by DI. * - * @var FilterInterface[] + * @var array|FilterInterface[] */ - private $filters = []; + private array $filters = []; /** * Collected Formatters, injected by DI. * - * @var FormatterInterface[] + * @var array|FormatterInterface[] */ - private $formatters = []; + private array $formatters = []; - /** - * a logger. - * - * @var LoggerInterface - */ - private $logger; + private LoggerInterface $logger; /** * @var \Symfony\Component\Security\Core\User\UserInterface @@ -98,7 +85,7 @@ class ExportManager LoggerInterface $logger, EntityManagerInterface $em, AuthorizationCheckerInterface $authorizationChecker, - AuthorizationHelper $authorizationHelper, + AuthorizationHelperInterface $authorizationHelper, TokenStorageInterface $tokenStorage ) { $this->logger = $logger; @@ -549,19 +536,16 @@ class ExportManager . 'an ExportInterface.'); } - if (null === $centers) { - $centers = $this->authorizationHelper->getReachableCenters( + if (null === $centers || [] !== $centers) { + // we want to try if at least one center is reachabler + return [] !== $this->authorizationHelper->getReachableCenters( $this->user, $role ); } - if (count($centers) === 0) { - return false; - } - foreach ($centers as $center) { - if ($this->authorizationChecker->isGranted($role, $center) === false) { + if (false === $this->authorizationChecker->isGranted($role, $center)) { //debugging $this->logger->debug('user has no access to element', [ 'method' => __METHOD__, @@ -570,10 +554,6 @@ class ExportManager 'role' => $role, ]); - ///// Bypasse les autorisations qui empêche d'afficher les nouveaux exports - return true; - ///// TODO supprimer le return true - return false; } } diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php index 86c304508..ab9b2d660 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php @@ -230,7 +230,8 @@ class SpreadSheetFormatter implements FormatterInterface $worksheet->fromArray( $sortedResults, null, - 'A' . $line + 'A' . $line, + true ); return $line + count($sortedResults) + 1; @@ -495,8 +496,13 @@ class SpreadSheetFormatter implements FormatterInterface // 3. iterate on `keysExportElementAssociation` to store the callable // in cache foreach ($keysExportElementAssociation as $key => [$element, $data]) { - $this->cacheDisplayableResult[$key] = - $element->getLabels($key, array_unique($allValues[$key]), $data); + // handle the case when there is not results lines (query is empty) + if ([] === $allValues) { + $this->cacheDisplayableResult[$key] = $element->getLabels($key, ['_header'], $data); + } else { + $this->cacheDisplayableResult[$key] = + $element->getLabels($key, array_unique($allValues[$key]), $data); + } } // the cache is initialized ! diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index c73402dd3..07776cb71 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Center\GroupingCenterInterface; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Export\ExportManager; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; @@ -24,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\User\UserInterface; use function array_intersect; use function array_key_exists; use function array_merge; @@ -38,30 +40,24 @@ class PickCenterType extends AbstractType { public const CENTERS_IDENTIFIERS = 'c'; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; + protected AuthorizationHelperInterface $authorizationHelper; + + protected ExportManager $exportManager; /** - * @var ExportManager + * @var array|GroupingCenterInterface[] */ - protected $exportManager; - - /** - * @var GroupingCenterInterface[] - */ - protected $groupingCenters = []; + protected array $groupingCenters = []; /** * @var \Symfony\Component\Security\Core\User\UserInterface */ - protected $user; + protected UserInterface $user; public function __construct( TokenStorageInterface $tokenStorage, ExportManager $exportManager, - AuthorizationHelper $authorizationHelper + AuthorizationHelperInterface $authorizationHelper ) { $this->exportManager = $exportManager; $this->user = $tokenStorage->getToken()->getUser(); @@ -78,22 +74,12 @@ class PickCenterType extends AbstractType $export = $this->exportManager->getExport($options['export_alias']); $centers = $this->authorizationHelper->getReachableCenters( $this->user, - (string) $export->requiredRole() + $export->requiredRole() ); $builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [ 'class' => Center::class, - 'query_builder' => static function (EntityRepository $er) use ($centers) { - $qb = $er->createQueryBuilder('c'); - $ids = array_map( - static function (Center $el) { - return $el->getId(); - }, - $centers - ); - - return $qb->where($qb->expr()->in('c.id', $ids)); - }, + 'choices' => $centers, 'multiple' => true, 'expanded' => true, 'choice_label' => static function (Center $c) { diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php index 554f39880..d8e54d1c4 100644 --- a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php @@ -16,7 +16,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\Persistence\ObjectRepository; -final class CenterRepository implements ObjectRepository +final class CenterRepository implements CenterRepositoryInterface { private EntityRepository $repository; @@ -30,6 +30,11 @@ final class CenterRepository implements ObjectRepository return $this->repository->find($id, $lockMode, $lockVersion); } + public function findActive(): array + { + return $this->findAll(); + } + /** * @return Center[] */ diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php new file mode 100644 index 000000000..27ba64caf --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/CenterRepositoryInterface.php @@ -0,0 +1,18 @@ +authorizationHelper = $authorizationHelper; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(null, [self::EXPORT]) + ->build(); } protected function supports($attribute, $subject): bool { - return self::EXPORT === $attribute; + return $this->helper->supports($attribute, $subject); } protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { - if (!$token->getUser() instanceof User) { - return false; - } - - return [] !== $this->authorizationHelper->getReachableCenters($token->getUser(), $attribute); + return $this->helper->voteOnAttribute($attribute, $subject, $token); } } diff --git a/src/Bundle/ChillMainBundle/Test/Export/AbstractAggregatorTest.php b/src/Bundle/ChillMainBundle/Test/Export/AbstractAggregatorTest.php index cf5fe5c31..40792a1c6 100644 --- a/src/Bundle/ChillMainBundle/Test/Export/AbstractAggregatorTest.php +++ b/src/Bundle/ChillMainBundle/Test/Export/AbstractAggregatorTest.php @@ -25,7 +25,6 @@ use function is_string; /** * Helper which creates a set of test for aggregators. * - * @internal */ abstract class AbstractAggregatorTest extends KernelTestCase { diff --git a/src/Bundle/ChillMainBundle/Test/Export/AbstractFilterTest.php b/src/Bundle/ChillMainBundle/Test/Export/AbstractFilterTest.php index bef4fd200..8e9761c67 100644 --- a/src/Bundle/ChillMainBundle/Test/Export/AbstractFilterTest.php +++ b/src/Bundle/ChillMainBundle/Test/Export/AbstractFilterTest.php @@ -24,7 +24,6 @@ use function is_string; /** * Helper to test filters. * - * @internal */ abstract class AbstractFilterTest extends KernelTestCase { diff --git a/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php b/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php index a25624719..ae274ca1d 100644 --- a/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php +++ b/src/Bundle/ChillMainBundle/Test/ProphecyTrait.php @@ -18,6 +18,7 @@ namespace Chill\MainBundle\Test; * and use tearDownTrait after usage. * * @codeCoverageIgnore + * @deprecated use @class{Prophecy\PhpUnit\ProphecyTrait} instead */ trait ProphecyTrait { diff --git a/src/Bundle/ChillMainBundle/chill.webpack.config.js b/src/Bundle/ChillMainBundle/chill.webpack.config.js index c4c445d31..628f04ba5 100644 --- a/src/Bundle/ChillMainBundle/chill.webpack.config.js +++ b/src/Bundle/ChillMainBundle/chill.webpack.config.js @@ -74,5 +74,4 @@ module.exports = function(encore, entries) // Vue entrypoints encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js'); encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js'); - encore.addEntry('vue_form_action_goal_result', __dirname + '/Resources/public/vuejs/FormActionGoalResult/index.js'); }; diff --git a/src/Bundle/ChillMainBundle/config/services.yaml b/src/Bundle/ChillMainBundle/config/services.yaml index 456f05936..10164932f 100644 --- a/src/Bundle/ChillMainBundle/config/services.yaml +++ b/src/Bundle/ChillMainBundle/config/services.yaml @@ -89,12 +89,8 @@ services: - { name: validator.constraint_validator, alias: 'role_scope_scope_presence' } Chill\MainBundle\Export\ExportManager: - arguments: - - "@logger" - - "@doctrine.orm.entity_manager" - - "@security.authorization_checker" - - "@chill.main.security.authorization.helper" - - "@security.token_storage" + autoconfigure: true + autowire: true Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher' diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index 754d3b042..0d0739e23 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -81,12 +81,8 @@ services: chill.main.form.pick_centers_type: class: Chill\MainBundle\Form\Type\Export\PickCenterType - arguments: - - "@security.token_storage" - - '@Chill\MainBundle\Export\ExportManager' - - "@chill.main.security.authorization.helper" - tags: - - { name: form.type } + autowire: true + autoconfigure: true chill.main.form.formatter_type: class: Chill\MainBundle\Form\Type\Export\FormatterType diff --git a/src/Bundle/ChillPersonBundle/Export/AbstractAccompanyingPeriodExportElement.php b/src/Bundle/ChillPersonBundle/Export/AbstractAccompanyingPeriodExportElement.php index 264f47955..4fa0b9ad8 100644 --- a/src/Bundle/ChillPersonBundle/Export/AbstractAccompanyingPeriodExportElement.php +++ b/src/Bundle/ChillPersonBundle/Export/AbstractAccompanyingPeriodExportElement.php @@ -25,23 +25,17 @@ class AbstractAccompanyingPeriodExportElement */ protected function addJoinAccompanyingPeriod(QueryBuilder $query): void { - if (false === $this->havingAccompanyingPeriodInJoin($query)) { - if (false === in_array('person', $query->getAllAliases(), true)) { - throw new LogicException("the alias 'person' does not exists in " - . 'query builder'); - } + if (false === in_array('person', $query->getAllAliases(), true)) { + throw new LogicException("the alias 'person' does not exists in " + . 'query builder'); + } - $query->join('person.accompanyingPeriods', 'accompanying_period'); + if (!in_array('acppart', $query->getAllAliases(), true)) { + $query->join('person.accompanyingPeriodParticipations', 'acppart'); + } + + if (!in_array('acp', $query->getAllAliases(), true)) { + $query->join('acppart.accompanyingPeriod', 'acp'); } } - - /** - * Return true if "accompanying_period" alias is present in the query alises. - */ - protected function havingAccompanyingPeriodInJoin(QueryBuilder $query): bool - { - $joins = $query->getDQLPart('join') ?? []; - - return in_array('accompanying_period', $query->getAllAliases(), true); - } } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php index 13185c2a2..c0d20e7c7 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php @@ -40,18 +40,11 @@ class AdministrativeLocationAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acploc', $qb->getAllAliases(), true)) { - $qb->join('acp.administrativeLocation', 'acploc'); + $qb->leftJoin('acp.administrativeLocation', 'acploc'); } $qb->addSelect('IDENTITY(acp.administrativeLocation) AS location_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('location_aggregator'); - } else { - $qb->groupBy('location_aggregator'); - } + $qb->addGroupBy('location_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ class AdministrativeLocationAggregator implements AggregatorInterface return 'Administrative location'; } + if (null === $value) { + return ''; + } + $l = $this->locationRepository->find($value); return $l->getName() . ' (' . $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ')'; diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php index 033ba4365..de276f007 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php @@ -15,21 +15,23 @@ use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive; use Chill\PersonBundle\Export\Declarations; +use Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository; +use Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepositoryInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; class ClosingMotiveAggregator implements AggregatorInterface { - private EntityManagerInterface $em; + private ClosingMotiveRepositoryInterface $motiveRepository; private TranslatableStringHelper $translatableStringHelper; public function __construct( - EntityManagerInterface $em, + ClosingMotiveRepositoryInterface $motiveRepository, TranslatableStringHelper $translatableStringHelper ) { - $this->motiveRepository = $em->getRepository(ClosingMotive::class); + $this->motiveRepository = $motiveRepository; $this->translatableStringHelper = $translatableStringHelper; } @@ -40,19 +42,8 @@ class ClosingMotiveAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acpmotive', $qb->getAllAliases(), true)) { - $qb->join('acp.closingMotive', 'acpmotive'); - } - $qb->addSelect('IDENTITY(acp.closingMotive) AS closingmotive_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('closingmotive_aggregator'); - } else { - $qb->groupBy('closingmotive_aggregator'); - } + $qb->addGroupBy('closingmotive_aggregator'); } public function applyOn(): string @@ -72,6 +63,10 @@ class ClosingMotiveAggregator implements AggregatorInterface return 'Closing motive'; } + if (NULL === $value) { + return ''; + } + $cm = $this->motiveRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php index ec9bdd348..a2a4919aa 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php @@ -35,14 +35,7 @@ class ConfidentialAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('acp.confidential AS confidential_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('confidential_aggregator'); - } else { - $qb->groupBy('confidential_aggregator'); - } + $qb->addGroupBy('confidential_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php index b43b0ba11..ee54da2af 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php @@ -44,15 +44,8 @@ final class DurationAggregator implements AggregatorInterface // et ajouter une fonction custom qui calcule plus précisément les intervals, comme doctrineum/date-interval // https://packagist.org/packages/doctrineum/date-interval#3.1.0 (mais composer fait un conflit de dépendance) - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('duration_aggregator'); - } else { - $qb->groupBy('duration_aggregator'); - } - - $qb->orderBy('duration_aggregator'); + $qb->addGroupBy('duration_aggregator'); + $qb->addOrderBy('duration_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php index f59491ec5..297faf049 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php @@ -35,14 +35,7 @@ class EmergencyAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('acp.emergency AS emergency_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('emergency_aggregator'); - } else { - $qb->groupBy('emergency_aggregator'); - } + $qb->addGroupBy('emergency_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php index 120506aae..292303cea 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php @@ -41,22 +41,15 @@ final class EvaluationAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpw', $qb->getAllAliases(), true)) { - $qb->join('acp.works', 'acpw'); + $qb->leftJoin('acp.works', 'acpw'); } if (!in_array('workeval', $qb->getAllAliases(), true)) { - $qb->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval'); + $qb->leftJoin('acpw.accompanyingPeriodWorkEvaluations', 'workeval'); } $qb->addSelect('IDENTITY(workeval.evaluation) AS evaluation_aggregator'); - - $groupby = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('evaluation_aggregator'); - } else { - $qb->groupBy('evaluation_aggregator'); - } + $qb->addGroupBy('evaluation_aggregator'); } public function applyOn(): string @@ -76,6 +69,10 @@ final class EvaluationAggregator implements AggregatorInterface return 'Evaluation'; } + if (null === $value) { + return ''; + } + $e = $this->evaluationRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php index 711f7ec0d..c418ea39f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php @@ -35,14 +35,7 @@ class IntensityAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('acp.intensity AS intensity_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('intensity_aggregator'); - } else { - $qb->groupBy('intensity_aggregator'); - } + $qb->addGroupBy('intensity_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobAggregator.php index 7634ea37f..0809f7654 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobAggregator.php @@ -40,18 +40,11 @@ final class JobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpjob', $qb->getAllAliases(), true)) { - $qb->join('acp.job', 'acpjob'); + $qb->leftJoin('acp.job', 'acpjob'); } $qb->addSelect('IDENTITY(acp.job) AS job_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('job_aggregator'); - } else { - $qb->groupBy('job_aggregator'); - } + $qb->addGroupBy('job_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class JobAggregator implements AggregatorInterface return 'Job'; } + if (null === $value) { + return ''; + } + $j = $this->jobRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php index 4c784e08d..c7a178fa3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php @@ -42,18 +42,11 @@ final class OriginAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acporigin', $qb->getAllAliases(), true)) { - $qb->join('acp.origin', 'acporigin'); + $qb->leftJoin('acp.origin', 'acporigin'); } - $qb->addSelect('o.id AS origin_aggregator'); - - $groupby = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('origin_aggregator'); - } else { - $qb->groupBy('origin_aggregator'); - } + $qb->addSelect('acporigin.id AS origin_aggregator'); + $qb->addGroupBy('origin_aggregator'); } public function applyOn(): string @@ -73,6 +66,10 @@ final class OriginAggregator implements AggregatorInterface return 'Origin'; } + if (null === $value) { + return ''; + } + $o = $this->repository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index 22eca6f76..7851fe203 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -40,18 +40,11 @@ final class ReferrerAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpuser', $qb->getAllAliases(), true)) { - $qb->join('acp.user', 'acpuser'); + $qb->leftJoin('acp.user', 'acpuser'); } $qb->addSelect('acpuser.id AS referrer_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('referrer_aggregator'); - } else { - $qb->groupBy('referrer_aggregator'); - } + $qb->addGroupBy('referrer_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class ReferrerAggregator implements AggregatorInterface return 'Referrer'; } + if (null === $value) { + return ''; + } + $r = $this->userRepository->find($value); return $this->userRender->renderString($r, []); diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php index 80195bdcc..2f716c92a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php @@ -57,15 +57,7 @@ final class RequestorAggregator implements AggregatorInterface END ) AS requestor_aggregator "); - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('requestor_aggregator'); - } else { - $qb->groupBy('requestor_aggregator'); - } - - // TODO 'order by' does not works ! + $qb->addGroupBy('requestor_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php index 5b2901921..0ff6aa747 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php @@ -40,18 +40,11 @@ final class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpscope', $qb->getAllAliases(), true)) { - $qb->join('acp.scopes', 'acpscope'); + $qb->leftJoin('acp.scopes', 'acpscope'); } $qb->addSelect('acpscope.id as scope_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('scope_aggregator'); - } else { - $qb->groupBy('scope_aggregator'); - } + $qb->addGroupBy('scope_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class ScopeAggregator implements AggregatorInterface return 'Scope'; } + if (null === $value) { + return ''; + } + $s = $this->scopeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php index 39ad085e3..dc8d2cfb3 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php @@ -41,18 +41,12 @@ final class SocialActionAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpw', $qb->getAllAliases(), true)) { + // here, we will only see accompanying period linked with a socialAction $qb->join('acp.works', 'acpw'); } - $qb->addSelect('IDENTITY(acpw.socialAction) AS socialaction_aggregator'); // DISTINCT ?? - - $groupby = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('socialaction_aggregator'); - } else { - $qb->groupBy('socialaction_aggregator'); - } + $qb->addSelect('IDENTITY(acpw.socialAction) AS socialaction_aggregator'); + $qb->addGroupBy('socialaction_aggregator'); } public function applyOn(): string @@ -72,6 +66,10 @@ final class SocialActionAggregator implements AggregatorInterface return 'Social action'; } + if (null === $value) { + return ''; + } + $sa = $this->actionRepository->find($value); return $this->actionRender->renderString($sa, []); diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php index ac5ac94c0..98fdbad0c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php @@ -40,18 +40,12 @@ final class SocialIssueAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpsocialissue', $qb->getAllAliases(), true)) { + // we will see accompanying period linked with social issues $qb->join('acp.socialIssues', 'acpsocialissue'); } - + $qb->addSelect('acpsocialissue.id as socialissue_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('socialissue_aggregator'); - } else { - $qb->groupBy('socialissue_aggregator'); - } + $qb->addGroupBy('socialissue_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php index 5c923fdc2..2a1a3db25 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php @@ -41,15 +41,9 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('acp.step AS step_aggregator'); + $qb->addGroupBy('step_aggregator'); - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('step_aggregator'); - } else { - $qb->groupBy('step_aggregator'); - } - + /* // add date in where clause $where = $qb->getDQLPart('where'); @@ -69,6 +63,7 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface $qb->add('where', $where); $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); + */ } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php index b4f5e0071..29420d5c9 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php @@ -39,15 +39,8 @@ class EvaluationTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->addSelect('IDENTITY(eval.evaluation) AS evaluationtype_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('evaluationtype_aggregator'); - } else { - $qb->groupBy('evaluationtype_aggregator'); - } + $qb->addSelect('IDENTITY(workeval.evaluation) AS eval_evaluationtype_aggregator'); + $qb->addGroupBy('eval_evaluationtype_aggregator'); } public function applyOn(): string @@ -67,6 +60,10 @@ class EvaluationTypeAggregator implements AggregatorInterface return 'Evaluation type'; } + if (null === $value) { + return ''; + } + $ev = $this->evaluationRepository->find($value); return $this->translatableStringHelper->localize($ev->getTitle()); @@ -75,7 +72,7 @@ class EvaluationTypeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['evaluationtype_aggregator']; + return ['eval_evaluationtype_aggregator']; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php index 240da475e..2343b2bab 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Form\Type\ChillDateType; use Chill\PersonBundle\Export\Declarations; use DateTime; use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -39,39 +40,23 @@ class ChildrenNumberAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('composition', $qb->getAllAliases(), true)) { - $qb->join('household.compositions', 'composition'); + if (!in_array('composition_children', $qb->getAllAliases(), true)) { + $clause = $qb->expr()->andX( + $qb->expr()->lte('composition_children.startDate', ':ondate_composition_children'), + $qb->expr()->orX( + $qb->expr()->gt('composition_children.endDate', ':ondate_composition_children'), + $qb->expr()->isNull('composition_children.endDate') + ) + ); + + $qb->leftJoin('household.compositions', 'composition_children', Expr\Join::WITH, $clause); } - $qb->addSelect('composition.numberOfChildren AS childrennumber_aggregator'); + $qb + ->addSelect('composition_children.numberOfChildren AS childrennumber_aggregator') + ->addGroupBy('childrennumber_aggregator'); - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('childrennumber_aggregator'); - } else { - $qb->groupBy('childrennumber_aggregator'); - } - - // add date in where clause - $where = $qb->getDQLPart('where'); - - $clause = $qb->expr()->andX( - $qb->expr()->lte('composition.startDate', ':ondate'), - $qb->expr()->orX( - $qb->expr()->gt('composition.endDate', ':ondate'), - $qb->expr()->isNull('composition.endDate') - ) - ); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); + $qb->setParameter('ondate_composition_children', $data['on_date'], Types::DATE_MUTABLE); } public function applyOn(): string @@ -93,12 +78,11 @@ class ChildrenNumberAggregator implements AggregatorInterface return 'Number of children'; } - return $this->translator->trans( - 'household_composition.numberOfChildren children in household', - [ - 'numberOfChildren' => $value, - ] - ); + if (null === $value) { + return ''; + } + + return $value; }; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php index fdb18e951..7e10ea429 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php @@ -18,6 +18,7 @@ use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Repository\Household\HouseholdCompositionTypeRepository; use DateTime; use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -44,39 +45,23 @@ class CompositionAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('composition', $qb->getAllAliases(), true)) { - $qb->join('household.compositions', 'composition'); + if (!in_array('composition_type', $qb->getAllAliases(), true)) { + $clause = $qb->expr()->andX( + $qb->expr()->lte('composition_type.startDate', ':ondate_composition_type'), + $qb->expr()->orX( + $qb->expr()->gt('composition_type.endDate', ':ondate_composition_type'), + $qb->expr()->isNull('composition_type.endDate') + ) + ); + + $qb->leftJoin('household.compositions', 'composition_type', Expr\Join::WITH, $clause); } - $qb->addSelect('IDENTITY(composition.householdCompositionType) AS composition_aggregator'); + $qb + ->addSelect('IDENTITY(composition_type.householdCompositionType) AS composition_aggregator') + ->addGroupBy('composition_aggregator'); - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('composition_aggregator'); - } else { - $qb->groupBy('composition_aggregator'); - } - - // add date in where clause - $where = $qb->getDQLPart('where'); - - $clause = $qb->expr()->andX( - $qb->expr()->lte('composition.startDate', ':ondate'), - $qb->expr()->orX( - $qb->expr()->gt('composition.endDate', ':ondate'), - $qb->expr()->isNull('composition.endDate') - ) - ); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); + $qb->setParameter('ondate_composition_type', $data['on_date'], Types::DATE_MUTABLE); } public function applyOn(): string @@ -98,6 +83,10 @@ class CompositionAggregator implements AggregatorInterface return 'Composition'; } + if (null === $value) { + return ''; + } + $c = $this->typeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php index 0b94cbd4f..3cfadc355 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php @@ -62,6 +62,9 @@ final class GenderAggregator implements AggregatorInterface case Person::BOTH_GENDER: return $this->translator->trans('both'); + case Person::NO_INFORMATION: + return $this->translator->trans('unknown'); + case null: return $this->translator->trans('Not given'); diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php index c0b52053d..89c0bb8f5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php @@ -16,8 +16,10 @@ use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\PersonBundle\Entity\Household\HouseholdMember; +use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Repository\Household\PositionRepository; use DateTime; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; @@ -31,8 +33,11 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl private TranslatorInterface $translator; - public function __construct(TranslatorInterface $translator, TranslatableStringHelper $translatableStringHelper, PositionRepository $positionRepository) - { + public function __construct( + TranslatorInterface $translator, + TranslatableStringHelper $translatableStringHelper, + PositionRepository $positionRepository + ) { $this->translator = $translator; $this->positionRepository = $positionRepository; $this->translatableStringHelper = $translatableStringHelper; @@ -45,28 +50,25 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from(HouseholdMember::class, 'member'); - - if (!in_array('memberperson', $qb->getAllAliases(), true)) { - $qb->join('member.person', 'memberperson'); + if (!in_array('householdmember', $qb->getAllAliases(), true)) { + $qb->join(HouseholdMember::class, 'householdmember', Expr\Join::WITH, 'householdmember.person = person'); } - if (!in_array('membercenter', $qb->getAllAliases(), true)) { - $qb->join('memberperson.center', 'membercenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } $qb->andWhere($qb->expr()->andX( - $qb->expr()->lte('member.startDate', ':date'), + $qb->expr()->lte('householdmember.startDate', ':date'), $qb->expr()->orX( - $qb->expr()->isNull('member.endDate'), - $qb->expr()->gte('member.endDate', ':date') + $qb->expr()->isNull('householdmember.endDate'), + $qb->expr()->gte('householdmember.endDate', ':date') ) )); $qb->setParameter('date', $data['date_position']); - $qb->addSelect('IDENTITY(member.position) AS household_position_aggregator'); + $qb->addSelect('IDENTITY(householdmember.position) AS household_position_aggregator'); $groupBy = $qb->getDQLPart('groupBy'); @@ -79,7 +81,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl public function applyOn() { - return 'person'; + return Declarations::PERSON_TYPE; } public function buildForm(FormBuilderInterface $builder) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php index e799d8dfa..2ed1752b0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php @@ -59,6 +59,7 @@ final class MaritalStatusAggregator implements AggregatorInterface public function buildForm(FormBuilderInterface $builder) { + // no form } public function getLabels($key, array $values, $data) diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php index fb64b3e01..fc96b9e6b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php @@ -40,18 +40,11 @@ final class ActionTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpwsocialaction', $qb->getAllAliases(), true)) { - $qb->join('acpw.socialAction', 'acpwsocialaction'); + $qb->leftJoin('acpw.socialAction', 'acpwsocialaction'); } $qb->addSelect('acpwsocialaction.id as action_type_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('action_type_aggregator'); - } else { - $qb->groupBy('action_type_aggregator'); - } + $qb->addGroupBy('action_type_aggregator'); } public function applyOn() @@ -71,6 +64,10 @@ final class ActionTypeAggregator implements AggregatorInterface return 'Social Action Type'; } + if (null === $value) { + return ''; + } + $sa = $this->socialActionRepository->find($value); return $this->actionRender->renderString($sa, []); diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php index 4310dcac2..0f418a678 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php @@ -38,21 +38,14 @@ final class GoalAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('goal', $qb->getAllAliases(), true)) { - $qb->join('acpw.goals', 'goal'); + $qb->leftJoin('acpw.goals', 'goal'); } - $qb->addSelect('goal.id as goal_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('goal_aggregator'); - } else { - $qb->groupBy('goal_aggregator'); - } + $qb->addSelect('IDENTITY(goal.goal) as acpw_goal_aggregator'); + $qb->addGroupBy('acpw_goal_aggregator'); } - public function applyOn() + public function applyOn(): string { return Declarations::SOCIAL_WORK_ACTION_TYPE; } @@ -69,18 +62,24 @@ final class GoalAggregator implements AggregatorInterface return 'Goal Type'; } + if (null === $value) { + return ''; + } + $g = $this->goalRepository->find($value); - return $this->translatableStringHelper->localize($g->getTitle()); + return $this->translatableStringHelper->localize( + $g->getTitle() + ); }; } - public function getQueryKeys($data) + public function getQueryKeys($data): array { - return ['goal_aggregator']; + return ['acpw_goal_aggregator']; } - public function getTitle() + public function getTitle(): string { return 'Group social work actions by goal'; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php new file mode 100644 index 000000000..48075c38b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php @@ -0,0 +1,133 @@ +resultRepository = $resultRepository; + $this->goalRepository = $goalRepository; + $this->translatableStringHelper = $translatableStringHelper; + } + + + /** + * @inheritDoc + */ + public function getLabels($key, array $values, $data) + { + return function ($value) use ($key): string { + if (null === $value) { + return ''; + } + + switch ($key) { + case 'goal_aggregator': + + if ('_header' === $value) { + return 'Goal Type'; + } + + $g = $this->goalRepository->find($value); + + return $this->translatableStringHelper->localize( + $g->getTitle() + ); + + case 'result_aggregator': + + if ('_header' === $value) { + return 'Result Type'; + } + + $r = $this->resultRepository->find($value); + + return $this->translatableStringHelper->localize( + $r->getTitle() + ); + + default: + throw new \LogicException(); + } + }; + } + + /** + * @inheritDoc + */ + public function getQueryKeys($data): array + { + return [ + 'goal_aggregator', + 'result_aggregator' + ]; + } + + /** + * @inheritDoc + */ + public function buildForm(FormBuilderInterface $builder) + { + // no form + } + + /** + * @inheritDoc + */ + public function getTitle(): string + { + return 'Group social work actions by goal and result'; + } + + /** + * @inheritDoc + */ + public function addRole(): ?string + { + return null; + } + + /** + * @inheritDoc + */ + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('goal', $qb->getAllAliases(), true)) { + $qb->leftJoin('acpw.goals', 'goal'); + } + + if (!in_array('goalresult', $qb->getAllAliases(), true)) { + $qb->leftJoin('goal.results', 'goalresult'); + } + + $qb->addSelect('IDENTITY(goal.goal) as goal_aggregator'); + $qb->addSelect('goalresult.id as result_aggregator'); + $qb->addGroupBy('goal_aggregator')->addGroupBy('result_aggregator'); + } + + /** + * @inheritDoc + */ + public function applyOn(): string + { + return Declarations::SOCIAL_WORK_ACTION_TYPE; + } +} diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php index 4d27aa873..ca2e36d97 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php @@ -40,18 +40,11 @@ final class JobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpwuser', $qb->getAllAliases(), true)) { - $qb->join('acpw.referrers', 'acpwuser'); + $qb->leftJoin('acpw.referrers', 'acpwuser'); } - $qb->addSelect('IDENTITY(acpwuser.userJob) as job_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('job_aggregator'); - } else { - $qb->groupBy('job_aggregator'); - } + $qb->addSelect('IDENTITY(acpwuser.userJob) as job_aggregator') + ->addGroupBy('job_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class JobAggregator implements AggregatorInterface return 'Job'; } + if (null === $value) { + return ''; + } + $j = $this->jobRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php index 35e1e218d..46ef78035 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php @@ -40,18 +40,11 @@ final class ReferrerAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpwuser', $qb->getAllAliases(), true)) { - $qb->join('acpw.referrers', 'acpwuser'); + $qb->leftJoin('acpw.referrers', 'acpwuser'); } $qb->addSelect('acpwuser.id AS referrer_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('referrer_aggregator'); - } else { - $qb->groupBy('referrer_aggregator'); - } + $qb->addGroupBy('referrer_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class ReferrerAggregator implements AggregatorInterface return 'Referrer'; } + if (null === $value) { + return ''; + } + $r = $this->userRepository->find($value); return $this->userRender->renderString($r, []); diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php index 47391ed69..4b190e0a5 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php @@ -37,30 +37,15 @@ final class ResultAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acpwresult', $qb->getAllAliases(), true)) { - $qb->join('acpw.results', 'acpwresult'); + if (!in_array('result', $qb->getAllAliases(), true)) { + $qb->leftJoin('acpw.results', 'result'); } - if (!in_array('goal', $qb->getAllAliases(), true)) { - $qb->join('acpw.goals', 'goal'); - } - - if (!in_array('goalresult', $qb->getAllAliases(), true)) { - $qb->join('goal.results', 'goalresult'); - } - - $qb->addSelect('acpwresult.id, IDENTITY(goal.results) as result_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('result_aggregator'); - } else { - $qb->groupBy('result_aggregator'); - } + $qb->addSelect('result.id AS acpw_result_aggregator'); + $qb->addGroupBy('acpw_result_aggregator'); } - public function applyOn() + public function applyOn(): string { return Declarations::SOCIAL_WORK_ACTION_TYPE; } @@ -77,18 +62,24 @@ final class ResultAggregator implements AggregatorInterface return 'Result Type'; } - $g = $this->resultRepository->find($value); + if (null === $value) { + return ''; + } - return $this->translatableStringHelper->localize($g->getTitle()); + $r = $this->resultRepository->find($value); + + return $this->translatableStringHelper->localize( + $r->getTitle() + ); }; } - public function getQueryKeys($data) + public function getQueryKeys($data): array { - return ['result_aggregator']; + return ['acpw_result_aggregator']; } - public function getTitle() + public function getTitle(): string { return 'Group social work actions by result'; } diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php index ee479d503..1cf29d46f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php @@ -40,18 +40,11 @@ final class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { if (!in_array('acpwuser', $qb->getAllAliases(), true)) { - $qb->join('acpw.referrers', 'acpwuser'); + $qb->leftJoin('acpw.referrers', 'acpwuser'); } $qb->addSelect('IDENTITY(acpwuser.mainScope) as scope_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('scope_aggregator'); - } else { - $qb->groupBy('scope_aggregator'); - } + $qb->addGroupBy('scope_aggregator'); } public function applyOn(): string @@ -71,6 +64,10 @@ final class ScopeAggregator implements AggregatorInterface return 'Scope'; } + if (null === $value) { + return ''; + } + $s = $this->scopeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php index 7178a54c8..634b351cf 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountEvaluation.php @@ -98,7 +98,7 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface $qb->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval'); } - $qb->select('COUNT(workeval.id) AS export_result'); + $qb->select('COUNT(DISTINCT workeval.id) AS export_result'); return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php index 18ddbaea1..106084e4f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountHousehold.php @@ -106,8 +106,7 @@ class CountHousehold implements ExportInterface, GroupedExportInterface $qb->join('member.household', 'household'); } - - $qb->select('COUNT(DISTINCT member.household) AS export_result'); + $qb->select('COUNT(DISTINCT household.id) AS export_result'); return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php index 51d85c479..057611032 100644 --- a/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php +++ b/src/Bundle/ChillPersonBundle/Export/Export/CountPersonWithAccompanyingCourse.php @@ -95,10 +95,10 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor } if (!in_array('partperson', $qb->getAllAliases(), true)) { - $qb->join('acppart.person', 'partperson'); + $qb->join('acppart.person', 'person'); } - $qb->select('COUNT(DISTINCT partperson.id) AS export_result'); + $qb->select('COUNT(DISTINCT person.id) AS export_result'); return $qb; } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php index 6e2fa3288..ae9535a67 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php @@ -29,24 +29,9 @@ class ActiveOneDayBetweenDatesFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $where = $qb->getDQLPart('where'); + $clause = "OVERLAPSI (acp.openingDate, acp.closingDate), (:datefrom, :dateto) = 'TRUE'"; - $clause = $qb->expr()->orX( - $qb->expr()->lt('(acp.openingDate + 1)', ':dateto'), - $qb->expr()->andX( - $qb->expr()->lt('acp.openingDate', ':datefrom'), - $qb->expr()->isNull('acp.closingDate') - ), - $qb->expr()->gt('(acp.closingDate - 1)', ':datefrom') - ); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); + $qb->andWhere($clause); $qb->setParameter('datefrom', $data['date_from'], Types::DATE_MUTABLE); $qb->setParameter('dateto', $data['date_to'], Types::DATE_MUTABLE); } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php index 4d1784cb3..9a4abbb1d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php @@ -73,6 +73,8 @@ class ConfidentialFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { + //dump($data, self::CHOICES); + foreach (self::CHOICES as $k => $v) { if ($v === $data['accepted_confidentials']) { $choice = $k; @@ -81,8 +83,8 @@ class ConfidentialFilter implements FilterInterface return [ 'Filtered by confidential: only %confidential%', [ - '%confidential%' => $this->translator->trans($choice), - ], + '%confidential%' => $this->translator->trans($choice) + ] ]; } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php index a782fdb88..b47f2020d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php @@ -29,20 +29,12 @@ class OpenBetweenDatesFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->andX( - $qb->expr()->lt('acp.openingDate', ':datefrom'), - $qb->expr()->gt('acp.closingDate', ':dateto') + $qb->expr()->gte('acp.openingDate', ':datefrom'), + $qb->expr()->lte('acp.openingDate', ':dateto') ); - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); + $qb->andWhere($clause); $qb->setParameter('datefrom', $data['date_from'], Types::DATE_MUTABLE); $qb->setParameter('dateto', $data['date_to'], Types::DATE_MUTABLE); } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php index c0338b42e..e81cf3114 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php @@ -70,10 +70,6 @@ final class RequestorFilter implements FilterInterface case 'other_person': $expr = $this->em->getExpressionBuilder(); - if (!in_array('acppart', $qb->getAllAliases(), true)) { - $qb->join('acp.participations', 'acppart'); - } - $clause = $expr->andX( $expr->isNotNull('acp.requestorPerson'), $expr->notIn( @@ -85,6 +81,7 @@ final class RequestorFilter implements FilterInterface ->join('acp2.participations', 'acppart2') ->select('identity(acp2.requestorPerson)') ->where($expr->eq('acp2.requestorPerson', 'acppart2.person')) + ->andWhere('acp2.id = acp.id') ->getDQL() ) ); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php index 3d00ed36b..1ca78d669 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/HouseholdFilters/CompositionFilter.php @@ -18,6 +18,7 @@ use Chill\PersonBundle\Entity\Household\HouseholdCompositionType; use Chill\PersonBundle\Export\Declarations; use DateTime; use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; @@ -41,32 +42,24 @@ class CompositionFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('composition', $qb->getAllAliases(), true)) { - $qb->join('household.compositions', 'composition'); + if (!in_array('composition_type_filter', $qb->getAllAliases(), true)) { + $clause = + $qb->expr()->andX( + $qb->expr()->lte('composition_type_filter.startDate', ':ondate_composition_type_filter'), + $qb->expr()->orX( + $qb->expr()->gt('composition_type_filter.endDate', ':ondate_composition_type_filter'), + $qb->expr()->isNull('composition_type_filter.endDate') + ) + ); + + $qb->join('household.compositions', 'composition', Expr\Join::WITH, $clause); } - $where = $qb->getDQLPart('where'); + $whereClause = $qb->expr()->in('composition_type_filter.householdCompositionType', ':compositions'); - $clause = $qb->expr()->andX( - $qb->expr()->in('composition.householdCompositionType', ':compositions'), - $qb->expr()->andX( - $qb->expr()->lte('composition.startDate', ':ondate'), - $qb->expr()->orX( - $qb->expr()->gt('composition.endDate', ':ondate'), - $qb->expr()->isNull('composition.endDate') - ) - ) - ); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); + $qb->andWhere($whereClause); $qb->setParameter('compositions', $data['accepted_composition']); - $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); + $qb->setParameter('ondate_composition_type_filter', $data['on_date'], Types::DATE_MUTABLE); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilter.php index e56782847..9258c9b0a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilter.php @@ -32,8 +32,8 @@ class AccompanyingPeriodClosingFilter extends AbstractAccompanyingPeriodExportEl $this->addJoinAccompanyingPeriod($qb); $clause = $qb->expr()->andX( - $qb->expr()->lte('accompanying_period.closingDate', ':date_to'), - $qb->expr()->gte('accompanying_period.closingDate', ':date_from') + $qb->expr()->lte('acp.closingDate', ':date_to'), + $qb->expr()->gte('acp.closingDate', ':date_from') ); $qb->andWhere($clause); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodFilter.php index 5a7ccb4a3..0c97ac6bf 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodFilter.php @@ -34,12 +34,12 @@ class AccompanyingPeriodFilter extends AbstractAccompanyingPeriodExportElement i $clause = $qb->expr()->andX(); $clause->add( - $qb->expr()->lte('accompanying_period.openingDate', ':date_to') + $qb->expr()->lte('acp.openingDate', ':date_to') ); $clause->add( $qb->expr()->orX( - $qb->expr()->gte('accompanying_period.closingDate', ':date_from'), - $qb->expr()->isNull('accompanying_period.closingDate') + $qb->expr()->gte('acp.closingDate', ':date_from'), + $qb->expr()->isNull('acp.closingDate') ) ); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilter.php index 33805d392..00ff885ba 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilter.php @@ -32,8 +32,8 @@ class AccompanyingPeriodOpeningFilter extends AbstractAccompanyingPeriodExportEl $this->addJoinAccompanyingPeriod($qb); $clause = $qb->expr()->andX( - $qb->expr()->lte('accompanying_period.openingDate', ':date_to'), - $qb->expr()->gte('accompanying_period.openingDate', ':date_from') + $qb->expr()->lte('acp.openingDate', ':date_to'), + $qb->expr()->gte('acp.openingDate', ':date_from') ); $qb->andWhere($clause); diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php index bada59a8d..eb83f3ff0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php @@ -34,17 +34,20 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface $where = $qb->getDQLPart('where'); $min = null !== $data['min_age'] ? $data['min_age'] : 0; - $max = null !== $data['max_age'] ? $data['max_age'] : 200; + $max = null !== $data['max_age'] ? $data['max_age'] : 3000; $calc = $data['date_calc']; + $minDate = $calc->sub(new \DateInterval('P' . $max . 'Y')); + $maxDate = $calc->sub(new \DateInterval('P' . $min . 'Y')); + $clause = $qb->expr()->andX( $qb->expr()->gte( - 'DATE_DIFF(:calc_date, person.birthdate)/365', - ':min_age' + 'person.birthdate', + ':min_date' ), $qb->expr()->lte( - 'DATE_DIFF(:calc_date, person.birthdate)/365', - ':max_age' + 'person.birthdate', + ':max_date' ) ); @@ -55,9 +58,8 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface } $qb->add('where', $where); - $qb->setParameter('min_age', $min); - $qb->setParameter('max_age', $max); - $qb->setParameter('calc_date', $calc); + $qb->setParameter('min_date', $minDate); + $qb->setParameter('max_date', $maxDate); } public function applyOn() @@ -77,7 +79,8 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface $builder->add('date_calc', ChillDateType::class, [ 'label' => 'Calculate age in relation to this date', - 'data' => new DateTime('now'), + 'data' => new \DateTimeImmutable('now'), + 'input' => 'datetime_immutable' ]); } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php index 00d05117b..a161df44f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php @@ -108,6 +108,6 @@ class DeadOrAliveFilter implements FilterInterface public function getTitle() { - return 'Filtered by person\'s that are alive or have deceased at a certain date'; + return "Filter by person's that are alive or have deceased at a certain date"; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php index 73c551286..2770ae82f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Export\Filter\PersonFilters; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\PersonBundle\Entity\Person\ResidentialAddress; use Chill\PersonBundle\Export\Declarations; use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory; use DateTime; @@ -38,15 +39,12 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from('ChillPersonBundle:Person\ResidentialAddress', 'resaddr'); - - if (!in_array('resaddrperson', $qb->getAllAliases(), true)) { - $qb->join('resaddr.person', 'resaddrperson'); + if (!in_array('resaddr', $qb->getAllAliases(), true)) { + $qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person'); } - if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) { - $qb->join('resaddrperson.center', 'resaddrcenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } if (!in_array('tparty', $qb->getAllAliases(), true)) { @@ -58,10 +56,17 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface } $where = $qb->getDQLPart('where'); + $clause = $qb->expr()->andX( $qb->expr()->isNotNull('resaddr.hostThirdParty'), - $qb->expr()->between(':date', 'resaddr.startDate', 'resaddr.endDate'), - $qb->expr()->in('tpartycat.id', ':type') + $qb->expr()->in('tpartycat.id', ':type'), + $qb->expr()->orX( + $qb->expr()->between(':date', 'resaddr.startDate', 'resaddr.endDate'), + $qb->expr()->andX( + $qb->expr()->lte('resaddr.startDate', ':date'), + $qb->expr()->isNull('resaddr.endDate') + ) + ) ); if ($where instanceof Expr\Andx) { @@ -108,6 +113,6 @@ class ResidentialAddressAtThirdpartyFilter implements FilterInterface public function getTitle() { - return 'Filtered by person\'s who have a residential address located at a thirdparty of type'; + return "Filter by person's who have a residential address located at a thirdparty of type"; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php index 5e78e574e..7c07121e1 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php @@ -12,7 +12,10 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\PersonFilters; use Chill\MainBundle\Export\FilterInterface; +use Chill\MainBundle\Form\Type\ChillDateType; +use Chill\PersonBundle\Entity\Person\ResidentialAddress; use Chill\PersonBundle\Export\Declarations; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; @@ -25,19 +28,26 @@ class ResidentialAddressAtUserFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $qb->resetDQLPart('from'); - $qb->from('ChillPersonBundle:Person\ResidentialAddress', 'resaddr'); - - if (!in_array('resaddrperson', $qb->getAllAliases(), true)) { - $qb->join('resaddr.person', 'resaddrperson'); + if (!in_array('resaddr', $qb->getAllAliases(), true)) { + $qb->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = person'); } - if (!in_array('resaddrcenter', $qb->getAllAliases(), true)) { - $qb->join('resaddrperson.center', 'resaddrcenter'); + if (!in_array('center', $qb->getAllAliases(), true)) { + $qb->join('person.center', 'center'); } $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->isNotNull('resaddr.hostPerson'); + + $clause = $qb->expr()->andX( + $qb->expr()->isNotNull('resaddr.hostPerson'), + $qb->expr()->orX( + $qb->expr()->between(':date', 'resaddr.startDate', 'resaddr.endDate'), + $qb->expr()->andX( + $qb->expr()->lte('resaddr.startDate', ':date'), + $qb->expr()->isNull('resaddr.endDate') + ) + ) + ); if ($where instanceof Andx) { $where->add($clause); @@ -45,6 +55,7 @@ class ResidentialAddressAtUserFilter implements FilterInterface $where = $qb->expr()->andX($clause); } + $qb->setParameter('date', $data['date_calc']); $qb->add('where', $where); } @@ -55,16 +66,19 @@ class ResidentialAddressAtUserFilter implements FilterInterface public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder) { - // No form needed unless validity date should be added ( not specified in doc as a parameter ). + $builder->add('date_calc', ChillDateType::class, [ + 'label' => 'Date during which residential address was valid', + 'data' => new \DateTime('now'), + ]); } public function describeAction($data, $format = 'string') { - return ['Filtered by person\'s who have a residential address located at another user']; + return ["Filtered by person's who have a residential address located at another user"]; } public function getTitle() { - return 'Filtered by person\'s who have a residential address located at another user'; + return "Filter by person's who have a residential address located at another user"; } } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index c2ffd74c6..0cf7f979d 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -50,97 +50,81 @@ class SocialWorkTypeFilter implements FilterInterface $builder ->add('actionType', HiddenType::class) ->get('actionType') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $actionsAsIterable): string { - if (null === $actionsAsIterable) { return ''; } - $actionIds = []; - foreach ($actionsAsIterable as $value) { - $actionIds[] = $value->getId(); - } - return implode(',', $actionIds); - }, - function (?string $actionsAsString): array { - if (null === $actionsAsString) { return []; } - return array_map( - fn (string $id): ?SocialAction - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $actionsAsString) - ); - } - )) + ->addModelTransformer( + $this->iterableToIdTransformer(SocialAction::class) + ) ; - $builder ->add('goal', HiddenType::class) ->get('goal') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $goalsAsIterable): string { - if (null === $goalsAsIterable) { return ''; } - $goalIds = []; - foreach ($goalsAsIterable as $value) { - $goalIds[] = $value->getId(); - } - return implode(',', $goalIds); - }, - function (?string $goalsAsString): array { - if (null === $goalsAsString) { return []; } - return array_map( - fn (string $id): ?Goal - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $goalsAsString) - ); - } - )) + ->addModelTransformer( + $this->iterableToIdTransformer(Goal::class) + ) ; - $builder ->add('result', HiddenType::class) ->get('result') - ->addModelTransformer(new CallbackTransformer( - static function (?iterable $resultsAsIterable): string { - if (null === $resultsAsIterable) { return ''; } - $resultIds = []; - foreach ($resultsAsIterable as $value) { - $resultIds[] = $value->getId(); - } - return implode(',', $resultIds); - }, - function (?string $resultsAsString): array { - if (null === $resultsAsString) { return []; } - return array_map( - fn (string $id): ?Result - => $this->socialActionRepository->findOneBy(['id' => (int) $id]), - explode(',', $resultsAsString) - ); - } - )) + ->addModelTransformer( + $this->iterableToIdTransformer(Result::class) + ) ; + } + private function iterableToIdTransformer(string $entity): CallbackTransformer + { + return new CallbackTransformer( + static function (?iterable $asIterable): string { + if (null === $asIterable) { return ''; } + $ids = []; + foreach ($asIterable as $value) { + $ids[] = $value->getId(); + } + return implode(',', $ids); + }, + function (?string $asString) use ($entity): array { + if (null === $asString) { return []; } + return array_map( + fn (string $id) + => $this->em + ->getRepository($entity) + ->findOneBy(['id' => (int) $id]), + explode(',', $asString) + ); + } + ); } public function getTitle(): string { - return 'Filter by type of action, objectives and results'; + return 'Filter by type of action, goals and results'; } public function describeAction($data, $format = 'string'): array { $actionTypes = []; - $objectives = []; + $goals = []; $results = []; foreach ($data['actionType'] as $at) { - $actionTypes[] = $at->getTitle(); - } - foreach ($data['objectives'] as $o) { - $objectives[] = $o->getTitle(); - } - foreach ($data['results'] as $r) { - $results[] = $r->getTitle(); + $actionTypes[] = $this->translatableStringHelper->localize( + $at->getTitle() + ); } - return ['Filtered by referrers: only %actionTypes%', [ - '%actionTypes%' => implode(', ou ', $actionTypes) + foreach ($data['goal'] as $g) { + $goals[] = $this->translatableStringHelper->localize( + $g->getTitle() + ); + } + + foreach ($data['result'] as $r) { + $results[] = $this->translatableStringHelper->localize( + $r->getTitle() + ); + } + + return ['Filtered actions by type, goals and results: %selected%', [ + '%selected%' => implode(', ', array_merge($actionTypes, $goals, $results)) ]]; } @@ -152,28 +136,44 @@ class SocialWorkTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->eq('acpw.socialAction',':actionType'); - /* - if (!empty($data['goal'])) { - $clause - $qb->expr()->in('acpw.goals', ':goals'); + if (count($data['actionType']) > 0) { + $clause = $qb->expr()->in('acpw.socialAction', ':actionType'); + + if ($where instanceof Andx) { + $where->add($clause); + } else { + $where = $qb->expr()->andX($clause); + } + + $qb->setParameter('actionType', $data['actionType']); } - $qb->expr()->in('acpw.results', ':results'); - */ - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); + if (count($data['goal']) > 0) { + if (!in_array('goal', $qb->getAllAliases(), true)) { + $qb->join('acpw.goals', 'goal'); + } + + $where->add( + $qb->expr()->in('goal.id', ':goals') + ); + + $qb->setParameter('goals', $data['goal']); + } + + if (count($data['result']) > 0) { + if (!in_array('result', $qb->getAllAliases(), true)) { + $qb->join('acpw.results', 'result'); + } + + $where->add( + $qb->expr()->in('result.id', ':results') + ); + + $qb->setParameter('results', $data['result']); } $qb->add('where', $where); - $qb->setParameters([ - 'actionType' => $data['actionType'], - 'goal' => $data['goal'], - 'result' => $data['result'], - ]); } public function applyOn(): string diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepository.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepository.php index ea5b1feff..283dac151 100644 --- a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepository.php @@ -15,8 +15,9 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\ResultSetMappingBuilder; +use UnexpectedValueException; -final class ClosingMotiveRepository +final class ClosingMotiveRepository implements ClosingMotiveRepositoryInterface { private EntityManagerInterface $entityManager; @@ -54,4 +55,35 @@ final class ClosingMotiveRepository ->createNativeQuery($sql, $rsm) ->getResult(); } + + public function find($id): ?ClosingMotive + { + return $this->repository->find($id); + } + + /** + * @return array|ClosingMotive[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array|ClosingMotive[] + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?ClosingMotive + { + return $this->findOneBy($criteria); + } + + public function getClassName(): string + { + return ClosingMotive::class; + } } diff --git a/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepositoryInterface.php new file mode 100644 index 000000000..fbea29a0b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/ClosingMotiveRepositoryInterface.php @@ -0,0 +1,13 @@ + new Promise((resolve, reject) => { - //console.log('fetch Goals', response); - this.addElementInData('goals', response.results); - resolve(); - })).catch; - getResultByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); - this.addElementInData('results', response.results); - resolve(); - })).catch; + //console.log('----'); console.log('select action', value.id); + let children = this.getChildrensFromParent(value); + this.addSelectedElement('actions', children); + + let parentAndChildren = [...[value], ...children]; + parentAndChildren.forEach(elem => { + getGoalByAction(elem.id).then(response => new Promise((resolve, reject) => { + this.addElementInData('goals', response.results); + resolve(); + })).catch; + getResultByAction(elem.id).then(response => new Promise((resolve, reject) => { + this.addElementInData('results', response.results); + resolve(); + })).catch; + }); }, unselectAction(value) { - console.log('unselectAction', value); + //console.log('----'); console.log('unselect action', value.id); getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Goals', response); - this.goals.options = this.removeElementInData('goals', response.results); + [ this.goals.options, this.goals.value ] = this.removeElementInData('goals', response.results); resolve(); })).catch; getResultByAction(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); - this.results.options = this.removeElementInData('results', response.results); + [ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); resolve(); })).catch; }, @@ -200,23 +203,48 @@ export default { * @param value */ selectGoal(value) { - console.log('selectGoal', value); + //console.log('----'); console.log('select goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); this.addElementInData('results', response.results); resolve(); })).catch; }, unselectGoal(value) { - console.log('unselectGoal', value); + //console.log('----'); console.log('unselect goal', value.id); getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { - //console.log('fetch Results', response); - this.results.options = this.removeElementInData('results', response.results); + [ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); resolve(); })).catch; }, + /** + * Select/unselect in Result Multiselect + * @param value + */ + selectResult(value) { + //console.log('----'); console.log('select result', value.id); + }, + + unselectResult(value) { + //console.log('----'); console.log('unselect result', value.id); + }, + + /** + * Choose parent action will involve retaining the "children" actions. + * @param value + * @return array + */ + getChildrensFromParent(value) { + if (null === value.parent) { + let excludeParent = this.actions.options.filter(o => o.parent !== null); + let children = excludeParent.filter(o => o.parent.id === value.id); + //console.log("get childrens", children.map(e => e.id)); + return children; + } + return []; + }, + /** * Add response elements in data target * @param target string -> 'actions', 'goals' or 'results' @@ -224,13 +252,17 @@ export default { */ addElementInData(target, response) { let data = this[target]; + let dump = []; response.forEach(elem => { let found = data.options.some(e => e.id === elem.id); if (!found) { - console.log('push elem in', target, elem.id); data.options.push(elem); + dump.push(elem.id); } }) + if (dump.length > 0) { + //console.log('push ' + dump.length + ' elems in', target, dump); + } }, /** @@ -241,28 +273,80 @@ export default { */ removeElementInData(target, response) { let data = this[target]; + let dump = []; response.forEach(elem => { let found = data.options.some(e => e.id === elem.id); if (found) { - console.log('remove elem from', target, elem.id); data.options = data.options.filter(e => e.id !== elem.id); + dump.push(elem.id); - /// remove too from selected and from hiddenField - let selected = data.value.some(e => e.id === elem.id); - if (selected) { - // remove from selected - data.value = data.value.filter(e => e.id !== elem.id); - // remove from hiddenField - this.rebuildHiddenFieldValues(target); - // remove should be recursive; here it works but is not fine - if (target === 'goals') { // <==== TODO improve loop - this.unselectGoal(elem); - } - } - /// + this.removeSelectedElement(target, elem); } }) - return data.options; + if (dump.length > 0) { + //console.log('remove ' + dump.length + ' elems from ' + target + ' options', dump); + } + return [ data.options, data.value ]; + }, + + /** + * + * @param target + * @param elements + */ + addSelectedElement(target, elements) { + let data = this[target]; + let dump = []; + elements.forEach(elem => { + let selected = data.value.some(e => e.id === elem.id); + if (!selected) { + + data.value.push(elem); + dump.push(elem.id); + + // add in hiddenField + this.rebuildHiddenFieldValues(target); + } + }); + if (dump.length > 0) { + //console.log('add ' + dump.length + ' selected elems in', target, dump); + } + }, + + /** + * Remove element from selected and from hiddenField + * @param target + * @param elem + */ + removeSelectedElement(target, elem) { + let data = this[target]; + let selected = data.value.some(e => e.id === elem.id); + if (selected) { + + // remove from selected + data.value = data.value.filter(e => e.id !== elem.id); + //console.log('remove ' + elem.id + ' from selected ' + target); + + // remove from hiddenField + this.rebuildHiddenFieldValues(target); + + // in any cases, remove should be recursive + this.unselectToNextField(target, elem); + } + }, + + /** + * When unselect Action, it could remove elements in goals multiselect. + * In that case, we have to unselect Goal to remove elements in results too. + * @param target + * @param elem + */ + unselectToNextField(target, elem) { + if (target === 'goals') { + //console.log('!!!! target is goal: unselect goal', elem.id); + this.unselectGoal(elem); + //console.log('!!!! done'); + } }, /** @@ -271,10 +355,12 @@ export default { */ rebuildHiddenFieldValues(target) { let data = this[target]; + //console.log('rebuild hiddenFields ' + target + ' values :'); data.hiddenField.value = ''; // reset data.value.forEach(elem => { data.hiddenField.value = this.addIdToValue(data.hiddenField.value, elem.id); }) + //console.log(data.hiddenField); }, addIdToValue(string, id) { diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/api.js similarity index 100% rename from src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js rename to src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/api.js diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js similarity index 100% rename from src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js rename to src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index 3efcf3c24..3b6c21db9 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; @@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH ->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK]) ->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL]) ->addCheckFor(Person::class, [self::SEE, self::CREATE]) + ->addCheckFor(Center::class, [self::STATS]) ->build(); } diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php index ca956db63..0288c9e61 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/HouseholdVoter.php @@ -11,6 +11,10 @@ declare(strict_types=1); namespace Chill\PersonBundle\Security\Authorization; +use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; +use Chill\MainBundle\Security\Authorization\VoterHelperInterface; +use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\HouseholdMember; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -19,7 +23,7 @@ use Symfony\Component\Security\Core\Security; use UnexpectedValueException; use function in_array; -class HouseholdVoter extends Voter +class HouseholdVoter extends Voter implements ProvideRoleHierarchyInterface { public const EDIT = 'CHILL_PERSON_HOUSEHOLD_EDIT'; @@ -36,17 +40,40 @@ class HouseholdVoter extends Voter self::EDIT, self::SEE, ]; + private VoterHelperInterface $helper; + private Security $security; - public function __construct(Security $security) + public function __construct(Security $security, VoterHelperFactoryInterface $voterHelperFactory) { $this->security = $security; + $this->helper = $voterHelperFactory + ->generate(self::class) + ->addCheckFor(Center::class, [self::STATS]) + ->build(); + } + + public function getRolesWithHierarchy(): array + { + return [ 'Person' => $this->getRoles() ]; + } + + public function getRoles(): array + { + return [self::STATS]; + } + + public function getRolesWithoutScope(): array + { + return $this->getRoles(); } protected function supports($attribute, $subject) { - return $subject instanceof Household - && in_array($attribute, self::ALL, true); + return ($subject instanceof Household + && in_array($attribute, self::ALL, true)) + || $this->helper->supports($attribute, $subject) + ; } protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool @@ -58,6 +85,9 @@ class HouseholdVoter extends Voter case self::EDIT: return $this->checkAssociatedMembersRole($subject, PersonVoter::UPDATE); + case self::STATS: + return $this->voteOnAttribute($attribute, $subject, $token); + default: throw new UnexpectedValueException('attribute not supported'); } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregatorTest.php new file mode 100644 index 000000000..82a879b19 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_administrative_location'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.administrativeLocation', 'acploc') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregatorTest.php new file mode 100644 index 000000000..279b621d4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_closingmotive'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.closingMotive', 'acpmotive') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregatorTest.php new file mode 100644 index 000000000..ab0e3dae3 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregatorTest.php @@ -0,0 +1,57 @@ +aggregator = self::$container->get('chill.person.export.aggregator_confidential'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregatorTest.php new file mode 100644 index 000000000..056c396e0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregatorTest.php @@ -0,0 +1,57 @@ +aggregator = self::$container->get('chill.person.export.aggregator_duration'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregatorTest.php new file mode 100644 index 000000000..0b8ff2b12 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregatorTest.php @@ -0,0 +1,57 @@ +aggregator = self::$container->get('chill.person.export.aggregator_emergency'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregatorTest.php new file mode 100644 index 000000000..8c67eb649 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_evaluation'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregatorTest.php new file mode 100644 index 000000000..b3da8ea13 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregatorTest.php @@ -0,0 +1,57 @@ +aggregator = self::$container->get('chill.person.export.aggregator_intensity'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/JobAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/JobAggregatorTest.php new file mode 100644 index 000000000..8e14ffe4c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/JobAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_referrer_job'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.job', 'acpjob') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregatorTest.php new file mode 100644 index 000000000..cdd709226 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_origin'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.origin', 'acporigin') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php new file mode 100644 index 000000000..789baa228 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_referrer'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.user', 'acpuser') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregatorTest.php new file mode 100644 index 000000000..f888e2535 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_requestor'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.participations', 'acppart') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregatorTest.php new file mode 100644 index 000000000..05fe5e980 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_referrer_scope'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.scopes', 'acpscope') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregatorTest.php new file mode 100644 index 000000000..cdf27c1a5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_socialaction'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregatorTest.php new file mode 100644 index 000000000..912a2b7c6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_socialissue'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.socialIssues', 'acpsocialissue') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/StepAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/StepAggregatorTest.php new file mode 100644 index 000000000..ee11eeee4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/AccompanyingCourseAggregators/StepAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_step'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'on_date' => \DateTime::createFromFormat('Y-m-d', '2022-01-01'), + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregatorTest.php new file mode 100644 index 000000000..60b8d838c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_evaluationtype'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregatorTest.php new file mode 100644 index 000000000..bef052329 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregatorTest.php @@ -0,0 +1,64 @@ +aggregator = self::$container->get('chill.person.export.aggregator_household_childrennumber'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'on_date' => \DateTime::createFromFormat('Y-m-d', '2022-07-01') + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.participations', 'acppart') + ->join('acppart.person', 'partperson') + ->join('partperson.householdParticipations', 'member') + ->join('member.household', 'household') + ->join('household.compositions', 'composition') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/CompositionAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/CompositionAggregatorTest.php new file mode 100644 index 000000000..fc808c03d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/HouseholdAggregators/CompositionAggregatorTest.php @@ -0,0 +1,64 @@ +aggregator = self::$container->get('chill.person.export.aggregator_household_composition'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'on_date' => \DateTime::createFromFormat('Y-m-d', '2022-07-01') + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.participations', 'acppart') + ->join('acppart.person', 'partperson') + ->join('partperson.householdParticipations', 'member') + ->join('member.household', 'household') + ->join('household.compositions', 'composition') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/AgeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/AgeAggregatorTest.php index a0d869462..031ded74c 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/AgeAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/AgeAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Aggregator\PersonAggregators; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; +use Chill\PersonBundle\Export\Aggregator\PersonAggregators\AgeAggregator; use DateTime; /** @@ -20,10 +21,7 @@ use DateTime; */ final class AgeAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\PersonBundle\Export\Aggregator\PersonAggregators\AgeAggregator - */ - private $aggregator; + private AgeAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/CountryOfBirthAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/CountryOfBirthAggregatorTest.php new file mode 100644 index 000000000..90596d892 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/CountryOfBirthAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_country_of_birth'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + ['group_by_level' => 'continent'], + ['group_by_level' => 'country',], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(person.id)') + ->from(Person::class, 'person') + ->leftJoin('person.countryOfBirth', 'countryOfBirth') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/GenderAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/GenderAggregatorTest.php index 6389ac33d..16bca62d9 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/GenderAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/GenderAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Aggregator\PersonAggregators; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; +use Chill\PersonBundle\Export\Aggregator\PersonAggregators\GenderAggregator; /** * @internal @@ -19,10 +20,7 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest; */ final class GenderAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\PersonBundle\Export\Aggregator\PersonAggregators\GenderAggregator - */ - private $aggregator; + private GenderAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/HouseholdPositionAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/HouseholdPositionAggregatorTest.php new file mode 100644 index 000000000..91a22d05a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/HouseholdPositionAggregatorTest.php @@ -0,0 +1,63 @@ +aggregator = self::$container->get('chill.person.export.aggregator_household_position'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [ + 'date_position' => \DateTime::createFromFormat('Y-m-d', '2022-07-01') + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(person.id)') + ->from(Person::class, 'person') + ->join(HouseholdMember::class, 'householdmember', Expr\Join::WITH, 'householdmember.person = person') + ->join('person.center', 'center') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/MaritalStatusAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/MaritalStatusAggregatorTest.php new file mode 100644 index 000000000..25ddb602d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/MaritalStatusAggregatorTest.php @@ -0,0 +1,58 @@ +aggregator = self::$container->get('chill.person.export.aggregator_marital_status'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(person.id)') + ->from(Person::class, 'person') + ->join('person.maritalStatus', 'personmarital') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/NationalityAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/NationalityAggregatorTest.php index c093d96cc..7de9587eb 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/NationalityAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/PersonAggregators/NationalityAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Aggregator\PersonAggregators; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; +use Chill\PersonBundle\Export\Aggregator\PersonAggregators\NationalityAggregator; /** * @internal @@ -19,10 +20,7 @@ use Chill\MainBundle\Test\Export\AbstractAggregatorTest; */ final class NationalityAggregatorTest extends AbstractAggregatorTest { - /** - * @var \Chill\PersonBundle\Export\Aggregator\PersonAggregators\NationalityAggregator - */ - private $aggregator; + private NationalityAggregator $aggregator; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregatorTest.php index ab0492d11..ed83c3af7 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); 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\ActionTypeAggregator; /** @@ -34,14 +35,14 @@ final class ActionTypeAggregatorTest extends AbstractAggregatorTest return $this->aggregator; } - public function getFormData() + public function getFormData(): array { return [ [], ]; } - public function getQueryBuilders() + public function getQueryBuilders(): array { if (null === self::$kernel) { self::bootKernel(); @@ -53,7 +54,8 @@ final class ActionTypeAggregatorTest extends AbstractAggregatorTest return [ $em->createQueryBuilder() ->select('count(acpw.id)') - ->from('ChillPersonBundle:AccompanyingPeriodWork', 'acpw'), + ->from(AccompanyingPeriodWork::class, 'acpw') + , ]; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalAggregatorTest.php index ef5bd5097..979f3c488 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); 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\GoalAggregator; /** @@ -34,14 +35,14 @@ final class GoalAggregatorTest extends AbstractAggregatorTest return $this->aggregator; } - public function getFormData() + public function getFormData(): array { return [ [], ]; } - public function getQueryBuilders() + public function getQueryBuilders(): array { if (null === self::$kernel) { self::bootKernel(); @@ -53,7 +54,8 @@ final class GoalAggregatorTest extends AbstractAggregatorTest return [ $em->createQueryBuilder() ->select('count(acpw.id)') - ->from('ChillPersonBundle:AccompanyingPeriodWork', 'acpw'), + ->from(AccompanyingPeriodWork::class, 'acpw') + , ]; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalResultAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalResultAggregatorTest.php new file mode 100644 index 000000000..37642fa33 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/GoalResultAggregatorTest.php @@ -0,0 +1,60 @@ +aggregator = self::$container->get('chill.person.export.aggregator_goalresult'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.goals', 'goal') + ->join('goal.results', 'goalresult') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/JobAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/JobAggregatorTest.php new file mode 100644 index 000000000..c686e66b6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/JobAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_treatingagent_job'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.referrers', 'acpwuser') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ReferrerAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ReferrerAggregatorTest.php index 446cf1e37..b8070398a 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ReferrerAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ReferrerAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); 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\ReferrerAggregator; /** @@ -34,14 +35,14 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest return $this->aggregator; } - public function getFormData() + public function getFormData(): array { return [ [], ]; } - public function getQueryBuilders() + public function getQueryBuilders(): array { if (null === self::$kernel) { self::bootKernel(); @@ -53,7 +54,8 @@ final class ReferrerAggregatorTest extends AbstractAggregatorTest return [ $em->createQueryBuilder() ->select('count(acpw.id)') - ->from('ChillPersonBundle:AccompanyingPeriodWork', 'acpw'), + ->from(AccompanyingPeriodWork::class, 'acpw') + , ]; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ResultAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ResultAggregatorTest.php index a34a16a8a..984e296bc 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ResultAggregatorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ResultAggregatorTest.php @@ -12,6 +12,7 @@ declare(strict_types=1); 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\ResultAggregator; /** @@ -34,14 +35,14 @@ final class ResultAggregatorTest extends AbstractAggregatorTest return $this->aggregator; } - public function getFormData() + public function getFormData(): array { return [ [], ]; } - public function getQueryBuilders() + public function getQueryBuilders(): array { if (null === self::$kernel) { self::bootKernel(); @@ -53,7 +54,8 @@ final class ResultAggregatorTest extends AbstractAggregatorTest return [ $em->createQueryBuilder() ->select('count(acpw.id)') - ->from('ChillPersonBundle:AccompanyingPeriodWork', 'acpw'), + ->from(AccompanyingPeriodWork::class, 'acpw') + , ]; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php new file mode 100644 index 000000000..3cece9ed9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Aggregator/SocialWorkAggregators/ScopeAggregatorTest.php @@ -0,0 +1,59 @@ +aggregator = self::$container->get('chill.person.export.aggregator_treatingagent_scope'); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(acp.id)') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.referrers', 'acpwuser') + , + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserJobFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserJobFilterTest.php index 77881a218..ab2c703b6 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserJobFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserJobFilterTest.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserJobFilter; +use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserJobFilter; use Doctrine\ORM\EntityManagerInterface; /** @@ -21,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface; */ final class CurrentUserJobFilterTest extends AbstractFilterTest { - private UserJobFilter $filter; + private CurrentUserJobFilter $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserScopeFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserScopeFilterTest.php index 1ea4d40b0..d4f4712bc 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserScopeFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/AccompanyingCourseFilters/CurrentUserScopeFilterTest.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserScopeFilter; +use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserScopeFilter; use Doctrine\ORM\EntityManagerInterface; /** @@ -21,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface; */ final class CurrentUserScopeFilterTest extends AbstractFilterTest { - private UserScopeFilter $filter; + private CurrentUserScopeFilter $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/EvaluationTypeFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/EvaluationTypeFilterTest.php new file mode 100644 index 000000000..8ba2b46c1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/EvaluationTypeFilterTest.php @@ -0,0 +1,83 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_evaluationtype'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(Evaluation::class, 'e') + ->select('e') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $r) { + $data[] = [ + 'accepted_evaluationtype' => $r + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('workeval.id') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/MaxDateFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/MaxDateFilterTest.php new file mode 100644 index 000000000..5c9533850 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/EvaluationFilters/MaxDateFilterTest.php @@ -0,0 +1,70 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_maxdate'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + ['maxdate' => false ], + ['maxdate' => true ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('workeval.id') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw') + ->join('acpw.accompanyingPeriodWorkEvaluations', 'workeval'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/HouseholdFilters/CompositionFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/HouseholdFilters/CompositionFilterTest.php new file mode 100644 index 000000000..6892c0afc --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/HouseholdFilters/CompositionFilterTest.php @@ -0,0 +1,82 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_household_composition'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(HouseholdCompositionType::class, 'r') + ->select('r') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $r) { + $data[] = [ + 'accepted_composition' => $r, + 'on_date' => \DateTime::createFromFormat('Y-m-d', '2022-05-01'), + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('h.id') + ->from(Household::class, 'h'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilterTest.php new file mode 100644 index 000000000..bf975c5a1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodClosingFilterTest.php @@ -0,0 +1,89 @@ +filter = self::$container->get('chill.person.export.filter_accompanying_period_closing'); + } catch (ServiceNotFoundException $e) { + $this->markTestSkipped('The current configuration does not use accompanying_periods'); + } + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2000-01-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2010-01-01'), + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container + ->get('doctrine.orm.entity_manager'); + + return [ + $em->createQueryBuilder() + ->select('person.firstName') + ->from('ChillPersonBundle:Person', 'person'), + $em->createQueryBuilder() + ->select('person.firstName') + ->from('ChillPersonBundle:Person', 'person') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('count(IDENTITY(p))') + ->from('ChillPersonBundle:Person', 'person') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('count(IDENTITY(p))') + ->from('ChillPersonBundle:Person', 'person') + ->join('person.accompanyingPeriods', 'accompanying_period') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('activity.date AS date') + ->select('activity.attendee as attendee') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.person', 'person') + ->join('person.center', 'center'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodFilterTest.php index fb975000a..943f20d73 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodFilterTest.php @@ -12,7 +12,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Tests\Export\Filter\PersonFilters; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use Chill\PersonBundle\Export\Filter\PersonFilters\BirthdateFilter; +use Chill\PersonBundle\Export\Filter\PersonFilters\AccompanyingPeriodFilter; use DateTime; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; @@ -22,7 +22,7 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; */ final class AccompanyingPeriodFilterTest extends AbstractFilterTest { - private BirthdateFilter $filter; + private AccompanyingPeriodFilter $filter; protected function setUp(): void { diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilterTest.php new file mode 100644 index 000000000..54ed981ec --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AccompanyingPeriodOpeningFilterTest.php @@ -0,0 +1,89 @@ +filter = self::$container->get('chill.person.export.filter_accompanying_period_opening'); + } catch (ServiceNotFoundException $e) { + $this->markTestSkipped('The current configuration does not use accompanying_periods'); + } + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData() + { + return [ + [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2000-01-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2010-01-01'), + ], + ]; + } + + public function getQueryBuilders() + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container + ->get('doctrine.orm.entity_manager'); + + return [ + $em->createQueryBuilder() + ->select('person.firstName') + ->from('ChillPersonBundle:Person', 'person'), + $em->createQueryBuilder() + ->select('person.firstName') + ->from('ChillPersonBundle:Person', 'person') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('count(IDENTITY(p))') + ->from('ChillPersonBundle:Person', 'person') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('count(IDENTITY(p))') + ->from('ChillPersonBundle:Person', 'person') + ->join('person.accompanyingPeriods', 'accompanying_period') + // add a dummy where clause + ->where('person.firstname IS NOT NULL'), + $em->createQueryBuilder() + ->select('activity.date AS date') + ->select('activity.attendee as attendee') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.person', 'person') + ->join('person.center', 'center'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AgeFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AgeFilterTest.php new file mode 100644 index 000000000..30ca43dfd --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/AgeFilterTest.php @@ -0,0 +1,75 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_age'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'min_age' => '18', + 'max_age' => '60', + 'date_calc' => \DateTime::createFromFormat('Y-m-d', '2020-05-01'), + ], + [ // ça devrait faire boum ! + 'min_age' => '35', + 'max_age' => '30', + 'date_calc' => \DateTime::createFromFormat('Y-m-d', '2020-05-01'), + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p'), + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdayFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdateFilterTest.php similarity index 96% rename from src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdayFilterTest.php rename to src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdateFilterTest.php index 4ff4f5ce3..68664b8b7 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdayFilterTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/BirthdateFilterTest.php @@ -19,7 +19,7 @@ use DateTime; * @internal * @coversNothing */ -final class BirthdayFilterTest extends AbstractFilterTest +final class BirthdateFilterTest extends AbstractFilterTest { private BirthdateFilter $filter; diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeadOrAliveFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeadOrAliveFilterTest.php new file mode 100644 index 000000000..ea2fa62cb --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeadOrAliveFilterTest.php @@ -0,0 +1,73 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_dead_or_alive'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'person_state' => 'alive', + 'date_calc' => \DateTime::createFromFormat('Y-m-d', '2021-05-01'), + ], + [ + 'person_state' => 'deceased', + 'date_calc' => \DateTime::createFromFormat('Y-m-d', '2021-05-01'), + ], + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeathdateFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeathdateFilterTest.php new file mode 100644 index 000000000..cb711af43 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/DeathdateFilterTest.php @@ -0,0 +1,69 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_deathdate'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2020-05-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2022-05-01'), + ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/MaritalStatusFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/MaritalStatusFilterTest.php new file mode 100644 index 000000000..8ce747f63 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/MaritalStatusFilterTest.php @@ -0,0 +1,83 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_marital_status'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(MaritalStatus::class, 'm') + ->select('m') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $m) { + $data[] = [ + 'maritalStatus' => $m, + 'calc_date' => \DateTime::createFromFormat('Y-m-d', '2022-05-01'), + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p'), + ]; + } +} + diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/NationalityFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/NationalityFilterTest.php new file mode 100644 index 000000000..4ea2c44cc --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/NationalityFilterTest.php @@ -0,0 +1,78 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_nationality'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $countries = $em->getRepository(Country::class)->findAll(); + + $data = []; + + foreach ($countries as $c) { + $data[] = [ + 'nationalities' => $c + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p'), + ]; + } + +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilterTest.php new file mode 100644 index 000000000..8bd07f75c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilterTest.php @@ -0,0 +1,89 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_residential_address_at_thirdparty'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(ThirdPartyCategory::class, 'tpc') + ->select('tpc') + ->getQuery() + ->getResult(); + + $data = []; + + foreach ($array as $r) { + $data[] = [ + 'thirdparty_cat' => $r, + 'date_calc' => \DateTime::createFromFormat('Y-m-d', '2022-05-01'), + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p') + ->join(ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = p') + ->join('p.center', 'center') + ->join('resaddr.hostThirdParty', 'tparty') + ->join('tparty.categories', 'tpartycat') + , + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtUserFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtUserFilterTest.php new file mode 100644 index 000000000..6a2cde4b0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/PersonFilters/ResidentialAddressAtUserFilterTest.php @@ -0,0 +1,69 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_residential_address_at_user'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return []; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('p.id') + ->from(Person::class, 'p') + ->join(Person\ResidentialAddress::class, 'resaddr', Expr\Join::WITH, 'resaddr.person = p') + ->join('p.center', 'center'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/ReferrerFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/ReferrerFilterTest.php new file mode 100644 index 000000000..c5cc9c523 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/ReferrerFilterTest.php @@ -0,0 +1,77 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_treatingagent'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $em = self::$container->get(EntityManagerInterface::class); + + $users = $em->getRepository(User::class)->findAll(); + + $data = []; + + foreach ($users as $u) { + $data[] = [ + 'accepted_agents' => $u + ]; + } + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('acpw.id') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php new file mode 100644 index 000000000..2e3b392ae --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Export/Filter/SocialWorkFilters/SocialWorkTypeFilterTest.php @@ -0,0 +1,111 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.person.export.filter_social_work_type'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + $action_repository = self::$container->get(SocialActionRepository::class); + $goal_repository = self::$container->get(GoalRepository::class); + $result_repository = self::$container->get(ResultRepository::class); + + $actions = []; + $goals = []; + $results = []; + + $social_actions = $action_repository->findAll(); + foreach ($social_actions as $action) { + $actions[] = $action->getId(); + $goals_by_action = $goal_repository->findBySocialActionWithDescendants($action); + foreach ($goals_by_action as $goal) { + $goals[] = $goal->getId(); + $results_by_goal = $result_repository->findByGoal($goal); + foreach ($results_by_goal as $result) { + $results[] = $result->getId(); + } + } + $results_by_action = $result_repository->findBySocialActionWithDescendants($action); + foreach ($results_by_action as $result) { + $results[] = $result->getId(); + } + } + + sort($actions); + sort($goals); + sort($results); + + $actions = array_unique($actions); + $goals = array_unique($goals); + $results = array_unique($results); + + $data = [ + [ + 'actionType' => implode(',', $actions), + 'goal' => implode(',', $goals), + 'result' => implode(',', $results), + ] + ]; + /// TODO ne fonctionne pas + var_dump($data); + + return $data; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('acpw.id') + ->from(AccompanyingPeriod::class, 'acp') + ->join('acp.works', 'acpw'), + ]; + } +} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/chill.webpack.config.js b/src/Bundle/ChillPersonBundle/chill.webpack.config.js index 85ee83c93..a445959e5 100644 --- a/src/Bundle/ChillPersonBundle/chill.webpack.config.js +++ b/src/Bundle/ChillPersonBundle/chill.webpack.config.js @@ -13,6 +13,7 @@ module.exports = function(encore, entries) encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js'); encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js'); encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js'); + encore.addEntry('vue_export_action_goal_result', __dirname + '/Resources/public/vuejs/ExportFormActionGoalResult/index.js'); encore.addEntry('mod_set_referrer', __dirname + '/Resources/public/mod/AccompanyingPeriod/setReferrer.js'); diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml index 73bd1cce3..f19db0649 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_accompanying_course.yaml @@ -65,13 +65,6 @@ services: tags: - { name: chill.export_filter, alias: accompanyingcourse_evaluation_filter } - chill.person.export.filter_activitytype: - class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\ActivityTypeFilter - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: accompanyingcourse_activitytype_filter } - chill.person.export.filter_origin: class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\OriginFilter autowire: true diff --git a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml index 04dc1a2ac..450899659 100644 --- a/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/exports_social_actions.yaml @@ -9,12 +9,12 @@ services: ## 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_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 @@ -79,3 +79,10 @@ services: 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 } diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 72edfa750..c94b4963d 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -86,8 +86,8 @@ Civility: Civilité choose civility: -- All genders: tous les genres Any person selected: Aucune personne sélectionnée -Create a household and add an address: Ajouter une adresse pour un usager non suivi et seul dans un ménage -A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage. +Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage +A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage. Comment on the gender: Commentaire sur le genre # dédoublonnage @@ -127,8 +127,8 @@ address_country_code: Code pays 'Alreay existing person': 'Dossiers déjà encodés' 'Add the person': 'Ajouter la personne' -'Add the person and create an accompanying period': "Créer l'usager ET créer une période d'accompagnement" -'Add the person and create a household': "Créer l'usager ET créer un ménage" +'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement" +'Add the person and create a household': "Créer la personne ET créer un ménage" Show person: Voir le dossier de la personne 'Confirm the creation': 'Confirmer la création' 'You will create this person': 'Vous allez créer le dossier suivant' @@ -200,7 +200,7 @@ Participants: Personnes impliquées Create an accompanying course: Créer un parcours Accompanying courses of users: Parcours des utilisateurs This accompanying course is still a draft: Ce parcours est encore à l'état brouillon. -Associated peoples: Usagers concernés +Associated peoples: Personnes concernées Resources: Interlocuteurs privilégiés Any requestor to this accompanying course: Aucun demandeur pour ce parcours Social action: Action d'accompagnement @@ -217,7 +217,7 @@ See this period: Voir cette période Requestor: Demandeur No requestor: Pas de demandeur No resources: "Pas d'interlocuteurs privilégiés" -Persons associated: Usagers concernés +Persons associated: Personnes concernés Referrer: Référent Referrers: Agents traitants Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible. @@ -244,7 +244,7 @@ List of resources: "Liste des ressources" There are no available resources: "Aucun ressource" no comment found: "Aucun commentaire" Select a type: "Choisissez un type" -Select a person: "Choisissez un usager" +Select a person: "Choisissez une personne" Select a thirdparty: "Choisissez un tiers" Contact person: "Personne de contact" Kind: "Type" @@ -276,11 +276,11 @@ Which kind of residential address would you create ?: Quel type d'adresse de ré The address of another person: L'adresse d'une autre personne The address of a third party: L'adresse d'un tiers A new address: Une nouvelle adresse -residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cet usager +residential_address_person_explanation: L'adresse sera positionnée auprès d'une personne. Lorsque la personne déménage, l'adresse de résidence suivra également cette personne residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers. residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe. New residential address: Nouvelle adresse de résidence -Host person: Choisir l'adresse d'un usager +Host person: Choisir l'adresse d'une personne Host third party: Choisir l'adresse d'un tiers The new residential address was created successfully: La nouvelle adresse de résidence a été créée Edit a residential address: Modifier l'addresse de résidence @@ -318,6 +318,7 @@ CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et m CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'une période d'accompagnement CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement +CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages #period Period closed!: Période clôturée! @@ -330,16 +331,16 @@ Accompanyied people: Personnes accompagnées ## exports Exports of persons: Exports des personnes -Count people by various parameters.: Compte le nombre d'usagers en fonction de différents filtres. -Count people: Nombre d'usagers +Count people by various parameters.: Compte le nombre de personnes en fonction de différents filtres. +Count people: Nombre de personnes List peoples: Liste des personnes Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres. Fields to include in export: Champs à inclure dans l'export Address valid at this date: Addresse valide à cette date List duplicates: Liste des doublons Create a list of duplicate people: Créer la liste des personnes détectées comme doublons. -Count people participating in an accompanying course by various parameters.: Nombre d'usagers concernées par un parcours -Count people participating in an accompanying course: Nombre d'usagers concernés par un parcours +Count people participating in an accompanying course: Nombre de personnes concernées par un parcours +Count people participating in an accompanying course by various parameters.: Compte le nombre de personnes concernées par un parcours Exports of accompanying courses: Exports des parcours d'accompagnement Count accompanying courses: Nombre de parcours @@ -362,72 +363,77 @@ Count households: Nombre de ménages Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres. ## persons filters -Filter by person gender: Filtrer par genre de la personne +Filter by person gender: Filtrer les personnes par genre Accepted genders: Genres acceptés 'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%' -Filter by person's nationality: Filtrer par nationalité +Filter by person's nationality: Filtrer les personnes par nationalité Nationalities: Nationalités Choose countries: Choisir les nationalités 'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%' -Filter by person's birthdate: Filtrer par date de naissance de la personne +Filter by person's birthdate: Filtrer les personnes par date de naissance Born after this date: Nés après cette date Born before this date: Nés avant cette date This field should not be empty: Ce champ ne peut pas être vide This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le" "Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%" -Filter by person's deathdate: Filtrer par date de décès de la personne +Filter by person's deathdate: Filtrer les personnes par date de décès "Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%" Death after this date: Décédé après cette date Deathdate before: Décédé avant cette date - Alive: Vivant Deceased: Décédé Filter in relation to this date: Filtrer par rapport à cette date -"Filtered by a state of %deadOrAlive% at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc% +"Filtered by a state of %deadOrAlive%: at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc% -Filter by person's age: Filtrer par âge de la personne +Filter by person's age: Filtrer les personnes par age "Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%" Minimum age: Âge minimum Maximum age: Âge maximum The minimum age should be less than the maximum age.: L'âge minimum doit être plus bas que l'âge maximum. Date during which residential address was valid: Date de validité -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% +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% Family composition: Composition familiale Family composition at this time: Composition familiale à cette date. +Filter by person's marital status: Filtrer les personnes par état matrimonial Filtered by person's marital status: Filtré par état matrimonial -Filter by person's marital status: Filtrer par état matrimonial Marital status at this time: État matrimonial par rapport à cette date -Filter by entrusted child status: Filtrer les usagers qui sont "enfant confié" -Filtered by entrusted child status: Uniquement les usagers qui sont "enfant confié" +Filter by entrusted child status: Filtrer les personnes "enfant confié" +Filtered by entrusted child status: Uniquement les personnes qui sont "enfant confié" -Filter by nomadic status: Filtrer les usagers qui sont "gens de voyage" -Filtered by nomadic status: Uniquement les usagers qui sont "gens de voyage" +Filter by nomadic status: Filtrer les personnes "gens du voyage" +Filtered by nomadic status: Uniquement les personnes qui sont "gens du voyage" -Filtered by person's who have a residential address located at another user: Uniquement les usagers qui ont une addresse de résidence chez un autre usager +"Filter by person's who have a residential address located at another user": Filtrer les personnes qui ont une addresse de résidence chez une autre personne +"Filtered by person's who have a residential address located at another user": Uniquement les personnes qui ont une addresse de résidence chez une autre personne -Filtered by person's that are alive or have deceased at a certain date: Filtrer par usagers qui sont décédé ou vivant à une certaine date +Filter by person's that are alive or have deceased at a certain date: Filtrer les personnes qui sont décédées ou vivantes à une certaine date +Filtered by person's that are alive or have deceased at a certain date: Uniquement les personnes qui sont décédées ou vivantes à une certaine date -"Filter by accompanying period: active period": "Filtrer par période d'accompagnement: en file active" +"Filter by accompanying period: active period": "Filtrer les personnes par période d'accompagnement: en file active" Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date "Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)" -"Filter by accompanying period: starting between two dates": "Filtrer par période d'accompagnement: début de la période entre deux dates" +"Filter by accompanying period: starting between two dates": "Filtrer les personnes par période d'accompagnement: début de la période entre deux dates" "Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date" "Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%" -"Filter by accompanying period: closed between two dates": "Filtrer par période d'accompagnement: période fermée entre deux dates" +"Filter by accompanying period: closed between two dates": "Filtrer les personnes par période d'accompagnement: période fermée entre deux dates" Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date "Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date" "Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%" +Filter by person having an activity in a period: Filtrer les personnes ayant eu une échange pendant la période donnée +Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à une échange entre %date_from% et %date_to% avec les sujets %reasons_name% + + ## accompanying course filters/aggr Filter by user scope: Filtrer les parcours par service du référent "Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%" @@ -456,7 +462,9 @@ Filter by socialaction: Filtrer les parcours par action d'accompagnement Accepted socialactions: Actions d'accompagnement "Filtered by socialactions: only %socialactions%": "Filtré par action d'accompagnement: uniquement %socialactions%" Group by social action: Grouper les parcours par action d'accompagnement -Filter by type of action, objectives and results: "Filtrer les actions par type, objectif et résultat" + +Filter by type of action, goals and results: "Filtrer les actions par type, objectif et résultat" +'Filtered actions by type, goals and results: %selected%': "Actions filtrées par: %selected%" Filter by evaluation: Filtrer les parcours par évaluation Accepted evaluations: Évaluations @@ -484,13 +492,13 @@ Administrative location: Localisation administrative "Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%" Group by administrative location: Grouper les parcours par localisation administrative -Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés +Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des personnes concernées Accepted choices: '' -is person concerned: Le demandeur est un usager concerné -is other person: Le demandeur est un usager, mais n'est pas concerné +is person concerned: Le demandeur est une personne concernée +is other person: Le demandeur est une personne, mais n'est pas concernée is thirdparty: Le demandeur est un tiers no requestor: Le parcours ne comporte pas de demandeur -"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%" +"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des personnes concernées: uniquement si %choice%" Group by requestor: Grouper les parcours selon la nature du demandeur Filter by confidential: Filtrer les parcours par confidentialité @@ -552,8 +560,11 @@ Group by treating agent: Grouper les actions par agent traitant Group social work actions by action type: Grouper les actions par type Group social work actions by goal: Grouper les actions par objectif -Goal Type: Objectif Group social work actions by result: Grouper les actions par résultat +Group social work actions by goal and result: Grouper les actions par objectif et résultat +Goal Type: Objectif +Result Type: Résultat +Goal and result Type: Objectif et résultat ## evaluations filters/aggr Filter by evaluation type: Filtrer les évaluations par type @@ -590,13 +601,15 @@ Group by country: Grouper par pays Group people by gender: Grouper les personnes par genre Group people by their professional situation: Grouper les personnes par situation professionelle Group people by marital status: Grouper les personnes par état matrimonial -Aggregate by household position: Grouper par position dans le ménage + +Aggregate by household position: Grouper les personnes par position dans le ménage Household position in relation to this date: Position dans le ménage par rapport à cette date Household position: Position dans le ménage -Filtered by person's who have a residential address located at a thirdparty of type: Uniquement 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%" -Aggregate by age: Grouper par âge +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%" + +Aggregate by age: Grouper les personnes par âge Calculate age in relation to this date: Calculer l'âge par rapport à cette date Group people by country of birth: Grouper les personnes par pays de naissance @@ -764,7 +777,7 @@ This course is located at a temporarily address. You should locate this course t Accompanying course location: Localisation du parcours This course is located by: Localisé auprès de This course has a temporarily location: Localisation temporaire -Choose a person to locate by: Localiser auprès d'un usager concerné +Choose a person to locate by: Localiser auprès d'une personne concernée Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage. Locate by: Localiser auprès de fix it: Compléter @@ -849,7 +862,7 @@ Person addresses: Adresses de résidence Household addresses: Adresses de domicile Insert an address: Insérer une adresse see social issues: Voir les problématiques sociales -see persons associated: Voir les usagers concernés +see persons associated: Voir les personnes concernées docgen: Accompanying Period basic: "Parcours d'accompagnement (basique)" @@ -870,10 +883,10 @@ docgen: period_notification: period_designated_subject: Vous êtes référent d'un parcours d'accompagnement You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement. - Persons are: Les usagers concernés sont les suivants + Persons are: Les personnes concernées sont les suivantes Social issues are: Les problématiques sociales renseignées sont les suivantes See it online: Visualisez le parcours en ligne - Person locating period has moved: L'usager qui localise un parcours a déménagé + Person locating period has moved: La personne qui localise un parcours a déménagé You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide. You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès. diff --git a/src/Bundle/ChillReportBundle/Tests/Export/Filter/ReportDateFilterTest.php b/src/Bundle/ChillReportBundle/Tests/Export/Filter/ReportDateFilterTest.php new file mode 100644 index 000000000..27c107f9d --- /dev/null +++ b/src/Bundle/ChillReportBundle/Tests/Export/Filter/ReportDateFilterTest.php @@ -0,0 +1,69 @@ +prophesize(); + + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); + $request->getLocale()->willReturn('fr'); + + $this->filter = self::$container->get('chill.report.export.filter_date'); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + return [ + [ + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2021-07-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2022-07-01'), + ] + ]; + } + + public function getQueryBuilders(): array + { + if (null === self::$kernel) { + self::bootKernel(); + } + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('r.id') + ->from(Report::class, 'r') + ]; + } +} diff --git a/src/Bundle/ChillReportBundle/config/services/export.yaml b/src/Bundle/ChillReportBundle/config/services/export.yaml index 1ae624118..9650b9e33 100644 --- a/src/Bundle/ChillReportBundle/config/services/export.yaml +++ b/src/Bundle/ChillReportBundle/config/services/export.yaml @@ -8,6 +8,7 @@ services: tags: - { name: chill.export_elements_provider, prefix: 'report' } - Chill\ReportBundle\Export\Filter\ReportDateFilter: + chill.report.export.filter_date: + class: Chill\ReportBundle\Export\Filter\ReportDateFilter tags: - - { name: chill.export_filter, alias: 'report_date' } + - { name: chill.export_filter, alias: 'report_date_filter' }