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;
|
||||
}
|
||||
|
||||
public function getLayerName(): ?string
|
||||
{
|
||||
return $this->layerName;
|
||||
}
|
||||
|
||||
public function getUnitName(): ?string
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\GeographicalUnit;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
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 DateTime;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
@ -24,17 +30,27 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* e) par zone géographique.
|
||||
*
|
||||
* 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.
|
||||
* Filter accompanying period by geographical zone
|
||||
*/
|
||||
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
|
||||
{
|
||||
return null;
|
||||
@ -42,33 +58,32 @@ class GeographicalUnitStatFilter implements FilterInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('location', $qb->getAllAliases(), true)) {
|
||||
$qb->join('acp.administrativeLocation', 'location');
|
||||
}
|
||||
$subQueryDql =
|
||||
'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->join('location.address', 'address');
|
||||
}
|
||||
|
||||
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']);
|
||||
$qb
|
||||
->andWhere($qb->expr()->exists($subQueryDql))
|
||||
->setParameter('acp_geog_filter_date', $data['date_calc'])
|
||||
->setParameter('acp_geog_filter_units', $data['units'])
|
||||
;
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
@ -79,23 +94,40 @@ class GeographicalUnitStatFilter implements FilterInterface
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('date', ChillDateType::class, [
|
||||
'data' => new DateTime(),
|
||||
->add('date_calc', ChillDateType::class, [
|
||||
'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,
|
||||
'choice_label' => static function (GeographicalUnit $u) {
|
||||
return $u->getUnitName();
|
||||
'choices' => $this->geographicalUnitRepository->findAll(),
|
||||
'choice_label' => function(GeographicalUnit $item) {
|
||||
return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName();
|
||||
},
|
||||
'attr' => [
|
||||
'class' => 'select2',
|
||||
],
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
return ['Filtered by geographic unit: only %date%', [
|
||||
'%date%' => $data['date']->format('d-m-Y'),
|
||||
return ['Filtered by geographic unit: computed at %date%, only in %units%', [
|
||||
'%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