mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
The AccompanyingPeriodWorkEvaluationStoredObjectVoter has been updated to use the AccompanyingPeriodWorkEvaluationDocument-related classes instead of the AccompanyingPeriodWork classes. Additionally, a new voters class, AccompanyingPeriodWorkEvaluationDocumentVoter has been created. Changes are also made in the repository to find the associated entity in the AccompanyingPeriodWorkEvaluationDocument repository instead of the AccompanyingPeriodWork repository.
255 lines
8.5 KiB
PHP
255 lines
8.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
|
|
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
|
use Doctrine\DBAL\Types\Types;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\EntityRepository;
|
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
use Doctrine\Persistence\ObjectRepository;
|
|
|
|
final readonly class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|
{
|
|
private EntityRepository $repository;
|
|
|
|
public function __construct(private EntityManagerInterface $em)
|
|
{
|
|
$this->repository = $em->getRepository(AccompanyingPeriodWork::class);
|
|
}
|
|
|
|
public function countByAccompanyingPeriod(AccompanyingPeriod $period): int
|
|
{
|
|
return $this->repository->countByAccompanyingPeriod($period);
|
|
}
|
|
|
|
public function countBySocialActionWithDescendants(SocialAction $action): int
|
|
{
|
|
$qb = $this->buildQueryBySocialActionWithDescendants($action);
|
|
$qb->select('COUNT(g)');
|
|
|
|
return $qb
|
|
->getQuery()
|
|
->getSingleScalarResult();
|
|
}
|
|
|
|
public function countNearEndDateByUser(User $user, \DateTimeImmutable $since, \DateTimeImmutable $until): int
|
|
{
|
|
return $this->buildQueryNearEndDateByUser($user, $since, $until)
|
|
->select('count(w)')->getQuery()->getSingleScalarResult();
|
|
}
|
|
|
|
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
|
|
{
|
|
return $this->repository->createQueryBuilder($alias, $indexBy);
|
|
}
|
|
|
|
public function find($id): ?AccompanyingPeriodWork
|
|
{
|
|
return $this->repository->find($id);
|
|
}
|
|
|
|
public function findAll(): array
|
|
{
|
|
return $this->repository->findAll();
|
|
}
|
|
|
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
|
|
{
|
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
|
}
|
|
|
|
/**
|
|
* @param mixed|null $orderBy
|
|
* @param mixed|null $limit
|
|
* @param mixed|null $offset
|
|
*
|
|
* @return AccompanyingPeriodWork[]
|
|
*/
|
|
public function findByAccompanyingPeriod(AccompanyingPeriod $period, $orderBy = null, $limit = null, $offset = null): array
|
|
{
|
|
return $this->repository->findByAccompanyingPeriod($period, $orderBy, $limit, $offset);
|
|
}
|
|
|
|
/**
|
|
* Return a list of accompanying period with a defined order:.
|
|
*
|
|
* * first, opened works
|
|
* * then, closed works
|
|
*
|
|
* @param array{types?: list<SocialAction>, user?: list<User>, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters
|
|
*
|
|
* @return AccompanyingPeriodWork[]
|
|
*/
|
|
public function findByAccompanyingPeriodOpenFirst(AccompanyingPeriod $period, array $filters, int $limit = 10, int $offset = 0): array
|
|
{
|
|
$rsm = new ResultSetMappingBuilder($this->em);
|
|
$rsm->addRootEntityFromClassMetadata(AccompanyingPeriodWork::class, 'w');
|
|
|
|
$sql = "SELECT {$rsm} FROM chill_person_accompanying_period_work w
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer AS rw ON accompanyingperiodwork_id = w.id
|
|
WHERE accompanyingPeriod_id = :periodId";
|
|
|
|
// implement filters
|
|
|
|
if ([] !== ($filters['types'] ?? [])) {
|
|
$sql .= ' AND w.socialaction_id IN (:types)';
|
|
}
|
|
|
|
if ([] !== ($filters['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, '[]')";
|
|
|
|
// 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
|
|
CASE WHEN w.enddate IS NULL THEN '-infinity'::timestamp ELSE 'infinity'::timestamp END ASC,
|
|
w.startdate DESC,
|
|
w.enddate DESC,
|
|
w.id DESC";
|
|
|
|
$sql .= ' LIMIT :limit OFFSET :offset';
|
|
|
|
$typeIds = [];
|
|
foreach ($filters['types'] as $type) {
|
|
$typeIds[] = $type->getId();
|
|
}
|
|
|
|
$nq = $this->em->createNativeQuery($sql, $rsm)
|
|
->setParameter('periodId', $period->getId(), Types::INTEGER)
|
|
->setParameter('types', $typeIds)
|
|
->setParameter('after', $after)
|
|
->setParameter('before', $before)
|
|
->setParameter('limit', $limit, Types::INTEGER)
|
|
->setParameter('offset', $offset, Types::INTEGER);
|
|
|
|
foreach ($filters['user'] as $key => $user) {
|
|
$nq->setParameter('user_'.$key, $user);
|
|
}
|
|
|
|
return $nq->getResult();
|
|
}
|
|
|
|
/**
|
|
* Return a list of types of social actions associated to the accompanying period.
|
|
*
|
|
* @return array<SocialAction>
|
|
*/
|
|
public function findActionTypeByPeriod(AccompanyingPeriod $period): array
|
|
{
|
|
$in = $this->em->createQueryBuilder();
|
|
$in
|
|
->select('1')
|
|
->from(AccompanyingPeriodWork::class, 'apw');
|
|
|
|
$in->andWhere('apw.accompanyingPeriod = :period')->setParameter('period', $period);
|
|
|
|
// join between the embedded exist query and the main query
|
|
$in->andWhere('apw.socialAction = sa');
|
|
|
|
$qb = $this->em->createQueryBuilder()->setParameters($in->getParameters());
|
|
$qb
|
|
->select('sa')
|
|
->from(SocialAction::class, 'sa')
|
|
->where(
|
|
$qb->expr()->exists($in->getDQL())
|
|
);
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
|
|
public function findNearEndDateByUser(User $user, \DateTimeImmutable $since, \DateTimeImmutable $until, int $limit = 20, int $offset = 0): array
|
|
{
|
|
return $this->buildQueryNearEndDateByUser($user, $since, $until)
|
|
->select('w')
|
|
->setFirstResult($offset)
|
|
->setMaxResults($limit)
|
|
->getQuery()
|
|
->getResult();
|
|
}
|
|
|
|
public function findOneBy(array $criteria): ?AccompanyingPeriodWork
|
|
{
|
|
return $this->repository->findOneBy($criteria);
|
|
}
|
|
|
|
public function getClassName()
|
|
{
|
|
return AccompanyingPeriodWork::class;
|
|
}
|
|
|
|
private function buildQueryBySocialActionWithDescendants(SocialAction $action): QueryBuilder
|
|
{
|
|
$actions = $action->getDescendantsWithThis();
|
|
|
|
$qb = $this->repository->createQueryBuilder('g');
|
|
|
|
$orx = $qb->expr()->orX();
|
|
$i = 0;
|
|
|
|
foreach ($actions as $a) {
|
|
$orx->add(":action_{$i} MEMBER OF g.socialActions");
|
|
$qb->setParameter("action_{$i}", $a);
|
|
}
|
|
$qb->where($orx);
|
|
|
|
return $qb;
|
|
}
|
|
|
|
private function buildQueryNearEndDateByUser(User $user, \DateTimeImmutable $since, \DateTimeImmutable $until): QueryBuilder
|
|
{
|
|
$qb = $this->repository->createQueryBuilder('w');
|
|
|
|
$qb
|
|
->join('w.accompanyingPeriod', 'period')
|
|
->where(
|
|
$qb->expr()->andX(
|
|
$qb->expr()->gte('w.endDate', ':since'),
|
|
$qb->expr()->lte('w.startDate', ':until'),
|
|
$qb->expr()->orX(
|
|
$qb->expr()->eq('period.user', ':user'),
|
|
$qb->expr()->exists(
|
|
'SELECT 1 FROM '.AccompanyingPeriodWork::class.' subw JOIN subw.referrersHistory subw_ref_history WHERE subw.id = w.id AND subw_ref_history.user = :user and subw.ref_history.endDate IS NULL'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
->setParameters([
|
|
'user' => $user,
|
|
'since' => $since,
|
|
'until' => $until,
|
|
]);
|
|
|
|
return $qb;
|
|
}
|
|
}
|