merge 111_exports_suite into testing branch

This commit is contained in:
Julie Lenaerts 2022-09-08 10:03:21 +02:00
commit 4aaf75a1a4
182 changed files with 4668 additions and 4386 deletions

View 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
1 Entity Join Attribute Alias
2 AccompanyingPeriod::class acp
3 AccompanyingPeriodWork::class acp.works acpw
4 AccompanyingPeriodParticipation::class acp.participations acppart
5 Location::class acp.administrativeLocation acploc
6 ClosingMotive::class acp.closingMotive acpmotive
7 UserJob::class acp.job acpjob
8 Origin::class acp.origin acporigin
9 Scope::class acp.scopes acpscope
10 SocialIssue::class acp.socialIssues acpsocialissue
11 User::class acp.user acpuser
12 AccompanyingPeriodWork::class acpw
13 AccompanyingPeriodWorkEvaluation::class acpw.accompanyingPeriodWorkEvaluations workeval
14 Goal::class acpw.goals goal
15 User::class acpw.referrers acpwuser
16 Result::class acpw.results acpwresult
17 SocialAction::class acpw.socialAction acpwsocialaction
18 AccompanyingPeriodParticipation::class acppart
19 Person::class acppart.person partperson
20 AccompanyingPeriodWorkEvaluation::class workeval
21 Evaluation::class workeval.evaluation eval
22 Goal::class goal
23 Result::class goal.results goalresult
24 Person::class person
25 Center::class person.center center
26 HouseholdMember::class partperson.householdParticipations member
27 MaritalStatus::class person.maritalStatus personmarital
28 ResidentialAddress::class resaddr
29 Person::class resaddr.person resaddrperson
30 Center::class resaddrperson.center resaddrcenter
31 ThirdParty::class resaddr.hostThirdParty tparty
32 ThirdParty::class tparty
33 ThirdPartyCategory::class tparty.categories tpartycat
34 HouseholdMember::class member
35 Household::class member.household household
36 Person::class member.person memberperson
37 memberperson.center membercenter
38 Household::class household
39 HouseholdComposition::class household.compositions composition
40 Activity::class activity
41 Person::class activity.person actperson
42 AccompanyingPeriod::class activity.accompanyingPeriod actacp
43 Person::class activity_person_having_activity.person person_person_having_activity
44 ActivityReason::class activity_person_having_activity.reasons reasons_person_having_activity
45 ActivityType::class activity.activityType acttype
46 Location::class activity.location actloc
47 SocialAction::class activity.socialActions actsocialaction
48 SocialIssue::class activity.socialIssues actsocialssue
49 ThirdParty::class activity.thirdParties acttparty
50 User::class activity.user actuser
51 User::class activity.users actusers
52 ActivityReason::class activity.reasons actreasons
53 Center::class actperson.center actcenter
54 ActivityReason::class actreasons
55 ActivityReasonCategory::class actreason.category actreasoncat
56 Calendar::class cal
57 CancelReason::class cal.cancelReason calcancel
58 Location::class cal.location calloc
59 User::class cal.user caluser
60 VendeePerson::class vp
61 Person::class vp.person vpperson
62 Center::class vpperson.center vpcenter
63 SituationProfessionelle::class vp.situationProfessionelle vpprof
64 StatutLogement::class vp.statutLogement vplog
65 TempsDeTravail::class vp.tempsDeTravail vptt
66 VendeePersonMineur::class vpm
67 Person::class vpm.person vpmperson
68 Center::class vpmperson.center vpmcenter

View 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 |

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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';
}

View File

@ -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
@ -94,10 +104,4 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
//PersonDeclarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
}
}

View File

@ -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
@ -94,10 +104,4 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
//PersonDeclarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
}
}

View File

@ -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
@ -102,9 +108,4 @@ class CountActivity implements ExportInterface, GroupedExportInterface
//PersonDeclarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
}

View File

@ -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
@ -94,10 +107,4 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
//PersonDeclarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
}
}

View File

@ -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
@ -94,9 +107,4 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
//PersonDeclarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of activities linked to an accompanying period';
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -52,7 +52,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}

View File

@ -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';
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}
}

View File

@ -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';
}
}
}

View File

@ -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';
}
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}
}

View File

@ -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

View File

@ -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;
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -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
),
];

View File

@ -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

View File

@ -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');
}
}

View File

@ -23,4 +23,4 @@ class HouseholdCompositionTypeController extends CRUDController
return parent::orderQuery($action, $query, $request, $paginator);
}
}
}

View File

@ -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');
}

View File

@ -31,7 +31,6 @@ class MaritalStatus
private ?string $id;
/**
* @var array
* @ORM\Column(type="json")
*/
private array $name;

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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

View File

@ -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';
}
}

View File

@ -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;
}
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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
]
];
}
*/
}
*/
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -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';
}
}

View File

@ -29,7 +29,7 @@ final class AgeAggregator implements AggregatorInterface, ExportElementValidated
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}

View File

@ -42,7 +42,7 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}

View File

@ -28,7 +28,7 @@ final class GenderAggregator implements AggregatorInterface
$this->translator = $translator;
}
public function addRole()
public function addRole(): ?string
{
return null;
}

View File

@ -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()

View File

@ -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');

View File

@ -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)

View File

@ -12,33 +12,37 @@ 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;
}
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 +51,6 @@ final class ActionTypeAggregator implements AggregatorInterface
} else {
$qb->groupBy('action_type_aggregator');
}
}
public function applyOn()
@ -62,7 +65,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 +72,7 @@ final class ActionTypeAggregator implements AggregatorInterface
$sa = $this->socialActionRepository->find($value);
return $this->translatableStringHelper->localize($sa->getTitle());
return $this->actionRender->renderString($sa, []);
};
}

View File

@ -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()

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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()

View File

@ -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;
}
}
}

View File

@ -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';
}

View File

@ -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';
}
}
}

View File

@ -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\Export;
use Chill\MainBundle\Export\ExportInterface;
@ -12,11 +21,9 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountEvaluation implements ExportInterface, GroupedExportInterface
{
private EntityRepository $repository;
public function __construct(
@ -25,41 +32,26 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
$this->repository = $em->getRepository(AccompanyingPeriod::class);
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// TODO: Implement buildForm() method.
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count evaluations';
}
/**
* @inheritDoc
*/
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
}
/**
* @inheritDoc
*/
public function getDescription(): string
{
return 'Count evaluation by various parameters.';
}
/**
* @inheritDoc
*/
public function getGroup(): string
{
return 'Exports of evaluations';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -74,56 +66,48 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['export_result'];
}
/**
* @inheritDoc
*/
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count evaluations';
}
public function getType(): string
{
return Declarations::EVAL_TYPE;
}
/**
* @inheritDoc
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('acp')
->join('acp.works', 'acpw')
->join('acpw.accompanyingPeriodWorkEvaluations', 'eval')
;
$qb = $this->repository->createQueryBuilder('acp');
$qb->select('COUNT(eval.id) AS export_result');
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->select('COUNT(workeval.id) AS export_result');
return $qb;
}
/**
* @inheritDoc
*/
public function requiredRole()
public function requiredRole(): string
{
return new Role(AccompanyingPeriodVoter::STATS);
return AccompanyingPeriodVoter::STATS;
}
/**
* @inheritDoc
*/
public function supportsModifiers(): array
{
return [
@ -132,9 +116,4 @@ class CountEvaluation implements ExportInterface, GroupedExportInterface
//Declarations::SOCIAL_WORK_ACTION_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of evaluations';
}
}
}

View File

@ -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\Export;
use Chill\MainBundle\Export\ExportInterface;
@ -7,12 +16,11 @@ use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountHousehold implements ExportInterface, GroupedExportInterface
{
@ -24,41 +32,26 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
$this->repository = $em->getRepository(AccompanyingPeriod::class);
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// TODO: Implement buildForm() method.
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count households';
}
/**
* @inheritDoc
*/
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
}
/**
* @inheritDoc
*/
public function getDescription(): string
{
return 'Count household by various parameters.';
}
/**
* @inheritDoc
*/
public function getGroup(): string
{
return 'Exports of households';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -73,59 +66,57 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['export_result'];
}
/**
* @inheritDoc
*/
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count households';
}
public function getType(): string
{
return Declarations::HOUSEHOLD_TYPE;
}
/**
* @inheritDoc
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('acp')
->join('acp.participations', 'acppart')
->join('acppart.person', 'person')
->join('person.householdParticipations', 'householdmember')
->join('householdmember.household', 'household')
;
$qb = $this->repository->createQueryBuilder('acp');
$qb->select('COUNT(DISTINCT householdmember.household) AS export_result');
if (!in_array('acppart', $qb->getAllAliases(), true)) {
$qb->join('acp.participations', 'acppart');
}
if (!in_array('partperson', $qb->getAllAliases(), true)) {
$qb->join('acppart.person', 'partperson');
}
if (!in_array('member', $qb->getAllAliases(), true)) {
$qb->join('partperson.householdParticipations', 'member');
}
if (!in_array('household', $qb->getAllAliases(), true)) {
$qb->join('member.household', 'household');
}
$qb->select('COUNT(DISTINCT member.household) AS export_result');
return $qb;
}
/**
* @inheritDoc
*/
public function requiredRole()
public function requiredRole(): string
{
// TODO HouseholdVoter::STATS !??
return new Role(AccompanyingPeriodVoter::STATS);
return HouseholdVoter::STATS;
}
/**
* @inheritDoc
*/
public function supportsModifiers(): array
{
return [
@ -133,9 +124,4 @@ class CountHousehold implements ExportInterface, GroupedExportInterface
//Declarations::ACP_TYPE
];
}
public function getGroup(): string
{
return 'Exports of households';
}
}
}

View File

@ -21,11 +21,9 @@ use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountPerson implements ExportInterface, GroupedExportInterface
{
protected PersonRepository $personRepository;
public function __construct(
@ -49,6 +47,11 @@ class CountPerson implements ExportInterface, GroupedExportInterface
return 'Count people by various parameters.';
}
public function getGroup(): string
{
return 'Exports of persons';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -104,9 +107,9 @@ class CountPerson implements ExportInterface, GroupedExportInterface
return $qb;
}
public function requiredRole()
public function requiredRole(): string
{
return new Role(PersonVoter::STATS);
return PersonVoter::STATS;
}
public function supportsModifiers()
@ -117,9 +120,4 @@ class CountPerson implements ExportInterface, GroupedExportInterface
//Declarations::ACP_TYPE
];
}
public function getGroup(): string
{
return 'Exports of persons';
}
}

View File

@ -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\Export;
use Chill\MainBundle\Export\ExportInterface;
@ -12,7 +21,6 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Role\Role;
class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExportInterface
{
@ -24,41 +32,26 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
$this->repository = $em->getRepository(AccompanyingPeriod::class);
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
// TODO: Implement buildForm() method.
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count people participating in an accompanying course';
}
/**
* @inheritDoc
*/
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
}
/**
* @inheritDoc
*/
public function getDescription(): string
{
return 'Count people participating in an accompanying course by various parameters.';
}
/**
* @inheritDoc
*/
public function getGroup(): string
{
return 'Exports of persons';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -73,66 +66,53 @@ class CountPersonWithAccompanyingCourse implements ExportInterface, GroupedExpor
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['export_result'];
}
/**
* @inheritDoc
*/
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Count people participating in an accompanying course';
}
public function getType(): string
{
return Declarations::HOUSEHOLD_TYPE;
}
/**
* @inheritDoc
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{
$qb = $this->repository->createQueryBuilder('acp')
->join('acp.participations', 'acppart')
->join('acppart.person', 'person')
;
$qb = $this->repository->createQueryBuilder('acp');
$qb->select('COUNT(DISTINCT person.id) AS export_result');
if (!in_array('acppart', $qb->getAllAliases(), true)) {
$qb->join('acp.participations', 'acppart');
}
if (!in_array('partperson', $qb->getAllAliases(), true)) {
$qb->join('acppart.person', 'partperson');
}
$qb->select('COUNT(DISTINCT partperson.id) AS export_result');
return $qb;
}
/**
* @inheritDoc
*/
public function requiredRole()
public function requiredRole(): string
{
return new Role(AccompanyingPeriodVoter::STATS);
return AccompanyingPeriodVoter::STATS;
}
/**
* @inheritDoc
*/
public function supportsModifiers(): array
{
return [
Declarations::ACP_TYPE,
Declarations::PERSON_TYPE
Declarations::PERSON_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of persons';
}
}
}

View File

@ -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 LogicException;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Form\FormBuilderInterface;
class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
{
@ -40,11 +39,6 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
// No form necessary?
}
public function getTitle(): string
{
return 'Count social work actions';
}
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
@ -55,6 +49,11 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
return 'Count social work actions by various parameters';
}
public function getGroup(): string
{
return 'Exports of social work actions';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -79,6 +78,11 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle(): string
{
return 'Count social work actions';
}
public function getType(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
@ -86,19 +90,20 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
{
$qb = $this->repository->createQueryBuilder('acp')
->join('acp.works', 'acpw')
;
$qb = $this->repository->createQueryBuilder('acp');
if (!in_array('acpw', $qb->getAllAliases(), true)) {
$qb->join('acp.works', 'acpw');
}
$qb->select('COUNT(acpw.id) as export_result');
return $qb;
}
public function requiredRole(): Role
public function requiredRole(): string
{
//TODO change to string, but changes needed also in ExportManager and possibly other locations.
return new Role(AccompanyingPeriodVoter::STATS);
return AccompanyingPeriodVoter::STATS;
}
public function supportsModifiers(): array
@ -107,9 +112,4 @@ class CountSocialWorkActions implements ExportInterface, GroupedExportInterface
Declarations::SOCIAL_WORK_ACTION_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of social work actions';
}
}
}

View File

@ -29,7 +29,6 @@ use Exception;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
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;
@ -136,6 +135,11 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
return 'Create a list of people according to various filters.';
}
public function getGroup(): string
{
return 'Exports of persons';
}
public function getLabels($key, array $values, $data)
{
switch ($key) {
@ -350,9 +354,9 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
return $qb;
}
public function requiredRole()
public function requiredRole(): string
{
return new Role(PersonVoter::LISTS);
return PersonVoter::LISTS;
}
public function supportsModifiers()
@ -426,9 +430,11 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
if ('_header' === $value) {
return $this->translatableStringHelper->localize($cf->getName());
}
if (null === $value) {
return '';
}
return $this->customFieldProvider
->getCustomFieldByType($cf->getType())
->render(json_decode($value, true), $cf, 'csv');
@ -437,6 +443,7 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
if ($cfType instanceof CustomFieldChoice && $cfType->isMultiple($cf)) {
return function ($value) use ($cf, $cfType, $key) {
$slugChoice = $this->extractInfosFromSlug($key)['additionnalInfos']['choiceSlug'];
if (null === $value) {
return '';
}
@ -475,9 +482,4 @@ class ListPerson implements ExportElementValidatedInterface, ListInterface, Grou
return $uid;
}
public function getGroup(): string
{
return 'Exports of persons';
}
}

View File

@ -129,6 +129,11 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
return 'Create a list of duplicate people';
}
public function getGroup(): string
{
return 'Exports of persons';
}
/**
* @return string
*/
@ -137,9 +142,9 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
return 'List duplicates';
}
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(PersonVoter::DUPLICATE);
return PersonVoter::DUPLICATE;
}
public function validateForm($data, ExecutionContextInterface $context)
@ -197,9 +202,4 @@ class ListPersonDuplicate implements DirectExportInterface, ExportElementValidat
return $result->fetchAllAssociative();
}
public function getGroup(): string
{
return 'Exports of persons';
}
}

View File

@ -18,16 +18,15 @@ use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use DateTime;
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 StatAccompanyingCourseDuration implements ExportInterface, GroupedExportInterface
{
private EntityRepository $repository;
public function __construct(
@ -36,44 +35,29 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
$this->repository = $em->getRepository(AccompanyingPeriod::class);
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('closingdate', ChillDateType::class, [
'label' => 'Closingdate to apply',
'data' => new \DateTime('now'),
'data' => new DateTime('now'),
]);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Accompanying courses duration';
}
/**
* @inheritDoc
*/
public function getAllowedFormattersTypes(): array
{
return [FormatterInterface::TYPE_TABULAR];
}
/**
* @inheritDoc
*/
public function getDescription(): string
{
return 'Create an average of accompanying courses duration according to various filters';
}
/**
* @inheritDoc
*/
public function getGroup(): string
{
return 'Exports of accompanying courses';
}
public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
@ -88,33 +72,26 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data): array
{
return ['export_result'];
}
/**
* @inheritDoc
*/
public function getResult($qb, $data)
{
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Accompanying courses duration';
}
public function getType(): string
{
return Declarations::ACP_TYPE;
}
/**
* @inheritDoc
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
{
$qb = $this->repository->createQueryBuilder('acp');
@ -125,34 +102,22 @@ class StatAccompanyingCourseDuration implements ExportInterface, GroupedExportIn
WHEN acp.closingDate IS NOT NULL
THEN acp.closingDate
ELSE :force_closingDate
END ) - acp.openingDate
END ) - acp.openingDate
) AS export_result')
->setParameter('force_closingDate', $data['closingdate'])
;
->setParameter('force_closingDate', $data['closingdate']);
return $qb;
}
/**
* @inheritDoc
*/
public function requiredRole(): Role
public function requiredRole(): string
{
return new Role(AccompanyingPeriodVoter::STATS);
return AccompanyingPeriodVoter::STATS;
}
/**
* @inheritDoc
*/
public function supportsModifiers(): array
{
return [
Declarations::ACP_TYPE
Declarations::ACP_TYPE,
];
}
public function getGroup(): string
{
return 'Exports of accompanying courses';
}
}
}

View File

@ -1,60 +1,32 @@
<?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\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Export\FilterInterface;
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 DateTime;
class ActiveOnDateFilter implements FilterInterface
{
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('on_date', ChillDateType::class, [
'data' => new DateTime(),
])
;
}
/**
* @inheritDoc
*/
public function getTitle(): string
{
return 'Filter by active on date';
}
/**
* @inheritDoc
*/
public function describeAction($data, $format = 'string'): array
{
return ['Filtered by actives courses: active on %ondate%', [
'%ondate%' => $data['on_date']->format('d-m-Y')
]];
}
/**
* @inheritDoc
*/
public function addRole()
public function addRole(): ?string
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
@ -77,11 +49,28 @@ class ActiveOnDateFilter implements 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 describeAction($data, $format = 'string'): array
{
return ['Filtered by actives courses: active on %ondate%', [
'%ondate%' => $data['on_date']->format('d-m-Y'),
]];
}
public function getTitle(): string
{
return 'Filter by active on date';
}
}

Some files were not shown because too many files have changed in this diff Show More