Merge branch '204-export-action-creator' into 'master'

[export] add filters/aggregators for creator works action

Closes #204

See merge request Chill-Projet/chill-bundles!610
This commit is contained in:
2023-11-15 12:49:08 +00:00
16 changed files with 1014 additions and 3 deletions

View File

@@ -0,0 +1,82 @@
<?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\Aggregator\SocialWorkAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorAggregator implements AggregatorInterface
{
private const PREFIX = 'acpw_aggr_creator';
public function __construct(
private readonly UserRepository $userRepository,
private readonly UserRender $userRender
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->addSelect("IDENTITY(acpw.createdBy) AS {$p}_select")
->addGroupBy("{$p}_select");
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function buildForm(FormBuilderInterface $builder) {}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'export.aggregator.course_work.by_creator.Creator';
}
if (null === $value || '' === $value) {
return '';
}
$r = $this->userRepository->find($value);
return $this->userRender->renderString($r, ['absence' => false, 'user_job' => false, 'main_scope' => false]);
};
}
public function getQueryKeys($data): array
{
return [self::PREFIX.'_select'];
}
public function getTitle(): string
{
return 'export.aggregator.course_work.by_creator.title';
}
}

View File

@@ -0,0 +1,99 @@
<?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\Aggregator\SocialWorkAggregators;
use Chill\MainBundle\Entity\User\UserJobHistory;
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\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorJobAggregator implements AggregatorInterface
{
private const PREFIX = 'acpw_aggr_creator_job';
public function __construct(
private readonly UserJobRepository $jobRepository,
private readonly TranslatableStringHelper $translatableStringHelper
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->leftJoin(
UserJobHistory::class,
"{$p}_history",
Join::WITH,
$qb->expr()->andX(
$qb->expr()->eq("{$p}_history.user", 'acpw.createdBy'),
$qb->expr()->andX(
$qb->expr()->lte("{$p}_history.startDate", 'acpw.createdAt'),
$qb->expr()->orX(
$qb->expr()->isNull("{$p}_history.endDate"),
$qb->expr()->gt("{$p}_history.endDate", 'acpw.createdAt')
)
)
)
)
->addSelect("IDENTITY({$p}_history.job) AS {$p}_select")
->addGroupBy("{$p}_select");
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function buildForm(FormBuilderInterface $builder) {}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'export.aggregator.course_work.by_creator_job.Creator\'s job';
}
if (null === $value || '' === $value || null === $j = $this->jobRepository->find($value)) {
return '';
}
return $this->translatableStringHelper->localize(
$j->getLabel()
);
};
}
public function getQueryKeys($data): array
{
return [self::PREFIX.'_select'];
}
public function getTitle(): string
{
return 'export.aggregator.course_work.by_creator_job.title';
}
}

View File

@@ -0,0 +1,99 @@
<?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\Aggregator\SocialWorkAggregators;
use Chill\MainBundle\Entity\User\UserScopeHistory;
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\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorScopeAggregator implements AggregatorInterface
{
private const PREFIX = 'acpw_aggr_creator_scope';
public function __construct(
private readonly ScopeRepository $scopeRepository,
private readonly TranslatableStringHelper $translatableStringHelper
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->leftJoin(
UserScopeHistory::class,
"{$p}_history",
Join::WITH,
$qb->expr()->andX(
$qb->expr()->eq("{$p}_history.user", 'acpw.createdBy'),
$qb->expr()->andX(
$qb->expr()->lte("{$p}_history.startDate", 'acpw.createdAt'),
$qb->expr()->orX(
$qb->expr()->isNull("{$p}_history.endDate"),
$qb->expr()->gt("{$p}_history.endDate", 'acpw.createdAt')
)
)
)
)
->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select")
->addGroupBy("{$p}_select");
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function buildForm(FormBuilderInterface $builder) {}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
{
return function ($value): string {
if ('_header' === $value) {
return 'export.aggregator.course_work.by_creator_scope.Creator\'s scope';
}
if (null === $value || '' === $value || null === $s = $this->scopeRepository->find($value)) {
return '';
}
return $this->translatableStringHelper->localize(
$s->getName()
);
};
}
public function getQueryKeys($data): array
{
return [self::PREFIX.'_select'];
}
public function getTitle(): string
{
return 'export.aggregator.course_work.by_creator_scope.title';
}
}

View File

@@ -0,0 +1,74 @@
<?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\SocialWorkFilters;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorFilter implements FilterInterface
{
private const PREFIX = 'acpw_filter_creator';
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->leftJoin('acpw.createdBy', "{$p}_creator")
->andWhere($qb->expr()->in("{$p}_creator", ":{$p}_creators"))
->setParameter("{$p}_creators", $data['creators']);
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
{
$builder
->add('creators', PickUserDynamicType::class, [
'multiple' => true,
'label' => 'export.filter.work.by_creator.Creators',
]);
}
public function describeAction($data, $format = 'string'): array
{
return [
'export.filter.work.by_creator.Filtered by creator: only %creators%', [
'%creators%' => implode(', ', array_map(static fn (User $u) => $u->getLabel(), $data['creators'])),
],
];
}
public function getFormDefaultData(): array
{
return [
'creators' => [],
];
}
public function getTitle(): string
{
return 'export.filter.work.by_creator.title';
}
}

View File

@@ -0,0 +1,107 @@
<?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\SocialWorkFilters;
use Chill\MainBundle\Entity\User\UserJobHistory;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\UserJobRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorJobFilter implements FilterInterface
{
private const PREFIX = 'acpw_filter_creator_job';
public function __construct(
private readonly UserJobRepository $userJobRepository,
private readonly TranslatableStringHelper $translatableStringHelper
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->leftJoin(
UserJobHistory::class,
"{$p}_history",
Join::WITH,
$qb->expr()->andX(
$qb->expr()->eq("{$p}_history.user", 'acpw.createdBy'),
$qb->expr()->andX(
$qb->expr()->lte("{$p}_history.startDate", 'acpw.createdAt'),
$qb->expr()->orX(
$qb->expr()->isNull("{$p}_history.endDate"),
$qb->expr()->gt("{$p}_history.endDate", 'acpw.createdAt')
)
)
)
)
->andWhere($qb->expr()->in("{$p}_history.job", ":{$p}_jobs"))
->setParameter("{$p}_jobs", $data['jobs']);
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_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',
]);
}
public function describeAction($data, $format = 'string'): array
{
$creatorJobs = [];
foreach ($data['jobs'] as $j) {
$creatorJobs[] = $this->translatableStringHelper->localize(
$j->getLabel()
);
}
return ['export.filter.work.by_creator_job.Filtered by creator job: only %jobs%', [
'%jobs%' => implode(', ', $creatorJobs),
]];
}
public function getFormDefaultData(): array
{
return [
'jobs' => [],
];
}
public function getTitle(): string
{
return 'export.filter.work.by_creator_job.title';
}
}

View File

@@ -0,0 +1,107 @@
<?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\SocialWorkFilters;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
class CreatorScopeFilter implements FilterInterface
{
private const PREFIX = 'acpw_filter_creator_scope';
public function __construct(
private readonly ScopeRepository $scopeRepository,
private readonly TranslatableStringHelper $translatableStringHelper
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
{
$p = self::PREFIX;
$qb
->leftJoin(
UserScopeHistory::class,
"{$p}_history",
Join::WITH,
$qb->expr()->andX(
$qb->expr()->eq("{$p}_history.user", 'acpw.createdBy'),
$qb->expr()->andX(
$qb->expr()->lte("{$p}_history.startDate", 'acpw.createdAt'),
$qb->expr()->orX(
$qb->expr()->isNull("{$p}_history.endDate"),
$qb->expr()->gt("{$p}_history.endDate", 'acpw.createdAt')
)
)
)
)
->andWhere($qb->expr()->in("{$p}_history.scope", ":{$p}_scopes"))
->setParameter("{$p}_scopes", $data['scopes']);
}
public function applyOn(): string
{
return Declarations::SOCIAL_WORK_ACTION_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,
'label' => 'Scope',
]);
}
public function describeAction($data, $format = 'string'): array
{
$creatorScopes = [];
foreach ($data['scopes'] as $s) {
$creatorScopes[] = $this->translatableStringHelper->localize(
$s->getName()
);
}
return ['export.filter.work.by_creator_scope.Filtered by creator scope: only %scopes%', [
'%scopes%' => implode(', ', $creatorScopes),
]];
}
public function getFormDefaultData(): array
{
return [
'scopes' => [],
];
}
public function getTitle(): string
{
return 'export.filter.work.by_creator_scope.title';
}
}