- Introduced clinic_id to weekly_schedules, date_overrides, and holidays to differentiate between personal and clinic schedules. - Updated unique constraints and indexes to accommodate the new clinic context. feat(command): create AssignScheduleClinicCommand to move schedules - Added a command to move a doctor's personal weekly schedule into a clinic context. - Implemented checks to ensure sessions align with the target clinic. feat(context): implement EntityContext and EntityContextResolver - Created EntityContext to represent the effective working environment of a request (doctor or clinic). - Developed EntityContextResolver to determine the execution context based on user roles and active contexts. test: add ServiceModeContextTest for appointment scheduling - Implemented tests to ensure service booking respects clinic and personal contexts. - Verified that financial data is omitted in clinic contexts in InvitedDoctorDashboardScopeTest.
114 lines
3.8 KiB
PHP
114 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Doctor\Repository;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Doctor\Entity\DoctorAddress;
|
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
|
|
class DoctorAddressRepository extends ServiceEntityRepository
|
|
{
|
|
public function __construct(ManagerRegistry $registry)
|
|
{
|
|
parent::__construct($registry, DoctorAddress::class);
|
|
}
|
|
|
|
public function save(DoctorAddress $address, bool $flush = true): void
|
|
{
|
|
$this->getEntityManager()->persist($address);
|
|
if ($flush) {
|
|
$this->getEntityManager()->flush();
|
|
}
|
|
}
|
|
|
|
public function remove(DoctorAddress $address, bool $flush = true): void
|
|
{
|
|
$this->getEntityManager()->remove($address);
|
|
if ($flush) {
|
|
$this->getEntityManager()->flush();
|
|
}
|
|
}
|
|
|
|
public function findByUuidAndClinic(string $uuid, int $clinicId): ?DoctorAddress
|
|
{
|
|
return $this->createQueryBuilder('a')
|
|
->where('a.uuid = :uuid')
|
|
->andWhere('a.clinicId = :clinicId')
|
|
->setParameter('uuid', $uuid)
|
|
->setParameter('clinicId', $clinicId)
|
|
->getQuery()
|
|
->getOneOrNullResult();
|
|
}
|
|
|
|
public function findOneByClinic(int $clinicId): ?DoctorAddress
|
|
{
|
|
return $this->createQueryBuilder('a')
|
|
->where('a.clinicId = :clinicId')
|
|
->setParameter('clinicId', $clinicId)
|
|
->orderBy('a.id', 'ASC')
|
|
->setMaxResults(1)
|
|
->getQuery()
|
|
->getOneOrNullResult();
|
|
}
|
|
|
|
public function countByClinic(int $clinicId): int
|
|
{
|
|
return (int) $this->createQueryBuilder('a')
|
|
->select('COUNT(a.id)')
|
|
->where('a.clinicId = :clinicId')
|
|
->setParameter('clinicId', $clinicId)
|
|
->getQuery()
|
|
->getSingleScalarResult();
|
|
}
|
|
|
|
/**
|
|
* آدرسهای قابلانتخاب در یک context. مطب شخصی فقط آدرسهای شخصی خود پزشک را
|
|
* میبیند و کلینیک فقط آدرسهای خودش — این دو هرگز union نمیشوند.
|
|
*
|
|
* @return DoctorAddress[]
|
|
*/
|
|
public function findForContext(Doctor $doctor, ?int $clinicId): array
|
|
{
|
|
$qb = $this->createQueryBuilder('a');
|
|
|
|
if ($clinicId === null) {
|
|
$qb->where('a.doctor = :doctor')
|
|
->andWhere('a.type = :personal')
|
|
->setParameter('doctor', $doctor)
|
|
->setParameter('personal', DoctorAddress::TYPE_PERSONAL);
|
|
} else {
|
|
$qb->where('a.clinicId = :clinicId')
|
|
->andWhere('a.type = :clinic')
|
|
->setParameter('clinicId', $clinicId)
|
|
->setParameter('clinic', DoctorAddress::TYPE_CLINIC);
|
|
}
|
|
|
|
return $qb->orderBy('a.id', 'ASC')->getQuery()->getResult();
|
|
}
|
|
|
|
/** @deprecated آدرسهای دو محیط را union میکند؛ از findForContext() استفاده کن. */
|
|
public function findAvailableForDoctor(Doctor $doctor, array $clinicIds): array
|
|
{
|
|
$qb = $this->createQueryBuilder('a');
|
|
$qb->where(
|
|
$qb->expr()->orX(
|
|
$qb->expr()->andX(
|
|
$qb->expr()->eq('a.doctor', ':doctor'),
|
|
$qb->expr()->eq('a.type', ':personal')
|
|
),
|
|
$qb->expr()->andX(
|
|
$qb->expr()->in('a.clinicId', ':clinicIds'),
|
|
$qb->expr()->eq('a.type', ':clinic')
|
|
)
|
|
)
|
|
)
|
|
->setParameter('doctor', $doctor)
|
|
->setParameter('personal', DoctorAddress::TYPE_PERSONAL)
|
|
->setParameter('clinicIds', empty($clinicIds) ? [0] : $clinicIds)
|
|
->setParameter('clinic', DoctorAddress::TYPE_CLINIC);
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
}
|