*/ class BookingEditDraftRepository extends ServiceEntityRepository { use AppliesListFiltersTrait; public function __construct(ManagerRegistry $registry) { parent::__construct($registry, BookingEditDraft::class); } public function createFilteredQueryBuilder(BookingEditDraftFilterDto $filter): QueryBuilder { $qb = $this ->createQueryBuilder('booking_edit_draft') ->leftJoin('booking_edit_draft.user', 'user') ; $this->applySearchTerm($qb, $filter->searchTerm(), [ 'user.email', 'booking_edit_draft.bookingNumber', 'booking_edit_draft.bookingId', ]); $this->applyDateWithin($qb, 'booking_edit_draft.createdAt', $filter->dateFrom, $filter->dateTo); if (null !== $filter->user) { $qb->andWhere('booking_edit_draft.user = :user')->setParameter('user', $filter->user); } return $qb; } /** * The accounts that actually have a draft — the full user table would be an unusable * choice list and most of it could never match. * * @return User[] */ public function findDraftOwners(): array { // Rooted at the user rather than the draft: DQL cannot select a joined entity on its own. /** @var User[] $users */ $users = $this->getEntityManager() ->createQueryBuilder() ->select('user') ->distinct() ->from(User::class, 'user') ->innerJoin(BookingEditDraft::class, 'draft', Join::ON, 'draft.user = user') ->orderBy('user.email', 'ASC') ->getQuery() ->getResult() ; return $users; } /** * Finds a draft for a specific user and booking combination. * * @param User $user The user who owns the draft * @param int $bookingId The BusProNet booking ID * * @return BookingEditDraft|null The draft if found, null otherwise */ public function findByUserAndBooking(User $user, int $bookingId): ?BookingEditDraft { return $this->findOneBy([ 'user' => $user, 'bookingId' => $bookingId, ]); } /** * Deletes a draft for a specific user and booking combination. * * @param User $user The user who owns the draft * @param int $bookingId The BusProNet booking ID */ public function deleteByUserAndBooking(User $user, int $bookingId): void { $this->createQueryBuilder('d') ->delete() ->where('d.user = :user') ->andWhere('d.bookingId = :bookingId') ->setParameters(new ArrayCollection([ new Parameter('user', $user), new Parameter('bookingId', $bookingId), ])) ->getQuery() ->execute(); } /** * Deletes all drafts where the travel date has passed. * * @return int Number of deleted drafts */ public function deleteExpiredDrafts(): int { return (int) $this->createQueryBuilder('d') ->delete() ->where('d.travelDate < :today') ->setParameter('today', new \DateTimeImmutable('today')) ->getQuery() ->execute(); } }