Files
clinicpro/src/Appointment/Repository/WeeklyScheduleRepository.php
T
hamed f1258d206d feat(migrations): add clinic_id context to weekly_schedules, date_overrides, and holidays
- 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.
2026-07-18 13:32:56 +03:30

89 lines
3.0 KiB
PHP

<?php
namespace App\Appointment\Repository;
use App\Appointment\Entity\WeeklySchedule;
use App\Clinic\Entity\Clinic;
use App\Doctor\Entity\Doctor;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class WeeklyScheduleRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, WeeklySchedule::class);
}
/**
* برنامهٔ یک context مشخص. $clinic === null یعنی مطب شخصی.
*
* چون MySQL در unique index مقادیر NULL را متمایز می‌شمارد، یکتایی رکورد شخصی
* را همین متد تضمین می‌کند: قبل از ساخت برنامهٔ جدید همیشه صدا زده می‌شود.
*/
public function findByDoctorAndClinic(Doctor $doctor, ?Clinic $clinic): ?WeeklySchedule
{
$qb = $this->createQueryBuilder('ws')
->where('ws.doctor = :doctor')
->setParameter('doctor', $doctor);
if ($clinic === null) {
$qb->andWhere('ws.clinic IS NULL');
} else {
$qb->andWhere('ws.clinic = :clinic')->setParameter('clinic', $clinic);
}
return $qb->setMaxResults(1)->getQuery()->getOneOrNullResult();
}
/** همهٔ برنامه‌های پزشک در همهٔ contextها (شخصی + هر کلینیک). @return WeeklySchedule[] */
public function findAllByDoctor(Doctor $doctor): array
{
return $this->createQueryBuilder('ws')
->where('ws.doctor = :doctor')
->setParameter('doctor', $doctor)
->orderBy('ws.clinic', 'ASC')
->getQuery()
->getResult();
}
/**
* @deprecated برنامهٔ context شخصی را برمی‌گرداند. برای کد جدید از
* findByDoctorAndClinic() استفاده کن تا context صریح باشد.
*/
public function findByDoctor(Doctor $doctor): ?WeeklySchedule
{
return $this->findByDoctorAndClinic($doctor, null);
}
/** @param Doctor[] $doctors @return WeeklySchedule[] */
public function findByDoctors(array $doctors): array
{
if (empty($doctors)) {
return [];
}
return $this->createQueryBuilder('ws')
->where('ws.doctor IN (:doctors)')
->setParameter('doctors', $doctors)
->getQuery()
->getResult();
}
public function findByUuid(string $uuid): ?WeeklySchedule
{
return $this->findOneBy(['uuid' => $uuid]);
}
public function save(WeeklySchedule $entity, bool $flush = true): void
{
$this->getEntityManager()->persist($entity);
if ($flush) $this->getEntityManager()->flush();
}
public function remove(WeeklySchedule $entity, bool $flush = true): void
{
$this->getEntityManager()->remove($entity);
if ($flush) $this->getEntityManager()->flush();
}
}