feat(doctors): enhance doctor listing with bookable sorting and filtering, add JSON_EXTRACT DQL function
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Doctor\Repository;
|
||||
|
||||
use App\Appointment\Entity\WeeklySchedule;
|
||||
use App\Auth\Entity\User;
|
||||
use App\Clinic\Entity\Clinic;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
@@ -88,13 +89,31 @@ class DoctorRepository extends ServiceEntityRepository
|
||||
if (!empty($filters['name'])) {
|
||||
$qb->andWhere('d.name LIKE :name')->setParameter('name', '%' . $filters['name'] . '%');
|
||||
}
|
||||
// Public list shows only doctors with appointment enabled unless the
|
||||
// caller explicitly asks otherwise (e.g. admin passing active=0).
|
||||
$active = isset($filters['active']) ? (bool) $filters['active'] : true;
|
||||
$qb->andWhere('d.activeDoctorAppointment = :active')
|
||||
->setParameter('active', $active);
|
||||
// "دارای نوبت" = appointment flag on AND a weekly schedule exists with
|
||||
// online booking not disabled AND at least one active session — same
|
||||
// definition as the `active` field in Doctor::toListArray(), so
|
||||
// filter/sort match what the doctor card shows.
|
||||
$bookable = fn(string $alias): string => sprintf(
|
||||
'd.activeDoctorAppointment = true AND EXISTS(SELECT %1$s.id FROM %2$s %1$s WHERE %1$s.doctor = d'
|
||||
. ' AND (JSON_EXTRACT(%1$s.setting, \'$.meta.online_booking_enabled\') IS NULL OR JSON_EXTRACT(%1$s.setting, \'$.meta.online_booking_enabled\') != \'false\')'
|
||||
. ' AND JSON_CONTAINS(JSON_EXTRACT(%1$s.setting, \'$**.sessions[*].active\'), \'true\') = 1)',
|
||||
$alias,
|
||||
WeeklySchedule::class
|
||||
);
|
||||
|
||||
$qb->orderBy('d.doctorRate', $sort);
|
||||
if (isset($filters['active'])) {
|
||||
if ((bool) $filters['active']) {
|
||||
$qb->andWhere($bookable('wsf'));
|
||||
} else {
|
||||
// Legacy admin escape hatch: active=0 → flag explicitly off.
|
||||
$qb->andWhere('d.activeDoctorAppointment = false');
|
||||
}
|
||||
}
|
||||
|
||||
// Bookable doctors always rank above non-bookable ones.
|
||||
$qb->addSelect('(CASE WHEN ' . $bookable('wss') . ' THEN 1 ELSE 0 END) AS HIDDEN bookableRank')
|
||||
->orderBy('bookableRank', 'DESC')
|
||||
->addOrderBy('d.doctorRate', $sort);
|
||||
|
||||
$total = (new Paginator($qb))->count();
|
||||
$results = $qb->setFirstResult(($page - 1) * $limit)
|
||||
|
||||
Reference in New Issue
Block a user