mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-08 00:39:50 +00:00
Fix: last fixes for accompanying period work filters
- avoid errors when the user inverse date from and date to (we correct them) - allow the user to filter by multiple users - do not show filter by types if only one action type - more type-hinting in the $filter argument for AccompanyingPeriodWorkRepository::findByAccompanyingPeriodOpenFirst
This commit is contained in:
parent
f2673d6c83
commit
a21cefab31
@ -14,21 +14,13 @@ namespace Chill\MainBundle\Templating\Listing;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
|
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
use Symfony\Component\PropertyAccess\PropertyAccessor;
|
|
||||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
|
||||||
use Symfony\Component\PropertyAccess\PropertyPath;
|
|
||||||
use Symfony\Component\PropertyAccess\PropertyPathInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
use function array_merge;
|
use function array_merge;
|
||||||
use function count;
|
|
||||||
|
|
||||||
class FilterOrderHelper
|
final class FilterOrderHelper
|
||||||
{
|
{
|
||||||
private array $checkboxes = [];
|
private array $checkboxes = [];
|
||||||
|
|
||||||
|
@ -26,13 +26,14 @@ use Psr\Log\LoggerInterface;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\Form;
|
use Symfony\Component\Form\Form;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class AccompanyingCourseWorkController extends AbstractController
|
final class AccompanyingCourseWorkController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly TranslatorInterface $trans,
|
private readonly TranslatorInterface $trans,
|
||||||
@ -158,7 +159,7 @@ class AccompanyingCourseWorkController extends AbstractController
|
|||||||
$filter = $this->buildFilterOrder($period);
|
$filter = $this->buildFilterOrder($period);
|
||||||
|
|
||||||
$filterData = [
|
$filterData = [
|
||||||
'types' => $filter->getEntityChoiceData('typesFilter'),
|
'types' => $filter->hasEntityChoice('typesFilter') ? $filter->getEntityChoiceData('typesFilter') : [],
|
||||||
'before' => $filter->getDateRangeData('dateFilter')['to'],
|
'before' => $filter->getDateRangeData('dateFilter')['to'],
|
||||||
'after' => $filter->getDateRangeData('dateFilter')['from'],
|
'after' => $filter->getDateRangeData('dateFilter')['from'],
|
||||||
'user' => $filter->getUserPickerData('userFilter')
|
'user' => $filter->getUserPickerData('userFilter')
|
||||||
@ -203,7 +204,7 @@ class AccompanyingCourseWorkController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createDeleteForm(int $id): Form
|
private function createDeleteForm(int $id): FormInterface
|
||||||
{
|
{
|
||||||
$params = [];
|
$params = [];
|
||||||
$params['id'] = $id;
|
$params['id'] = $id;
|
||||||
@ -217,16 +218,21 @@ class AccompanyingCourseWorkController extends AbstractController
|
|||||||
|
|
||||||
private function buildFilterOrder($associatedPeriod): FilterOrderHelper
|
private function buildFilterOrder($associatedPeriod): FilterOrderHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
$filterBuilder = $this->filterOrderHelperFactory->create(self::class);
|
$filterBuilder = $this->filterOrderHelperFactory->create(self::class);
|
||||||
$types = $this->workRepository->findActionTypeByPeriod($associatedPeriod);
|
$types = $this->workRepository->findActionTypeByPeriod($associatedPeriod);
|
||||||
|
|
||||||
$filterBuilder
|
$filterBuilder
|
||||||
->addDateRange('dateFilter', 'accompanying_course_work.date_filter')
|
->addDateRange('dateFilter', 'accompanying_course_work.date_filter');
|
||||||
|
|
||||||
|
if (1 < count($types)) {
|
||||||
|
$filterBuilder
|
||||||
->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialWork\SocialAction::class, $types, [
|
->addEntityChoice('typesFilter', 'accompanying_course_work.types_filter', \Chill\PersonBundle\Entity\SocialWork\SocialAction::class, $types, [
|
||||||
'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle())
|
'choice_label' => fn (SocialAction $sa) => $this->translatableStringHelper->localize($sa->getTitle())
|
||||||
])
|
]);
|
||||||
->addUserPicker('userFilter', 'accompanying_course_work.user_filter', ['required' => false, 'multiple' => false])
|
}
|
||||||
|
|
||||||
|
$filterBuilder
|
||||||
|
->addUserPicker('userFilter', 'accompanying_course_work.user_filter', ['required' => false])
|
||||||
;
|
;
|
||||||
|
|
||||||
return $filterBuilder->build();
|
return $filterBuilder->build();
|
||||||
|
@ -95,9 +95,9 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|||||||
* * then, closed works
|
* * then, closed works
|
||||||
*
|
*
|
||||||
* @return AccompanyingPeriodWork[]
|
* @return AccompanyingPeriodWork[]
|
||||||
* @param mixed $filters
|
* @param array{types?: list<SocialAction>, user?: list<User>, after?: null|\DateTimeImmutable, before?: null|\DateTimeImmutable} $filters
|
||||||
*/
|
*/
|
||||||
public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, $filters, int $limit = 10, int $offset = 0): array
|
public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, array $filters, int $limit = 10, int $offset = 0): array
|
||||||
{
|
{
|
||||||
$rsm = new ResultSetMappingBuilder($this->em);
|
$rsm = new ResultSetMappingBuilder($this->em);
|
||||||
$rsm->addRootEntityFromClassMetadata(AccompanyingPeriodWork::class, 'w');
|
$rsm->addRootEntityFromClassMetadata(AccompanyingPeriodWork::class, 'w');
|
||||||
@ -113,13 +113,27 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ([] !== ($filters['user'] ?? [])) {
|
if ([] !== ($filters['user'] ?? [])) {
|
||||||
$sql .= " AND rw.user_id = :user";
|
$sql .= " AND rw.user_id IN ("
|
||||||
|
. implode(
|
||||||
|
', ',
|
||||||
|
// we add a user_xx for each key of the 'user' list
|
||||||
|
array_map(fn (User $u, int $idx) => ':user_' . $idx, $filters['user'], array_keys($filters['user']))
|
||||||
|
)
|
||||||
|
. ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql .= " AND daterange(:after::date, :before::date) && daterange(w.startDate, w.endDate)";
|
$sql .= " AND daterange(:after::date, :before::date) && daterange(w.startDate, w.endDate)";
|
||||||
|
|
||||||
// set limit and offset
|
// if the start and end date were inversed, we inverse the order to avoid an error
|
||||||
|
if (null !== ($filters['after'] ?? null) && null !== ($filters['before']) && $filters['after'] > $filters['before']) {
|
||||||
|
$before = $filters['after'];
|
||||||
|
$after = $filters['before'];
|
||||||
|
} else {
|
||||||
|
$before = $filters['before'];
|
||||||
|
$after = $filters['after'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// set limit and offset
|
||||||
$sql .= " ORDER BY
|
$sql .= " ORDER BY
|
||||||
CASE WHEN enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC,
|
CASE WHEN enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC,
|
||||||
startdate DESC,
|
startdate DESC,
|
||||||
@ -136,12 +150,15 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|||||||
$nq = $this->em->createNativeQuery($sql, $rsm)
|
$nq = $this->em->createNativeQuery($sql, $rsm)
|
||||||
->setParameter('periodId', $period->getId(), Types::INTEGER)
|
->setParameter('periodId', $period->getId(), Types::INTEGER)
|
||||||
->setParameter('types', $typeIds)
|
->setParameter('types', $typeIds)
|
||||||
->setParameter('user', null !== $filters['user'] ? $filters['user']->getId() : null)
|
->setParameter('after', $after)
|
||||||
->setParameter('after', ($filters['after'] ?? null))
|
->setParameter('before', $before)
|
||||||
->setParameter('before', ($filters['before'] ?? null))
|
|
||||||
->setParameter('limit', $limit, Types::INTEGER)
|
->setParameter('limit', $limit, Types::INTEGER)
|
||||||
->setParameter('offset', $offset, Types::INTEGER);
|
->setParameter('offset', $offset, Types::INTEGER);
|
||||||
|
|
||||||
|
foreach ($filters['user'] as $key => $user) {
|
||||||
|
$nq->setParameter('user_' . $key, $user);
|
||||||
|
}
|
||||||
|
|
||||||
return $nq->getResult();
|
return $nq->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user