* * @method Availability|null find($id, $lockMode = null, $lockVersion = null) * @method Availability|null findOneBy(array $criteria, array $orderBy = null) * @method Availability[] findAll() * @method Availability[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class AvailabilityRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Availability::class); } public function getListQuery(bool $custom = false, ?AvailabilityFilterDto $filterDto = null): Query { $qb = $this->createQueryBuilder('availability'); $qb ->select('availability', 'teamer') ->leftJoin('availability.owner', 'teamer') ->where($qb->expr()->andX( $qb->expr()->gt('availability.dateFrom', ':today'), $qb->expr()->isNull('availability.deletedAt') )) ->orderBy('availability.dateFrom', \SortDirection::Ascending) ->setParameter('today', new \DateTimeImmutable()) ; if (false === $custom) { $qb->andWhere($qb->expr()->isNull('availability.owner')); } else { $qb ->andWhere($qb->expr()->isNotNull('availability.owner')) // a deleted teamer takes no further assignments, so their own // availabilities must no longer be offered for disposition ->andWhere($qb->expr()->isNull('teamer.deletedAt')) ; } if (null === $filterDto) { return $qb->getQuery(); } if (null !== $dateFrom = $filterDto->getDateFrom()) { $qb ->andWhere($qb->expr()->gte('availability.dateFrom', ':dateFrom')) ->setParameter('dateFrom', $dateFrom) ; } if (null !== $dateTo = $filterDto->getDateTo()) { $qb ->andWhere($qb->expr()->lte('availability.dateTo', ':dateTo')) ->setParameter('dateTo', $dateTo) ; } if (null !== $teamer = $filterDto->getTeamer()) { $qb ->andWhere($qb->expr()->eq('availability.owner', ':teamer')) ->setParameter('teamer', $teamer) ; } if (0 < count($jobProfiles = $filterDto->getJobProfiles())) { // a join on the job-profiles would multiply the availability whenever its // owner holds more than one of the selected profiles, which would break // the pagination count, so the owner is matched against a subquery instead $subQuery = $this ->getEntityManager() ->createQueryBuilder() ->select('profileTeamer.id') ->from(Teamer::class, 'profileTeamer') ->innerJoin('profileTeamer.jobProfiles', 'filterJobProfile') ->where('filterJobProfile IN (:jobProfiles)') ; $qb ->andWhere($qb->expr()->in('availability.owner', $subQuery->getDQL())) ->setParameter('jobProfiles', $jobProfiles) ; } return $qb->getQuery(); } public function getSelectableForTeamer(Teamer $teamer): array { if (true === $teamer->isDeleted()) { return []; } $qb = $this->createQueryBuilder('availability'); return $qb ->leftJoin('availability.teamers', 'teamer') ->where($qb->expr()->andX( $qb->expr()->gt('availability.dateFrom', ':today'), $qb->expr()->notIn('availability', ':availabilities'), $qb->expr()->orX( $qb->expr()->isNull('availability.owner'), $qb->expr()->eq('availability.owner', ':teamer') ), $qb->expr()->isNull('availability.deletedAt') )) ->orderBy('availability.dateFrom', \SortDirection::Ascending) ->setParameter('teamer', $teamer) ->setParameter('availabilities', $teamer->getAvailabilities()) ->setParameter('today', new \DateTimeImmutable()) ->getQuery() ->getResult() ; } public function getNew(int $limit = 5): array { $qb = $this->createQueryBuilder('availability'); return $qb ->where($qb->expr()->isNotNull('availability.owner')) ->orderBy('availability.createdAt', \SortDirection::Descending) ->setMaxResults($limit) ->getQuery() ->getResult() ; } public function assertUnique(array $fields): array { $qb = $this->createQueryBuilder('availability'); return $qb ->where($qb->expr()->andX( $qb->expr()->eq('availability.dateFrom', ':dateFrom'), $qb->expr()->eq('availability.dateTo', ':dateTo'), $qb->expr()->isNull('availability.owner') )) ->setParameters($fields) ->getQuery() ->getResult() ; } }