mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
[export][person] Feature: allow to filter accompanying period by
geographical unit
This commit is contained in:
parent
52435f5331
commit
fc567868c1
@ -53,20 +53,36 @@ class GeographicalUnit
|
|||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLayerName(): ?string
|
|
||||||
{
|
|
||||||
return $this->layerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUnitName(): ?string
|
public function getUnitName(): ?string
|
||||||
{
|
{
|
||||||
return $this->unitName;
|
return $this->unitName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLayerName(?string $layerName): self
|
/**
|
||||||
|
* @return GeographicalUnitLayer|null
|
||||||
|
*/
|
||||||
|
public function getLayer(): ?GeographicalUnitLayer
|
||||||
{
|
{
|
||||||
$this->layerName = $layerName;
|
return $this->layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $unitRefId
|
||||||
|
* @return GeographicalUnit
|
||||||
|
*/
|
||||||
|
public function setUnitRefId(string $unitRefId): GeographicalUnit
|
||||||
|
{
|
||||||
|
$this->unitRefId = $unitRefId;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param GeographicalUnitLayer|null $layer
|
||||||
|
* @return GeographicalUnit
|
||||||
|
*/
|
||||||
|
public function setLayer(?GeographicalUnitLayer $layer): GeographicalUnit
|
||||||
|
{
|
||||||
|
$this->layer = $layer;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\GeographicalUnit;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
|
||||||
|
class GeographicalUnitRepository implements GeographicalUnitRepositoryInterface
|
||||||
|
{
|
||||||
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em)
|
||||||
|
{
|
||||||
|
$this->repository = $em->getRepository($this->getClassName());
|
||||||
|
$this->em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function find($id): ?GeographicalUnit
|
||||||
|
{
|
||||||
|
return $this->repository->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return only partial object, where the @link{GeographicalUnit::geom} property is not loaded
|
||||||
|
*
|
||||||
|
* @return array|GeographicalUnit[]
|
||||||
|
*/
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
return $this->repository
|
||||||
|
->createQueryBuilder('gu')
|
||||||
|
->addSelect('PARTIAL gu.{id,unitName,unitRefId,layer}')
|
||||||
|
->addOrderBy('IDENTITY(gu.layer)')
|
||||||
|
->addOrderBy(('gu.unitName'))
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): ?GeographicalUnit
|
||||||
|
{
|
||||||
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?GeographicalUnit
|
||||||
|
{
|
||||||
|
return $this->repository->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassName(): string
|
||||||
|
{
|
||||||
|
return GeographicalUnit::class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface GeographicalUnitRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -11,12 +11,18 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\GeographicalUnit;
|
use Chill\MainBundle\Entity\GeographicalUnit;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
|
use Chill\MainBundle\Repository\GeographicalUnitRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Query\Expr;
|
use Doctrine\ORM\Query\Expr;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
use Doctrine\ORM\Query\Expr\Andx;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
@ -24,17 +30,27 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* e) par zone géographique.
|
* Filter accompanying period by geographical zone
|
||||||
*
|
|
||||||
* Paramètre:
|
|
||||||
* * Date
|
|
||||||
* * Choix unique entre: territoire, epci, canton, commune, secteur d'intervention
|
|
||||||
* * une fois le premier choix effectué, l'utilisateur choisi parmi les zones (choix multiple)
|
|
||||||
*
|
|
||||||
* Le filtre retiendra les parcours localisé dans un des territoires cochés, à la date indiquée en paramètre.
|
|
||||||
*/
|
*/
|
||||||
class GeographicalUnitStatFilter implements FilterInterface
|
class GeographicalUnitStatFilter implements FilterInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private GeographicalUnitRepositoryInterface $geographicalUnitRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
EntityManagerInterface $em,
|
||||||
|
GeographicalUnitRepositoryInterface $geographicalUnitRepository,
|
||||||
|
TranslatableStringHelperInterface $translatableStringHelper
|
||||||
|
) {
|
||||||
|
$this->em = $em;
|
||||||
|
$this->geographicalUnitRepository = $geographicalUnitRepository;
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
public function addRole(): ?string
|
public function addRole(): ?string
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -42,33 +58,32 @@ class GeographicalUnitStatFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
if (!in_array('location', $qb->getAllAliases(), true)) {
|
$subQueryDql =
|
||||||
$qb->join('acp.administrativeLocation', 'location');
|
'SELECT
|
||||||
}
|
1
|
||||||
|
FROM '.AccompanyingPeriod\AccompanyingPeriodLocationHistory::class.' acp_geog_filter_location_history
|
||||||
|
LEFT JOIN '.PersonHouseholdAddress::class.' acp_geog_filter_address_person_location
|
||||||
|
WITH IDENTITY(acp_geog_filter_location_history.personLocation) = IDENTITY(acp_geog_filter_address_person_location.person)
|
||||||
|
LEFT JOIN '.Address::class.' acp_geog_filter_address
|
||||||
|
WITH COALESCE(IDENTITY(acp_geog_filter_address_person_location.address), IDENTITY(acp_geog_filter_location_history.addressLocation)) = acp_geog_filter_address.id
|
||||||
|
LEFT JOIN '.GeographicalUnit::class.' acp_geog_filter_units WITH ST_CONTAINS(acp_geog_units.geom, acp_geog_filter_address.point) = TRUE
|
||||||
|
WHERE
|
||||||
|
(acp_geog_filter_location_history.startDate <= :acp_geog_filter_date AND (
|
||||||
|
acp_geog_filter_location_history.endDate IS NULL OR acp_geog_filter_location_history.endDate < :acp_geog_filter_date
|
||||||
|
))
|
||||||
|
AND
|
||||||
|
(acp_geog_filter_address_person_location.validFrom < :acp_geog_filter_date AND (
|
||||||
|
acp_geog_filter_address_person_location.validTo IS NULL OR acp_geog_filter_address_person_location.validTo < :acp_geog_filter_date
|
||||||
|
))
|
||||||
|
AND acp_geog_filter_units IN (:acp_geog_filter_units)
|
||||||
|
AND acp_geog_filter_location_history.period = acp.id
|
||||||
|
';
|
||||||
|
|
||||||
if (!in_array('address', $qb->getAllAliases(), true)) {
|
$qb
|
||||||
$qb->join('location.address', 'address');
|
->andWhere($qb->expr()->exists($subQueryDql))
|
||||||
}
|
->setParameter('acp_geog_filter_date', $data['date_calc'])
|
||||||
|
->setParameter('acp_geog_filter_units', $data['units'])
|
||||||
if (!in_array('geounit', $qb->getAllAliases(), true)) {
|
;
|
||||||
$qb->join(GeographicalUnit::class, 'geounit', Expr\Join::WITH, 'ST_CONTAINS(address.point, geounit.geom) = TRUE');
|
|
||||||
}
|
|
||||||
|
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
$clause = $qb->expr()->andX(
|
|
||||||
$qb->expr()->eq($x, ':date'),
|
|
||||||
$qb->expr()->in($x, ':loctype')
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($where instanceof Andx) {
|
|
||||||
$where->add($clause);
|
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
|
||||||
}
|
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('date', $data['date'], Types::DATE_MUTABLE);
|
|
||||||
$qb->setParameter('loctype', $data['accepted_loctype']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
@ -79,23 +94,40 @@ class GeographicalUnitStatFilter implements FilterInterface
|
|||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
->add('date', ChillDateType::class, [
|
->add('date_calc', ChillDateType::class, [
|
||||||
'data' => new DateTime(),
|
'label' => 'Compute geographical location at date',
|
||||||
|
'required' => true,
|
||||||
|
'data' => new \DateTimeImmutable('today'),
|
||||||
|
'input' => 'datetime_immutable',
|
||||||
])
|
])
|
||||||
->add('accepted_loctype', EntityType::class, [
|
->add('units', EntityType::class, [
|
||||||
|
'label' => 'Geographical unit',
|
||||||
|
'placeholder' => 'Select a geographical unit',
|
||||||
'class' => GeographicalUnit::class,
|
'class' => GeographicalUnit::class,
|
||||||
'choice_label' => static function (GeographicalUnit $u) {
|
'choices' => $this->geographicalUnitRepository->findAll(),
|
||||||
return $u->getUnitName();
|
'choice_label' => function(GeographicalUnit $item) {
|
||||||
|
return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName();
|
||||||
},
|
},
|
||||||
|
'attr' => [
|
||||||
|
'class' => 'select2',
|
||||||
|
],
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAction($data, $format = 'string'): array
|
public function describeAction($data, $format = 'string'): array
|
||||||
{
|
{
|
||||||
return ['Filtered by geographic unit: only %date%', [
|
return ['Filtered by geographic unit: computed at %date%, only in %units%', [
|
||||||
'%date%' => $data['date']->format('d-m-Y'),
|
'%date%' => $data['date_calc']->format('d-m-Y'),
|
||||||
|
'%units' => implode(
|
||||||
|
', ',
|
||||||
|
array_map(
|
||||||
|
function(GeographicalUnit $item) {
|
||||||
|
return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName();
|
||||||
|
},
|
||||||
|
$data['units']
|
||||||
|
)
|
||||||
|
)
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user