feat(doctor): update schedule fields in doctor API responses to reflect actual availability
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Doctor\Entity;
|
||||
|
||||
use App\Appointment\Entity\WeeklySchedule;
|
||||
use App\Auth\Entity\User;
|
||||
use App\DoctorService\Entity\DoctorService;
|
||||
use App\Location\Entity\City;
|
||||
@@ -167,6 +168,78 @@ class Doctor
|
||||
|
||||
private function touch(): void { $this->updatedAt = time(); }
|
||||
|
||||
private const DAY_NAMES = ['شنبه', 'یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه'];
|
||||
|
||||
private function computeScheduleFields(?WeeklySchedule $schedule): array
|
||||
{
|
||||
if ($schedule === null) {
|
||||
return ['free_turn' => 'نوبت آزادی موجود نیست', 'hours_of_work' => 'برنامه کاری تنظیم نشده', 'has_schedule' => false];
|
||||
}
|
||||
|
||||
$setting = $schedule->getSetting();
|
||||
|
||||
// استخراج ساعتهای هر روز — key: dayIdx، value: رشته ساعتها یا null
|
||||
$dayTimes = [];
|
||||
for ($i = 0; $i < 7; $i++) {
|
||||
$activeSessions = array_values(array_filter(
|
||||
$setting[$i]['sessions'] ?? [],
|
||||
fn($s) => ($s['active'] ?? false) && !empty($s['start_time'])
|
||||
));
|
||||
$dayTimes[$i] = empty($activeSessions)
|
||||
? null
|
||||
: implode(' و ', array_map(fn($s) => $s['start_time'] . '–' . $s['end_time'], $activeSessions));
|
||||
}
|
||||
|
||||
$hasAnyDay = array_filter($dayTimes) !== [];
|
||||
if (!$hasAnyDay) {
|
||||
return ['free_turn' => 'نوبت آزادی موجود نیست', 'hours_of_work' => 'برنامه کاری تنظیم نشده', 'has_schedule' => false];
|
||||
}
|
||||
|
||||
// گروهبندی روزهای متوالی با ساعت یکسان
|
||||
// مثال: شنبه–پنجشنبه ۹–۱۳ و ۱۴–۱۸ | جمعه تعطیل
|
||||
$groups = [];
|
||||
$current = ['start' => 0, 'times' => $dayTimes[0]];
|
||||
for ($i = 1; $i < 7; $i++) {
|
||||
if ($dayTimes[$i] === $current['times']) {
|
||||
continue; // ادامه همان گروه
|
||||
}
|
||||
if ($current['times'] !== null) {
|
||||
$groups[] = ['start' => $current['start'], 'end' => $i - 1, 'times' => $current['times']];
|
||||
}
|
||||
$current = ['start' => $i, 'times' => $dayTimes[$i]];
|
||||
}
|
||||
if ($current['times'] !== null) {
|
||||
$groups[] = ['start' => $current['start'], 'end' => 6, 'times' => $current['times']];
|
||||
}
|
||||
|
||||
$parts = [];
|
||||
foreach ($groups as $g) {
|
||||
$parts[] = $g['start'] === $g['end']
|
||||
? self::DAY_NAMES[$g['start']]
|
||||
: self::DAY_NAMES[$g['start']] . ' تا ' . self::DAY_NAMES[$g['end']];
|
||||
}
|
||||
|
||||
// نزدیکترین روز کاری — PHP date('w'): 0=Sun,6=Sat → ایندکس ایرانی: 0=Sat,...,6=Fri
|
||||
$phpDay = (int) date('w');
|
||||
$iranDay = $phpDay === 0 ? 1 : ($phpDay === 6 ? 0 : $phpDay + 1);
|
||||
|
||||
$freeTurn = null;
|
||||
for ($i = 0; $i < 7; $i++) {
|
||||
$idx = ($iranDay + $i) % 7;
|
||||
if ($dayTimes[$idx] !== null) {
|
||||
$firstTime = explode(' و ', $dayTimes[$idx])[0];
|
||||
$freeTurn = self::DAY_NAMES[$idx] . ' ' . $firstTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'free_turn' => $freeTurn ?? 'نوبت آزادی موجود نیست',
|
||||
'hours_of_work' => implode(' | ', $parts),
|
||||
'has_schedule' => true,
|
||||
];
|
||||
}
|
||||
|
||||
public function getExperience(): int
|
||||
{
|
||||
if ($this->activityTime === null) {
|
||||
@@ -175,8 +248,9 @@ class Doctor
|
||||
return max(0, (int)((time() - $this->activityTime) / (365.25 * 24 * 3600)));
|
||||
}
|
||||
|
||||
public function toListArray(): array
|
||||
public function toListArray(?WeeklySchedule $schedule = null): array
|
||||
{
|
||||
$sf = $this->computeScheduleFields($schedule);
|
||||
return [
|
||||
'id' => (string) $this->id,
|
||||
'uuid' => $this->uuid,
|
||||
@@ -189,14 +263,15 @@ class Doctor
|
||||
], $this->specialties->toArray()),
|
||||
'satisfaction' => (string) $this->doctorRatePercentage,
|
||||
'point' => (string) $this->doctorRate,
|
||||
'free_turn' => 'نوبت آزادی موجود نیست',
|
||||
'hours_of_work' => 'برنامه کاری تنظیم نشده',
|
||||
'active' => $this->activeDoctorAppointment,
|
||||
'free_turn' => $sf['free_turn'],
|
||||
'hours_of_work' => $sf['hours_of_work'],
|
||||
'active' => $this->activeDoctorAppointment && $sf['has_schedule'],
|
||||
];
|
||||
}
|
||||
|
||||
public function toDetailArray(): array
|
||||
public function toDetailArray(?WeeklySchedule $schedule = null): array
|
||||
{
|
||||
$sf = $this->computeScheduleFields($schedule);
|
||||
return [
|
||||
'id' => (string) $this->id,
|
||||
'uuid' => $this->uuid,
|
||||
@@ -211,15 +286,15 @@ class Doctor
|
||||
'uuid' => $s->getUuid(), 'id' => (string) $s->getId(), 'name' => $s->getName(),
|
||||
'parent_id' => $s->getParent()?->getId() !== null ? (string) $s->getParent()->getId() : null,
|
||||
], $this->specialties->toArray()),
|
||||
'active' => $this->activeDoctorAppointment,
|
||||
'active' => $this->activeDoctorAppointment && $sf['has_schedule'],
|
||||
'img' => $this->images ?? [],
|
||||
'expertise' => array_map(fn(DoctorService $ds) => [
|
||||
'uuid' => $ds->getUuid(), 'id' => (string) $ds->getId(), 'name' => $ds->getName(),
|
||||
], $this->services->toArray()),
|
||||
'satisfaction' => (string) $this->doctorRatePercentage,
|
||||
'point' => (string) $this->doctorRate,
|
||||
'free_turn' => 'نوبت آزادی موجود نیست',
|
||||
'hours_of_work' => 'برنامه کاری تنظیم نشده',
|
||||
'free_turn' => $sf['free_turn'],
|
||||
'hours_of_work' => $sf['hours_of_work'],
|
||||
'address' => array_map(fn(DoctorAddress $a) => $a->toArray(), $this->addresses->toArray()),
|
||||
'average_rate' => ['total_rates' => null],
|
||||
'state' => array_map(fn(Province $p) => [
|
||||
|
||||
Reference in New Issue
Block a user