[Export] Feature: create a aggregator for referrer's main scope on

aggregator
This commit is contained in:
Julien Fastré 2022-10-05 14:57:15 +02:00
parent 491570a21c
commit 8a740a25da
4 changed files with 212 additions and 1 deletions

View File

@ -0,0 +1,133 @@
<?php
namespace Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ReferrerScopeAggregator implements AggregatorInterface
{
private const SCOPE_KEY = 'acp_agg_refscope_user_history_ref_scope_name';
private TranslatableStringHelperInterface $translatableStringHelper;
private ScopeRepositoryInterface $scopeRepository;
public function __construct(
ScopeRepositoryInterface $scopeRepository,
TranslatableStringHelperInterface $translatableStringHelper
) {
$this->scopeRepository = $scopeRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
* @inheritDoc
*/
public function getLabels($key, array $values, $data)
{
return function ($value) {
if ('_header' === $value) {
return 'export.aggregator.course.by_user_scope.Referrer\'s scope';
}
if (null === $value) {
return '';
}
$scope = $this->scopeRepository->find($value);
if (null === $scope) {
throw new \LogicException('no scope found with this id: ' . $value);
}
return $this->translatableStringHelper->localize($scope->getName());
};
}
/**
* @inheritDoc
*/
public function getQueryKeys($data)
{
return [self::SCOPE_KEY];
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add('date_calc', ChillDateType::class, [
'input' => 'datetime_immutable',
'data' => new \DateTimeImmutable('now'),
'label' => 'export.aggregator.course.by_user_scope.Computation date for referrer',
'required' => true,
]);
}
/**
* @inheritDoc
*/
public function getTitle()
{
return 'export.aggregator.course.by_user_scope.Group course by referrer\'s scope';
}
/**
* @inheritDoc
*/
public function addRole(): ?string
{
return null;
}
/**
* @inheritDoc
*/
public function alterQuery(QueryBuilder $qb, $data)
{
$userHistory = 'acp_agg_refscope_user_history';
$ref = 'acp_agg_refscope_user_history_ref';
$scopeName = self::SCOPE_KEY;
$dateCalc = 'acp_agg_refscope_user_history_date_calc';
$qb
->leftJoin('acp.userHistories', $userHistory)
->leftJoin($userHistory.'.user', $ref)
->andWhere(
$qb->expr()->orX(
$qb->expr()->isNull($userHistory),
$qb->expr()->andX(
$qb->expr()->lte($userHistory.'.startDate', ':'.$dateCalc),
$qb->expr()->orX(
$qb->expr()->isNull($userHistory.'.endDate'),
$qb->expr()->lt($userHistory.'.endDate', ':'.$dateCalc)
)
)
)
)
->setParameter($dateCalc, $data['date_calc']);
// add groups
$qb
->addSelect('IDENTITY('.$ref.'.mainScope) AS '.$scopeName)
->addGroupBy($scopeName)
;
}
/**
* @inheritDoc
*/
public function applyOn()
{
return Declarations::ACP_TYPE;
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace Export\Aggregator\AccompanyingCourseAggregators;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\ReferrerScopeAggregator;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
class ReferrerScopeAggregatorTest extends AbstractAggregatorTest
{
use ProphecyTrait;
public function getAggregator()
{
$translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
$translatableStringHelper->localize(Argument::type('array'))->willReturn('localized');
$scopeRepository = $this->prophesize(ScopeRepositoryInterface::class);
$scopeRepository->find(Argument::type('int'))->willReturn(
(new Scope())->setName(['fr' => 'scope'])
);
return new ReferrerScopeAggregator(
$scopeRepository->reveal(),
$translatableStringHelper->reveal()
);
}
public function getFormData()
{
return [
[
'date_calc' => new \DateTimeImmutable('now')
]
];
}
public function getQueryBuilders()
{
if (null === self::$kernel) {
self::bootKernel();
}
$em = self::$container->get(EntityManagerInterface::class);
return [
$em->createQueryBuilder()
->select('count(acp.id)')
->from(AccompanyingPeriod::class, 'acp')
->join('acp.scopes', 'acpscope')
,
];
}
}

View File

@ -148,7 +148,7 @@ services:
autowire: true
autoconfigure: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_referrer_scope_aggregator }
- { name: chill.export_aggregator, alias: accompanyingcourse_scope_aggregator }
chill.person.export.aggregator_referrer_job:
class: Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\JobAggregator
@ -255,3 +255,10 @@ services:
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_duration_aggregator }
Chill\PersonBundle\Export\Aggregator\AccompanyingCourseAggregators\REferrerScopeAggregator:
autoconfigure: true
autowire: true
tags:
- { name: chill.export_aggregator, alias: accompanyingcourse_ref_scope_aggregator }

View File

@ -941,3 +941,11 @@ reassign:
notification:
Notify referrer: Notifier le référent
Notify any: Notifier d'autres utilisateurs
export:
aggregator:
course:
by_user_scope:
Group course by referrer's scope: Grouper les parcours par service du référent
Computation date for referrer: Date à laquelle le référent était actif
Referrer's scope: Service du référent de parcours