Merge branch '111_exports_suite' into 641_issues_with_children

This commit is contained in:
2022-10-17 18:16:30 +02:00
99 changed files with 3043 additions and 512 deletions

View File

@@ -13,12 +13,21 @@ namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\PersonBundle\Export\Declarations;
use DateTimeImmutable;
use Doctrine\ORM\QueryBuilder;
use LogicException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
final class DurationAggregator implements AggregatorInterface
{
private const CHOICES = [
'month',
'week',
'day',
];
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
@@ -33,19 +42,31 @@ final class DurationAggregator implements AggregatorInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->addSelect(
'
(acp.closingDate - acp.openingDate +15) *12/365
AS duration_aggregator'
);
switch ($data['precision']) {
case 'day':
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) 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)
break;
$qb->addGroupBy('duration_aggregator');
$qb->addOrderBy('duration_aggregator');
case 'week':
$qb->addSelect('(COALESCE(acp.closingDate, :now) - acp.openingDate) / 7 AS duration_aggregator');
break;
case 'month':
$qb->addSelect('(EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate)) * 12 +
EXTRACT (MONTH FROM AGE(COALESCE(acp.closingDate, :now), acp.openingDate))) AS duration_aggregator');
break;
default:
throw new LogicException('precision not supported: ' . $data['precision']);
}
$qb
->setParameter('now', new DateTimeImmutable('now'))
->addGroupBy('duration_aggregator')
->addOrderBy('duration_aggregator');
}
public function applyOn(): string
@@ -55,25 +76,27 @@ final class DurationAggregator implements AggregatorInterface
public function buildForm(FormBuilderInterface $builder)
{
// no form
$builder->add('precision', ChoiceType::class, [
'choices' => array_combine(self::CHOICES, self::CHOICES),
'label' => 'export.aggregator.course.duration.Precision',
'choice_label' => static fn (string $c) => 'export.aggregator.course.duration.' . $c,
'multiple' => false,
'expanded' => true,
]);
}
public function getLabels($key, array $values, $data)
{
return function ($value): ?string {
return static function ($value) use ($data) {
if ('_header' === $value) {
return 'Rounded month duration';
return 'export.aggregator.course.duration.' . $data['precision'];
}
if (null === $value) {
return $this->translator->trans('current duration'); // when closingDate is null
return 0;
}
if (0 === $value) {
return $this->translator->trans('duration 0 month');
}
return $value . $this->translator->trans(' months');
return $value;
};
}

View File

@@ -12,15 +12,20 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\PersonBundle\Export\Declarations;
use DateTimeImmutable;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use function in_array;
final class ReferrerAggregator implements AggregatorInterface
{
private const A = 'acp_ref_agg_uhistory';
private const P = 'acp_ref_agg_date';
private UserRender $userRender;
private UserRepository $userRepository;
@@ -40,12 +45,23 @@ final class ReferrerAggregator implements AggregatorInterface
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('acpuser', $qb->getAllAliases(), true)) {
$qb->leftJoin('acp.user', 'acpuser');
}
$qb->addSelect('acpuser.id AS referrer_aggregator');
$qb->addGroupBy('referrer_aggregator');
$qb
->addSelect('IDENTITY(' . self::A . '.user) AS referrer_aggregator')
->addGroupBy('referrer_aggregator')
->leftJoin('acp.userHistories', self::A)
->andWhere(
$qb->expr()->orX(
$qb->expr()->isNull(self::A),
$qb->expr()->andX(
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.endDate'),
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
)
)
)
)
->setParameter(self::P, $data['date_calc']);
}
public function applyOn(): string
@@ -55,7 +71,13 @@ final class ReferrerAggregator implements AggregatorInterface
public function buildForm(FormBuilderInterface $builder)
{
// no form
$builder
->add('date_calc', ChillDateType::class, [
'input' => 'datetime_immutable',
'data' => new DateTimeImmutable('now'),
'label' => 'export.aggregator.course.by_referrer.Computation date for referrer',
'required' => true,
]);
}
public function getLabels($key, array $values, $data)

View File

@@ -12,20 +12,21 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
//use Chill\MainBundle\Export\FilterInterface;
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;
use LogicException;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use function in_array;
final class StepAggregator implements AggregatorInterface //, FilterInterface
final class StepAggregator implements AggregatorInterface
{
private const A = 'acpstephistories';
private const P = 'acp_step_agg_date';
private TranslatorInterface $translator;
public function __construct(
@@ -41,30 +42,26 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$qb->addSelect('acp.step AS step_aggregator');
$qb->addGroupBy('step_aggregator');
/*
// add date in where clause
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->andX(
$qb->expr()->lte('acp.openingDate', ':ondate'),
$qb->expr()->orX(
$qb->expr()->gt('acp.closingDate', ':ondate'),
$qb->expr()->isNull('acp.closingDate')
)
);
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
if (!in_array(self::A, $qb->getAllAliases(), true)) {
$qb->leftJoin('acp.stepHistories', self::A);
}
$qb->add('where', $where);
$qb->setParameter('ondate', $data['on_date'], Types::DATE_MUTABLE);
*/
$qb
->addSelect(self::A . '.step AS step_aggregator')
->andWhere(
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.step'),
$qb->expr()->andX(
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.endDate'),
$qb->expr()->lt(self::A . '.endDate', ':' . self::P)
)
)
)
)
->setParameter(self::P, $data['on_date'])
->addGroupBy('step_aggregator');
}
public function applyOn(): string
@@ -95,8 +92,11 @@ final class StepAggregator implements AggregatorInterface //, FilterInterface
case '_header':
return 'Step';
case null:
return '';
default:
throw new LogicException(sprintf('The value %s is not valid', $value));
return $value;
}
};
}

View File

@@ -23,6 +23,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use function in_array;
final class CountryOfBirthAggregator implements AggregatorInterface, ExportElementValidatedInterface
{
@@ -83,7 +84,9 @@ final class CountryOfBirthAggregator implements AggregatorInterface, ExportEleme
. ' is not known.');
}
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
if (!in_array('countryOfBirth', $qb->getAllAliases(), true)) {
$qb->leftJoin('person.countryOfBirth', 'countryOfBirth');
}
// add group by
$qb->addGroupBy('country_of_birth_aggregator');

View File

@@ -99,6 +99,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
$qb = $this->repository->createQueryBuilder('acp');
$qb
->andWhere('acp.step != :count_acp_step')
->andWhere(
$qb->expr()->exists(
'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part
@@ -107,6 +108,7 @@ class CountAccompanyingCourse implements ExportInterface, GroupedExportInterface
'
)
)
->setParameter('count_acp_step', AccompanyingPeriod::STEP_DRAFT)
->setParameter('authorized_centers', $centers);
$qb->select('COUNT(DISTINCT acp.id) AS export_result');

View File

@@ -50,9 +50,6 @@ class AdministrativeLocationFilter implements FilterInterface
{
$builder->add('accepted_locations', PickUserLocationType::class, [
'label' => 'Accepted locations',
'label_attr' => [
//'class' => 'd-none'
],
'multiple' => true,
]);
}

View File

@@ -1,90 +0,0 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
class CurrentUserJobFilter implements FilterInterface
{
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acp.job', ':userjob');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('userjob', $this->getUserJob());
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
}
public function describeAction($data, $format = 'string')
{
return [
'Filtered by user job: only %job%', [
'%job%' => $this->translatableStringHelper->localize(
$this->getUserJob()->getLabel()
),
],
];
}
public function getTitle()
{
return 'Filter by user job';
}
private function getUserJob(): UserJob
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getUserJob();
}
}

View File

@@ -1,95 +0,0 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
use function in_array;
class CurrentUserScopeFilter implements FilterInterface
{
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
TranslatableStringHelper $translatableStringHelper,
Security $security
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->security = $security;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
if (!in_array('acpscope', $qb->getAllAliases(), true)) {
$qb->join('acp.scopes', 'acpscope');
}
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acpscope.id', ':userscope');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('userscope', $this->getUserMainScope());
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
}
public function describeAction($data, $format = 'string')
{
return [
'Filtered by user main scope: only %scope%', [
'%scope%' => $this->translatableStringHelper->localize(
$this->getUserMainScope()->getName()
),
],
];
}
public function getTitle()
{
return 'Filter by user scope';
}
private function getUserMainScope(): Scope
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getMainScope();
}
}

View File

@@ -15,7 +15,7 @@ use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepositoryInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -23,11 +23,15 @@ use function in_array;
class EvaluationFilter implements FilterInterface
{
private EvaluationRepositoryInterface $evaluationRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
EvaluationRepositoryInterface $evaluationRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->evaluationRepository = $evaluationRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
@@ -50,16 +54,8 @@ class EvaluationFilter implements FilterInterface
$qb->join('workeval.evaluation', 'eval');
}
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('eval.id', ':evaluations');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->andWhere($clause);
$qb->setParameter('evaluations', $data['accepted_evaluations']);
}
@@ -72,11 +68,13 @@ class EvaluationFilter implements FilterInterface
{
$builder->add('accepted_evaluations', EntityType::class, [
'class' => Evaluation::class,
'choices' => $this->evaluationRepository->findAllActive(),
'choice_label' => function (Evaluation $ev) {
return $this->translatableStringHelper->localize($ev->getTitle());
},
'multiple' => true,
'expanded' => true,
'expanded' => false,
'attr' => ['class' => 'select2'],
]);
}

View File

@@ -11,17 +11,23 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use DateTimeImmutable;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class ReferrerFilter implements FilterInterface
{
private const A = 'acp_referrer_filter_uhistory';
private const P = 'acp_referrer_filter_date';
private const PU = 'acp_referrer_filter_users';
private UserRender $userRender;
public function __construct(UserRender $userRender)
@@ -36,17 +42,22 @@ class ReferrerFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->in('acp.user', ':referrers');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('referrers', $data['accepted_referrers']);
$qb
->join('acp.userHistories', self::A)
->andWhere(
$qb->expr()->andX(
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.endDate'),
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
)
)
)
->andWhere(
$qb->expr()->in(self::A . '.user', ':' . self::PU)
)
->setParameter(self::PU, $data['accepted_referrers'])
->setParameter(self::P, $data['date_calc']);
}
public function applyOn(): string
@@ -56,14 +67,16 @@ class ReferrerFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('accepted_referrers', EntityType::class, [
'class' => User::class,
'choice_label' => function (User $u) {
return $this->userRender->renderString($u, []);
},
'multiple' => true,
'expanded' => true,
]);
$builder
->add('accepted_referrers', PickUserDynamicType::class, [
'multiple' => true,
])
->add('date_calc', ChillDateType::class, [
'input' => 'datetime_immutable',
'data' => new DateTimeImmutable('now'),
'label' => 'export.filter.course.by_referrer.Computation date for referrer',
'required' => true,
]);
}
public function describeAction($data, $format = 'string'): array

View File

@@ -0,0 +1,130 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use DateTimeImmutable;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
class UserJobFilter implements FilterInterface
{
private const A = 'acp_ujob_filter_uhistory';
private const AU = 'acp_ujob_filter_uhistory_user';
private const P = 'acp_ujob_filter_date';
private const PJ = 'acp_ujob_filter_job';
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
private UserJobRepositoryInterface $userJobRepository;
public function __construct(
Security $security,
TranslatableStringHelper $translatableStringHelper,
UserJobRepositoryInterface $userJobRepository
) {
$this->security = $security;
$this->translatableStringHelper = $translatableStringHelper;
$this->userJobRepository = $userJobRepository;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->join('acp.userHistories', self::A)
->andWhere(
$qb->expr()->andX(
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.endDate'),
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
)
)
)
->setParameter(self::P, $data['date_calc'])
->join(self::A . '.user', self::AU)
->andWhere(
$qb->expr()->in(self::AU . '.userJob', ':' . self::PJ)
)
->setParameter(self::PJ, $data['jobs']);
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('jobs', EntityType::class, [
'class' => UserJob::class,
'choices' => $this->userJobRepository->findAllActive(),
'multiple' => true,
'expanded' => true,
'choice_label' => fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
'label' => 'Job',
])
->add('date_calc', ChillDateType::class, [
'input' => 'datetime_immutable',
'data' => new DateTimeImmutable('now'),
'label' => 'export.filter.course.by_user_scope.Computation date for referrer',
'required' => true,
]);
}
public function describeAction($data, $format = 'string')
{
return [
'Filtered by user job: only %job%', [
'%job%' => implode(
', ',
array_map(
fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),
$data['jobs']->toArray()
)
),
],
];
}
public function getTitle()
{
return 'Filter by user job';
}
private function getUserJob(): UserJob
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getUserJob();
}
}

View File

@@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
/*
* 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.
*/
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use DateTimeImmutable;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security;
class UserScopeFilter implements FilterInterface
{
private const A = 'acp_uscope_filter_uhistory';
private const AU = 'acp_uscope_filter_uhistory_user';
private const P = 'acp_uscope_filter_date';
private const PS = 'acp_uscope_filter_scopes';
private ScopeRepositoryInterface $scopeRepository;
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(
ScopeRepositoryInterface $scopeRepository,
Security $security,
TranslatableStringHelper $translatableStringHelper
) {
$this->scopeRepository = $scopeRepository;
$this->security = $security;
$this->translatableStringHelper = $translatableStringHelper;
}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$qb
->join('acp.userHistories', self::A)
->andWhere(
$qb->expr()->andX(
$qb->expr()->lte(self::A . '.startDate', ':' . self::P),
$qb->expr()->orX(
$qb->expr()->isNull(self::A . '.endDate'),
$qb->expr()->gt(self::A . '.endDate', ':' . self::P)
)
)
)
->setParameter(self::P, $data['date_calc'])
->join(self::A . '.user', self::AU)
->andWhere(
$qb->expr()->in(self::AU . '.mainScope', ':' . self::PS)
)
->setParameter(self::PS, $data['scopes']);
}
public function applyOn()
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('scopes', EntityType::class, [
'class' => Scope::class,
'choices' => $this->scopeRepository->findAllActive(),
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
'multiple' => true,
'expanded' => true,
])
->add('date_calc', ChillDateType::class, [
'input' => 'datetime_immutable',
'data' => new DateTimeImmutable('now'),
'label' => 'export.filter.course.by_user_scope.Computation date for referrer',
'required' => true,
]);
}
public function describeAction($data, $format = 'string')
{
return [
'Filtered by user main scope: only %scope%', [
'%scope%' => implode(
', ',
array_map(
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
$data['scopes']->toArray()
)
),
],
];
}
public function getTitle()
{
return 'Filter by user scope';
}
private function getUserMainScope(): Scope
{
/** @var User $user */
$user = $this->security->getUser();
return $user->getMainScope();
}
}

View File

@@ -35,7 +35,7 @@ class AgeFilter implements ExportElementValidatedInterface, FilterInterface
$where = $qb->getDQLPart('where');
$min = null !== $data['min_age'] ? $data['min_age'] : 0;
$max = null !== $data['max_age'] ? $data['max_age'] : 3000;
$max = null !== $data['max_age'] ? $data['max_age'] : 150;
$calc = $data['date_calc'];
$minDate = $calc->sub(new DateInterval('P' . $max . 'Y'));

View File

@@ -12,12 +12,9 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\MaritalStatus;
use Chill\PersonBundle\Export\Declarations;
use DateTime;
use Doctrine\ORM\Query\Expr\Andx;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class MaritalStatusFilter implements FilterInterface
@@ -37,25 +34,10 @@ class MaritalStatusFilter implements FilterInterface
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->andX(
$qb->expr()->in('person.maritalStatus', ':maritalStatus'),
$qb->expr()->orX(
$qb->expr()->eq('person.maritalStatusDate', ':calc_date'),
$qb->expr()->isNull('person.maritalStatusDate')
)
$qb->andWhere(
$qb->expr()->in('person.maritalStatus', ':maritalStatus')
);
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('maritalStatus', $data['maritalStatus']);
$qb->setParameter('calc_date', $data['calc_date']);
}
public function applyOn()
@@ -75,11 +57,6 @@ class MaritalStatusFilter implements FilterInterface
'multiple' => true,
'expanded' => true,
]);
$builder->add('calc_date', ChillDateType::class, [
'label' => 'Marital status at this time',
'data' => new DateTime(),
]);
}
public function describeAction($data, $format = 'string')