src/Repository/User/UserRepository.php line 65

Open in your IDE?
  1. <?php
  2. namespace App\Repository\User;
  3. use App\Entity\ParameterCodes;
  4. use App\Entity\User\User;
  5. use App\Voter\__Accounting\AccountingTurnoverVoter;
  6. use App\Voter\BookingVoter;
  7. use App\Voter\QuoteVoter;
  8. use App\Voter\__Accounting\AccountingSellingVoter;
  9. use Crea\HRBundle\Helper\PlanningHelper;
  10. use Crea\SecurityBundle\Helper\AccessHelper;
  11. use Crea\SecurityBundle\Model\Access;
  12. use Crea\SecurityBundle\Repository\UserRepository as BaseUserRepository;
  13. use DateTime;
  14. use Doctrine\ORM\NonUniqueResultException;
  15. use Doctrine\ORM\Query\Expr\Join;
  16. use Doctrine\ORM\QueryBuilder;
  17. use Doctrine\Persistence\ManagerRegistry;
  18. use Symfony\Component\Security\Core\Security;
  19. use Throwable;
  20. /**
  21.  * @method User|null find($id, $lockMode = null, $lockVersion = null)
  22.  * @method User|null findOneBy(array $criteria, array $orderBy = null)
  23.  * @method User[]    findAll()
  24.  * @method User[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  25.  */
  26. class UserRepository extends BaseUserRepository
  27. {
  28.     public const CRM_USER_GROUPS = [
  29.         ['label' => 'Administrateur''code' => 'Administrateur''crmId' => 1],
  30.         ['label' => 'Commercial''code' => 'Commercial''crmId' => 2],
  31.         ['label' => 'Marketing''code' => 'Marketing''crmId' => 3],
  32.         ['label' => 'Stagiaire''code' => 'Stagiaire''crmId' => 4],
  33.         ['label' => 'Comptabilité''code' => 'Comptabilite''crmId' => 5],
  34.         ['label' => 'Direction''code' => 'Direction''crmId' => 6],
  35.         ['label' => 'Back-Office''code' => 'Back-Office''crmId' => 7],
  36.         ['label' => 'Vendeur''code' => 'Vendeur''crmId' => 8],
  37.         ['label' => 'Manager plateau''code' => 'Manager-plateau''crmId' => 9],
  38.         ['label' => 'Partenariats''code' => 'Partenariats''crmId' => 10],
  39.         ['label' => 'Technique''code' => 'Technique''crmId' => 11],
  40.         ['label' => 'Anciens utilisateurs''code' => 'Anciens-utilisateurs''crmId' => 12],
  41.     ];
  42.     public const DEFAULT_USER_GROUP_CODE 'Anciens-utilisateurs';
  43.     public const SELLER_USER_GROUP_CODE 'Vendeur';
  44.     public const BACK_OFFICE_USER_GROUP_CODE 'Back-Office';
  45.     public const ACCOUNTING_USER_GROUP_CODE 'Comptabilite';
  46.     public const MANAGER_USER_GROUP_CODE 'Manager-plateau';
  47.     public const MARKETING_USER_GROUP_CODE 'Marketing';
  48.     public const FULLWEB_USER_LOGIN 'croisiland';
  49.     protected Security $security;
  50.     protected AccessHelper $accessHelper;
  51.     protected PlanningHelper $planningHelper;
  52.     public function __construct(ManagerRegistry $registry,
  53.                                 Security $security,
  54.                                 AccessHelper $accessHelper,
  55.                                 PlanningHelper $planningHelper)
  56.     {
  57.         parent::__construct($registryUser::class);
  58.         $this->security $security;
  59.         $this->accessHelper $accessHelper;
  60.         $this->planningHelper $planningHelper;
  61.     }
  62.     public function loadUserByUsername(string $usernameOrEmail): ?User
  63.     {
  64.         try {
  65.             return $this->createQueryBuilder('u')
  66.                 ->where('u.login = :usernameOrEmail')
  67.                 ->orWhere('u.email = :usernameOrEmail')
  68.                 ->setParameter('usernameOrEmail'$usernameOrEmail)
  69.                 ->getQuery()
  70.                 ->getOneOrNullResult();
  71.         } catch (NonUniqueResultException $e) {
  72.             return null;
  73.         }
  74.     }
  75.     public function getAllOrderedByNameQueryBuilder(): QueryBuilder
  76.     {
  77.         return $this->createQueryBuilder('u')
  78.             ->addOrderBy('u.firstName''ASC')
  79.             ->addOrderBy('u.lastName''ASC');
  80.     }
  81.     /**
  82.      * @throws NonUniqueResultException
  83.      */
  84.     public function findOneByAccountToken(string $token): ?User
  85.     {
  86.         return $this->createQueryBuilder('u')
  87.             ->where('u.accountToken = :token')
  88.             ->setParameter('token'$token)
  89.             ->getQuery()
  90.             ->getOneOrNullResult();
  91.     }
  92.     /**
  93.      * @throws NonUniqueResultException
  94.      */
  95.     public function findFullwebUser(): ?User
  96.     {
  97.         return $this->createQueryBuilder('u')
  98.             ->where('u.login = :login')
  99.             ->setParameter('login'self::FULLWEB_USER_LOGIN)
  100.             ->getQuery()
  101.             ->getOneOrNullResult();
  102.     }
  103.     /**
  104.      * @return User[]
  105.      */
  106.     public function findIn(array $ids): array
  107.     {
  108.         $qb $this->createQueryBuilder('u');
  109.         return $qb
  110.             ->where($qb->expr()->in('u.id'':ids'))
  111.             ->setParameter('ids'$ids)
  112.             ->getQuery()
  113.             ->getResult()
  114.             ;
  115.     }
  116.     /*********************************** By Users Group ***************************************************************/
  117.     public function getByUserGroupCodeQB(string $userGroupCode, ?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  118.     {
  119.         $qb $this->createQueryBuilder('u');
  120.         $qb->leftjoin('u.userGroups''ug')
  121.             ->andWhere($qb->expr()->eq('ug.code'':userGroupCode'))
  122.             ->setParameter('userGroupCode'$userGroupCode);
  123.         if ($enabled !== null) {
  124.             $qb->andWhere($qb->expr()->eq('u.enabled'':enabled'))
  125.                 ->setParameter('enabled'$enabled);
  126.         }
  127.         $qb->groupBy('u.id');
  128.         if ($orderedByName === true) {
  129.             $qb->addOrderBy('u.firstName''ASC')
  130.                 ->addOrderBy('u.lastName''ASC');
  131.         }
  132.         return $qb;
  133.     }
  134.     public function getByUserGroupsCodeQB(array $userGroupsCode, ?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  135.     {
  136.         $qb $this->createQueryBuilder('u');
  137.         $qb->leftjoin('u.userGroups''ug')
  138.             ->andWhere($qb->expr()->in('ug.code'':userGroupsCode'))
  139.             ->setParameter('userGroupsCode'$userGroupsCode);
  140.         if ($enabled !== null) {
  141.             $qb->andWhere($qb->expr()->eq('u.enabled'':enabled'))
  142.                 ->setParameter('enabled'$enabled);
  143.         }
  144.         $qb->groupBy('u.id');
  145.         if ($orderedByName === true) {
  146.             $qb->addOrderBy('u.firstName''ASC')
  147.                 ->addOrderBy('u.lastName''ASC');
  148.         }
  149.         return $qb;
  150.     }
  151.     /**
  152.      * @return User[]
  153.      */
  154.     public function findGroupUsers(string $userGroupCode, ?bool $enabled true, ?bool $orderedByName true): array
  155.     {
  156.         return $this->getByUserGroupCodeQB($userGroupCode$enabled$orderedByName)->getQuery()->getResult();
  157.     }
  158.     /*********************************** ADV Users Group **************************************************************/
  159.     public function getAdvUsersQueryBuilder(?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  160.     {
  161.         return $this->getByUserGroupCodeQB(self::BACK_OFFICE_USER_GROUP_CODE$enabled$orderedByName);
  162.     }
  163.     /**
  164.      * @return User[]
  165.      */
  166.     public function findAdvUsers(?bool $enabled true, ?bool $orderedByName true): array
  167.     {
  168.         return $this->getAdvUsersQueryBuilder($enabled$orderedByName)->getQuery()->getResult();
  169.     }
  170.     public function getAdvRequestsCount(): array
  171.     {
  172.         return $this->getSellerUsersQueryBuilder()
  173.             ->select('u.id as sellerId')
  174.             ->addSelect('count(DISTINCT ar) as count')
  175.             ->leftjoin('u.advRequests''ar')
  176.             ->getQuery()
  177.             ->getResult();
  178.     }
  179.     /*********************************** Seller Users Group ***********************************************************/
  180.     public function getSellerUsersQueryBuilder(?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  181.     {
  182.         return $this->getByUserGroupCodeQB(self::SELLER_USER_GROUP_CODE$enabled$orderedByName);
  183.     }
  184.     public function getSellerUsersAvailableQueryBuilder(bool $availableDateTime $date,  ?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  185.     {
  186.         $qb $this->getSellerUsersQueryBuilder($enabled$orderedByName);
  187.         $unavailableUsers $this->planningHelper->getNotAvailableUsersFromGroupAndDateQb(self::SELLER_USER_GROUP_CODE$date)->getQuery()->getResult();
  188.         if ($available) {
  189.             if (count($unavailableUsers) > 0) {
  190.                 $qb->andWhere($qb->expr()->notIn('u'':userList'))
  191.                     ->setParameter('userList'$unavailableUsers);
  192.             }
  193.         }
  194.         else {
  195.             $qb->andWhere($qb->expr()->in('u'':userList'))
  196.                 ->setParameter('userList'$unavailableUsers);
  197.         }
  198.         return $qb;
  199.     }
  200.     /********************************** Marketing Users Group *********************************************************/
  201.     public function getMarketingUsersQueryBuilder(?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  202.     {
  203.         return $this->getByUserGroupCodeQB(self::MARKETING_USER_GROUP_CODE$enabled$orderedByName);
  204.     }
  205.     public function getMarketingUsersAvailableQueryBuilder(bool $availableDateTime $date,  ?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  206.     {
  207.         $qb $this->getMarketingUsersQueryBuilder($enabled$orderedByName);
  208.         $unavailableUsers $this->planningHelper->getNotAvailableUsersFromGroupAndDateQb(self::MARKETING_USER_GROUP_CODE$date)->getQuery()->getResult();
  209.         if ($available) {
  210.             if (count($unavailableUsers) > 0) {
  211.                 $qb->andWhere($qb->expr()->notIn('u'':userList'))
  212.                     ->setParameter('userList'$unavailableUsers);
  213.             }
  214.         }
  215.         else {
  216.             $qb->andWhere($qb->expr()->in('u'':userList'))
  217.                 ->setParameter('userList'$unavailableUsers);
  218.         }
  219.         return $qb;
  220.     }
  221.     private function completeQueryBuilderForUserWithoutAccess(QueryBuilder $qb, array $rights): QueryBuilder
  222.     {
  223.         if (!$this->accessHelper->hasAccess(new Access($rights))) {
  224.             /** @var User $user */
  225.             $user $this->security->getUser();
  226.             $qb $qb->andWhere($qb->expr()->eq('u.id'$user->getId()));
  227.         }
  228.         return $qb;
  229.     }
  230.     public function getSellerUsersForQuoteListQueryBuilder(): QueryBuilder
  231.     {
  232.         return $this->completeQueryBuilderForUserWithoutAccess(
  233.             $this->getSellerUsersQueryBuilder(),
  234.             [QuoteVoter::SHOW_ALL_SELLERS]
  235.         );
  236.     }
  237.     public function getSellerUsersForQuoteOptionInProgressQueryBuilder(): QueryBuilder
  238.     {
  239.         return $this->completeQueryBuilderForUserWithoutAccess(
  240.             $this->getSellerUsersQueryBuilder(),
  241.             [QuoteVoter::OPTION_IN_PROGRESS_SHOW_ALL_SELLERS]
  242.         );
  243.     }
  244.     public function getSellerUsersForBookingListQueryBuilder(): QueryBuilder
  245.     {
  246.         return $this->completeQueryBuilderForUserWithoutAccess(
  247.             $this->getSellerUsersQueryBuilder(),
  248.             [BookingVoter::SHOW_ALL_SELLERS]
  249.         );
  250.     }
  251.     public function getSellerUsersForSellerRecapQueryBuilder(): QueryBuilder
  252.     {
  253.         return $this->completeQueryBuilderForUserWithoutAccess(
  254.             $this->getSellerUsersQueryBuilder(),
  255.             [AccountingSellingVoter::SELLER_SALE_SHOW_ALL_SELLERS]
  256.         );
  257.     }
  258.     public function getSellerUsersForPartnerRecapQueryBuilder(): QueryBuilder
  259.     {
  260.         return $this->completeQueryBuilderForUserWithoutAccess(
  261.             $this->getSellerUsersQueryBuilder(),
  262.             [AccountingSellingVoter::PARTNER_SALE_SHOW_ALL_SELLERS]
  263.         );
  264.     }
  265.     public function getSellerUsersForCompanyRecapQueryBuilder(): QueryBuilder
  266.     {
  267.         return $this->completeQueryBuilderForUserWithoutAccess(
  268.             $this->getSellerUsersQueryBuilder(),
  269.             [AccountingSellingVoter::COMPANY_SALE_SHOW_ALL_SELLERS]
  270.         );
  271.     }
  272.     public function getSellerUsersForCabinTypeRecapQueryBuilder(): QueryBuilder
  273.     {
  274.         return $this->completeQueryBuilderForUserWithoutAccess(
  275.             $this->getSellerUsersQueryBuilder(),
  276.             [AccountingSellingVoter::CABIN_SALE_SHOW_ALL_SELLERS]
  277.         );
  278.     }
  279.     public function getSellerUsersForTurnoverRecapBySellerQueryBuilder(): QueryBuilder
  280.     {
  281.         return $this->completeQueryBuilderForUserWithoutAccess(
  282.             $this->getSellerUsersQueryBuilder(),
  283.             [AccountingTurnoverVoter::SELLER_SHOW_ALL_SELLERS]
  284.         );
  285.     }
  286.     /**
  287.      * @return User[]
  288.      */
  289.     public function findSellerUsers(?bool $enabled true, ?bool $orderedByName true): array
  290.     {
  291.         return $this->getSellerUsersQueryBuilder($enabled$orderedByName)->getQuery()->getResult();
  292.     }
  293.     /**
  294.      * @return User[]
  295.      */
  296.     public function findMarketingUsers(?bool $enabled true, ?bool $orderedByName true): array
  297.     {
  298.         return $this->getMarketingUsersQueryBuilder($enabled$orderedByName)->getQuery()->getResult();
  299.     }
  300.     public function getSellersRequestsCount(): array
  301.     {
  302.         return $this->getSellerUsersQueryBuilder()
  303.             ->select('u.id as sellerId')
  304.             ->addSelect('count(DISTINCT pr) as count')
  305.             ->leftjoin('u.prospectRequests''pr'Join::WITH'pr.stateType = :attributedStateTypeId')
  306.             ->leftJoin('pr.status''prs')
  307.             ->where('prs.code'':attributedStateCode')
  308.             ->setParameter('attributedStateCode'ParameterCOdes::PROSPECT_REQUEST_STATUS_ATTRIBUTED_AND_NOT_PROCESSED)
  309.             ->getQuery()
  310.             ->getResult();
  311.     }
  312.     /**
  313.      * Retourne le nombre des réservations des vendeurs sur une période donnée.
  314.      *
  315.      * @return User[]
  316.      */
  317.     public function getSellersCabinCount(DateTime $startingDateDateTime $endingDate): array
  318.     {
  319.         $qb $this->getSellerUsersQueryBuilder(null)
  320.             ->select('u.id as sellerId')
  321.             ->addSelect('count(DISTINCT qrg) as count')
  322.             ->join('u.bookings''b')
  323.             ->andWhere('b.assignedAt >= :startingDate')
  324.             ->setParameter('startingDate'$startingDate)
  325.             ->andWhere('b.assignedAt <= :endingDate')
  326.             ->setParameter('endingDate'$endingDate);
  327.         return $qb->getQuery()->getResult();
  328.     }
  329.     /**
  330.      * @return User[]
  331.      */
  332.     public function getSellersBookingCount(?DateTime $startingDate, ?DateTime $endingDate, ?string $status null): array
  333.     {
  334.         $queryBuilder $this->createQueryBuilder('u')
  335.             ->leftjoin('u.quotes''q')
  336.             ->select('u.id as sellerId')
  337.             ->addSelect('count(DISTINCT booking) as count')
  338.             ->join('q.booking''booking');
  339.         if (null !== $startingDate) {
  340.             $queryBuilder
  341.                 ->andWhere('booking.assignedAt >= :startingDate')
  342.                 ->setParameter('startingDate'$startingDate);
  343.         }
  344.         if (null !== $endingDate) {
  345.             $queryBuilder
  346.                 ->andWhere('booking.assignedAt <= :endingDate')
  347.                 ->setParameter('endingDate'$endingDate);
  348.         }
  349.         if (null !== $status) {
  350.             $queryBuilder
  351.                 ->andWhere('booking.status = :status')
  352.                 ->setParameter('status'$status);
  353.         }
  354.         return $queryBuilder
  355.             ->groupBy('u.id')
  356.             ->addGroupBy('booking.id')
  357.             ->getQuery()
  358.             ->getResult()
  359.             ;
  360.     }
  361.     /*********************************** Accounting Users Group *******************************************************/
  362.     public function getAccountingUsersQueryBuilder(?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  363.     {
  364.         return $this->getByUserGroupCodeQB(self::ACCOUNTING_USER_GROUP_CODE$enabled$orderedByName);
  365.     }
  366.     /**
  367.      * @return User[]
  368.      */
  369.     public function findAccountingUsers(?bool $enabled true, ?bool $orderedByName true): array
  370.     {
  371.         return $this->getAccountingUsersQueryBuilder($enabled$orderedByName)->getQuery()->getResult();
  372.     }
  373.     /*********************************** Manager Users Group **********************************************************/
  374.     public function getManagerUsersQueryBuilder(?bool $enabled true, ?bool $orderedByName true): QueryBuilder
  375.     {
  376.         return $this->getByUserGroupCodeQB(self::MANAGER_USER_GROUP_CODE$enabled$orderedByName);
  377.     }
  378.     /**
  379.      * @return User[]
  380.      */
  381.     public function findManagerUsers(?bool $enabled true, ?bool $orderedByName true): array
  382.     {
  383.         return $this->getManagerUsersQueryBuilder($enabled$orderedByName)->getQuery()->getResult();
  384.     }
  385.     public function findAdvManager(?bool $enabled true, ?bool $orderedByName true): ?User
  386.     {
  387.         try {
  388.             return $this->getManagerUsersQueryBuilder($enabled$orderedByName)
  389.                 ->setMaxResults(1)
  390.                 ->getQuery()
  391.                 ->getOneOrNullResult();
  392.         } catch (Throwable $exception) {
  393.             return null;
  394.         }
  395.     }
  396.     /*********************************** Schedule *********************************************************************/
  397.     /**
  398.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs informations liées au planning.
  399.      *
  400.      * @return User[]
  401.      */
  402.     public function getScheduleEvents(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  403.     {
  404.         return $this->getByUserGroupCodeQB($userGroupCode)
  405.             ->select('u, se')
  406.             ->leftJoin('u.scheduleEvents''se''WITH''se.date >= :startingDate AND se.date <= :endingDate')
  407.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  408.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  409.             ->addOrderBy('se.date''ASC')
  410.             ->addOrderBy('se.startingTime''ASC')
  411.             ->getQuery()
  412.             ->getResult();
  413.     }
  414.     /**
  415.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs commentaires planning.
  416.      *
  417.      * @return User[]
  418.      */
  419.     public function getScheduleComments(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  420.     {
  421.         return $this->getByUserGroupCodeQB($userGroupCode)
  422.             ->select('u, sc')
  423.             ->leftJoin('u.scheduleComments''sc''WITH''sc.date >= :startingDate AND sc.date <= :endingDate')
  424.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  425.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  426.             ->getQuery()
  427.             ->getResult();
  428.     }
  429.     /**
  430.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs congés.
  431.      *
  432.      * @return User[]
  433.      */
  434.     public function getScheduleLeaves(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  435.     {
  436.         return $this->getByUserGroupCodeQB($userGroupCode)
  437.             ->select('u, l')
  438.             ->leftJoin('u.leaves''l''WITH''l.endingDate >= :startingDate AND l.startingDate <= :endingDate')
  439.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  440.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  441.             ->getQuery()
  442.             ->getResult();
  443.     }
  444.     /**
  445.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs informations liées au planning pour les PDF.
  446.      *
  447.      * @return User[]
  448.      */
  449.     public function getScheduleDataForPdf(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  450.     {
  451.         return $this->getByUserGroupCodeQB($userGroupCode)
  452.             ->select('u, se, l')
  453.             ->leftJoin('u.scheduleEvents''se''WITH''se.date >= :startingDate AND se.date <= :endingDate')
  454.             ->leftJoin('u.leaves''l''WITH''l.endingDate >= :startingDate AND l.startingDate <= :endingDate')
  455.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  456.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  457.             ->addOrderBy('u.firstName''ASC')
  458.             ->addOrderBy('se.date''ASC')
  459.             ->addOrderBy('se.startingTime''ASC')
  460.             ->getQuery()
  461.             ->getResult();
  462.     }
  463.     /**
  464.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs demandes à traiter.
  465.      *
  466.      * @return User[]
  467.      */
  468.     public function getProspectRequestsForSchedule(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  469.     {
  470.         return $this->getByUserGroupCodeQB($userGroupCode)
  471.             ->select('u, pr')
  472.             ->leftJoin('u.prospectRequests''pr''WITH''pr.appointmentDate >= :startingDate AND pr.appointmentDate <= :endingDate')
  473.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  474.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  475.             ->addOrderBy('pr.appointmentDate''ASC')
  476.             ->addOrderBy('pr.appointmentHours''ASC')
  477.             ->getQuery()
  478.             ->getResult();
  479.     }
  480.     /**
  481.      * Retourne la liste des utilisateurs du groupe passé en paramètre avec leurs demandes ADV à traiter.
  482.      *
  483.      * @return User[]
  484.      */
  485.     public function getAdvRequestsForSchedule(string $userGroupCodeDateTime $startingDateDateTime $endingDate): array
  486.     {
  487.         return $this->getByUserGroupCodeQB($userGroupCode)
  488.             ->select('u, ar')
  489.             ->leftJoin('u.advRequests''ar''WITH''ar.appointmentDate >= :startingDate AND ar.appointmentDate <= :endingDate')
  490.             ->setParameter('startingDate'$startingDate->format('Y-m-d'))
  491.             ->setParameter('endingDate'$endingDate->format('Y-m-d'))
  492.             ->addOrderBy('ar.appointmentDate''ASC')
  493.             ->addOrderBy('ar.appointmentHours''ASC')
  494.             ->getQuery()
  495.             ->getResult();
  496.     }
  497.     /*********************************** Recap ************************************************************************/
  498.     /**
  499.      * @param QueryBuilder $bookingRecapFiltersQueryBuilder Voir fonction getRecapBaseQueryBuilderForFilters du BookingRepository
  500.      */
  501.     public function getRecapBaseQueryBuilder(QueryBuilder $bookingRecapFiltersQueryBuilder): QueryBuilder
  502.     {
  503.         return $this->createQueryBuilder('u')
  504.             ->select('CONCAT(u.firstName, \' \', u.lastName) as seller')
  505.             ->innerJoin('u.sellerBookings''b')
  506.             ->where('b.id IN ('.$bookingRecapFiltersQueryBuilder->getQuery()->getDQL().')')
  507.             ->andWhere('b.seller IS NOT NULL')
  508.             ->groupBy('u.id')
  509.             ->addOrderBy('u.firstName''ASC')
  510.             ->addOrderBy('u.lastName''ASC');
  511.     }
  512.     public function getTurnoverRecapBySellerQueryBuilder(QueryBuilder $bookingRecapFiltersQueryBuilder): QueryBuilder
  513.     {
  514.         return $this->completeQueryBuilderForUserWithoutAccess(
  515.             $this->getRecapBaseQueryBuilder($bookingRecapFiltersQueryBuilder),
  516.             [AccountingTurnoverVoter::SELLER_SHOW_ALL_SELLERS]
  517.         );
  518.     }
  519.     /*********************************** Grid / Notifications *********************************************************/
  520.     public function getAppUsersQueryBuilder(?bool $enabled true): QueryBuilder
  521.     {
  522.         $queryBuilder $this->createQueryBuilder('u');
  523.         if (null !== $enabled) {
  524.             $queryBuilder
  525.                 ->andWhere('u.enabled = :enabled')
  526.                 ->setParameter('enabled'$enabled);
  527.         }
  528.         return $queryBuilder
  529.             ->addOrderBy('u.firstName''ASC')
  530.             ->addOrderBy('u.lastName''ASC');
  531.     }
  532.     public function getSellerFilterGridQueryBuilder(): QueryBuilder
  533.     {
  534.         return $this->getByUserGroupCodeQB(self::SELLER_USER_GROUP_CODE);
  535.     }
  536. }