<?php
declare(strict_types=1);
namespace App\Repository\Franchise;
use App\Entity\Franchise\Franchise;
use App\Entity\Security\Manager;
use App\Entity\Security\User;
use App\Helper\Date\DateTimeHelper;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method null|Franchise find($id, $lockMode = null, $lockVersion = null)
* @method null|Franchise findOneBy(array $criteria, array $orderBy = null)
* @method Franchise[] findAll()
* @method Franchise[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class FranchiseRepository extends ServiceEntityRepository
{
public function __construct(
ManagerRegistry $registry,
private DateTimeHelper $dateTimeHelper,
) {
parent::__construct($registry, Franchise::class);
}
/**
* Query for getting all mode with specific columns (Default Columns).
*/
public function getDefaultQB(): QueryBuilder
{
return $this->createQueryBuilder('f')
->select('f.id', 'f.name', 'f.status', 'f.createdAt')
->orderBy('f.id', 'ASC')
;
}
public function getMultipleFranchisesQB(): QueryBuilder
{
return $this->createQueryBuilder('f')
->where('f.multiple = :multiple')
->setParameter('multiple', true)
;
}
public function getFranchisesQuery(array $criteria = []): Query
{
$qb = $this->getDefaultQB()
->addSelect('m.email AS managerEmail', 'COUNT(DISTINCT s.id) AS countShops', 'src.name AS source', 'MIN(d.url) AS domainUrl')
->leftJoin('f.shops', 's')
->leftJoin('s.source', 'src')
->leftJoin('f.managers', 'm')
->leftJoin('f.domains', 'd')
;
if (true === isset($criteria['search'])) {
$qb->andWhere('f.id LIKE :search OR f.name LIKE :search OR m.email LIKE :search OR m.firstName LIKE :search OR m.lastName LIKE :search')
->setParameter('search', '%' . $criteria['search'] . '%')
;
}
if (true === isset($criteria['status'])) {
$qb->andWhere('f.status = :status')
->setParameter('status', $criteria['status'])
;
}
if (true === isset($criteria['period'])) {
[$start, $end] = $this->dateTimeHelper->periodToDates($criteria['period']);
$qb->andWhere('f.createdAt BETWEEN :startingDate AND :endingDate')
->setParameter('startingDate', $start)
->setParameter('endingDate', $end)
;
}
if (true === isset($criteria['source'])) {
$qb->andWhere('s.source = :source')
->setParameter('source', $criteria['source'])
;
}
return $qb->groupBy('f.id')->getQuery();
}
/**
* findByIdAndUser.
*/
public function findByIdAndUser(int $id, User $user): ?Franchise
{
$qb = $this->createQueryBuilder('f')
->where('f.id = :id')
->setParameter('id', $id)
->setMaxResults(1)
;
if ($user instanceof Manager) {
$qb->join('f.managers', 'm')
->andWhere('m.id = :manager')
->setParameter('manager', $user)
;
}
return $qb->getQuery()->getOneOrNullResult();
}
/**
* Results for KnpPaginator.
*/
public function getFranchises(): array
{
return $this->getFranchisesQuery()->getResult();
}
public function findByDomain(string $domain): ?Franchise
{
return $this->createQueryBuilder('f')
->join('f.domains', 'd')
->where('d.url = :domain')
->setParameter('domain', $domain)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult()
;
}
public function getAll(): array
{
return $this->createQueryBuilder('f')
->select('f.id', 'f.name')
->orderBy('f.name', 'ASC')
->getQuery()
->getResult()
;
}
}