- Updated the clinic API response to include new fields: title, phone, logo, images_clinic, doctors_count, city, state, 24_7, and field_working_days. - Modified the ClinicController to fetch and include city and state information based on the clinic's address. - Refactored the toListArray method in the Clinic entity to accept city and state parameters. - Added a new method in the ClinicRepository to retrieve city and province names for each clinic based on their address.
136 lines
4.4 KiB
PHP
136 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Clinic\Repository;
|
|
|
|
use App\Auth\Entity\User;
|
|
use App\Clinic\Entity\Clinic;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Doctor\Entity\DoctorAddress;
|
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
use Doctrine\ORM\Query\Expr\Join;
|
|
use Doctrine\ORM\Tools\Pagination\Paginator;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
|
|
class ClinicRepository extends ServiceEntityRepository
|
|
{
|
|
public function __construct(ManagerRegistry $registry)
|
|
{
|
|
parent::__construct($registry, Clinic::class);
|
|
}
|
|
|
|
public function findByUuid(string $uuid): ?Clinic
|
|
{
|
|
return $this->findOneBy(['uuid' => $uuid]);
|
|
}
|
|
|
|
/** @return Clinic[] */
|
|
public function findByDoctor(Doctor $doctor): array
|
|
{
|
|
return $this->createQueryBuilder('c')
|
|
->innerJoin('c.doctors', 'd')
|
|
->where('d.id = :doctorId')
|
|
->setParameter('doctorId', $doctor->getId())
|
|
->getQuery()
|
|
->getResult();
|
|
}
|
|
|
|
public function findByUser(User $user): ?Clinic
|
|
{
|
|
return $this->findOneBy(['user' => $user]);
|
|
}
|
|
|
|
public function findWithFilters(array $filters): array
|
|
{
|
|
$page = max(1, (int) ($filters['page'] ?? 1));
|
|
$limit = min(50, max(1, (int) ($filters['limit'] ?? 10)));
|
|
$sort = strtoupper($filters['sort'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC';
|
|
|
|
$qb = $this->createQueryBuilder('c')
|
|
->leftJoin('c.specialties', 's')
|
|
->distinct();
|
|
|
|
// City/province live on the clinic's address (DoctorAddress.clinicId),
|
|
// not on the clinic itself. DoctorAddress has no Doctrine relation to
|
|
// Clinic, so join on the scalar clinicId with a WITH condition.
|
|
if (!empty($filters['city']) || !empty($filters['state'])) {
|
|
$qb->join(DoctorAddress::class, 'addr', Join::WITH, 'addr.clinicId = c.id');
|
|
|
|
if (!empty($filters['city'])) {
|
|
$qb->andWhere('IDENTITY(addr.city) = :city')->setParameter('city', (int) $filters['city']);
|
|
}
|
|
if (!empty($filters['state'])) {
|
|
$qb->andWhere('IDENTITY(addr.province) = :state')->setParameter('state', (int) $filters['state']);
|
|
}
|
|
}
|
|
if (!empty($filters['specialty'])) {
|
|
$qb->andWhere('s.id = :specialty')->setParameter('specialty', (int) $filters['specialty']);
|
|
}
|
|
|
|
$qb->orderBy('c.id', $sort);
|
|
|
|
$total = (new Paginator($qb))->count();
|
|
$results = $qb->setFirstResult(($page - 1) * $limit)
|
|
->setMaxResults($limit)
|
|
->getQuery()
|
|
->getResult();
|
|
|
|
return [
|
|
'items' => $results,
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'limit' => $limit,
|
|
'totalPages' => (int) ceil($total / $limit),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* City/province names for each clinic, taken from the clinic's address
|
|
* (DoctorAddress.clinicId). Returns [clinicId => ['city' => ?string, 'state' => ?string]].
|
|
*
|
|
* @param int[] $clinicIds
|
|
* @return array<int, array{city: ?string, state: ?string}>
|
|
*/
|
|
public function findAddressLocations(array $clinicIds): array
|
|
{
|
|
if ($clinicIds === []) {
|
|
return [];
|
|
}
|
|
|
|
$rows = $this->getEntityManager()->createQueryBuilder()
|
|
->select('addr.clinicId AS clinic_id', 'cityCat.name AS city', 'provinceCat.name AS state')
|
|
->from(DoctorAddress::class, 'addr')
|
|
->leftJoin('addr.city', 'cityCat')
|
|
->leftJoin('addr.province', 'provinceCat')
|
|
->where('addr.clinicId IN (:ids)')
|
|
->setParameter('ids', $clinicIds)
|
|
->getQuery()
|
|
->getResult();
|
|
|
|
$map = [];
|
|
foreach ($rows as $row) {
|
|
$id = (int) $row['clinic_id'];
|
|
if (!isset($map[$id])) {
|
|
$map[$id] = ['city' => $row['city'], 'state' => $row['state']];
|
|
}
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
public function save(Clinic $clinic, bool $flush = true): void
|
|
{
|
|
$this->getEntityManager()->persist($clinic);
|
|
if ($flush) {
|
|
$this->getEntityManager()->flush();
|
|
}
|
|
}
|
|
|
|
public function remove(Clinic $clinic, bool $flush = true): void
|
|
{
|
|
$this->getEntityManager()->remove($clinic);
|
|
if ($flush) {
|
|
$this->getEntityManager()->flush();
|
|
}
|
|
}
|
|
}
|