Merge branch 'dev' into main
# Conflicts: # docs/api/doctor.md
This commit is contained in:
@@ -62,6 +62,32 @@ class DoctorAddressRepository extends ServiceEntityRepository
|
||||
->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');
|
||||
|
||||
@@ -138,6 +138,88 @@ class DoctorRepository extends ServiceEntityRepository
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
/**
|
||||
* شهر/استان دستهای پزشکان برای پاسخ لیست — دو کوئری ثابت، نه یکی بهازای هر پزشک.
|
||||
*
|
||||
* همان قاعدهای که فیلتر city_id/state_id در findWithFilters اعمال میکند اینجا هم
|
||||
* برقرار است: اول آدرس شخصی خود پزشک، و اگر نداشت آدرس کلینیکی که عضو آن است
|
||||
* (آدرس کلینیک ردیفی از DoctorAddress با doctor IS NULL و clinicId پرشده است).
|
||||
* بدون این fallback، پزشکی که فقط از طریق کلینیک مکان دارد در فیلتر city_id
|
||||
* میآمد ولی در پاسخ شهرش خالی بود.
|
||||
*
|
||||
* @param Doctor[] $doctors
|
||||
* @return array<int, array{city: ?array, province: ?array}>
|
||||
*/
|
||||
public function findLocationsByDoctors(array $doctors): array
|
||||
{
|
||||
$ids = array_values(array_filter(array_map(fn(Doctor $d) => $d->getId(), $doctors)));
|
||||
if (!$ids) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$locationFields = [
|
||||
'c.id AS cityId', 'c.uuid AS cityUuid', 'c.name AS cityName',
|
||||
'p.id AS provinceId', 'p.uuid AS provinceUuid', 'p.name AS provinceName',
|
||||
];
|
||||
|
||||
$ownRows = $this->getEntityManager()->createQueryBuilder()
|
||||
->select('IDENTITY(da.doctor) AS doctorId', ...$locationFields)
|
||||
->from(DoctorAddress::class, 'da')
|
||||
->join('da.city', 'c')
|
||||
->leftJoin('da.province', 'p')
|
||||
->where('da.doctor IN (:ids)')
|
||||
->setParameter('ids', $ids)
|
||||
->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$map = $this->indexLocationRows($ownRows, []);
|
||||
|
||||
$missing = array_values(array_diff($ids, array_keys($map)));
|
||||
if ($missing) {
|
||||
$clinicRows = $this->getEntityManager()->createQueryBuilder()
|
||||
->select('cd.id AS doctorId', ...$locationFields)
|
||||
->from(Clinic::class, 'cl')
|
||||
->join('cl.doctors', 'cd')
|
||||
->join(DoctorAddress::class, 'ca', Join::WITH, 'ca.clinicId = cl.id AND ca.doctor IS NULL')
|
||||
->join('ca.city', 'c')
|
||||
->leftJoin('ca.province', 'p')
|
||||
->where('cd.id IN (:ids)')
|
||||
->setParameter('ids', $missing)
|
||||
->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$map = $this->indexLocationRows($clinicRows, $map);
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/** اولین مکانِ هر پزشک برنده است — پزشک چند-مطبی یک شهر اصلی میگیرد. */
|
||||
private function indexLocationRows(array $rows, array $map): array
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
$doctorId = (int) $row['doctorId'];
|
||||
if (isset($map[$doctorId])) {
|
||||
continue;
|
||||
}
|
||||
$map[$doctorId] = [
|
||||
'city' => [
|
||||
'uuid' => $row['cityUuid'],
|
||||
'id' => (string) $row['cityId'],
|
||||
'name' => $row['cityName'],
|
||||
'parent' => $row['provinceId'] !== null ? (string) $row['provinceId'] : null,
|
||||
],
|
||||
'province' => $row['provinceId'] !== null ? [
|
||||
'uuid' => $row['provinceUuid'],
|
||||
'id' => (string) $row['provinceId'],
|
||||
'name' => $row['provinceName'],
|
||||
] : null,
|
||||
];
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
private function doctorIdsViaClinicLocation(string $field, int $locationId): array
|
||||
{
|
||||
$column = $field === 'city' ? 'ca.city' : 'ca.province';
|
||||
|
||||
Reference in New Issue
Block a user