mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-05 22:35:01 +00:00
[export][person] Feature: add filter and aggregator by geographical unit on person
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\MainBundle\Entity\GeographicalUnit;
|
||||
use Chill\MainBundle\Entity\GeographicalUnitLayer;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Repository\GeographicalUnitLayerRepositoryInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
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 GeographicalUnitAggregator implements AggregatorInterface
|
||||
{
|
||||
private GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository,
|
||||
TranslatableStringHelperInterface $translatableStringHelper
|
||||
) {
|
||||
$this->geographicalUnitLayerRepository = $geographicalUnitLayerRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'geog_unit_name':
|
||||
return function ($value): string {
|
||||
if ('_header' === $value) {
|
||||
return 'acp_geog_agg_unitname';
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $value;
|
||||
};
|
||||
|
||||
case 'geog_unit_key':
|
||||
return function ($value): string {
|
||||
if ('_header' === $value) {
|
||||
return 'acp_geog_agg_unitrefid';
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $value;
|
||||
};
|
||||
|
||||
default:
|
||||
throw new \LogicException('key not supported');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getQueryKeys($data)
|
||||
{
|
||||
return ['geog_unit_name', 'geog_unit_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'label' => 'Address valid at this date',
|
||||
'required' => true,
|
||||
'data' => new \DateTimeImmutable('today'),
|
||||
'input' => 'datetime_immutable',
|
||||
])
|
||||
->add('level', EntityType::class, [
|
||||
'label' => 'Geographical layer',
|
||||
'placeholder' => 'Select a geographical layer',
|
||||
'class' => GeographicalUnitLayer::class,
|
||||
'choices' => $this->geographicalUnitLayerRepository->findAllHavingUnits(),
|
||||
'choice_label' => function(GeographicalUnitLayer $item) {
|
||||
return $this->translatableStringHelper->localize($item->getName());
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Group people by geographical unit based on his address';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addRole(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function alterQuery(QueryBuilder $qb, $data): void
|
||||
{
|
||||
$qb
|
||||
->leftJoin('person.householdAddresses', 'person_geog_agg_current_household_address')
|
||||
->leftJoin('person_geog_agg_current_household_address.address', 'person_geog_agg_address')
|
||||
->leftJoin(GeographicalUnit::class, 'person_geog_agg_geog_unit', Join::WITH, 'ST_CONTAINS(person_geog_agg_geog_unit.geom, person_geog_agg_address.point) = TRUE')
|
||||
->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('person_geog_agg_current_household_address'),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->lte('person_geog_agg_current_household_address.validFrom', ':person_geog_agg_date'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('person_geog_agg_current_household_address.validTo'),
|
||||
$qb->expr()->gt('person_geog_agg_current_household_address.validTo', ':person_geog_agg_date')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('person_geog_agg_geog_unit'),
|
||||
$qb->expr()->in('person_geog_agg_geog_unit.layer', ':person_geog_agg_layers')
|
||||
)
|
||||
)
|
||||
->setParameter('person_geog_agg_date', $data['date_calc'])
|
||||
->setParameter('person_geog_agg_layers', $data['level'])
|
||||
->addSelect('person_geog_agg_geog_unit.unitName AS geog_unit_name')
|
||||
->addSelect('person_geog_agg_geog_unit.unitRefId AS geog_unit_key')
|
||||
->addGroupBy('geog_unit_name')
|
||||
->addGroupBy('geog_unit_key')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::PERSON_TYPE;
|
||||
}
|
||||
|
||||
public static function getDefaultAlias(): string
|
||||
{
|
||||
return 'person_geog_agg';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user