mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 17:28:23 +00:00 
			
		
		
		
	Merge branch '111_exports_suite' into chill_amli
This commit is contained in:
		
							
								
								
									
										68
									
								
								exports_alias_conventions.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								exports_alias_conventions.csv
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| 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 | ||||
| 
 | 
							
								
								
									
										76
									
								
								exports_alias_conventions.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								exports_alias_conventions.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| # Export conventions | ||||
|  | ||||
|  | ||||
| Add condition with distinct alias on each export join clauses (Indicators + Filters + Aggregators) | ||||
|  | ||||
| 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                         | | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,9 +15,9 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialActionRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class BySocialActionAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -26,9 +33,41 @@ class BySocialActionAggregator implements AggregatorInterface | ||||
|         $this->actionRepository = $actionRepository; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('actsocialaction', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function($value) { | ||||
|         return function ($value) { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social action'; | ||||
|             } | ||||
| @@ -44,40 +83,8 @@ class BySocialActionAggregator implements AggregatorInterface | ||||
|         return ['socialaction_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked socialaction'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if(!in_array('socialaction', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.socialActions', 'socialaction'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('socialaction.id AS socialaction_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('socialaction_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('socialaction_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,16 +15,16 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialIssueRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class BySocialIssueAggregator implements AggregatorInterface | ||||
| { | ||||
|     private SocialIssueRepository $issueRepository; | ||||
|  | ||||
|     private SocialIssueRender $issueRender; | ||||
|  | ||||
|     private SocialIssueRepository $issueRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         SocialIssueRepository $issueRepository, | ||||
|         SocialIssueRender $issueRender | ||||
| @@ -26,47 +33,18 @@ class BySocialIssueAggregator implements AggregatorInterface | ||||
|         $this->issueRender = $issueRender; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|  | ||||
|             if ($value === '_header') { | ||||
|                 return 'Social issues'; | ||||
|             } | ||||
|  | ||||
|             $i = $this->issueRepository->find($value); | ||||
|  | ||||
|             return $this->issueRender->renderString($i, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialissue_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked socialissue'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('socialissue', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.socialIssues', 'socialissue'); | ||||
|         if (!in_array('actsocialissue', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.socialIssues', 'actsocialissue'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('socialissue.id AS socialissue_aggregator'); | ||||
|         $qb->addSelect('actsocialissue.id AS socialissue_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -81,4 +59,32 @@ class BySocialIssueAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social issues'; | ||||
|             } | ||||
|  | ||||
|             $i = $this->issueRepository->find($value); | ||||
|  | ||||
|             return $this->issueRender->renderString($i, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialissue_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked socialissue'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,16 +15,16 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; | ||||
| use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class ByThirdpartyAggregator implements AggregatorInterface | ||||
| { | ||||
|     private ThirdPartyRepository $thirdPartyRepository; | ||||
|  | ||||
|     private ThirdPartyRender $thirdPartyRender; | ||||
|  | ||||
|     private ThirdPartyRepository $thirdPartyRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         ThirdPartyRepository $thirdPartyRepository, | ||||
|         ThirdPartyRender $thirdPartyRender | ||||
| @@ -26,46 +33,18 @@ class ByThirdpartyAggregator implements AggregatorInterface | ||||
|         $this->thirdPartyRender = $thirdPartyRender; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Accepted thirdparty'; | ||||
|             } | ||||
|  | ||||
|             $tp = $this->thirdPartyRepository->find($value); | ||||
|  | ||||
|             return $this->thirdPartyRender->renderString($tp, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['thirdparty_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked thirdparties'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('thirdparty', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.thirdParties', 'thirdparty'); | ||||
|         if (!in_array('acttparty', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.thirdParties', 'acttparty'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('thirdparty.id AS thirdparty_aggregator'); | ||||
|         $qb->addSelect('acttparty.id AS thirdparty_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -80,4 +59,32 @@ class ByThirdpartyAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Accepted thirdparty'; | ||||
|             } | ||||
|  | ||||
|             $tp = $this->thirdPartyRepository->find($value); | ||||
|  | ||||
|             return $this->thirdPartyRender->renderString($tp, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['thirdparty_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked thirdparties'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,16 +15,16 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserRepository; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class ByUserAggregator implements AggregatorInterface | ||||
| { | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     private UserRender $userRender; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         UserRepository $userRepository, | ||||
|         UserRender $userRender | ||||
| @@ -26,46 +33,18 @@ class ByUserAggregator implements AggregatorInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Accepted users'; | ||||
|             } | ||||
|  | ||||
|             $u = $this->userRepository->find($value); | ||||
|  | ||||
|             return $this->userRender->renderString($u, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['users_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked users'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('user', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.users', 'user'); | ||||
|         if (!in_array('actusers', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.users', 'actusers'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('user.id AS users_aggregator'); | ||||
|         $qb->addSelect('actusers.id AS users_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -80,4 +59,32 @@ class ByUserAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Accepted users'; | ||||
|             } | ||||
|  | ||||
|             $u = $this->userRepository->find($value); | ||||
|  | ||||
|             return $this->userRender->renderString($u, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['users_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by linked users'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Closure; | ||||
| use DateTime; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use RuntimeException; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| @@ -21,7 +28,7 @@ class DateAggregator implements AggregatorInterface | ||||
|         'by year' => 'year', | ||||
|     ]; | ||||
|  | ||||
|     private CONST DEFAULT_CHOICE = 'year'; | ||||
|     private const DEFAULT_CHOICE = 'year'; | ||||
|  | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
| @@ -31,55 +38,7 @@ class DateAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value) use ($data): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'by '. $data['frequency']; | ||||
|             } | ||||
|             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 ; | ||||
|  | ||||
|                 case 'year': | ||||
|                     //return $this->translator->trans('in year') .' '. $value ; | ||||
|  | ||||
|                 default: | ||||
|                     return $value; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['date_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('frequency', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by date'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -90,13 +49,19 @@ class DateAggregator implements AggregatorInterface | ||||
|  | ||||
|         switch ($data['frequency']) { | ||||
|             case 'month': | ||||
|                 $fmt = 'MM'; break; | ||||
|                 $fmt = 'MM'; | ||||
|  | ||||
| break; | ||||
|  | ||||
|             case 'week': | ||||
|                 $fmt = 'IW'; break; | ||||
|                 $fmt = 'IW'; | ||||
|  | ||||
| break; | ||||
|  | ||||
|             case 'year': | ||||
|                 $fmt = 'YYYY'; $order = 'DESC'; break; | ||||
|                 $fmt = 'YYYY'; $order = 'DESC'; | ||||
|  | ||||
| break; // order DESC does not works ! | ||||
|  | ||||
|             default: | ||||
|                 throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); | ||||
| @@ -126,4 +91,53 @@ class DateAggregator implements AggregatorInterface | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('frequency', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return static function ($value) use ($data): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'by ' . $data['frequency']; | ||||
|             } | ||||
|  | ||||
|             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 ; | ||||
|  | ||||
|                 case 'year': | ||||
|                     //return $this->translator->trans('in year') .' '. $value ; | ||||
|  | ||||
|                 default: | ||||
|                     return $value; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['date_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by date'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,9 +15,9 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\LocationTypeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class LocationTypeAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -26,10 +33,42 @@ class LocationTypeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('actloc', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Accepted locationtype'; | ||||
|             } | ||||
|  | ||||
| @@ -46,41 +85,8 @@ class LocationTypeAggregator implements AggregatorInterface | ||||
|         return ['locationtype_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by locationtype'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('location', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.location', 'location'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(location.locationType) AS locationtype_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('locationtype_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('locationtype_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators; | ||||
| @@ -8,9 +15,9 @@ use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\ScopeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class UserScopeAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -26,10 +33,42 @@ class UserScopeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('actuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Scope'; | ||||
|             } | ||||
|  | ||||
| @@ -46,41 +85,8 @@ class UserScopeAggregator implements AggregatorInterface | ||||
|         return ['userscope_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group activity by userscope'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('user', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.user', 'user'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(user.mainScope) AS userscope_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('userscope_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('userscope_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -13,14 +13,13 @@ namespace Chill\ActivityBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityTypeRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelperInterface; | ||||
| use Closure; | ||||
| use Doctrine\ORM\Query\Expr\Join; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use function in_array; | ||||
|  | ||||
| class ActivityTypeAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -38,15 +37,15 @@ class ActivityTypeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('type', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.activityType', 'type'); | ||||
|         if (!in_array('acttype', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.activityType', 'acttype'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect(sprintf('IDENTITY(activity.activityType) AS %s', self::KEY)); | ||||
| @@ -95,23 +94,4 @@ class ActivityTypeAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return 'Aggregate by activity type'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if a join between Activity and another alias. | ||||
|      * | ||||
|      * @param Join[] $joins | ||||
|      * @param string $alias the alias to search for | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function checkJoinAlreadyDefined(array $joins, $alias) | ||||
|     { | ||||
|         foreach ($joins as $join) { | ||||
|             if ($join->getAlias() === $alias) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -12,23 +12,21 @@ declare(strict_types=1); | ||||
| namespace Chill\ActivityBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserRepository; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class ActivityUserAggregator implements AggregatorInterface | ||||
| { | ||||
|     public const KEY = 'activity_user_id'; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     private UserRender $userRender; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         UserRepository $userRepository, | ||||
|         UserRender $userRender | ||||
| @@ -37,9 +35,9 @@ class ActivityUserAggregator implements AggregatorInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|   | ||||
| @@ -14,7 +14,6 @@ namespace Chill\ActivityBundle\Export\Aggregator\PersonAggregators; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository; | ||||
| use Chill\ActivityBundle\Repository\ActivityReasonRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Export\ExportElementValidatedInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| @@ -24,7 +23,6 @@ use Doctrine\ORM\QueryBuilder; | ||||
| use RuntimeException; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||||
|  | ||||
| use function array_key_exists; | ||||
| @@ -48,9 +46,9 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
| @@ -69,29 +67,15 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali | ||||
|         $qb->addSelect($elem . ' as ' . $alias); | ||||
|  | ||||
|         // make a jointure only if needed | ||||
|         $join = $qb->getDQLPart('join'); | ||||
|  | ||||
|         if ( | ||||
|             ( | ||||
|                 array_key_exists('activity', $join) | ||||
|             && !$this->checkJoinAlreadyDefined($join['activity'], 'reasons') | ||||
|             ) | ||||
|             || (!array_key_exists('activity', $join)) | ||||
|         ) { | ||||
|             $qb->add( | ||||
|                 'join', | ||||
|                 [ | ||||
|                     'activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons'), | ||||
|                 ], | ||||
|                 true | ||||
|             ); | ||||
|         if (!in_array( 'actreasons', $qb->getAllAliases(), true)) { | ||||
|             $qb->innerJoin('activity.reasons', 'actreasons'); | ||||
|         } | ||||
|  | ||||
|         // join category if necessary | ||||
|         if ('activity_categories_id' === $alias) { | ||||
|             // add join only if needed | ||||
|             if (!$this->checkJoinAlreadyDefined($qb->getDQLPart('join')['activity'], 'category')) { | ||||
|                 $qb->join('reasons.category', 'category'); | ||||
|             if (!in_array('actreasoncat', $qb->getAllAliases(), true)) { | ||||
|                 $qb->join('actreasons.category', 'actreasoncat'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -195,23 +179,4 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali | ||||
|                 ->addViolation(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if a join between Activity and another alias. | ||||
|      * | ||||
|      * @param Join[] $joins | ||||
|      * @param string $alias the alias to search for | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function checkJoinAlreadyDefined(array $joins, $alias) | ||||
|     { | ||||
|         foreach ($joins as $join) { | ||||
|             if ($join->getAlias() === $alias) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -18,7 +18,7 @@ abstract class Declarations | ||||
| { | ||||
|     public const ACTIVITY = 'activity'; | ||||
|  | ||||
|     public const ACTIVITY_ACP = "activity_linked_to_acp"; | ||||
|     public const ACTIVITY_ACP = 'activity_linked_to_acp'; | ||||
|  | ||||
|     public const ACTIVITY_PERSON = "activity_linked_to_person"; | ||||
|     public const ACTIVITY_PERSON = 'activity_linked_to_person'; | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToACP; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\Activity; | ||||
| @@ -8,13 +17,10 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Closure; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -31,11 +37,6 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average activity linked to an accompanying period duration'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -46,6 +47,11 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return 'Average activities linked to an accompanying period duration by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_avg_activity_duration' !== $key) { | ||||
| @@ -65,6 +71,11 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average activity linked to an accompanying period duration'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY; | ||||
| @@ -73,17 +84,16 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|     public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) | ||||
|     { | ||||
|         $qb = $this->repository->createQueryBuilder('activity') | ||||
|             ->join('activity.accompanyingPeriod', 'acp') | ||||
|         ; | ||||
|             ->join('activity.accompanyingPeriod', 'actacp'); | ||||
|  | ||||
|         $qb->select('AVG(activity.durationTime) as export_avg_activity_duration'); | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -91,13 +101,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return [ | ||||
|             Declarations::ACTIVITY, | ||||
|             Declarations::ACTIVITY_ACP, | ||||
|             //PersonDeclarations::ACP_TYPE, | ||||
|             PersonDeclarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToACP; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\Activity; | ||||
| @@ -8,13 +17,10 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Closure; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -31,11 +37,6 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average activity linked to an accompanying period visit duration'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -46,6 +47,11 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return 'Average activities linked to an accompanying period visit duration by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_avg_activity_visit_duration' !== $key) { | ||||
| @@ -65,6 +71,11 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average activity linked to an accompanying period visit duration'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY; | ||||
| @@ -73,17 +84,16 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|     public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) | ||||
|     { | ||||
|         $qb = $this->repository->createQueryBuilder('activity') | ||||
|             ->join('activity.accompanyingPeriod', 'acp') | ||||
|         ; | ||||
|             ->join('activity.accompanyingPeriod', 'actacp'); | ||||
|  | ||||
|         $qb->select('AVG(activity.travelTime) as export_avg_activity_visit_duration'); | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -91,13 +101,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return [ | ||||
|             Declarations::ACTIVITY, | ||||
|             Declarations::ACTIVITY_ACP, | ||||
|             //PersonDeclarations::ACP_TYPE, | ||||
|             PersonDeclarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -23,14 +23,13 @@ use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class CountActivity implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
|     protected EntityRepository $repository; | ||||
|  | ||||
|     public function __construct( | ||||
|          EntityManagerInterface $em | ||||
|         EntityManagerInterface $em | ||||
|     ) { | ||||
|         $this->repository = $em->getRepository(Activity::class); | ||||
|     } | ||||
| @@ -49,6 +48,11 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|         return 'Count activities linked to an accompanying period by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_count_activity' !== $key) { | ||||
| @@ -80,18 +84,20 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|  | ||||
|     public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) | ||||
|     { | ||||
|         $qb = $this->repository->createQueryBuilder('activity') | ||||
|             ->join('activity.accompanyingPeriod', 'acp') | ||||
|         ; | ||||
|         $qb = $this->repository->createQueryBuilder('activity'); | ||||
|  | ||||
|         if (!in_array('actacp', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.accompanyingPeriod', 'actacp'); | ||||
|         } | ||||
|  | ||||
|         $qb->select('COUNT(activity.id) as export_count_activity'); | ||||
|          | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -99,12 +105,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|         return [ | ||||
|             Declarations::ACTIVITY, | ||||
|             Declarations::ACTIVITY_ACP, | ||||
|             //PersonDeclarations::ACP_TYPE, | ||||
|             PersonDeclarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToACP; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\Activity; | ||||
| @@ -8,13 +17,10 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Closure; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -31,11 +37,6 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum activity linked to an accompanying period duration'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -46,6 +47,11 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return 'Sum activities linked to an accompanying period duration by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_sum_activity_duration' !== $key) { | ||||
| @@ -65,6 +71,11 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum activity linked to an accompanying period duration'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY; | ||||
| @@ -72,18 +83,20 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|  | ||||
|     public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) | ||||
|     { | ||||
|         $qb = $this->repository->createQueryBuilder('activity') | ||||
|             ->join('activity.accompanyingPeriod', 'acp') | ||||
|         ; | ||||
|         $qb = $this->repository->createQueryBuilder('activity'); | ||||
|  | ||||
|         if (!in_array('actacp', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.accompanyingPeriod', 'actacp'); | ||||
|         } | ||||
|  | ||||
|         $qb->select('SUM(activity.durationTime) as export_sum_activity_duration'); | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -91,13 +104,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         return [ | ||||
|             Declarations::ACTIVITY, | ||||
|             Declarations::ACTIVITY_ACP, | ||||
|             //PersonDeclarations::ACP_TYPE, | ||||
|             PersonDeclarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToACP; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\Activity; | ||||
| @@ -8,13 +17,10 @@ use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Closure; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class SumActivityVisitDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -31,11 +37,6 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum activity linked to an accompanying period visit duration'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -46,6 +47,11 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return 'Sum activities linked to an accompanying period visit duration by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_sum_activity_visit_duration' !== $key) { | ||||
| @@ -65,6 +71,11 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum activity linked to an accompanying period visit duration'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY; | ||||
| @@ -72,18 +83,20 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|  | ||||
|     public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) | ||||
|     { | ||||
|         $qb = $this->repository->createQueryBuilder('activity') | ||||
|             ->join('activity.accompanyingPeriod', 'acp') | ||||
|         ; | ||||
|         $qb = $this->repository->createQueryBuilder('activity'); | ||||
|  | ||||
|         if (!in_array('actacp', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.accompanyingPeriod', 'actacp'); | ||||
|         } | ||||
|  | ||||
|         $qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration'); | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -91,12 +104,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac | ||||
|         return [ | ||||
|             Declarations::ACTIVITY, | ||||
|             Declarations::ACTIVITY_ACP, | ||||
|             //PersonDeclarations::ACP_TYPE, | ||||
|             PersonDeclarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to an accompanying period'; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -11,17 +11,16 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToPerson; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Export\Declarations as PersonDeclarations; | ||||
| use Doctrine\ORM\Query; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class CountActivity implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -47,6 +46,11 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|         return 'Count activities linked to a person by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_count_activity' !== $key) { | ||||
| @@ -80,23 +84,24 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|     { | ||||
|         $centers = array_map(static fn ($el) => $el['center'], $acl); | ||||
|  | ||||
|         $qb = $this->activityRepository->createQueryBuilder('activity') | ||||
|             ->join('activity.person', 'person') | ||||
|         ; | ||||
|         $qb = $this->activityRepository->createQueryBuilder('activity'); | ||||
|  | ||||
|         if (!in_array('actperson', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.person', 'actperson'); | ||||
|         } | ||||
|  | ||||
|         $qb->select('COUNT(activity.id) as export_count_activity'); | ||||
|  | ||||
|         $qb | ||||
|             ->where($qb->expr()->in('person.center', ':centers')) | ||||
|             ->setParameter('centers', $centers) | ||||
|         ; | ||||
|             ->setParameter('centers', $centers); | ||||
|  | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole() | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers() | ||||
| @@ -107,9 +112,4 @@ class CountActivity implements ExportInterface, GroupedExportInterface | ||||
|             //PersonDeclarations::PERSON_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -12,24 +12,23 @@ declare(strict_types=1); | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToPerson; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\ActivityReason; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\MainBundle\Export\ListInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelperInterface; | ||||
| use Chill\PersonBundle\Export\Declarations as PersonDeclarations; | ||||
| use DateTime; | ||||
| use Doctrine\DBAL\Exception\InvalidArgumentException; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\Query; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use Symfony\Component\Validator\Constraints\Callback; | ||||
| use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Export\Declarations as PersonDeclarations; | ||||
|  | ||||
| use function array_key_exists; | ||||
| use function count; | ||||
| @@ -100,6 +99,11 @@ class ListActivity implements ListInterface, GroupedExportInterface | ||||
|         return 'List activities linked to a person description'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         switch ($key) { | ||||
| @@ -206,9 +210,9 @@ class ListActivity implements ListInterface, GroupedExportInterface | ||||
|  | ||||
|         $qb | ||||
|             ->from('ChillActivityBundle:Activity', 'activity') | ||||
|             ->join('activity.person', 'person') | ||||
|             ->join('person.center', 'center') | ||||
|             ->andWhere('center IN (:authorized_centers)') | ||||
|             ->join('activity.person', 'actperson') | ||||
|             ->join('actperson.center', 'actcenter') | ||||
|             ->andWhere('actcenter IN (:authorized_centers)') | ||||
|             ->setParameter('authorized_centers', $centers); | ||||
|  | ||||
|         foreach ($this->fields as $f) { | ||||
| @@ -235,8 +239,8 @@ class ListActivity implements ListInterface, GroupedExportInterface | ||||
|                         break; | ||||
|  | ||||
|                     case 'user_username': | ||||
|                         $qb->join('activity.user', 'user'); | ||||
|                         $qb->addSelect('user.username AS user_username'); | ||||
|                         $qb->join('activity.user', 'actuser'); | ||||
|                         $qb->addSelect('actuser.username AS user_username'); | ||||
|  | ||||
|                         break; | ||||
|  | ||||
| @@ -270,9 +274,9 @@ class ListActivity implements ListInterface, GroupedExportInterface | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole() | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::LISTS); | ||||
|         return ActivityStatsVoter::LISTS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers() | ||||
| @@ -283,9 +287,4 @@ class ListActivity implements ListInterface, GroupedExportInterface | ||||
|             //PersonDeclarations::PERSON_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Export\LinkedToPerson; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Entity\Center; | ||||
| @@ -18,11 +19,9 @@ use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\PersonBundle\Export\Declarations as PersonDeclarations; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| /** | ||||
|  * This export allow to compute stats on activity duration. | ||||
| @@ -67,6 +66,11 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_stat_activity' !== $key) { | ||||
| @@ -116,15 +120,15 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|         } | ||||
|  | ||||
|         return $qb->select($select) | ||||
|             ->join('activity.person', 'person') | ||||
|             ->join('person.center', 'center') | ||||
|             ->where($qb->expr()->in('center', ':centers')) | ||||
|             ->join('activity.person', 'actperson') | ||||
|             ->join('actperson.center', 'actcenter') | ||||
|             ->where($qb->expr()->in('actcenter', ':centers')) | ||||
|             ->setParameter(':centers', $centers); | ||||
|     } | ||||
|  | ||||
|     public function requiredRole() | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return ActivityStatsVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers() | ||||
| @@ -135,9 +139,4 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface | ||||
|             //PersonDeclarations::PERSON_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of activities linked to a person'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\PersonBundle\Entity\SocialWork\SocialAction; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialActionRender; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class BySocialActionFilter implements FilterInterface | ||||
| { | ||||
| @@ -22,6 +30,36 @@ class BySocialActionFilter implements FilterInterface | ||||
|         $this->actionRender = $actionRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         if (!in_array('actsocialaction', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.socialActions', 'actsocialaction'); | ||||
|         } | ||||
|  | ||||
|         $clause = $qb->expr()->in('actsocialaction.id', ':socialactions'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('socialactions', $data['accepted_socialactions']); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_socialactions', EntityType::class, [ | ||||
| @@ -34,11 +72,6 @@ class BySocialActionFilter implements FilterInterface | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by linked socialaction'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $actions = []; | ||||
| @@ -48,38 +81,12 @@ class BySocialActionFilter implements FilterInterface | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by linked socialaction: only %actions%', [ | ||||
|             '%actions%' => implode(", ou ", $actions) | ||||
|             '%actions%' => implode(', ou ', $actions), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return null; | ||||
|         return 'Filter activity by linked socialaction'; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         if (!in_array('socialaction', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.socialActions', 'socialaction'); | ||||
|         } | ||||
|  | ||||
|         $clause = $qb->expr()->in('socialaction.id', ':socialactions'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('socialactions', $data['accepted_socialactions']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\PersonBundle\Entity\SocialWork\SocialIssue; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialIssueRender; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class BySocialIssueFilter implements FilterInterface | ||||
| { | ||||
| @@ -22,37 +30,7 @@ class BySocialIssueFilter implements FilterInterface | ||||
|         $this->issueRender = $issueRender; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_socialissues', EntityType::class, [ | ||||
|             'class' => SocialIssue::class, | ||||
|             'choice_label' => function(SocialIssue $si) { | ||||
|                 return $this->issueRender->renderString($si, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by linked socialissue'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $issues = []; | ||||
|  | ||||
|         foreach ($data['accepted_socialissues'] as $si) { | ||||
|             $issues[] = $this->issueRender->renderString($si, []); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by linked socialissue: only %issues%', [ | ||||
|             '%issues%' => implode(", ou ", $issues) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -61,11 +39,11 @@ class BySocialIssueFilter implements FilterInterface | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         if (!in_array('socialissue', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.socialIssues', 'socialissue'); | ||||
|         if (!in_array('actsocialissue', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.socialIssues', 'actsocialissue'); | ||||
|         } | ||||
|  | ||||
|         $clause = $qb->expr()->in('socialissue.id', ':socialissues'); | ||||
|         $clause = $qb->expr()->in('actsocialissue.id', ':socialissues'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
| @@ -77,9 +55,38 @@ class BySocialIssueFilter implements FilterInterface | ||||
|         $qb->setParameter('socialissues', $data['accepted_socialissues']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_socialissues', EntityType::class, [ | ||||
|             'class' => SocialIssue::class, | ||||
|             'choice_label' => function (SocialIssue $si) { | ||||
|                 return $this->issueRender->renderString($si, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $issues = []; | ||||
|  | ||||
|         foreach ($data['accepted_socialissues'] as $si) { | ||||
|             $issues[] = $this->issueRender->renderString($si, []); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by linked socialissue: only %issues%', [ | ||||
|             '%issues%' => implode(', ou ', $issues), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by linked socialissue'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Entity\User; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class ByUserFilter implements FilterInterface | ||||
| { | ||||
| @@ -22,6 +30,36 @@ class ByUserFilter implements FilterInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         if (!in_array('actusers', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.users', 'actusers'); | ||||
|         } | ||||
|  | ||||
|         $clause = $qb->expr()->in('actusers.id', ':users'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('users', $data['accepted_users']); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_users', EntityType::class, [ | ||||
| @@ -34,11 +72,6 @@ class ByUserFilter implements FilterInterface | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by linked users'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $users = []; | ||||
| @@ -48,37 +81,12 @@ class ByUserFilter implements FilterInterface | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by linked users: only %users%', [ | ||||
|             '%users%' => implode(", ou ", $users) | ||||
|             '%users%' => implode(', ou ', $users), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return null; | ||||
|         return 'Filter activity by linked users'; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         if (!in_array('user', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.users', 'user'); | ||||
|         } | ||||
|  | ||||
|         $clause = $qb->expr()->in('user.id', ':users'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('users', $data['accepted_users']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,18 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| @@ -19,7 +26,7 @@ class EmergencyFilter implements FilterInterface | ||||
|         'activity is not emergency' => false, | ||||
|     ]; | ||||
|  | ||||
|     private CONST DEFAULT_CHOICE = false; | ||||
|     private const DEFAULT_CHOICE = false; | ||||
|  | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
| @@ -28,36 +35,7 @@ class EmergencyFilter implements FilterInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_emergency', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by emergency'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         foreach (self::CHOICES as $k => $v) { | ||||
|             if ($v === $data['accepted_emergency']) { | ||||
|                 $choice = $k; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by emergency: only %emergency%', [ | ||||
|             '%emergency%' => $this->translator->trans($choice) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -78,9 +56,37 @@ class EmergencyFilter implements FilterInterface | ||||
|         $qb->setParameter('emergency', $data['accepted_emergency']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_emergency', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         foreach (self::CHOICES as $k => $v) { | ||||
|             if ($v === $data['accepted_emergency']) { | ||||
|                 $choice = $k; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by emergency: only %emergency%', [ | ||||
|             '%emergency%' => $this->translator->trans($choice), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by emergency'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Entity\LocationType; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class LocationTypeFilter implements FilterInterface | ||||
| { | ||||
| @@ -22,11 +30,40 @@ class LocationTypeFilter implements FilterInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('actloc', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.location', 'actloc'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|         $clause = $qb->expr()->in('actloc.locationType', ':locationtype'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('locationtype', $data['accepted_locationtype']); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_locationtype', EntityType::class, [ | ||||
|             'class' => LocationType::class, | ||||
|             'choice_label' => function(LocationType $type) { | ||||
|             'choice_label' => function (LocationType $type) { | ||||
|                 return $this->translatableStringHelper->localize($type->getTitle()); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
| @@ -34,11 +71,6 @@ class LocationTypeFilter implements FilterInterface | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by locationtype'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $types = []; | ||||
| @@ -50,36 +82,12 @@ class LocationTypeFilter implements FilterInterface | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by locationtype: only %types%', [ | ||||
|             '%types%' => implode(", ou ", $types) | ||||
|             '%types%' => implode(', ou ', $types), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return null; | ||||
|         return 'Filter activity by locationtype'; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('location', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.location', 'location'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|         $clause = $qb->expr()->in('location.locationType', ':locationtype'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('locationtype', $data['accepted_locationtype']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\ActivityBundle\Entity\Activity; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| @@ -20,7 +27,7 @@ class SentReceivedFilter implements FilterInterface | ||||
|         'is received' => Activity::SENTRECEIVED_RECEIVED, | ||||
|     ]; | ||||
|  | ||||
|     private CONST DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT; | ||||
|     private const DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT; | ||||
|  | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
| @@ -29,32 +36,7 @@ class SentReceivedFilter implements FilterInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_sentreceived', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by sentreceived'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $sentreceived = array_flip(self::CHOICES)[$data['accepted_sentreceived']]; | ||||
|  | ||||
|         return ['Filtered activity by sentreceived: only %sentreceived%', [ | ||||
|             '%sentreceived%' => $this->translator->trans($sentreceived) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -75,8 +57,33 @@ class SentReceivedFilter implements FilterInterface | ||||
|         $qb->setParameter('sentreceived', $data['accepted_sentreceived']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_sentreceived', ChoiceType::class, [ | ||||
|             'choices' => self::CHOICES, | ||||
|             'multiple' => false, | ||||
|             'expanded' => true, | ||||
|             'empty_data' => self::DEFAULT_CHOICE, | ||||
|             'data' => self::DEFAULT_CHOICE, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $sentreceived = array_flip(self::CHOICES)[$data['accepted_sentreceived']]; | ||||
|  | ||||
|         return ['Filtered activity by sentreceived: only %sentreceived%', [ | ||||
|             '%sentreceived%' => $this->translator->trans($sentreceived), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by sentreceived'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,19 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Entity\User; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| @@ -22,38 +29,7 @@ class UserFilter implements FilterInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_users', EntityType::class, [ | ||||
|             'class' => User::class, | ||||
|             'choice_label' => function (User $u) { | ||||
|                 return $this->userRender->renderString($u, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|             'label' => 'Creators' | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by user'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $users = []; | ||||
|  | ||||
|         foreach ($data['accepted_users'] as $u) { | ||||
|             $users[] = $this->userRender->renderString($u, []); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by user: only %users%', [ | ||||
|             '%users%' => implode(", ou ", $users) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -74,9 +50,39 @@ class UserFilter implements FilterInterface | ||||
|         $qb->setParameter('users', $data['accepted_users']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_users', EntityType::class, [ | ||||
|             'class' => User::class, | ||||
|             'choice_label' => function (User $u) { | ||||
|                 return $this->userRender->renderString($u, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|             'label' => 'Creators', | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $users = []; | ||||
|  | ||||
|         foreach ($data['accepted_users'] as $u) { | ||||
|             $users[] = $this->userRender->renderString($u, []); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by user: only %users%', [ | ||||
|             '%users%' => implode(', ou ', $users), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by user'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\ActivityBundle\Export\Filter\ACPFilters; | ||||
|  | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Entity\Scope; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class UserScopeFilter implements FilterInterface | ||||
| { | ||||
| @@ -22,6 +30,36 @@ class UserScopeFilter implements FilterInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('actuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.user', 'actuser'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         $clause = $qb->expr()->in('actuser.mainScope', ':userscope'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('userscope', $data['accepted_userscope']); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_userscope', EntityType::class, [ | ||||
| @@ -32,15 +70,10 @@ class UserScopeFilter implements FilterInterface | ||||
|                 ); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter activity by userscope'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $scopes = []; | ||||
| @@ -52,38 +85,12 @@ class UserScopeFilter implements FilterInterface | ||||
|         } | ||||
|  | ||||
|         return ['Filtered activity by userscope: only %scopes%', [ | ||||
|             '%scopes%' => implode(", ou ", $scopes) | ||||
|             '%scopes%' => implode(', ou ', $scopes), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return null; | ||||
|         return 'Filter activity by userscope'; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('user', $qb->getAllAliases())) { | ||||
|             $qb->join('activity.user', 'user'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         $clause = $qb->expr()->in('user.mainScope', ':userscope'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('userscope', $data['accepted_userscope']); | ||||
|     } | ||||
|  | ||||
|     public  function applyOn(): string | ||||
|     { | ||||
|          return Declarations::ACTIVITY_ACP; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -33,7 +33,7 @@ class ActivityDateFilter implements FilterInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -73,8 +73,7 @@ class ActivityDateFilter implements FilterInterface | ||||
|             ->add('date_to', ChillDateType::class, [ | ||||
|                 'label' => 'Activities before this date', | ||||
|                 'data' => new DateTime(), | ||||
|             ]) | ||||
|         ; | ||||
|             ]); | ||||
|  | ||||
|         $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { | ||||
|             /** @var \Symfony\Component\Form\FormInterface $filterForm */ | ||||
|   | ||||
| @@ -14,7 +14,6 @@ namespace Chill\ActivityBundle\Export\Filter; | ||||
| use Chill\ActivityBundle\Entity\ActivityType; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityTypeRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportElementValidatedInterface; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelperInterface; | ||||
| @@ -23,7 +22,6 @@ use Doctrine\ORM\Query\Expr\Join; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||||
|  | ||||
| use function count; | ||||
| @@ -42,9 +40,9 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter | ||||
|         $this->activityTypeRepository = $activityTypeRepository; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
| @@ -104,23 +102,4 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter | ||||
|                 ->addViolation(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if a join between Activity and Reason is already defined. | ||||
|      * | ||||
|      * @param Join[] $joins | ||||
|      * @param mixed $alias | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function checkJoinAlreadyDefined(array $joins, $alias) | ||||
|     { | ||||
|         foreach ($joins as $join) { | ||||
|             if ($join->getAlias() === $alias) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -14,7 +14,6 @@ namespace Chill\ActivityBundle\Export\Filter\PersonFilters; | ||||
| use Chill\ActivityBundle\Entity\ActivityReason; | ||||
| use Chill\ActivityBundle\Export\Declarations; | ||||
| use Chill\ActivityBundle\Repository\ActivityReasonRepository; | ||||
| use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; | ||||
| use Chill\MainBundle\Export\ExportElementValidatedInterface; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| @@ -24,7 +23,6 @@ use Doctrine\ORM\Query\Expr\Join; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||||
|  | ||||
| use function array_key_exists; | ||||
| @@ -44,9 +42,9 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt | ||||
|         $this->activityReasonRepository = $activityReasonRepository; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return new Role(ActivityStatsVoter::STATS); | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
| @@ -54,20 +52,9 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|         $join = $qb->getDQLPart('join'); | ||||
|         $clause = $qb->expr()->in('reasons', ':selected_activity_reasons'); | ||||
|         //dump($join); | ||||
|         // add a join to reasons only if needed | ||||
|         if ( | ||||
|             ( | ||||
|                 array_key_exists('activity', $join) | ||||
|             && !$this->checkJoinAlreadyDefined($join['activity'], 'reasons') | ||||
|             ) | ||||
|             || (!array_key_exists('activity', $join)) | ||||
|         ) { | ||||
|             $qb->add( | ||||
|                 'join', | ||||
|                 ['activity' => new Join(Join::INNER_JOIN, 'activity.reasons', 'reasons')], | ||||
|                 true | ||||
|             ); | ||||
|  | ||||
|         if (!in_array('actreasons', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('activity.reasons', 'actreasons'); | ||||
|         } | ||||
|  | ||||
|         if ($where instanceof Expr\Andx) { | ||||
| @@ -125,21 +112,4 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt | ||||
|                 ->addViolation(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if a join between Activity and Reason is already defined. | ||||
|      * | ||||
|      * @param Join[] $joins | ||||
|      * @param mixed $alias | ||||
|      */ | ||||
|     private function checkJoinAlreadyDefined(array $joins, $alias): bool | ||||
|     { | ||||
|         foreach ($joins as $join) { | ||||
|             if ($join->getAlias() === $alias) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|   | ||||
| @@ -1,20 +1,30 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserRepository; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class AgentAggregator implements AggregatorInterface | ||||
| { | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     private UserRender $userRender; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         UserRepository $userRepository, | ||||
|         UserRender $userRender | ||||
| @@ -23,16 +33,18 @@ final class AgentAggregator implements AggregatorInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.user', 'u'); | ||||
|         if (!in_array('caluser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.user', 'caluser'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('u.id AS agent_aggregator'); | ||||
|         $qb->addSelect('caluser.id AS agent_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -41,7 +53,6 @@ final class AgentAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('agent_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
| @@ -54,7 +65,7 @@ final class AgentAggregator implements AggregatorInterface | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
| @@ -74,6 +85,6 @@ final class AgentAggregator implements AggregatorInterface | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by agent'; | ||||
|         return 'Group appointments by agent'; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\CalendarBundle\Repository\CancelReasonRepository; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| @@ -23,37 +33,7 @@ class CancelReasonAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Cancel reason'; | ||||
|             } | ||||
|  | ||||
|             $j = $this->cancelReasonRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $j->getName() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['cancel_reason_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by cancel reason'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -61,7 +41,9 @@ class CancelReasonAggregator implements AggregatorInterface | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         // TODO: still needs to take into account appointments without a cancel reason somehow | ||||
|         $qb->join('cal.cancelReason', 'cr'); | ||||
|         if (!in_array('calcancel', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.cancelReason', 'calcancel'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(cal.cancelReason) as cancel_reason_aggregator'); | ||||
|  | ||||
| @@ -78,4 +60,34 @@ class CancelReasonAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Cancel reason'; | ||||
|             } | ||||
|  | ||||
|             $j = $this->cancelReasonRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $j->getName() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['cancel_reason_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group appointments by cancel reason'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserJobRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| @@ -23,10 +33,42 @@ final class JobAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('caluser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.user', 'caluser'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('job_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('job_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Job'; | ||||
|             } | ||||
|  | ||||
| @@ -43,38 +85,8 @@ final class JobAggregator implements AggregatorInterface | ||||
|         return ['job_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by agent job'; | ||||
|         return 'Group appointments by agent job'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.user', 'u'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(u.userJob) as job_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('job_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('job_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,20 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\LocationRepository; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| @@ -19,43 +29,16 @@ final class LocationAggregator implements AggregatorInterface | ||||
|         $this->locationRepository = $locationRepository; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Location'; | ||||
|             } | ||||
|  | ||||
|             $l = $this->locationRepository->find($value); | ||||
|  | ||||
|             return $l->getName(); | ||||
|  | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['location_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by location'; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?Role | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.location', 'l'); | ||||
|         if (!in_array('calloc', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.location', 'calloc'); | ||||
|         } | ||||
|         $qb->addSelect('IDENTITY(cal.location) as location_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
| @@ -72,4 +55,31 @@ final class LocationAggregator implements AggregatorInterface | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
| } | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Location'; | ||||
|             } | ||||
|  | ||||
|             $l = $this->locationRepository->find($value); | ||||
|  | ||||
|             return $l->getName(); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['location_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group appointments by location'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\LocationTypeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| @@ -23,10 +33,42 @@ final class LocationTypeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('calloc', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.location', 'calloc'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(calloc.locationType) as location_type_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('location_type_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('location_type_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Location type'; | ||||
|             } | ||||
|  | ||||
| @@ -43,39 +85,8 @@ final class LocationTypeAggregator implements AggregatorInterface | ||||
|         return ['location_type_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by location type'; | ||||
|         return 'Group appointments by location type'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.location', 'l'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(l.locationType) as location_type_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('location_type_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('location_type_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| @@ -11,37 +20,7 @@ use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class MonthYearAggregator implements AggregatorInterface | ||||
| { | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['month_year_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'by month and year'; | ||||
|             } | ||||
|  | ||||
|             $month = substr($value,0, 2); | ||||
|             $year = substr($value, 3, 4); | ||||
|  | ||||
|             return strftime('%B %G', mktime(0, 0, 0, $month, '1', $year)); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // No form needed | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by month and year'; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?Role | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -63,4 +42,33 @@ class MonthYearAggregator implements AggregatorInterface | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // No form needed | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return static function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'by month and year'; | ||||
|             } | ||||
|  | ||||
|             $month = substr($value, 0, 2); | ||||
|             $year = substr($value, 3, 4); | ||||
|  | ||||
|             return strftime('%B %G', mktime(0, 0, 0, $month, '1', $year)); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['month_year_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group appointments by month and year'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Aggregator; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\ScopeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Closure; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| @@ -23,10 +33,42 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('caluser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.user', 'caluser'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('scope_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('scope_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Scope'; | ||||
|             } | ||||
|  | ||||
| @@ -43,38 +85,8 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         return ['scope_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by agent scope'; | ||||
|         return 'Group appointments by agent scope'; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.user', 'u'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(u.mainScope) as scope_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('scope_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('scope_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,23 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Export; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\CalendarBundle\Repository\CalendarRepository; | ||||
| use Chill\MainBundle\Export\ExportInterface; | ||||
| use Chill\MainBundle\Export\FormatterInterface; | ||||
| use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Security\Authorization\PersonVoter; | ||||
| use Closure; | ||||
| use Doctrine\ORM\AbstractQuery; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| @@ -16,7 +26,6 @@ use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class CountAppointments implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
|  | ||||
|     private CalendarRepository $calendarRepository; | ||||
|  | ||||
|     public function __construct(CalendarRepository $calendarRepository) | ||||
| @@ -39,7 +48,12 @@ class CountAppointments implements ExportInterface, GroupedExportInterface | ||||
|         return 'Count appointments by various parameters.'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): \Closure | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data): Closure | ||||
|     { | ||||
|         if ('export_result' !== $key) { | ||||
|             throw new LogicException("the key {$key} is not used by this export"); | ||||
| @@ -89,11 +103,10 @@ class CountAppointments implements ExportInterface, GroupedExportInterface | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|  | ||||
|         // which role should we give here? | ||||
|         return new Role(PersonVoter::STATS); | ||||
|         return PersonVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -102,10 +115,4 @@ class CountAppointments implements ExportInterface, GroupedExportInterface | ||||
|             Declarations::CALENDAR_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Export; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| @@ -10,12 +19,11 @@ use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
|  | ||||
|     private CalendarRepository $calendarRepository; | ||||
|  | ||||
|     public function __construct( | ||||
| @@ -29,11 +37,6 @@ class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterf | ||||
|         // no form needed | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average appointment duration'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -44,10 +47,15 @@ class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterf | ||||
|         return 'Get the average of appointment duration according to various filters'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_result' !== $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"); | ||||
|         } | ||||
|  | ||||
|         $labels = array_combine($values, $values); | ||||
| @@ -68,6 +76,11 @@ class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterf | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Average appointment duration'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
| @@ -83,21 +96,15 @@ class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterf | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(AccompanyingPeriodVoter::STATS); | ||||
|         return AccompanyingPeriodVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
|     { | ||||
|         return [ | ||||
|             Declarations::CALENDAR_TYPE | ||||
|             Declarations::CALENDAR_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Export; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| @@ -10,8 +19,8 @@ use Chill\MainBundle\Export\GroupedExportInterface; | ||||
| use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
|  | ||||
| class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -28,11 +37,6 @@ class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterf | ||||
|         // no form needed | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum of appointment durations'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -43,10 +47,15 @@ class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterf | ||||
|         return 'Get the sum of appointment durations according to various filters'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_result' !== $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"); | ||||
|         } | ||||
|  | ||||
|         $labels = array_combine($values, $values); | ||||
| @@ -67,6 +76,11 @@ class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterf | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Sum of appointment durations'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
| @@ -82,21 +96,15 @@ class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterf | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(AccompanyingPeriodVoter::STATS); | ||||
|         return AccompanyingPeriodVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
|     { | ||||
|         return [ | ||||
|             Declarations::CALENDAR_TYPE | ||||
|             Declarations::CALENDAR_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of calendar'; | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Filter; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| @@ -20,39 +29,7 @@ class AgentFilter implements FilterInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_agents', EntityType::class, [ | ||||
|             'class' => User::class, | ||||
|             'choice_label' => function (User $u) { | ||||
|                 return $this->userRender->renderString($u, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true | ||||
|         ]); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter by agent'; | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $users = []; | ||||
|  | ||||
|         foreach ($data['accepted_agents'] as $r) { | ||||
|             $users[] = $r; | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'Filtered by agent: only %agents%', [ | ||||
|                 '%agents' => implode(", ou ", $users) | ||||
|             ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -76,4 +53,35 @@ class AgentFilter implements FilterInterface | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('accepted_agents', EntityType::class, [ | ||||
|             'class' => User::class, | ||||
|             'choice_label' => function (User $u) { | ||||
|                 return $this->userRender->renderString($u, []); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $users = []; | ||||
|  | ||||
|         foreach ($data['accepted_agents'] as $r) { | ||||
|             $users[] = $r; | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'Filtered by agent: only %agents%', [ | ||||
|                 '%agents' => implode(', ou ', $users), | ||||
|             ], ]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter appointments by agent'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,32 +1,67 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\CalendarBundle\Export\Filter; | ||||
|  | ||||
| use Chill\CalendarBundle\Export\Declarations; | ||||
| use Chill\MainBundle\Export\FilterInterface; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use DateTime; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| class BetweenDatesFilter implements FilterInterface | ||||
| { | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         $clause = $qb->expr()->andX( | ||||
|             $qb->expr()->gte('cal.startDate', ':dateFrom'), | ||||
|             $qb->expr()->lte('cal.endDate', ':dateTo') | ||||
|         ); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('dateFrom', $data['date_from'], Types::DATE_MUTABLE); | ||||
|         // modify dateTo so that entire day is also taken into account up until the beginning of the next day. | ||||
|         $qb->setParameter('dateTo', $data['date_to']->modify('+1 day'), Types::DATE_MUTABLE); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder | ||||
|             ->add('date_from', ChillDateType::class, [ | ||||
|                 'data' => new \DateTime(), | ||||
|                 'data' => new DateTime(), | ||||
|             ]) | ||||
|             ->add('date_to', ChillDateType::class, [ | ||||
|                 'data' => new \DateTime(), | ||||
|             ]) | ||||
|         ; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter by appointments between certain dates'; | ||||
|                 'data' => new DateTime(), | ||||
|             ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
| @@ -37,34 +72,8 @@ class BetweenDatesFilter implements FilterInterface | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return null; | ||||
|         return 'Filter appointments between certain dates'; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|  | ||||
|         $clause = $qb->expr()->andX( | ||||
|                 $qb->expr()->gte('cal.startDate', ':dateFrom'), | ||||
|                 $qb->expr()->lte('cal.endDate', ':dateTo') | ||||
|             ); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
|         } else { | ||||
|             $where = $qb->expr()->andX($clause); | ||||
|         } | ||||
|  | ||||
|         $qb->add('where', $where); | ||||
|         $qb->setParameter('dateFrom', $data['date_from']); | ||||
|         // modify dateTo so that entire day is also taken into account up until the beginning of the next day. | ||||
|         $qb->setParameter('dateTo', $data['date_to']->modify('+1 day')); | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,6 @@ use Symfony\Contracts\Translation\TranslatorInterface; | ||||
|  | ||||
| class JobFilter implements FilterInterface | ||||
| { | ||||
|  | ||||
|     protected TranslatorInterface $translator; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -36,45 +35,19 @@ class JobFilter implements FilterInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('job', EntityType::class, [ | ||||
|             'class' => UserJob::class, | ||||
|             'choice_label' => function (UserJob $j) { | ||||
|                 return $this->translatableStringHelper->localize( | ||||
|                     $j->getLabel() | ||||
|                 ); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $userJobs = []; | ||||
|  | ||||
|         foreach ($data['job'] as $j) { | ||||
|             $userJobs[] = $this->translatableStringHelper->localize( | ||||
|                 $j->getLabel()); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered by agent job: only %jobs%', [ | ||||
|             '%jobs%' => implode(', ou ', $userJobs) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.user', 'u'); | ||||
|         if (!in_array('caluser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.user', 'caluser'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|         $clause = $qb->expr()->in('u.userJob', ':job'); | ||||
|         $clause = $qb->expr()->in('caluser.userJob', ':job'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
| @@ -91,9 +64,37 @@ class JobFilter implements FilterInterface | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('job', EntityType::class, [ | ||||
|             'class' => UserJob::class, | ||||
|             'choice_label' => function (UserJob $j) { | ||||
|                 return $this->translatableStringHelper->localize( | ||||
|                     $j->getLabel() | ||||
|                 ); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string'): array | ||||
|     { | ||||
|         $userJobs = []; | ||||
|  | ||||
|         foreach ($data['job'] as $j) { | ||||
|             $userJobs[] = $this->translatableStringHelper->localize( | ||||
|                 $j->getLabel() | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered by agent job: only %jobs%', [ | ||||
|             '%jobs%' => implode(', ou ', $userJobs), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Filter by agent job'; | ||||
|         return 'Filter appointments by agent job'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,6 @@ use Symfony\Contracts\Translation\TranslatorInterface; | ||||
|  | ||||
| class ScopeFilter implements FilterInterface | ||||
| { | ||||
|  | ||||
|     protected TranslatorInterface $translator; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -36,45 +35,19 @@ class ScopeFilter implements FilterInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('scope', EntityType::class, [ | ||||
|             'class' => Scope::class, | ||||
|             'choice_label' => function (Scope $s) { | ||||
|                 return $this->translatableStringHelper->localize( | ||||
|                     $s->getName() | ||||
|                 ); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string') | ||||
|     { | ||||
|         $scopes = []; | ||||
|  | ||||
|         foreach ($data['scope'] as $s) { | ||||
|             $scopes[] = $this->translatableStringHelper->localize( | ||||
|                 $s->getName()); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered by agent scope: only %scopes%', [ | ||||
|             '%scopes%' => implode(', ou ', $scopes) | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('cal.user', 'u'); | ||||
|         if (!in_array('caluser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('cal.user', 'caluser'); | ||||
|         } | ||||
|  | ||||
|         $where = $qb->getDQLPart('where'); | ||||
|         $clause = $qb->expr()->in('u.mainScope', ':scope'); | ||||
|         $clause = $qb->expr()->in('caluser.mainScope', ':scope'); | ||||
|  | ||||
|         if ($where instanceof Andx) { | ||||
|             $where->add($clause); | ||||
| @@ -91,9 +64,37 @@ class ScopeFilter implements FilterInterface | ||||
|         return Declarations::CALENDAR_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('scope', EntityType::class, [ | ||||
|             'class' => Scope::class, | ||||
|             'choice_label' => function (Scope $s) { | ||||
|                 return $this->translatableStringHelper->localize( | ||||
|                     $s->getName() | ||||
|                 ); | ||||
|             }, | ||||
|             'multiple' => true, | ||||
|             'expanded' => true, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function describeAction($data, $format = 'string') | ||||
|     { | ||||
|         $scopes = []; | ||||
|  | ||||
|         foreach ($data['scope'] as $s) { | ||||
|             $scopes[] = $this->translatableStringHelper->localize( | ||||
|                 $s->getName() | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return ['Filtered by agent scope: only %scopes%', [ | ||||
|             '%scopes%' => implode(', ou ', $scopes), | ||||
|         ]]; | ||||
|     } | ||||
|  | ||||
|     public function getTitle() | ||||
|     { | ||||
|         return 'Filter by agent scope'; | ||||
|         return 'Filter appointments by agent scope'; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -82,21 +82,21 @@ Sum of appointment durations: Somme de la durée des rendez-vous | ||||
| Get the sum of appointment durations according to various filters: Calcule la somme des durées des rendez-vous en fonction de différents paramètres. | ||||
|  | ||||
| 'Filtered by agent: only %agents%': "Filtré par agents: uniquement %agents%" | ||||
| Filter by agent: Filtrer par agents | ||||
| Filter by agent job: Filtrer par métiers des agents | ||||
| Filter appointments by agent: Filtrer les rendez-vous par agents | ||||
| Filter appointments by agent job: Filtrer les rendez-vous par métiers des agents | ||||
| 'Filtered by agent job: only %jobs%': 'Filtré par métiers des agents: uniquement les %jobs%' | ||||
| Filter by agent scope: Filtrer par services des agents | ||||
| Filter appointments by agent scope: Filtrer les rendez-vous par services des agents | ||||
| 'Filtered by agent scope: only %scopes%': 'Filtré par services des agents: uniquement les services %scopes%' | ||||
| Filter by appointments between certain dates: Filtrer par date du rendez-vous | ||||
| Filter appointments between certain dates: Filtrer les rendez-vous par date du rendez-vous | ||||
| 'Filtered by appointments between %dateFrom% and %dateTo%': 'Filtré par rendez-vous entre %dateFrom% et %dateTo%' | ||||
|  | ||||
| Group by agent: Grouper par agent | ||||
| Group by agent job: Grouper par métier de l'agent | ||||
| Group by agent scope: Grouper par service de l'agent | ||||
| Group by location type: Grouper par type de localisation | ||||
| Group by location: Grouper par lieu de rendez-vous | ||||
| Group by cancel reason: Grouper par motif d'annulation | ||||
| Group by month and year: Grouper par mois et année | ||||
| Group appointments by agent: Grouper les rendez-vous par agent | ||||
| Group appointments by agent job: Grouper les rendez-vous par métier de l'agent | ||||
| Group appointments by agent scope: Grouper les rendez-vous par service de l'agent | ||||
| Group appointments by location type: Grouper les rendez-vous par type de localisation | ||||
| Group appointments by location: Grouper les rendez-vous par lieu de rendez-vous | ||||
| Group appointments by cancel reason: Grouper les rendez-vous par motif d'annulation | ||||
| Group appointments by month and year: Grouper les rendez-vous par mois et année | ||||
| Scope: Service | ||||
| Job: Métier | ||||
| Location type: Type de localisation | ||||
|   | ||||
| @@ -525,6 +525,21 @@ class ExportController extends AbstractController | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     private function getExportGroup($target): string | ||||
|     { | ||||
|         $exportManager = $this->exportManager; | ||||
|  | ||||
|         $groups = $exportManager->getExportsGrouped(true); | ||||
|  | ||||
|         foreach ($groups as $group => $array) { | ||||
|             foreach ($array as $alias => $export) { | ||||
|                 if ($export === $target) { | ||||
|                     return $group; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * get the next step. If $reverse === true, the previous step is returned. | ||||
|      * | ||||
| @@ -572,19 +587,4 @@ class ExportController extends AbstractController | ||||
|                 throw new LogicException("the step {$step} is not defined."); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function getExportGroup($target): string | ||||
|     { | ||||
|         $exportManager = $this->exportManager; | ||||
|  | ||||
|         $groups = $exportManager->getExportsGrouped(true); | ||||
|  | ||||
|         foreach ($groups as $group => $array) { | ||||
|             foreach ($array as $alias => $export) { | ||||
|                 if ($export === $target) { | ||||
|                     return $group; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,18 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\MainBundle\Doctrine\DQL; | ||||
|  | ||||
| use Doctrine\ORM\Query\AST\Functions\DateDiffFunction; | ||||
| use Doctrine\ORM\Query\AST\Functions\FunctionNode; | ||||
| use Doctrine\ORM\Query\AST\Node; | ||||
| use Doctrine\ORM\Query\AST\PathExpression; | ||||
| use Doctrine\ORM\Query\Lexer; | ||||
| use Doctrine\ORM\Query\Parser; | ||||
| @@ -12,7 +20,7 @@ use Doctrine\ORM\Query\SqlWalker; | ||||
|  | ||||
| /** | ||||
|  * Extract postgresql function | ||||
|  * https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT | ||||
|  * https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT. | ||||
|  * | ||||
|  * Usage : EXTRACT(field FROM timestamp) | ||||
|  * TODO allow interval usage -> EXTRACT(field FROM interval) | ||||
| @@ -50,5 +58,4 @@ class Extract extends FunctionNode | ||||
|  | ||||
|         $parser->match(Lexer::T_CLOSE_PARENTHESIS); | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\MainBundle\Doctrine\DQL; | ||||
|  | ||||
| use Doctrine\ORM\Query\AST\Functions\FunctionNode; | ||||
| @@ -8,7 +17,7 @@ use Doctrine\ORM\Query\Parser; | ||||
| use Doctrine\ORM\Query\SqlWalker; | ||||
|  | ||||
| /** | ||||
|  * Usage : TO_CHAR(datetime, fmt) | ||||
|  * Usage : TO_CHAR(datetime, fmt). | ||||
|  */ | ||||
| class ToChar extends FunctionNode | ||||
| { | ||||
| @@ -34,5 +43,4 @@ class ToChar extends FunctionNode | ||||
|         $this->fmt = $parser->StringExpression(); | ||||
|         $parser->match(Lexer::T_CLOSE_PARENTHESIS); | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -139,10 +139,8 @@ interface ExportInterface extends ExportElementInterface | ||||
|  | ||||
|     /** | ||||
|      * Return the required Role to execute the Export. | ||||
|      * | ||||
|      * @return \Symfony\Component\Security\Core\Role\Role | ||||
|      */ | ||||
|     public function requiredRole(); | ||||
|     public function requiredRole(): string; | ||||
|  | ||||
|     /** | ||||
|      * Inform which ModifiersInterface (i.e. AggregatorInterface, FilterInterface) | ||||
|   | ||||
| @@ -550,7 +550,7 @@ class ExportManager | ||||
|         if (null === $centers) { | ||||
|             $centers = $this->authorizationHelper->getReachableCenters( | ||||
|                 $this->user, | ||||
|                 $role->getRole(), | ||||
|                 $role | ||||
|             ); | ||||
|         } | ||||
|  | ||||
| @@ -559,13 +559,13 @@ class ExportManager | ||||
|         } | ||||
|  | ||||
|         foreach ($centers as $center) { | ||||
|             if ($this->authorizationChecker->isGranted($role->getRole(), $center) === false) { | ||||
|             if ($this->authorizationChecker->isGranted($role, $center) === false) { | ||||
|                 //debugging | ||||
|                 $this->logger->debug('user has no access to element', [ | ||||
|                     'method' => __METHOD__, | ||||
|                     'type' => get_class($element), | ||||
|                     'center' => $center->getName(), | ||||
|                     'role' => $role->getRole(), | ||||
|                     'role' => $role, | ||||
|                 ]); | ||||
|  | ||||
|                 ///// Bypasse les autorisations qui empêche d'afficher les nouveaux exports | ||||
| @@ -594,7 +594,7 @@ class ExportManager | ||||
|                 'center' => $center, | ||||
|                 'circles' => $this->authorizationHelper->getReachableScopes( | ||||
|                     $this->user, | ||||
|                     $element->requiredRole()->getRole(), | ||||
|                     $element->requiredRole(), | ||||
|                     $center | ||||
|                 ), | ||||
|             ]; | ||||
|   | ||||
| @@ -26,9 +26,9 @@ interface ModifierInterface extends ExportElementInterface | ||||
|      * If null, will used the ExportInterface::requiredRole role from | ||||
|      * the current executing export. | ||||
|      * | ||||
|      * @return \Symfony\Component\Security\Core\Role\Role|null A role required to execute this ModifiersInterface | ||||
|      * @return string|null A role required to execute this ModifiersInterface | ||||
|      */ | ||||
|     public function addRole(); | ||||
|     public function addRole(): ?string; | ||||
|  | ||||
|     /** | ||||
|      * Alter the query initiated by the export, to add the required statements | ||||
|   | ||||
| @@ -0,0 +1,295 @@ | ||||
| <template> | ||||
|    <teleport to="#export_filters_social_work_type_filter_form"> | ||||
|        | ||||
|       <fieldset class="mb-3" id="actionType"> | ||||
|          <div class="row"> | ||||
|             <legend class="col-sm-4 col-form-label">{{ $t('action.label')}}</legend> | ||||
|             <div class="col-sm-8"> | ||||
|        | ||||
|                <VueMultiselect | ||||
|                   name="actionType" | ||||
|                   v-model="action" | ||||
|                   :options="actions.options" | ||||
|                   @select="selectAction" | ||||
|                   @remove="unselectAction" | ||||
|                   :multiple="true" | ||||
|                   :close-on-select="false" | ||||
|                   :placeholder="$t('action.placeholder')" | ||||
|                   label="text" | ||||
|                   track-by="id" | ||||
|                   :searchable="true" | ||||
|                ></VueMultiselect> | ||||
|                 | ||||
|             </div> | ||||
|          </div> | ||||
|       </fieldset> | ||||
|     | ||||
|       <fieldset class="mb-3" id="goal"> | ||||
|          <div class="row"> | ||||
|             <legend class="col-sm-4 col-form-label">{{ $t('goal.label')}}</legend> | ||||
|             <div class="col-sm-8"> | ||||
|              | ||||
|                <VueMultiselect | ||||
|                   name="goal" | ||||
|                   v-model="goal" | ||||
|                   :options="goals.options" | ||||
|                   @select="selectGoal" | ||||
|                   @remove="unselectGoal" | ||||
|                   :multiple="true" | ||||
|                   :close-on-select="false" | ||||
|                   :placeholder="$t('goal.placeholder')" | ||||
|                   label="title" | ||||
|                   :custom-label="transTitle" | ||||
|                   track-by="id" | ||||
|                   :searchable="true" | ||||
|                ></VueMultiselect> | ||||
|           | ||||
|             </div> | ||||
|          </div> | ||||
|       </fieldset> | ||||
|     | ||||
|       <fieldset class="mb-3" id="result"> | ||||
|          <div class="row"> | ||||
|             <legend class="col-sm-4 col-form-label">{{ $t('result.label')}}</legend> | ||||
|             <div class="col-sm-8"> | ||||
|              | ||||
|                <VueMultiselect | ||||
|                   name="result" | ||||
|                   v-model="result" | ||||
|                   :options="results.options" | ||||
|                   :multiple="true" | ||||
|                   :close-on-select="false" | ||||
|                   :placeholder="$t('result.placeholder')" | ||||
|                   label="title" | ||||
|                   :custom-label="transTitle" | ||||
|                   track-by="id" | ||||
|                   :searchable="true" | ||||
|                ></VueMultiselect> | ||||
|           | ||||
|             </div> | ||||
|          </div> | ||||
|       </fieldset> | ||||
|     | ||||
|    </teleport> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import VueMultiselect from 'vue-multiselect'; | ||||
| import { getSocialActions, getGoalByAction, getResultByAction, getResultByGoal } from './api'; | ||||
|  | ||||
| export default { | ||||
|    name: "App", | ||||
|    components: { | ||||
|       VueMultiselect | ||||
|    }, | ||||
|    i18n: { | ||||
|       messages: { | ||||
|          fr: { | ||||
|             action: { | ||||
|                label: 'Types d\'actions', | ||||
|                placeholder: 'Choisissez une ou plusieurs actions', | ||||
|             }, | ||||
|             goal: { | ||||
|                label: 'Objectifs', | ||||
|                placeholder: 'Choisissez un ou plusieurs objectifs', | ||||
|             }, | ||||
|             result: { | ||||
|                label: 'Résultats', | ||||
|                placeholder: 'Choisissez un ou plusieurs résultats', | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|    }, | ||||
|    data() { | ||||
|       return { | ||||
|          actions: { | ||||
|             options: [], // array with multiselect options | ||||
|             value: [],   // array with selected values | ||||
|             hiddenField: document.getElementById( | ||||
|                'export_filters_social_work_type_filter_form_actionType'), | ||||
|          }, | ||||
|          goals: { | ||||
|             options: [], | ||||
|             value: [], | ||||
|             hiddenField: document.getElementById( | ||||
|                'export_filters_social_work_type_filter_form_goal'), | ||||
|          }, | ||||
|          results: { | ||||
|             options: [], | ||||
|             value: [], | ||||
|             hiddenField: document.getElementById( | ||||
|                'export_filters_social_work_type_filter_form_result'), | ||||
|          }, | ||||
|       } | ||||
|    }, | ||||
|    computed: { | ||||
|       action: { | ||||
|          get() { | ||||
|             return this.actions.value; | ||||
|          }, | ||||
|          set(value) { | ||||
|             this.actions.value = value; | ||||
|             this.rebuildHiddenFieldValues('actions'); | ||||
|          } | ||||
|       }, | ||||
|       goal: { | ||||
|          get() { | ||||
|             return this.goals.value; | ||||
|          }, | ||||
|          set(value) { | ||||
|             this.goals.value = value; | ||||
|             this.rebuildHiddenFieldValues('goals'); | ||||
|          } | ||||
|       }, | ||||
|       result: { | ||||
|          get() { | ||||
|             return this.results.value; | ||||
|          }, | ||||
|          set(value) { | ||||
|             this.results.value = value; | ||||
|             this.rebuildHiddenFieldValues('results'); | ||||
|          } | ||||
|       }, | ||||
|    }, | ||||
|    mounted() { | ||||
|       this.getSocialActionsList(); | ||||
|        | ||||
|       this.actions.hiddenField.value = ''; | ||||
|       this.goals.hiddenField.value = ''; | ||||
|       this.results.hiddenField.value = ''; | ||||
|    }, | ||||
|    methods: { | ||||
|       async getSocialActionsList() { | ||||
|          this.actions.options = await getSocialActions(); | ||||
|       }, | ||||
|     | ||||
|       /** | ||||
|        * Select/unselect in Action Multiselect | ||||
|        * @param value | ||||
|        */ | ||||
|       selectAction(value) { | ||||
|          console.log('selectAction', value); | ||||
|          getGoalByAction(value.id).then(response => 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; | ||||
|       }, | ||||
|        | ||||
|       unselectAction(value) { | ||||
|          console.log('unselectAction', value); | ||||
|          getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { | ||||
|             //console.log('fetch Goals', response); | ||||
|             this.goals.options = 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); | ||||
|             resolve(); | ||||
|          })).catch; | ||||
|       }, | ||||
|     | ||||
|       /** | ||||
|        * Select/unselect in Goal Multiselect | ||||
|        * @param value | ||||
|        */ | ||||
|       selectGoal(value) { | ||||
|          console.log('selectGoal', value); | ||||
|          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); | ||||
|          getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { | ||||
|             //console.log('fetch Results', response); | ||||
|             this.results.options = this.removeElementInData('results', response.results); | ||||
|             resolve(); | ||||
|          })).catch; | ||||
|       }, | ||||
|     | ||||
|       /** | ||||
|        * Add response elements in data target | ||||
|        * @param target string -> 'actions', 'goals' or 'results' | ||||
|        * @param response array of objects with fetch results | ||||
|        */ | ||||
|       addElementInData(target, response) { | ||||
|          let data = this[target]; | ||||
|          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); | ||||
|             } | ||||
|          }) | ||||
|       }, | ||||
|     | ||||
|       /** | ||||
|        * Remove response elements from data target | ||||
|        * @param target string -> 'actions', 'goals' or 'results' | ||||
|        * @param response array of objects with fetch results | ||||
|        * @returns data.<target>.options | ||||
|        */ | ||||
|       removeElementInData(target, response) { | ||||
|          let data = this[target]; | ||||
|          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); | ||||
|                 | ||||
|                /// 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); | ||||
|                   } | ||||
|                } | ||||
|                /// | ||||
|             } | ||||
|          }) | ||||
|          return data.options; | ||||
|       }, | ||||
|     | ||||
|       /** | ||||
|        * Rebuild values serie (string) in target HiddenField | ||||
|        * @param target | ||||
|        */ | ||||
|       rebuildHiddenFieldValues(target) { | ||||
|          let data = this[target]; | ||||
|          data.hiddenField.value = ''; // reset | ||||
|          data.value.forEach(elem => { | ||||
|             data.hiddenField.value = this.addIdToValue(data.hiddenField.value, elem.id); | ||||
|          }) | ||||
|       }, | ||||
|        | ||||
|       addIdToValue(string, id) { | ||||
|          let array = string ? string.split(',') : []; | ||||
|          array.push(id.toString()); | ||||
|          let str = array.join(); | ||||
|          return str; | ||||
|       }, | ||||
|        | ||||
|       transTitle ({ title }) { | ||||
|          return title.fr //TODO multilang | ||||
|       }, | ||||
|    }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| </style> | ||||
| @@ -0,0 +1,41 @@ | ||||
| import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods'; | ||||
|  | ||||
| const getSocialActions = () => fetchResults( | ||||
|     '/api/1.0/person/social/social-action.json', { | ||||
|         item_per_page: 200 | ||||
|     } | ||||
| ); | ||||
|  | ||||
| const getGoalByAction = (id) => { | ||||
|     let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`; | ||||
|     return fetch(url) | ||||
|         .then(response => { | ||||
|             if (response.ok) { return response.json(); } | ||||
|             throw Error('Error with request resource response'); | ||||
|         }); | ||||
| }; | ||||
|  | ||||
| const getResultByAction = (id) => { | ||||
|     let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`; | ||||
|     return fetch(url) | ||||
|         .then(response => { | ||||
|             if (response.ok) { return response.json(); } | ||||
|             throw Error('Error with request resource response'); | ||||
|         }); | ||||
| }; | ||||
|  | ||||
| const getResultByGoal = (id) => { | ||||
|     let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`; | ||||
|     return fetch(url) | ||||
|         .then(response => { | ||||
|             if (response.ok) { return response.json(); } | ||||
|             throw Error('Error with request resource response'); | ||||
|         }); | ||||
| }; | ||||
|  | ||||
| export { | ||||
|     getSocialActions, | ||||
|     getGoalByAction, | ||||
|     getResultByAction, | ||||
|     getResultByGoal, | ||||
| } | ||||
| @@ -0,0 +1,13 @@ | ||||
| import { createApp } from "vue"; | ||||
| import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'; | ||||
| import App from './App.vue'; | ||||
|  | ||||
| const i18n = _createI18n({}); | ||||
|  | ||||
| const app = createApp({ | ||||
|     template: `<app></app>`, | ||||
| }) | ||||
| .use(i18n) | ||||
| .component('app', App) | ||||
| .mount('#export_export') | ||||
| ; | ||||
| @@ -0,0 +1,6 @@ | ||||
| <h6> | ||||
|     <a href="{{ path('chill_main_export_index') }}" title="{{ 'Back to the list'|trans }}"> | ||||
|         <i class="fa fa-folder-open-o fa-fw"></i> | ||||
|     </a> | ||||
|     {{ export_group|trans }} | ||||
| </h6> | ||||
| @@ -36,10 +36,7 @@ window.addEventListener("DOMContentLoaded", function(e) { | ||||
| {% block content %} | ||||
|     <div class="col-md-10"> | ||||
|      | ||||
|         <h6> | ||||
|             <i class="fa fa-folder-open-o fa-fw"></i> | ||||
|             {{ export_group|trans }} | ||||
|         </h6> | ||||
|         {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} | ||||
|          | ||||
|         <h1>{{ export.title|trans }}</h1> | ||||
|         <h2>{{ "Download export"|trans }}</h2> | ||||
|   | ||||
| @@ -22,15 +22,21 @@ | ||||
|  | ||||
| {% block js %} | ||||
|     {{ encore_entry_script_tags('page_export') }} | ||||
|     {% if export_alias == 'count_social_work_actions' %} | ||||
|         {# | ||||
|             TODO: [debug] comprendre pq l'activation du composant Vue bloque le passage de | ||||
|                   http://localhost:8001/fr/exports/new/count_social_work_actions?step=export | ||||
|             vers  http://localhost:8001/fr/exports/new/count_social_work_actions?step=formatter | ||||
|              | ||||
|         {{ encore_entry_script_tags('vue_form_action_goal_result') }} | ||||
|         #} | ||||
|     {% endif %} | ||||
| {% endblock js %} | ||||
|  | ||||
| {% block content  %} | ||||
|     <div class="col-md-10"> | ||||
|      | ||||
|         <h6> | ||||
|             <i class="fa fa-folder-open-o fa-fw"></i> | ||||
|             {{ export_group|trans }} | ||||
|         </h6> | ||||
|         {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} | ||||
|      | ||||
|         <h1>{{ export.title|trans }}</h1> | ||||
|          | ||||
|   | ||||
| @@ -22,11 +22,8 @@ | ||||
|  | ||||
| {% block content %} | ||||
|     <div class="col-md-10"> | ||||
|          | ||||
|         <h6> | ||||
|             <i class="fa fa-folder-open-o fa-fw"></i> | ||||
|             {{ export_group|trans }} | ||||
|         </h6> | ||||
|      | ||||
|         {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} | ||||
|          | ||||
|         <h1>{{ export.title|trans }}</h1> | ||||
|          | ||||
|   | ||||
| @@ -23,10 +23,7 @@ | ||||
| {% block content %} | ||||
|     <div class="col-md-10"> | ||||
|      | ||||
|         <h6> | ||||
|             <i class="fa fa-folder-open-o fa-fw"></i> | ||||
|             {{ export_group|trans }} | ||||
|         </h6> | ||||
|         {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} | ||||
|          | ||||
|         <h1>{{ export.title|trans }}</h1> | ||||
|          | ||||
| @@ -36,19 +33,21 @@ | ||||
|         <section class="formatter mb-4"> | ||||
|             <h2>{{ 'Formatter'| trans }}</h2> | ||||
|              | ||||
|             <div> | ||||
|             {% if form.children.formatter.children|length == 0 %} | ||||
|                 <p> | ||||
|                     <span class="chill-no-data-statement">{{ "No options availables. Your report is fully configured."|trans }}</span> | ||||
|                 </p> | ||||
|                 {{ form_widget(form.children.formatter) }} | ||||
|             {% else %} | ||||
|                 {# we always have to render children, to mark as rendered #} | ||||
|                 {% for input in form.children.formatter.children %} | ||||
|                 {{ form_row(input) }} | ||||
|                 {% endfor %} | ||||
|                 <div class="container py-4"> | ||||
|                     {# we always have to render children, to mark as rendered #} | ||||
|                     {% for input in form.children.formatter.children %} | ||||
|                         <div class="row"> | ||||
|                             {{ form_row(input) }} | ||||
|                         </div> | ||||
|                     {% endfor %} | ||||
|                 </div> | ||||
|             {% endif %} | ||||
|             </div> | ||||
|         </section> | ||||
|          | ||||
|         <div class="mb-4"> | ||||
|   | ||||
| @@ -74,4 +74,5 @@ 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'); | ||||
| }; | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\Migrations\Main; | ||||
| @@ -8,10 +15,16 @@ use Doctrine\DBAL\Schema\Schema; | ||||
| use Doctrine\Migrations\AbstractMigration; | ||||
|  | ||||
| /** | ||||
|  * Add new entity GeographicalUnit | ||||
|  * Add new entity GeographicalUnit. | ||||
|  */ | ||||
| final class Version20220829132409 extends AbstractMigration | ||||
| { | ||||
|     public function down(Schema $schema): void | ||||
|     { | ||||
|         $this->addSql('DROP SEQUENCE chill_main_geographical_unit_id_seq CASCADE'); | ||||
|         $this->addSql('DROP TABLE chill_main_geographical_unit'); | ||||
|     } | ||||
|  | ||||
|     public function getDescription(): string | ||||
|     { | ||||
|         return 'Add new entity GeographicalUnit'; | ||||
| @@ -22,10 +35,4 @@ final class Version20220829132409 extends AbstractMigration | ||||
|         $this->addSql('CREATE SEQUENCE chill_main_geographical_unit_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); | ||||
|         $this->addSql('CREATE TABLE chill_main_geographical_unit (id INT NOT NULL, geom TEXT DEFAULT NULL, layerName VARCHAR(255) DEFAULT NULL, unitName VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'); | ||||
|     } | ||||
|  | ||||
|     public function down(Schema $schema): void | ||||
|     { | ||||
|         $this->addSql('DROP SEQUENCE chill_main_geographical_unit_id_seq CASCADE'); | ||||
|         $this->addSql('DROP TABLE chill_main_geographical_unit'); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,4 +23,4 @@ class HouseholdCompositionTypeController extends CRUDController | ||||
|  | ||||
|         return parent::orderQuery($action, $query, $request, $paginator); | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -95,6 +95,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac | ||||
|         $loader->load('services/accompanyingPeriodConsistency.yaml'); | ||||
|  | ||||
|         $loader->load('services/exports_person.yaml'); | ||||
|  | ||||
|         if ($container->getParameter('chill_person.accompanying_period') !== 'hidden') { | ||||
|             $loader->load('services/exports_accompanying_period.yaml'); | ||||
|         } | ||||
|   | ||||
| @@ -31,7 +31,6 @@ class MaritalStatus | ||||
|     private ?string $id; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      * @ORM\Column(type="json") | ||||
|      */ | ||||
|     private array $name; | ||||
|   | ||||
| @@ -1,8 +1,16 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Entity\Location; | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\LocationRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| @@ -24,60 +32,16 @@ class AdministrativeLocationAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Administrative location'; | ||||
|             } | ||||
|  | ||||
|             $l = $this->locationRepository->find($value); | ||||
|  | ||||
|             return $l->getName() .' ('. $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ')'; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['location_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle() | ||||
|     { | ||||
|         return 'Group by administrative location'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.administrativeLocation', 'al'); | ||||
|         if (!in_array('acploc', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.administrativeLocation', 'acploc'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(acp.administrativeLocation) AS location_aggregator'); | ||||
|  | ||||
| @@ -90,11 +54,36 @@ class AdministrativeLocationAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Administrative location'; | ||||
|             } | ||||
|  | ||||
|             $l = $this->locationRepository->find($value); | ||||
|  | ||||
|             return $l->getName() . ' (' . $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ')'; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['location_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle() | ||||
|     { | ||||
|         return 'Group by administrative location'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,20 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| 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 Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| @@ -25,9 +33,38 @@ class ClosingMotiveAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
| @@ -43,61 +80,13 @@ class ClosingMotiveAggregator implements AggregatorInterface | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data) | ||||
|     { | ||||
|         return ['closingmotive_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by closing motive'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.closingMotive', 'cm'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(acp.closingMotive) AS closingmotive_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('closingmotive_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('closingmotive_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -18,65 +27,11 @@ class ConfidentialAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Confidentiality'; | ||||
|             } | ||||
|             switch ($value) { | ||||
|  | ||||
|                 case true: | ||||
|                     return $this->translator->trans('is confidential'); | ||||
|  | ||||
|                 case false: | ||||
|                     return $this->translator->trans('is not confidential'); | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|             return $value; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['confidential_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by confidential'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->addSelect('acp.confidential AS confidential_aggregator'); | ||||
| @@ -90,11 +45,45 @@ class ConfidentialAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Confidentiality'; | ||||
|             } | ||||
|  | ||||
|             switch ($value) { | ||||
|                 case true: | ||||
|                     return $this->translator->trans('is confidential'); | ||||
|  | ||||
|                 case false: | ||||
|                     return $this->translator->trans('is not confidential'); | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|  | ||||
|             return $value; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['confidential_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by confidential'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,131 +1,48 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\PersonBundle\Entity\AccompanyingPeriod; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
|  | ||||
| /** | ||||
|  * Les regroupements seront un nombre de mois, arrondi à l'unité la plus proche (donc | ||||
|  * - au dela de 15 jours => 1 mois, | ||||
|  * - jusqu'à 45 jours => 1 mois, | ||||
|  *    15   |    45   |    75 | ||||
|  *  --+----o----+----o----+---- | ||||
|  *    |   30    |   60    | | ||||
|  * etc.) | ||||
|  */ | ||||
| class DurationAggregator implements AggregatorInterface | ||||
| final class DurationAggregator implements AggregatorInterface | ||||
| { | ||||
|     private TranslatorInterface $translator; | ||||
|      | ||||
|  | ||||
|     public function __construct(TranslatorInterface $translator) | ||||
|     { | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value) use ($data): string { | ||||
|  | ||||
|             if ($value === '_header') { | ||||
|                 return $this->translator->trans('Rounded month duration'); | ||||
|             } | ||||
|  | ||||
|             if ($value === null) { | ||||
|                 return $this->translator->trans('current duration'); // when closingDate is null | ||||
|             } | ||||
|  | ||||
|             if ($value === 0) { | ||||
|                 return $this->translator->trans("duration 0 month"); | ||||
|             } | ||||
|  | ||||
|             return ''. $value . $this->translator->trans(' months'); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['duration_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by duration'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb | ||||
|             // OUI | ||||
|             ->addSelect(' | ||||
|                 (acp.closingDate - acp.openingDate +15) *12/365  | ||||
|                 AS duration_aggregator' | ||||
|             ) | ||||
|             //->addSelect('DATE_DIFF(acp.closingDate, acp.openingDate) AS duration_aggregator') | ||||
|             //->addSelect('EXTRACT(month FROM acp.openingDate) AS duration_aggregator') | ||||
|             //->addSelect("DATE_SUB(acp.openingDate, 6, 'day') AS duration_aggregator") | ||||
|         $qb->addSelect( | ||||
|             ' | ||||
|             (acp.closingDate - acp.openingDate +15) *12/365 | ||||
|             AS duration_aggregator' | ||||
|         ); | ||||
|  | ||||
|             // TODO adapter la fonction extract pour l'utiliser avec des intervals: extract(month from interval) | ||||
|             // et ajouter une fonction custom qui calcule les intervals, comme doctrineum/date-interval | ||||
|             // https://packagist.org/packages/doctrineum/date-interval#3.1.0 | ||||
|             // (composer fait un conflit de dépendance) | ||||
|  | ||||
|             //->addSelect(" | ||||
|             //    EXTRACT( | ||||
|             //        month FROM | ||||
|             //        DATE_INTERVAL(acp.closingDate, acp.openingDate) | ||||
|             //    ) | ||||
|             //    AS duration_aggregator") | ||||
|  | ||||
|             // NON | ||||
|             //->addSelect("BETWEEN acp.openingDate AND acp.closingDate AS duration_aggregator") | ||||
|             //->addSelect("EXTRACT(month FROM DATE_SUB(acp.openingDate, 6, 'day')) AS duration_aggregator") | ||||
|             //->addSelect('EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) AS duration_aggregator') | ||||
|             /* | ||||
|             ->addSelect(' | ||||
|                 ( CASE | ||||
|                     WHEN EXTRACT(day FROM DATE_DIFF(acp.closingDate, acp.openingDate)) > 15 | ||||
|                         THEN EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) +1 | ||||
|                         ELSE EXTRACT(month FROM DATE_DIFF(acp.closingDate, acp.openingDate)) | ||||
|                 END ) AS duration_aggregator | ||||
|             ') | ||||
|             */ | ||||
|         ; | ||||
|         // TODO Pour avoir un interval plus précis (nécessaire ?): | ||||
|         // adapter la fonction extract pour pouvoir l'utiliser avec des intervals: extract(month from interval) | ||||
|         // 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'); | ||||
|  | ||||
| @@ -138,11 +55,42 @@ class DurationAggregator implements AggregatorInterface | ||||
|         $qb->orderBy('duration_aggregator'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): ?string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Rounded month duration'; | ||||
|             } | ||||
|  | ||||
|             if (null === $value) { | ||||
|                 return $this->translator->trans('current duration'); // when closingDate is null | ||||
|             } | ||||
|  | ||||
|             if (0 === $value) { | ||||
|                 return $this->translator->trans('duration 0 month'); | ||||
|             } | ||||
|  | ||||
|             return $value . $this->translator->trans(' months'); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['duration_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by duration'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -18,65 +27,11 @@ class EmergencyAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Emergency'; | ||||
|             } | ||||
|             switch ($value) { | ||||
|  | ||||
|                 case true: | ||||
|                     return $this->translator->trans('is emergency'); | ||||
|  | ||||
|                 case false: | ||||
|                     return $this->translator->trans('is not emergency'); | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|             return $value; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['emergency_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by emergency'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->addSelect('acp.emergency AS emergency_aggregator'); | ||||
| @@ -90,11 +45,45 @@ class EmergencyAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Emergency'; | ||||
|             } | ||||
|  | ||||
|             switch ($value) { | ||||
|                 case true: | ||||
|                     return $this->translator->trans('is emergency'); | ||||
|  | ||||
|                 case false: | ||||
|                     return $this->translator->trans('is not emergency'); | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|  | ||||
|             return $value; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['emergency_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by emergency'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -8,6 +17,7 @@ use Chill\PersonBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| final class EvaluationAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -23,9 +33,42 @@ final class EvaluationAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpw', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.works', 'acpw'); | ||||
|         } | ||||
|  | ||||
|         if (!in_array('workeval', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
| @@ -41,64 +84,13 @@ final class EvaluationAggregator implements AggregatorInterface | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['evaluation_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by evaluation'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpw', $qb->getAllAliases())) { | ||||
|             $qb->join('acp.works', 'acpw'); | ||||
|         } | ||||
|         $qb->join('acpw.accompanyingPeriodWorkEvaluations', 'we'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(we.evaluation) AS evaluation_aggregator'); | ||||
|  | ||||
|         $groupby = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('evaluation_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('evaluation_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,96 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class GeographicalUnitStatAggregator implements AggregatorInterface | ||||
| { | ||||
|     /* | ||||
|     private EntityRepository $repository; | ||||
|  | ||||
|     public function __construct( | ||||
|         EntityManagerInterface $em | ||||
|     ) { | ||||
|         $this->repository = $em->getRepository(...::class); | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Geographical unit'; | ||||
|             } | ||||
|  | ||||
|             $g = $this->repository->find($value); | ||||
|  | ||||
|             return $g; //... | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['geographicalunitstat_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by geographical unit'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|  | ||||
|         //$qb->addSelect('... AS geographicalunitstat_aggregator'); | ||||
|  | ||||
|         $groupby = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('geographicalunitstat_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('geographicalunitstat_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -18,61 +27,11 @@ class IntensityAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Intensity'; | ||||
|             } | ||||
|             switch ($value) { | ||||
|                 case 'occasional': | ||||
|                     return $this->translator->trans('is occasional'); | ||||
|                 case 'regular': | ||||
|                     return $this->translator->trans('is regular'); | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['intensity_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by intensity'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->addSelect('acp.intensity AS intensity_aggregator'); | ||||
| @@ -86,11 +45,43 @@ class IntensityAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Intensity'; | ||||
|             } | ||||
|  | ||||
|             switch ($value) { | ||||
|                 case 'occasional': | ||||
|                     return $this->translator->trans('is occasional'); | ||||
|  | ||||
|                 case 'regular': | ||||
|                     return $this->translator->trans('is regular'); | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['intensity_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by intensity'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,18 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserJobRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class JobAggregator implements AggregatorInterface | ||||
| { | ||||
|  | ||||
|     private UserJobRepository $jobRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -25,62 +32,16 @@ final class JobAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Job'; | ||||
|             } | ||||
|  | ||||
|             $j = $this->jobRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $j->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['job_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by user job'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.job', 'j'); | ||||
|         if (!in_array('acpjob', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.job', 'acpjob'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(acp.job) AS job_aggregator'); | ||||
|  | ||||
| @@ -93,11 +54,38 @@ final class JobAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Job'; | ||||
|             } | ||||
|  | ||||
|             $j = $this->jobRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $j->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['job_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by user job'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -14,9 +23,9 @@ use Symfony\Component\Form\FormBuilderInterface; | ||||
| final class OriginAggregator implements AggregatorInterface | ||||
| { | ||||
|     private EntityRepository $repository; | ||||
|      | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
|      | ||||
|  | ||||
|     public function __construct( | ||||
|         EntityManagerInterface $em, | ||||
|         TranslatableStringHelper $translatableStringHelper | ||||
| @@ -25,62 +34,16 @@ final class OriginAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Origin'; | ||||
|             } | ||||
|              | ||||
|             $o = $this->repository->find($value); | ||||
|              | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $o->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['origin_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by origin'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.origin', 'o'); | ||||
|         if (!in_array('acporigin', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.origin', 'acporigin'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('o.id AS origin_aggregator'); | ||||
|  | ||||
| @@ -93,11 +56,38 @@ final class OriginAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Origin'; | ||||
|             } | ||||
|  | ||||
|             $o = $this->repository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $o->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['origin_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by origin'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -15,16 +15,15 @@ use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserRepository; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class ReferrerAggregator implements AggregatorInterface | ||||
| { | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     private UserRender $userRender; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         UserRepository $userRepository, | ||||
|         UserRender $userRender | ||||
| @@ -33,16 +32,18 @@ final class ReferrerAggregator implements AggregatorInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.user', 'u'); | ||||
|         if (!in_array('acpuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.user', 'acpuser'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('u.id AS referrer_aggregator'); | ||||
|         $qb->addSelect('acpuser.id AS referrer_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -51,7 +52,6 @@ final class ReferrerAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('referrer_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|   | ||||
| @@ -0,0 +1,101 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
| use function in_array; | ||||
|  | ||||
| final class RequestorAggregator implements AggregatorInterface | ||||
| { | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
|     public function __construct( | ||||
|         TranslatorInterface $translator | ||||
|     ) { | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acppart', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.participations', 'acppart'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect(" | ||||
|             ( CASE | ||||
|                 WHEN acp.requestorPerson IS NOT NULL | ||||
|                 THEN | ||||
|                     ( CASE | ||||
|                         WHEN acp.requestorPerson = acppart.person | ||||
|                         THEN 'is person concerned' | ||||
|                         ELSE 'is other person' | ||||
|                     END ) | ||||
|                 ELSE | ||||
|                     ( CASE | ||||
|                         WHEN acp.requestorThirdParty IS NOT NULL | ||||
|                         THEN 'is thirdparty' | ||||
|                         ELSE 'no requestor' | ||||
|                     END ) | ||||
|             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 ! | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Requestor'; | ||||
|             } | ||||
|  | ||||
|             return $this->translator->trans($value); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['requestor_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by requestor'; | ||||
|     } | ||||
| } | ||||
| @@ -1,18 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\ScopeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class ScopeAggregator implements AggregatorInterface | ||||
| { | ||||
|  | ||||
|     private ScopeRepository $scopeRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -25,13 +32,42 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpscope', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Scope'; | ||||
|             } | ||||
|  | ||||
| @@ -43,61 +79,13 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['scope_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by user scope'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.scopes', 's'); | ||||
|  | ||||
|         $qb->addSelect('s.id as scope_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('scope_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('scope_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -8,6 +17,7 @@ use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialActionRender; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| final class SocialActionAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -23,60 +33,14 @@ final class SocialActionAggregator implements AggregatorInterface | ||||
|         $this->actionRepository = $actionRepository; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function($value) { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social action'; | ||||
|             } | ||||
|  | ||||
|             $sa = $this->actionRepository->find($value); | ||||
|  | ||||
|             return $this->actionRender->renderString($sa, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialaction_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by social action'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpw', $qb->getAllAliases())) { | ||||
|         if (!in_array('acpw', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.works', 'acpw'); | ||||
|         } | ||||
|  | ||||
| @@ -91,11 +55,36 @@ final class SocialActionAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value) { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social action'; | ||||
|             } | ||||
|  | ||||
|             $sa = $this->actionRepository->find($value); | ||||
|  | ||||
|             return $this->actionRender->renderString($sa, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialaction_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by social action'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -11,11 +20,10 @@ use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class SocialIssueAggregator implements AggregatorInterface | ||||
| { | ||||
|     private SocialIssueRender $issueRender; | ||||
|  | ||||
|     private SocialIssueRepository $issueRepository; | ||||
|  | ||||
|     private SocialIssueRender $issueRender; | ||||
|  | ||||
|     public function __construct( | ||||
|         SocialIssueRepository $issueRepository, | ||||
|         SocialIssueRender $issueRender | ||||
| @@ -24,62 +32,18 @@ final class SocialIssueAggregator implements AggregatorInterface | ||||
|         $this->issueRender = $issueRender; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|  | ||||
|             if ($value === '_header') { | ||||
|                 return 'Social issues'; | ||||
|             } | ||||
|  | ||||
|             $i = $this->issueRepository->find($value); | ||||
|  | ||||
|             return $this->issueRender->renderString($i, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialissue_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by social issue'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acp.socialIssues', 'si'); | ||||
|         $qb->addSelect('si.id as socialissue_aggregator'); | ||||
|         if (!in_array('acpsocialissue', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acp.socialIssues', 'acpsocialissue'); | ||||
|         } | ||||
|          | ||||
|         $qb->addSelect('acpsocialissue.id as socialissue_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -90,11 +54,36 @@ final class SocialIssueAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social issues'; | ||||
|             } | ||||
|  | ||||
|             $i = $this->issueRepository->find($value); | ||||
|  | ||||
|             return $this->issueRender->renderString($i, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['socialissue_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by social issue'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -7,6 +16,7 @@ use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\PersonBundle\Entity\AccompanyingPeriod; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use DateTime; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| @@ -23,69 +33,11 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             switch ($value) { | ||||
|  | ||||
|                 case AccompanyingPeriod::STEP_DRAFT: | ||||
|                     return $this->translator->trans('Draft'); | ||||
|  | ||||
|                 case AccompanyingPeriod::STEP_CONFIRMED: | ||||
|                     return $this->translator->trans('Confirmed'); | ||||
|  | ||||
|                 case AccompanyingPeriod::STEP_CLOSED: | ||||
|                     return $this->translator->trans('Closed'); | ||||
|  | ||||
|                 case '_header': | ||||
|                     return 'Step'; | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['step_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new \DateTime(), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by step'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->addSelect('acp.step AS step_aggregator'); | ||||
| @@ -119,14 +71,50 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface | ||||
|         $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new DateTime(), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             switch ($value) { | ||||
|                 case AccompanyingPeriod::STEP_DRAFT: | ||||
|                     return $this->translator->trans('Draft'); | ||||
|  | ||||
|                 case AccompanyingPeriod::STEP_CONFIRMED: | ||||
|                     return $this->translator->trans('Confirmed'); | ||||
|  | ||||
|                 case AccompanyingPeriod::STEP_CLOSED: | ||||
|                     return $this->translator->trans('Closed'); | ||||
|  | ||||
|                 case '_header': | ||||
|                     return 'Step'; | ||||
|  | ||||
|                 default: | ||||
|                     throw new LogicException(sprintf('The value %s is not valid', $value)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['step_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by step'; | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * TODO check if we need to add FilterInterface and DescribeAction Method to describe date filter ?? | ||||
|      * | ||||
| @@ -138,5 +126,5 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface | ||||
|             ] | ||||
|         ]; | ||||
|     } | ||||
|     */ | ||||
| } | ||||
|      */ | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\EvaluationAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -23,57 +32,11 @@ class EvaluationTypeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Evaluation type'; | ||||
|             } | ||||
|  | ||||
|             $ev = $this->evaluationRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize($ev->getTitle()); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['evaluationtype_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by evaluation type'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->addSelect('IDENTITY(eval.evaluation) AS evaluationtype_aggregator'); | ||||
| @@ -87,11 +50,36 @@ class EvaluationTypeAggregator implements AggregatorInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::EVAL_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Evaluation type'; | ||||
|             } | ||||
|  | ||||
|             $ev = $this->evaluationRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize($ev->getTitle()); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['evaluationtype_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by evaluation type'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,26 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\HouseholdAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use DateTime; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class ChildrenNumberAggregator implements AggregatorInterface | ||||
| { | ||||
| @@ -19,64 +32,14 @@ class ChildrenNumberAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|  | ||||
|             if ($value === '_header') { | ||||
|                 return 'Number of children'; | ||||
|             } | ||||
|  | ||||
|             return $this->translator->trans( | ||||
|                 'household_composition.numberOfChildren children in household', [ | ||||
|                 'numberOfChildren' => $value | ||||
|             ]); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['childrennumber_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new \DateTime('now'), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by number of children'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('composition', $qb->getAllAliases())) { | ||||
|         if (!in_array('composition', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('household.compositions', 'composition'); | ||||
|         } | ||||
|  | ||||
| @@ -100,13 +63,52 @@ class ChildrenNumberAggregator implements AggregatorInterface | ||||
|                 $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); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::HOUSEHOLD_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new DateTime('now'), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Number of children'; | ||||
|             } | ||||
|  | ||||
|             return $this->translator->trans( | ||||
|                 'household_composition.numberOfChildren children in household', | ||||
|                 [ | ||||
|                     'numberOfChildren' => $value, | ||||
|                 ] | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['childrennumber_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by number of children'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,14 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\HouseholdAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| @@ -7,17 +16,19 @@ use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Repository\Household\HouseholdCompositionTypeRepository; | ||||
| use DateTime; | ||||
| use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Query\Expr\Andx; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use function in_array; | ||||
|  | ||||
| class CompositionAggregator implements AggregatorInterface | ||||
| { | ||||
|     private HouseholdCompositionTypeRepository $typeRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
|  | ||||
|     private HouseholdCompositionTypeRepository $typeRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         HouseholdCompositionTypeRepository $typeRepository, | ||||
|         TranslatableStringHelper $translatableStringHelper | ||||
| @@ -26,64 +37,14 @@ class CompositionAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|                 return 'Composition'; | ||||
|             } | ||||
|  | ||||
|             $c = $this->typeRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $c->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['composition_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new \DateTime('now'), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by composition'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('composition', $qb->getAllAliases())) { | ||||
|         if (!in_array('composition', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('household.compositions', 'composition'); | ||||
|         } | ||||
|  | ||||
| @@ -118,11 +79,40 @@ class CompositionAggregator implements AggregatorInterface | ||||
|         $qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::HOUSEHOLD_TYPE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         $builder->add('on_date', ChillDateType::class, [ | ||||
|             'data' => new DateTime('now'), | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Composition'; | ||||
|             } | ||||
|  | ||||
|             $c = $this->typeRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize( | ||||
|                 $c->getLabel() | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['composition_aggregator']; | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by composition'; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,7 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|   | ||||
| @@ -42,7 +42,7 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ final class GenderAggregator implements AggregatorInterface | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|   | ||||
| @@ -15,22 +15,22 @@ use Chill\MainBundle\Export\AggregatorInterface; | ||||
| 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\Repository\Household\PositionRepository; | ||||
| use DateTime; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\Extension\Core\Type\DateType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
|  | ||||
| final class HouseholdPositionAggregator implements AggregatorInterface, ExportElementValidatedInterface | ||||
| { | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
|     private PositionRepository $positionRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
|  | ||||
|     private TranslatorInterface $translator; | ||||
|  | ||||
|     public function __construct(TranslatorInterface $translator, TranslatableStringHelper $translatableStringHelper, PositionRepository $positionRepository) | ||||
|     { | ||||
|         $this->translator = $translator; | ||||
| @@ -38,7 +38,7 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -46,22 +46,27 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->resetDQLPart('from'); | ||||
|         $qb->from('ChillPersonBundle:Household\HouseholdMember', 'hm'); | ||||
|         $qb->from(HouseholdMember::class, 'member'); | ||||
|  | ||||
|         $qb->join('hm.person', 'person'); | ||||
|         $qb->join('person.center', 'center'); | ||||
|         if (!in_array('memberperson', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('member.person', 'memberperson'); | ||||
|         } | ||||
|  | ||||
|         if (!in_array('membercenter', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('memberperson.center', 'membercenter'); | ||||
|         } | ||||
|  | ||||
|         $qb->andWhere($qb->expr()->andX( | ||||
|             $qb->expr()->lte('hm.startDate', ':date'), | ||||
|             $qb->expr()->lte('member.startDate', ':date'), | ||||
|             $qb->expr()->orX( | ||||
|                 $qb->expr()->isNull('hm.endDate'), | ||||
|                 $qb->expr()->gte('hm.endDate', ':date') | ||||
|                 $qb->expr()->isNull('member.endDate'), | ||||
|                 $qb->expr()->gte('member.endDate', ':date') | ||||
|             ) | ||||
|         )); | ||||
|  | ||||
|         $qb->setParameter('date', $data['date_position']); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(hm.position) AS household_position_aggregator'); | ||||
|         $qb->addSelect('IDENTITY(member.position) AS household_position_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -70,7 +75,6 @@ final class HouseholdPositionAggregator implements AggregatorInterface, ExportEl | ||||
|         } else { | ||||
|             $qb->groupBy('household_position_aggregator'); | ||||
|         } | ||||
|          | ||||
|     } | ||||
|  | ||||
|     public function applyOn() | ||||
|   | ||||
| @@ -18,7 +18,6 @@ use Chill\PersonBundle\Repository\MaritalStatusRepository; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
|  | ||||
| final class MaritalStatusAggregator implements AggregatorInterface | ||||
| { | ||||
|     private MaritalStatusRepository $maritalStatusRepository; | ||||
| @@ -31,15 +30,18 @@ final class MaritalStatusAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('person.maritalStatus', 'ms'); | ||||
|         $qb->addSelect('ms.id as marital_status_aggregator'); | ||||
|         if (!in_array('personmarital', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('person.maritalStatus', 'personmarital'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('personmarital.id as marital_status_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|   | ||||
| @@ -41,7 +41,7 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV | ||||
|         $this->translator = $translator; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| @@ -124,19 +124,17 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV | ||||
|                 ->getQuery() | ||||
|                 ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR); | ||||
|  | ||||
|                  | ||||
|             // initialize array and add blank key for null values | ||||
|             $labels = [ | ||||
|                 '' => $this->translator->trans('without data'), | ||||
|                 '_header' => $this->translator->trans('Nationality'), | ||||
|             ]; | ||||
|  | ||||
|              | ||||
|             foreach ($countries as $row) { | ||||
|                 $labels[$row['c_countryCode']] = $this->translatableStringHelper->localize($row['c_name']); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|  | ||||
|         if ('continent' === $data['group_by_level']) { | ||||
|             $labels = [ | ||||
|                 'EU' => $this->translator->trans('Europe'), | ||||
| @@ -151,10 +149,9 @@ final class NationalityAggregator implements AggregatorInterface, ExportElementV | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return function ($value) use ($labels): string { | ||||
|         return static function ($value) use ($labels): string { | ||||
|             return $labels[$value]; | ||||
|         }; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function getQueryKeys($data) | ||||
|   | ||||
| @@ -12,33 +12,38 @@ declare(strict_types=1); | ||||
| namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; | ||||
| use Chill\PersonBundle\Templating\Entity\SocialActionRender; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class ActionTypeAggregator implements AggregatorInterface | ||||
| { | ||||
|     private SocialActionRender $actionRender; | ||||
|  | ||||
|     private SocialActionRepository $socialActionRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
|  | ||||
|     public function __construct(SocialActionRepository $socialActionRepository, TranslatableStringHelper $translatableStringHelper) | ||||
|     { | ||||
|     public function __construct( | ||||
|         SocialActionRepository $socialActionRepository, | ||||
|         SocialActionRender $actionRender | ||||
|     ) { | ||||
|         $this->socialActionRepository = $socialActionRepository; | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|         $this->actionRender = $actionRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.socialAction', 'sa'); | ||||
|         $qb->addSelect('sa.id as action_type_aggregator'); | ||||
|         if (!in_array('acpwsocialaction', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acpw.socialAction', 'acpwsocialaction'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('acpwsocialaction.id as action_type_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -47,7 +52,6 @@ final class ActionTypeAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('action_type_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn() | ||||
| @@ -62,7 +66,6 @@ final class ActionTypeAggregator implements AggregatorInterface | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         //TODO certain social actions have the same title as other, but are linked to different social issues, should we make a visual distinction? | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Social Action Type'; | ||||
| @@ -70,7 +73,7 @@ final class ActionTypeAggregator implements AggregatorInterface | ||||
|  | ||||
|             $sa = $this->socialActionRepository->find($value); | ||||
|  | ||||
|             return $this->translatableStringHelper->localize($sa->getTitle()); | ||||
|             return $this->actionRender->renderString($sa, []); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -30,15 +30,18 @@ final class GoalAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.goals', 'g'); | ||||
|         $qb->addSelect('g.id as goal_aggregator'); | ||||
|         if (!in_array('goal', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acpw.goals', 'goal'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('goal.id as goal_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -47,7 +50,6 @@ final class GoalAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('goal_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn() | ||||
|   | ||||
| @@ -1,18 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserJobRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class JobAggregator implements AggregatorInterface | ||||
| { | ||||
|  | ||||
|     private UserJobRepository $jobRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -25,13 +32,42 @@ final class JobAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpwuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::SOCIAL_WORK_ACTION_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function($value): string { | ||||
|             if ($value === '_header') { | ||||
|         return function ($value): string { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Job'; | ||||
|             } | ||||
|  | ||||
| @@ -43,61 +79,13 @@ final class JobAggregator implements AggregatorInterface | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['job_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by treating agent job'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.referrers', 'u'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(u.userJob) as job_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('job_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('job_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::SOCIAL_WORK_ACTION_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -15,16 +15,15 @@ use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\UserRepository; | ||||
| use Chill\MainBundle\Templating\Entity\UserRender; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class ReferrerAggregator implements AggregatorInterface | ||||
| { | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     private UserRender $userRender; | ||||
|  | ||||
|     private UserRepository $userRepository; | ||||
|  | ||||
|     public function __construct( | ||||
|         UserRepository $userRepository, | ||||
|         UserRender $userRender | ||||
| @@ -33,16 +32,18 @@ final class ReferrerAggregator implements AggregatorInterface | ||||
|         $this->userRender = $userRender; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.referrers', 'u'); | ||||
|         if (!in_array('acpwuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acpw.referrers', 'acpwuser'); | ||||
|         } | ||||
|  | ||||
|         $qb->addSelect('u.id AS referrer_aggregator'); | ||||
|         $qb->addSelect('acpwuser.id AS referrer_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
| @@ -51,7 +52,6 @@ final class ReferrerAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('referrer_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|   | ||||
| @@ -30,17 +30,26 @@ final class ResultAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     public function addRole() | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.results', 'res'); | ||||
|         $qb->join('acpw.goals', 'g'); | ||||
|         $qb->join('g.results', 'gres'); | ||||
|         $qb->addSelect('res.id, IDENTITY(g.results) as result_aggregator'); | ||||
|         if (!in_array('acpwresult', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('acpw.results', 'acpwresult'); | ||||
|         } | ||||
|  | ||||
|         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'); | ||||
|  | ||||
| @@ -49,7 +58,6 @@ final class ResultAggregator implements AggregatorInterface | ||||
|         } else { | ||||
|             $qb->groupBy('result_aggregator'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function applyOn() | ||||
|   | ||||
| @@ -1,18 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Chill is a software for social workers | ||||
|  * | ||||
|  * For the full copyright and license information, please view | ||||
|  * the LICENSE file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\PersonBundle\Export\Aggregator\SocialWorkAggregators; | ||||
|  | ||||
| use Chill\MainBundle\Export\AggregatorInterface; | ||||
| use Chill\MainBundle\Repository\ScopeRepository; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelper; | ||||
| use Chill\PersonBundle\Export\Declarations; | ||||
| use Doctrine\ORM\Query\Expr\From; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| final class ScopeAggregator implements AggregatorInterface | ||||
| { | ||||
|  | ||||
|     private ScopeRepository $scopeRepository; | ||||
|  | ||||
|     private TranslatableStringHelper $translatableStringHelper; | ||||
| @@ -25,13 +32,42 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         $this->translatableStringHelper = $translatableStringHelper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole(): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         if (!in_array('acpwuser', $qb->getAllAliases(), true)) { | ||||
|             $qb->join('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'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::SOCIAL_WORK_ACTION_TYPE; | ||||
|     } | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         return function ($value): string { | ||||
|             if ($value === '_header') { | ||||
|             if ('_header' === $value) { | ||||
|                 return 'Scope'; | ||||
|             } | ||||
|  | ||||
| @@ -43,61 +79,13 @@ final class ScopeAggregator implements AggregatorInterface | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getQueryKeys($data): array | ||||
|     { | ||||
|         return ['scope_aggregator']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function buildForm(FormBuilderInterface $builder) | ||||
|     { | ||||
|         // no form | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Group by treating agent scope'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function addRole() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function alterQuery(QueryBuilder $qb, $data) | ||||
|     { | ||||
|         $qb->join('acpw.referrers', 'u'); | ||||
|  | ||||
|         $qb->addSelect('IDENTITY(u.mainScope) as scope_aggregator'); | ||||
|  | ||||
|         $groupBy = $qb->getDQLPart('groupBy'); | ||||
|  | ||||
|         if (!empty($groupBy)) { | ||||
|             $qb->addGroupBy('scope_aggregator'); | ||||
|         } else { | ||||
|             $qb->groupBy('scope_aggregator'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function applyOn(): string | ||||
|     { | ||||
|         return Declarations::SOCIAL_WORK_ACTION_TYPE; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -16,15 +16,15 @@ namespace Chill\PersonBundle\Export; | ||||
|  */ | ||||
| abstract class Declarations | ||||
| { | ||||
|     public const PERSON_IMPLIED_IN = 'person_implied_in'; | ||||
|  | ||||
|     public const PERSON_TYPE = 'person'; | ||||
|  | ||||
|     public const ACP_TYPE = 'accompanying_period'; | ||||
|  | ||||
|     public const SOCIAL_WORK_ACTION_TYPE = 'social_actions'; | ||||
|  | ||||
|     public const EVAL_TYPE = 'evaluation'; | ||||
|  | ||||
|     public const HOUSEHOLD_TYPE = 'household'; | ||||
|  | ||||
|     public const PERSON_IMPLIED_IN = 'person_implied_in'; | ||||
|  | ||||
|     public const PERSON_TYPE = 'person'; | ||||
|  | ||||
|     public const SOCIAL_WORK_ACTION_TYPE = 'social_actions'; | ||||
| } | ||||
|   | ||||
| @@ -21,9 +21,8 @@ use Doctrine\ORM\EntityManagerInterface; | ||||
| use Doctrine\ORM\EntityRepository; | ||||
| use Doctrine\ORM\Query; | ||||
| use Doctrine\ORM\QueryBuilder; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use LogicException; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
|  | ||||
| class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
| { | ||||
| @@ -40,11 +39,6 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
|         // TODO: Implement buildForm() method. | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Count accompanying courses'; | ||||
|     } | ||||
|  | ||||
|     public function getAllowedFormattersTypes(): array | ||||
|     { | ||||
|         return [FormatterInterface::TYPE_TABULAR]; | ||||
| @@ -55,6 +49,11 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
|         return 'Count accompanying courses by various parameters'; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of accompanying courses'; | ||||
|     } | ||||
|  | ||||
|     public function getLabels($key, array $values, $data) | ||||
|     { | ||||
|         if ('export_result' !== $key) { | ||||
| @@ -79,6 +78,11 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
|         return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); | ||||
|     } | ||||
|  | ||||
|     public function getTitle(): string | ||||
|     { | ||||
|         return 'Count accompanying courses'; | ||||
|     } | ||||
|  | ||||
|     public function getType(): string | ||||
|     { | ||||
|         return Declarations::ACP_TYPE; | ||||
| @@ -93,9 +97,9 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
|         return $qb; | ||||
|     } | ||||
|  | ||||
|     public function requiredRole(): Role | ||||
|     public function requiredRole(): string | ||||
|     { | ||||
|         return new Role(AccompanyingPeriodVoter::STATS); | ||||
|         return AccompanyingPeriodVoter::STATS; | ||||
|     } | ||||
|  | ||||
|     public function supportsModifiers(): array | ||||
| @@ -104,9 +108,4 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface | ||||
|             Declarations::ACP_TYPE, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     public function getGroup(): string | ||||
|     { | ||||
|         return 'Exports of accompanying courses'; | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user