fix: update active doctor appointment logic to use online_booking_enabled field

This commit is contained in:
hamed
2026-06-22 09:47:06 +03:30
parent 447ffc8862
commit 8ed119e12a
2 changed files with 220 additions and 45 deletions
+3 -1
View File
@@ -162,7 +162,9 @@ Get doctor detail for clinic owner — only doctors who are members of the authe
|-------|---------------------|-----------------|
| `free_turn` | نزدیک‌ترین روز/ساعت کاری از امروز (مثلاً «دوشنبه ۹:۰۰–۱۳:۰۰») | «نوبت آزادی موجود نیست» |
| `hours_of_work` | خلاصه ساعت‌های روزهای فعال با `\|` جداشده | «برنامه کاری تنظیم نشده» |
| `active` | `activeDoctorAppointment && has_active_sessions` | `false` — نوبت‌دهی غیرفعال |
| `active` | `online_booking_enabled && has_active_sessions` | `false` — نوبت‌دهی غیرفعال |
> **نوبت‌دهی آنلاین غیرفعال:** منبعِ فعال/غیرفعال بودن نوبت‌دهی آنلاین، فیلد `meta.online_booking_enabled` در `WeeklySchedule` پزشک است. اگر `false` باشد، صرف‌نظر از سشن‌های برنامه‌ی هفتگی، `free_turn` همیشه `"نوبت‌دهی آنلاین غیرفعال است"` و `active` برابر `false` برمی‌گردد؛ `hours_of_work` در صورت وجود برنامه حفظ می‌شود. چنین پزشکی در لیست عمومی `GET /api/v1/doctors` (پیش‌فرض `active=true`) نمایش داده نمی‌شود، ولی صفحه‌ی تکی `GET /api/v1/doctor/{slug}` همچنان قابل دسترسی است.
---
+217 -44
View File
@@ -131,51 +131,214 @@ class Doctor
$this->addresses = new ArrayCollection();
}
public function getId(): ?int { return $this->id; }
public function getUuid(): string { return $this->uuid; }
public function getUser(): User { return $this->user; }
public function getName(): string { return $this->name; }
public function getGender(): ?string { return $this->gender; }
public function getMedicalSystemCode(): ?string { return $this->medicalSystemCode; }
public function getMobileNumber(): ?string { return $this->mobileNumber; }
public function getActivityTime(): ?int { return $this->activityTime; }
public function getDegree(): ?string { return $this->degree; }
public function getInfo(): ?string { return $this->info; }
public function getImages(): ?array { return $this->images; }
public function getSocialMedia(): ?array { return $this->socialMedia; }
public function getDoctorRate(): float { return $this->doctorRate; }
public function getDoctorRatePercentage(): float { return $this->doctorRatePercentage; }
public function isActiveDoctorAppointment(): bool { return $this->activeDoctorAppointment; }
public function getRepresentationId(): ?int { return $this->representationId; }
public function getNotificationMobile(): ?string { return $this->notificationMobile; }
public function getCreatedAt(): int { return $this->createdAt; }
public function getUpdatedAt(): int { return $this->updatedAt; }
public function getSpecialties(): Collection { return $this->specialties; }
public function getServices(): Collection { return $this->services; }
public function getProvinces(): Collection { return $this->provinces; }
public function getCities(): Collection { return $this->cities; }
public function getAddresses(): Collection { return $this->addresses; }
public function getId(): ?int
{
return $this->id;
}
public function getUuid(): string
{
return $this->uuid;
}
public function getUser(): User
{
return $this->user;
}
public function getName(): string
{
return $this->name;
}
public function getGender(): ?string
{
return $this->gender;
}
public function getMedicalSystemCode(): ?string
{
return $this->medicalSystemCode;
}
public function getMobileNumber(): ?string
{
return $this->mobileNumber;
}
public function getActivityTime(): ?int
{
return $this->activityTime;
}
public function getDegree(): ?string
{
return $this->degree;
}
public function getInfo(): ?string
{
return $this->info;
}
public function getImages(): ?array
{
return $this->images;
}
public function getSocialMedia(): ?array
{
return $this->socialMedia;
}
public function getDoctorRate(): float
{
return $this->doctorRate;
}
public function getDoctorRatePercentage(): float
{
return $this->doctorRatePercentage;
}
public function isActiveDoctorAppointment(): bool
{
return $this->activeDoctorAppointment;
}
public function getRepresentationId(): ?int
{
return $this->representationId;
}
public function getNotificationMobile(): ?string
{
return $this->notificationMobile;
}
public function getCreatedAt(): int
{
return $this->createdAt;
}
public function getUpdatedAt(): int
{
return $this->updatedAt;
}
public function getSpecialties(): Collection
{
return $this->specialties;
}
public function getServices(): Collection
{
return $this->services;
}
public function getProvinces(): Collection
{
return $this->provinces;
}
public function getCities(): Collection
{
return $this->cities;
}
public function getAddresses(): Collection
{
return $this->addresses;
}
public function setName(string $v): self { $this->name = $v; return $this; }
public function setGender(?string $v): self { $this->gender = $v; $this->touch(); return $this; }
public function setMedicalSystemCode(?string $v): self { $this->medicalSystemCode = $v; $this->touch(); return $this; }
public function setMobileNumber(?string $v): self { $this->mobileNumber = $v; $this->touch(); return $this; }
public function setActivityTime(?int $v): self { $this->activityTime = $v; $this->touch(); return $this; }
public function setDegree(?string $v): self { $this->degree = $v; $this->touch(); return $this; }
public function setInfo(?string $v): self { $this->info = $v; $this->touch(); return $this; }
public function setImages(?array $v): self { $this->images = $v; $this->touch(); return $this; }
public function setSocialMedia(?array $v): self { $this->socialMedia = $v; $this->touch(); return $this; }
public function setDoctorRate(float $v): self { $this->doctorRate = $v; $this->touch(); return $this; }
public function setDoctorRatePercentage(float $v): self { $this->doctorRatePercentage = $v; $this->touch(); return $this; }
public function setActiveDoctorAppointment(bool $v): self { $this->activeDoctorAppointment = $v; $this->touch(); return $this; }
public function setRepresentationId(?int $v): self { $this->representationId = $v; $this->touch(); return $this; }
public function setNotificationMobile(?string $v): self { $this->notificationMobile = $v; $this->touch(); return $this; }
public function setName(string $v): self
{
$this->name = $v;
return $this;
}
public function setGender(?string $v): self
{
$this->gender = $v;
$this->touch();
return $this;
}
public function setMedicalSystemCode(?string $v): self
{
$this->medicalSystemCode = $v;
$this->touch();
return $this;
}
public function setMobileNumber(?string $v): self
{
$this->mobileNumber = $v;
$this->touch();
return $this;
}
public function setActivityTime(?int $v): self
{
$this->activityTime = $v;
$this->touch();
return $this;
}
public function setDegree(?string $v): self
{
$this->degree = $v;
$this->touch();
return $this;
}
public function setInfo(?string $v): self
{
$this->info = $v;
$this->touch();
return $this;
}
public function setImages(?array $v): self
{
$this->images = $v;
$this->touch();
return $this;
}
public function setSocialMedia(?array $v): self
{
$this->socialMedia = $v;
$this->touch();
return $this;
}
public function setDoctorRate(float $v): self
{
$this->doctorRate = $v;
$this->touch();
return $this;
}
public function setDoctorRatePercentage(float $v): self
{
$this->doctorRatePercentage = $v;
$this->touch();
return $this;
}
public function setActiveDoctorAppointment(bool $v): self
{
$this->activeDoctorAppointment = $v;
$this->touch();
return $this;
}
public function setRepresentationId(?int $v): self
{
$this->representationId = $v;
$this->touch();
return $this;
}
public function setNotificationMobile(?string $v): self
{
$this->notificationMobile = $v;
$this->touch();
return $this;
}
private function touch(): void { $this->updatedAt = time(); }
private function touch(): void
{
$this->updatedAt = time();
}
private const DAY_NAMES = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه'];
private const APPOINTMENT_DISABLED_LABEL = 'نوبت‌دهی آنلاین غیرفعال است';
private function computeScheduleFields(?WeeklySchedule $schedule): array
{
$parts = $this->computeScheduleParts($schedule);
// Online booking enabled flag lives in the weekly schedule meta.
// When disabled, free_turn reflects that while hours_of_work is kept.
if ($schedule !== null && !$schedule->getMeta()['online_booking_enabled']) {
return [
'free_turn' => self::APPOINTMENT_DISABLED_LABEL,
'hours_of_work' => $parts['hours_of_work'],
'has_schedule' => false,
];
}
return $parts;
}
private function computeScheduleParts(?WeeklySchedule $schedule): array
{
if ($schedule === null) {
return ['free_turn' => 'نوبت آزادی موجود نیست', 'hours_of_work' => 'برنامه کاری تنظیم نشده', 'has_schedule' => false];
@@ -264,7 +427,9 @@ class Doctor
'degree' => $this->degree,
'img' => $this->images ?? [],
'specialties' => array_map(fn(Specialty $s) => [
'uuid' => $s->getUuid(), 'id' => (string) $s->getId(), 'name' => $s->getName(),
'uuid' => $s->getUuid(),
'id' => (string) $s->getId(),
'name' => $s->getName(),
], $this->specialties->toArray()),
'satisfaction' => (string) $this->doctorRatePercentage,
'point' => (string) $this->doctorRate,
@@ -288,14 +453,18 @@ class Doctor
'detail' => $this->info,
'degree' => $this->degree,
'specialties' => array_map(fn(Specialty $s) => [
'uuid' => $s->getUuid(), 'id' => (string) $s->getId(), 'name' => $s->getName(),
'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 && $sf['has_schedule'],
'img' => $this->images ?? [],
'social_media' => $this->socialMedia,
'expertise' => array_map(fn(DoctorService $ds) => [
'uuid' => $ds->getUuid(), 'id' => (string) $ds->getId(), 'name' => $ds->getName(),
'uuid' => $ds->getUuid(),
'id' => (string) $ds->getId(),
'name' => $ds->getName(),
], $this->services->toArray()),
'satisfaction' => (string) $this->doctorRatePercentage,
'point' => (string) $this->doctorRate,
@@ -304,10 +473,14 @@ class Doctor
'address' => array_map(fn(DoctorAddress $a) => $a->toArray(), $this->addresses->toArray()),
'average_rate' => ['total_rates' => null],
'state' => array_map(fn(Province $p) => [
'uuid' => $p->getUuid(), 'id' => (string) $p->getId(), 'name' => $p->getName(),
'uuid' => $p->getUuid(),
'id' => (string) $p->getId(),
'name' => $p->getName(),
], $this->provinces->toArray()),
'city' => array_map(fn(City $c) => [
'uuid' => $c->getUuid(), 'id' => (string) $c->getId(), 'name' => $c->getName(),
'uuid' => $c->getUuid(),
'id' => (string) $c->getId(),
'name' => $c->getName(),
'parent' => $c->getProvince() !== null ? (string) $c->getProvince()->getId() : null,
], $this->cities->toArray()),
];