Merge branch '111_exports' into social_action_exports

This commit is contained in:
Julie Lenaerts 2022-08-25 09:28:01 +02:00
commit f3ceee7485
27 changed files with 1572 additions and 33 deletions

View File

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class BySocialActionAggregator implements AggregatorInterface
{
private SocialActionRender $actionRender;
private SocialActionRepository $actionRepository;
public function __construct(
SocialActionRender $actionRender,
SocialActionRepository $actionRepository
) {
$this->actionRender = $actionRender;
$this->actionRepository = $actionRepository;
}
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 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

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class BySocialIssueAggregator implements AggregatorInterface
{
private SocialIssueRepository $issueRepository;
private SocialIssueRender $issueRender;
public function __construct(
SocialIssueRepository $issueRepository,
SocialIssueRender $issueRender
) {
$this->issueRepository = $issueRepository;
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('socialissue', $qb->getAllAliases())) {
$qb->join('activity.socialIssues', 'socialissue');
}
$qb->addSelect('socialissue.id AS socialissue_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('socialissue_aggregator');
} else {
$qb->groupBy('socialissue_aggregator');
}
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class ByThirdpartyAggregator implements AggregatorInterface
{
private ThirdPartyRepository $thirdPartyRepository;
private ThirdPartyRender $thirdPartyRender;
public function __construct(
ThirdPartyRepository $thirdPartyRepository,
ThirdPartyRender $thirdPartyRender
) {
$this->thirdPartyRepository = $thirdPartyRepository;
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('thirdparty', $qb->getAllAliases())) {
$qb->join('activity.thirdParties', 'thirdparty');
}
$qb->addSelect('thirdparty.id AS thirdparty_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('thirdparty_aggregator');
} else {
$qb->groupBy('thirdparty_aggregator');
}
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class ByUserAggregator implements AggregatorInterface
{
private UserRepository $userRepository;
private UserRender $userRender;
public function __construct(
UserRepository $userRepository,
UserRender $userRender
) {
$this->userRepository = $userRepository;
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('user', $qb->getAllAliases())) {
$qb->join('activity.users', 'user');
}
$qb->addSelect('user.id AS users_aggregator');
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('users_aggregator');
} else {
$qb->groupBy('users_aggregator');
}
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,136 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\AggregatorInterface;
use Closure;
use Doctrine\ORM\QueryBuilder;
use RuntimeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class DateAggregator implements AggregatorInterface
{
private const CHOICES = [
'by month' => 'month',
'by week' => 'week',
'by year' => 'year',
];
private CONST DEFAULT_CHOICE = 'year';
private TranslatorInterface $translator;
public function __construct(
TranslatorInterface $translator
) {
$this->translator = $translator;
}
public function getLabels($key, array $values, $data)
{
return function ($value) use ($data): string {
switch ($data['frequency']) {
case 'month':
if ($value === '_header') {
return 'by month';
}
$month = \DateTime::createFromFormat('!m', $value);
return
sprintf("%02d", $value) .'/'.
$month->format('F') // TODO translation ?!?
;
case 'week':
if ($value === '_header') {
return 'by week';
}
return $this->translator->trans('for week') .' '. $value ;
case 'year':
if ($value === '_header') {
return 'by year';
}
return $this->translator->trans('in year') .' '. $value ;
default:
throw new RuntimeException(sprintf('The value %s is not valid', $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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
switch ($data['frequency']) {
case 'month':
$qb
//->addSelect("TO_CHAR(activity.date,'Mon') AS MON")
->addSelect('EXTRACT(month FROM activity.date) AS date_aggregator')
//->orderBy('date_aggregator')
;
break;
case 'week':
$qb
->addSelect("TO_CHAR(activity.date, 'IW') AS date_aggregator")
//->orderBy('date_aggregator')
;
break;
case 'year':
$qb
//->addSelect("TO_CHAR(activity.date, 'YYYY') AS date_aggregator")
->addSelect('EXTRACT(year FROM activity.date) AS date_aggregator')
//->orderBy('date_aggregator', 'ASC')
;
break;
default:
throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency']));
}
$groupBy = $qb->getDQLPart('groupBy');
if (!empty($groupBy)) {
$qb->addGroupBy('date_aggregator');
} else {
$qb->groupBy('date_aggregator');
}
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class LocationTypeAggregator implements AggregatorInterface
{
private LocationTypeRepository $locationTypeRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
LocationTypeRepository $locationTypeRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->locationTypeRepository = $locationTypeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ($value === '_header') {
return 'Accepted locationtype';
}
$lt = $this->locationTypeRepository->find($value);
return $this->translatableStringHelper->localize(
$lt->getTitle()
);
};
}
public function getQueryKeys($data): array
{
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

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
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;
class UserScopeAggregator implements AggregatorInterface
{
private ScopeRepository $scopeRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
ScopeRepository $scopeRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->scopeRepository = $scopeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function getLabels($key, array $values, $data)
{
return function ($value): string {
if ($value === '_header') {
return 'Scope';
}
$s = $this->scopeRepository->find($value);
return $this->translatableStringHelper->localize(
$s->getName()
);
};
}
public function getQueryKeys($data): array
{
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

@ -15,6 +15,7 @@ use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Entity\UserRender;
use Closure; use Closure;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
@ -26,10 +27,14 @@ class ActivityUserAggregator implements AggregatorInterface
private UserRepository $userRepository; private UserRepository $userRepository;
private UserRender $userRender;
public function __construct( public function __construct(
UserRepository $userRepository UserRepository $userRepository,
UserRender $userRender
) { ) {
$this->userRepository = $userRepository; $this->userRepository = $userRepository;
$this->userRender = $userRender;
} }
public function addRole() public function addRole()
@ -48,7 +53,7 @@ class ActivityUserAggregator implements AggregatorInterface
public function applyOn(): string public function applyOn(): string
{ {
return Declarations::ACTIVITY_PERSON; return Declarations::ACTIVITY;
} }
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
@ -63,10 +68,12 @@ class ActivityUserAggregator implements AggregatorInterface
return function ($value) { return function ($value) {
if ('_header' === $value) { if ('_header' === $value) {
return 'activity user'; return 'Activity user';
} }
return $this->userRepository->find($value)->getUsername(); $u = $this->userRepository->find($value);
return $this->userRender->renderString($u, []);
}; };
} }

View File

@ -9,7 +9,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Aggregator; namespace Chill\ActivityBundle\Export\Aggregator\PersonAggregators;
use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository; use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;

View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\MainBundle\Export\FilterInterface;
use Chill\ActivityBundle\Export\Declarations;
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;
class BySocialActionFilter implements FilterInterface
{
private SocialActionRender $actionRender;
public function __construct(SocialActionRender $actionRender)
{
$this->actionRender = $actionRender;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_socialactions', EntityType::class, [
'class' => SocialAction::class,
'choice_label' => function (SocialAction $sa) {
return $this->actionRender->renderString($sa, []);
},
'multiple' => true,
'expanded' => true,
]);
}
public function getTitle(): string
{
return 'Filter activity by linked socialaction';
}
public function describeAction($data, $format = 'string'): array
{
$actions = [];
foreach ($data['accepted_socialactions'] as $sa) {
$actions[] = $this->actionRender->renderString($sa, []);
}
return ['Filtered activity by linked socialaction: only %actions%', [
'%actions%' => implode(", ou ", $actions)
]];
}
public function addRole()
{
return null;
}
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

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\MainBundle\Export\FilterInterface;
use Chill\ActivityBundle\Export\Declarations;
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;
class BySocialIssueFilter implements FilterInterface
{
private SocialIssueRender $issueRender;
public function __construct(SocialIssueRender $issueRender)
{
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
if (!in_array('socialissue', $qb->getAllAliases())) {
$qb->join('activity.socialIssues', 'socialissue');
}
$clause = $qb->expr()->in('socialissue.id', ':socialissues');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('socialissues', $data['accepted_socialissues']);
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
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;
class ByUserFilter implements FilterInterface
{
private UserRender $userRender;
public function __construct(UserRender $userRender)
{
$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,
]);
}
public function getTitle(): string
{
return 'Filter activity by linked users';
}
public function describeAction($data, $format = 'string'): array
{
$users = [];
foreach ($data['accepted_users'] as $u) {
$users[] = $this->userRender->renderString($u, []);
}
return ['Filtered activity by linked users: only %users%', [
'%users%' => implode(", ou ", $users)
]];
}
public function addRole()
{
return null;
}
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

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\MainBundle\Export\FilterInterface;
use Chill\ActivityBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class EmergencyFilter implements FilterInterface
{
private const CHOICES = [
'activity is emergency' => true,
'activity is not emergency' => false,
];
private CONST DEFAULT_CHOICE = false;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('activity.emergency', ':emergency');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('emergency', $data['accepted_emergency']);
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
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;
class LocationTypeFilter implements FilterInterface
{
private TranslatableStringHelper $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_locationtype', EntityType::class, [
'class' => LocationType::class,
'choice_label' => function(LocationType $type) {
return $this->translatableStringHelper->localize($type->getTitle());
},
'multiple' => true,
'expanded' => true,
]);
}
public function getTitle(): string
{
return 'Filter activity by locationtype';
}
public function describeAction($data, $format = 'string'): array
{
$types = [];
foreach ($data['accepted_locationtype'] as $type) {
$types[] = $this->translatableStringHelper->localize(
$type->getTitle()
);
}
return ['Filtered activity by locationtype: only %types%', [
'%types%' => implode(", ou ", $types)
]];
}
public function addRole()
{
return null;
}
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

@ -0,0 +1,82 @@
<?php
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 Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SentReceivedFilter implements FilterInterface
{
private const CHOICES = [
'is sent' => Activity::SENTRECEIVED_SENT,
'is received' => Activity::SENTRECEIVED_RECEIVED,
];
private CONST DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('activity.sentReceived', ':sentreceived');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('sentreceived', $data['accepted_sentreceived']);
}
public function applyOn(): string
{
return Declarations::ACTIVITY_ACP;
}
}

View File

@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
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;
class UserFilter implements FilterInterface
{
private UserRender $userRender;
public function __construct(UserRender $userRender)
{
$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()
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('activity.user', ':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

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
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;
class UserScopeFilter implements FilterInterface
{
private TranslatableStringHelper $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_userscope', EntityType::class, [
'class' => Scope::class,
'choice_label' => function (Scope $s) {
return $this->translatableStringHelper->localize(
$s->getName()
);
},
'multiple' => true,
'expanded' => true
]);
}
public function getTitle(): string
{
return 'Filter activity by userscope';
}
public function describeAction($data, $format = 'string'): array
{
$scopes = [];
foreach ($data['accepted_userscope'] as $s) {
$scopes[] = $this->translatableStringHelper->localize(
$s->getName()
);
}
return ['Filtered activity by userscope: only %scopes%', [
'%scopes%' => implode(", ou ", $scopes)
]];
}
public function addRole()
{
return null;
}
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

@ -9,7 +9,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Export\Declarations;

View File

@ -9,7 +9,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter; namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\ActivityBundle\Repository\ActivityReasonRepository;

View File

@ -45,11 +45,6 @@ services:
- { name: chill.export, alias: 'avg_activity_visit_duration_linked_to_acp' } - { name: chill.export, alias: 'avg_activity_visit_duration_linked_to_acp' }
## Filters ## Filters
chill.activity.export.reason_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityReasonFilter
tags:
- { name: chill.export_filter, alias: 'activity_reason_filter' }
chill.activity.export.type_filter: chill.activity.export.type_filter:
class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter
tags: tags:
@ -60,16 +55,61 @@ services:
tags: tags:
- { name: chill.export_filter, alias: 'activity_date_filter' } - { name: chill.export_filter, alias: 'activity_date_filter' }
chill.activity.export.reason_filter:
class: Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter
tags:
- { name: chill.export_filter, alias: 'activity_reason_filter' }
chill.activity.export.person_having_an_activity_between_date_filter: chill.activity.export.person_having_an_activity_between_date_filter:
class: Chill\ActivityBundle\Export\Filter\PersonHavingActivityBetweenDateFilter class: Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter
tags: tags:
- #0 register as a filter - #0 register as a filter
name: chill.export_filter name: chill.export_filter
alias: 'activity_person_having_ac_bw_date_filter' alias: 'activity_person_having_ac_bw_date_filter'
chill.activity.export.locationtype_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter
tags:
- { name: chill.export_filter, alias: 'activity_locationtype_filter' }
chill.activity.export.byuser_filter: # TMS (M2M)
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ByUserFilter
tags:
- { name: chill.export_filter, alias: 'activity_byuser_filter' }
chill.activity.export.emergency_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter
tags:
- { name: chill.export_filter, alias: 'activity_emergency_filter' }
chill.activity.export.sentreceived_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\SentReceivedFilter
tags:
- { name: chill.export_filter, alias: 'activity_sentreceived_filter' }
chill.activity.export.bysocialaction_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialActionFilter
tags:
- { name: chill.export_filter, alias: 'activity_bysocialaction_filter' }
chill.activity.export.bysocialissue_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialIssueFilter
tags:
- { name: chill.export_filter, alias: 'activity_bysocialissue_filter' }
chill.activity.export.user_filter: # Creator (M2O)
class: Chill\ActivityBundle\Export\Filter\ACPFilters\UserFilter
tags:
- { name: chill.export_filter, alias: 'activity_user_filter' }
chill.activity.export.userscope_filter:
class: Chill\ActivityBundle\Export\Filter\ACPFilters\UserScopeFilter
tags:
- { name: chill.export_filter, alias: 'activity_userscope_filter' }
## Aggregators ## Aggregators
chill.activity.export.reason_aggregator: chill.activity.export.reason_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator class: Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator
tags: tags:
- { name: chill.export_aggregator, alias: activity_reason_aggregator } - { name: chill.export_aggregator, alias: activity_reason_aggregator }
@ -82,3 +122,38 @@ services:
class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
tags: tags:
- { name: chill.export_aggregator, alias: activity_user_aggregator } - { name: chill.export_aggregator, alias: activity_user_aggregator }
chill.activity.export.locationtype_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\LocationTypeAggregator
tags:
- { name: chill.export_aggregator, alias: activity_locationtype_aggregator }
chill.activity.export.date_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\DateAggregator
tags:
- { name: chill.export_aggregator, alias: activity_date_aggregator }
chill.activity.export.byuser_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByUserAggregator
tags:
- { name: chill.export_aggregator, alias: activity_byuser_aggregator }
chill.activity.export.bythirdparty_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator
tags:
- { name: chill.export_aggregator, alias: activity_bythirdparty_aggregator }
chill.activity.export.bysocialaction_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialActionAggregator
tags:
- { name: chill.export_aggregator, alias: activity_bysocialaction_aggregator }
chill.activity.export.bysocialissue_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialIssueAggregator
tags:
- { name: chill.export_aggregator, alias: activity_bysocialissue_aggregator }
chill.activity.export.userscope_aggregator:
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\UserScopeAggregator
tags:
- { name: chill.export_aggregator, alias: activity_userscope_aggregator }

View File

@ -249,9 +249,35 @@ Activity reasons for those activities: Sujets de ces activités
Filter by activity type: Filtrer les activités par type Filter by activity type: Filtrer les activités par type
Filter activity by locationtype: Filtrer les activités par type de localisation
'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%"
Accepted locationtype: Types de localisation
Filter activity by linked users: Filtrer les activités par TMS
'Filtered activity by linked users: only %users%': "Filtré par TMS: uniquement %users%"
Accepted users: TMS(s)
Filter activity by emergency: Filtrer les activités par urgence
'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%"
activity is emergency: l'activité est urgente
activity is not emergency: l'activité n'est pas urgente
Filter activity by sentreceived: Filtrer les activités par envoyé/reçu
'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%"
Accepted sentreceived: ''
is sent: envoyé
is received: reçu
Filter activity by linked socialaction: Filtrer les activités par action liée
'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%"
Filter activity by linked socialissue: Filtrer les activités par problématique liée
'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%"
Filter activity by user: Filtrer les activités par créateur
'Filtered activity by user: only %users%': "Filtré par créateur: uniquement %users%"
Creators: Créateurs
Filter activity by userscope: Filtrer les activités par service du créateur
'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%"
Accepted userscope: Services
#aggregators #aggregators
Activity type: Type d'activité Activity type: Type d'activité
Activity user: Utilisateur lié à l'activity Activity user: Utilisateur lié à l'activité
By reason: Par sujet By reason: Par sujet
By category of reason: Par catégorie de sujet By category of reason: Par catégorie de sujet
Reason's level: Niveau du sujet Reason's level: Niveau du sujet
@ -260,6 +286,21 @@ Aggregate by activity user: Grouper les activités par utilisateur
Aggregate by activity type: Grouper les activités par type Aggregate by activity type: Grouper les activités par type
Aggregate by activity reason: Grouper les activités par sujet Aggregate by activity reason: Grouper les activités par sujet
Group activity by locationtype: Grouper les activités par type de localisation
Group activity by date: Grouper les activités par date
Frequency: Fréquence
by month: Par mois
by week: Par semaine
for week: Semaine
by year: Par année
in year: En
Group activity by linked users: Grouper les activités par TMS impliqué
Group activity by linked thirdparties: Grouper les activités par tiers impliqué
Accepted thirdparty: Tiers impliqué
Group activity by linked socialaction: Grouper les activités par action liée
Group activity by linked socialissue: Grouper les activités par problématique liée
Group activity by userscope: Grouper les activités par service du créateur
Last activities: Les dernières activités Last activities: Les dernières activités
See activity in accompanying course context: Voir l'activité dans le contexte du parcours d'accompagnement See activity in accompanying course context: Voir l'activité dans le contexte du parcours d'accompagnement

View File

@ -41,13 +41,14 @@ crud:
# exports # exports
Exports of calendar: Exports des rendez-vous Exports of calendar: Exports des rendez-vous
Count appointments: Nombre des rendez-vous Count appointments: Nombre de rendez-vous
Count appointments by various parameters.: Compte le nombre de rendez-vous en fonction de différents paramètres.
Average appointment duration: Moyenne des durées des rendez-vous Average appointment duration: Moyenne de la durée des rendez-vous
Get the average of appointment duration according to various filters: Calculer la moyenne des durées des rendez-vous Get the average of appointment duration according to various filters: Calcule la moyenne des durées des rendez-vous en fonction de différents paramètres.
Sum of appointment durations: Somme des durées des rendez-vous Sum of appointment durations: Somme de la durée des rendez-vous
Get the sum of appointment durations according to various filters: Calculer la somme des durées 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%" 'Filtered by agent: only %agents%': "Filtré par agents: uniquement %agents%"
Filter by agent: Filtrer par agents Filter by agent: Filtrer par agents

View File

@ -22,6 +22,7 @@ use Chill\MainBundle\Controller\UserController;
use Chill\MainBundle\Controller\UserJobApiController; use Chill\MainBundle\Controller\UserJobApiController;
use Chill\MainBundle\Controller\UserJobController; use Chill\MainBundle\Controller\UserJobController;
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface; use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
use Chill\MainBundle\Doctrine\DQL\Extract;
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey; use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
use Chill\MainBundle\Doctrine\DQL\JsonAggregate; use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength; use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength;
@ -31,6 +32,7 @@ use Chill\MainBundle\Doctrine\DQL\Replace;
use Chill\MainBundle\Doctrine\DQL\Similarity; use Chill\MainBundle\Doctrine\DQL\Similarity;
use Chill\MainBundle\Doctrine\DQL\STContains; use Chill\MainBundle\Doctrine\DQL\STContains;
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS; use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
use Chill\MainBundle\Doctrine\DQL\ToChar;
use Chill\MainBundle\Doctrine\DQL\Unaccent; use Chill\MainBundle\Doctrine\DQL\Unaccent;
use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator; use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator;
use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType; use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType;
@ -238,6 +240,10 @@ class ChillMainExtension extends Extension implements
'ST_CONTAINS' => STContains::class, 'ST_CONTAINS' => STContains::class,
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class, 'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
], ],
'datetime_functions' => [
'EXTRACT' => Extract::class,
'TO_CHAR' => ToChar::class,
],
], ],
'hydrators' => [ 'hydrators' => [
'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class, 'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class,

View File

@ -0,0 +1,47 @@
<?php
namespace Chill\MainBundle\Doctrine\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\AST\PathExpression;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
/**
* Extract postgresql function
* https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
*
* Usage : EXTRACT(field FROM value)
*/
class Extract extends FunctionNode
{
private string $field;
private PathExpression $value;
public function getSql(SqlWalker $sqlWalker)
{
return sprintf(
'EXTRACT(%s FROM %s)',
$this->field,
$this->value->dispatch($sqlWalker)
);
}
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_IDENTIFIER);
$this->field = $parser->getLexer()->token['value'];
$parser->match(Lexer::T_FROM);
$this->value = $parser->ScalarExpression();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Chill\MainBundle\Doctrine\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
/**
* Usage : TO_CHAR(datetime, fmt)
*/
class ToChar extends FunctionNode
{
private $datetime;
private $fmt;
public function getSql(SqlWalker $sqlWalker)
{
return sprintf(
'TO_CHAR(%s, %s)',
$sqlWalker->walkArithmeticPrimary($this->datetime),
$sqlWalker->walkArithmeticPrimary($this->fmt)
);
}
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->datetime = $parser->ArithmeticExpression();
$parser->match(Lexer::T_COMMA);
$this->fmt = $parser->StringExpression();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}

View File

@ -13,8 +13,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class EmergencyFilter implements FilterInterface class EmergencyFilter implements FilterInterface
{ {
private const CHOICES = [ private const CHOICES = [
'is not emergency' => false,
'is emergency' => true, 'is emergency' => true,
'is not emergency' => false,
]; ];
private CONST DEFAULT_CHOICE = false; private CONST DEFAULT_CHOICE = false;
@ -28,7 +28,7 @@ class EmergencyFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder->add('accepted_emergencies', ChoiceType::class, [ $builder->add('accepted_emergency', ChoiceType::class, [
'choices' => self::CHOICES, 'choices' => self::CHOICES,
'multiple' => false, 'multiple' => false,
'expanded' => true, 'expanded' => true,
@ -45,7 +45,7 @@ class EmergencyFilter implements FilterInterface
public function describeAction($data, $format = 'string'): array public function describeAction($data, $format = 'string'): array
{ {
foreach (self::CHOICES as $k => $v) { foreach (self::CHOICES as $k => $v) {
if ($v === $data['accepted_emergencies']) { if ($v === $data['accepted_emergency']) {
$choice = $k; $choice = $k;
} }
} }
@ -74,7 +74,7 @@ class EmergencyFilter implements FilterInterface
} }
$qb->add('where', $where); $qb->add('where', $where);
$qb->setParameter('emergency', $data['accepted_emergencies']); $qb->setParameter('emergency', $data['accepted_emergency']);
} }
public function applyOn(): string public function applyOn(): string

View File

@ -349,7 +349,7 @@ Create an average of accompanying courses duration according to various filters:
Closingdate to apply: Date de fin à prendre en compte lorsque le parcours n'est pas clotûré Closingdate to apply: Date de fin à prendre en compte lorsque le parcours n'est pas clotûré
Exports of social work actions: Exports des actions d'accompagnement Exports of social work actions: Exports des actions d'accompagnement
Count social work actions: Nombre d'actions d'accompagnement Count social work actions: Nombre d'actions
Count social work actions by various parameters: Compte le nombre d'actions d'accompagnement en fonction de différents filtres. Count social work actions by various parameters: Compte le nombre d'actions d'accompagnement en fonction de différents filtres.
@ -361,7 +361,7 @@ Exports of households: Exports des ménages
Count households: Nombre de ménages Count households: Nombre de ménages
Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres. Count household by various parameters.: Compte le nombre de ménages impliqués dans un parcours selon différents filtres.
## filters ## persons filters
Filter by person gender: Filtrer par genre de la personne Filter by person gender: Filtrer par genre de la personne
Accepted genders: Genres acceptés Accepted genders: Genres acceptés
'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%' 'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%'
@ -424,6 +424,7 @@ Having an accompanying period closed after this date: Ayant une période d'accom
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date" "Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%" "Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
## accompanying course filters/aggr
Filter by user scope: Filtrer les parcours par service du référent Filter by user scope: Filtrer les parcours par service du référent
"Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%" "Filtered by user main scope: only %scope%": "Filtré par service du référent: uniquement %scope%"
Group by user scope: Grouper les parcours par service du référent Group by user scope: Grouper les parcours par service du référent
@ -433,7 +434,6 @@ Filter by user job: Filtrer les parcours par métier du référent
Group by user job: Grouper les parcours par métier du référent Group by user job: Grouper les parcours par métier du référent
Filter by social issue: Filtrer les parcours par problématiques sociales Filter by social issue: Filtrer les parcours par problématiques sociales
Filter by scope: Filtrer par service
Accepted socialissues: Problématiques sociales Accepted socialissues: Problématiques sociales
"Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%" "Filtered by socialissues: only %socialissues%": "Filtré par problématique sociale: uniquement %socialissues%"
Group by social issue: Grouper les parcours par problématiques sociales Group by social issue: Grouper les parcours par problématiques sociales
@ -458,10 +458,6 @@ Evaluation: Évaluation
"Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%" "Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%"
Group by evaluation: Grouper les parcours par évaluation Group by evaluation: Grouper les parcours par évaluation
Group social work actions by action type: Grouper par type d'action
Group social work actions by goal: Grouper par objectif
Group social work actions by result: Grouper par résultat
Filter accompanying course by activity type: Filtrer les parcours par type d'activité Filter accompanying course by activity type: Filtrer les parcours par type d'activité
Accepted activitytypes: Types d'activités Accepted activitytypes: Types d'activités
"Filtered by activity types: only %activitytypes%": "Filtré par type d'activité: seulement %activitytypes%" "Filtered by activity types: only %activitytypes%": "Filtré par type d'activité: seulement %activitytypes%"
@ -499,7 +495,7 @@ Confidentiality: Confidentialité
Group by confidential: Grouper les parcours par confidentialité Group by confidential: Grouper les parcours par confidentialité
Filter by emergency: Filtrer les parcours par urgence Filter by emergency: Filtrer les parcours par urgence
Accepted emergencies: '' Accepted emergency: ''
is emergency: le parcours est urgent is emergency: le parcours est urgent
is not emergency: le parcours n'est pas urgent is not emergency: le parcours n'est pas urgent
"Filtered by emergency: only %emergency%": "Filtré par urgence: uniquement si %emergency%" "Filtered by emergency: only %emergency%": "Filtré par urgence: uniquement si %emergency%"
@ -531,10 +527,13 @@ Date from: Date de début
Date to: Date de fin Date to: Date de fin
"Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%" "Filtered by opening dates: between %datefrom% and %dateto%": "Filtrer les parcours ouverts entre deux dates: entre le %datefrom% et le %dateto%"
## social actions filters/aggr
Filter by treating agent scope: Filtrer les actions par service de l'agent traitant Filter by treating agent scope: Filtrer les actions par service de l'agent traitant
"Filtered by treating agent scope: only %scopes%": "Filtré par service de l'agent traitant: uniquement %scopes%" "Filtered by treating agent scope: only %scopes%": "Filtré par service de l'agent traitant: uniquement %scopes%"
Group by treating agent scope: Grouper les actions par service de l'agent traitant Group by treating agent scope: Grouper les actions par service de l'agent traitant
Filter by scope: Filtrer par service
Filter by treating agent job: Filtrer les actions par métier de l'agent traitant Filter by treating agent job: Filtrer les actions par métier de l'agent traitant
"Filtered by treating agent job: only %jobs%": "Filtré par métier de l'agent traitant: uniquement %jobs%" "Filtered by treating agent job: only %jobs%": "Filtré par métier de l'agent traitant: uniquement %jobs%"
Group by treating agent job: Grouper les actions par métier de l'agent traitant Group by treating agent job: Grouper les actions par métier de l'agent traitant
@ -544,6 +543,11 @@ Accepted agents: Agent traitant
"Filtered by treating agent: only %agents%": "Filtré par agent traitant: uniquement %agents%" "Filtered by treating agent: only %agents%": "Filtré par agent traitant: uniquement %agents%"
Group by treating agent: Grouper les actions par agent traitant Group by treating agent: Grouper les actions par agent traitant
Group social work actions by action type: Grouper les actions par type
Group social work actions by goal: Grouper les actions par objectif
Group social work actions by result: Grouper les actions par résultat
## evaluations filters/aggr
Filter by evaluation type: Filtrer les évaluations par type Filter by evaluation type: Filtrer les évaluations par type
Accepted evaluationtype: Évaluations Accepted evaluationtype: Évaluations
"Filtered by evaluation type: only %evals%": "Filtré par type d'évaluation: uniquement %evals%" "Filtered by evaluation type: only %evals%": "Filtré par type d'évaluation: uniquement %evals%"
@ -556,6 +560,7 @@ is specified: La date d'échéance est spécifiée
is not specified: La date d'échéance n'est pas spécifiée is not specified: La date d'échéance n'est pas spécifiée
"Filtered by maxdate: only %choice%": "Filtré par date d'échéance: uniquement si %choice%" "Filtered by maxdate: only %choice%": "Filtré par date d'échéance: uniquement si %choice%"
## household filters/aggr
Filter by composition: Filtrer les ménages par composition familiale Filter by composition: Filtrer les ménages par composition familiale
Accepted composition: Composition familiale Accepted composition: Composition familiale
"Filtered by composition: only %compositions% on %ondate%": "Filtré par composition familiale: uniquement %compositions%, en date du %ondate%" "Filtered by composition: only %compositions% on %ondate%": "Filtré par composition familiale: uniquement %compositions%, en date du %ondate%"
@ -563,7 +568,7 @@ Group by composition: Grouper les ménages par composition familiale
Group by number of children: Grouper les ménages par nombre d'enfants Group by number of children: Grouper les ménages par nombre d'enfants
## aggregators ## persons aggregators
Group people by nationality: Grouper les personnes par nationalités Group people by nationality: Grouper les personnes par nationalités
Group by level: Grouper par niveau Group by level: Grouper par niveau
Group by continents: Grouper par continent Group by continents: Grouper par continent