feat: Enhance appointment management by decoupling online booking toggle for admin context
- Introduced management mode for appointment slots, allowing doctors, admins, and clinic managers to view and book slots regardless of the online booking status. - Updated SlotCalculatorService to accept a management context parameter, bypassing online booking restrictions. - Modified appointment-related endpoints to handle management context and ensure proper authorization checks. - Added tests to verify that management users can access slots even when online booking is disabled, while public users are still restricted. - Improved documentation for API endpoints to reflect new management parameters and behaviors.
This commit is contained in:
@@ -78,6 +78,67 @@ class AppointmentAccessChecker
|
||||
return $this->secretaryCan($appointment, $user, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* آیا این کاربر میتواند در محیطِ (پزشک + کلینیک) نوبت مدیریت/ثبت کند — بدون آنکه
|
||||
* هنوز نوبتی وجود داشته باشد. برای اندپوینتهای اسلات که عمومیاند ولی وقتی از پنل
|
||||
* (با management=1) صدا زده میشوند باید توگلِ نوبتدهی آنلاین را دور بزنند.
|
||||
*
|
||||
* منطق همان can() است اما روی محیط، نه روی یک Appointment مشخص.
|
||||
*/
|
||||
public function canManageContext(User $user, \App\Doctor\Entity\Doctor $doctor, ?\App\Clinic\Entity\Clinic $clinic): bool
|
||||
{
|
||||
if ($user->hasRole('ROLE_ADMIN')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($doctor->getUser()->getId() === $user->getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($clinic !== null && $this->clinicPermissions->can($user, $clinic, self::RESOURCE, self::ACTION_UPDATE_STATUS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->secretaryCanContext($user, $doctor, $clinic);
|
||||
}
|
||||
|
||||
/**
|
||||
* منشی در محیطِ فعالِ خودش، اما روی محیط (پزشک/کلینیک) نه یک نوبت مشخص.
|
||||
* قرینهٔ secretaryCan() است.
|
||||
*/
|
||||
private function secretaryCanContext(User $user, \App\Doctor\Entity\Doctor $doctor, ?\App\Clinic\Entity\Clinic $clinic): bool
|
||||
{
|
||||
$dbUuid = $this->contextRepo->findByUser($user)?->getDbUuid();
|
||||
if ($dbUuid === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ctxClinic = $this->clinicRepo->findByUuid($dbUuid);
|
||||
if ($ctxClinic !== null) {
|
||||
if ($clinic === null || $ctxClinic->getId() !== $clinic->getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$relation = $this->secretaryRepo->findActiveClinicRow($user, $ctxClinic, $doctor);
|
||||
|
||||
return $relation !== null && $this->secretaryPermissions->can($relation, self::RESOURCE, self::ACTION_UPDATE_STATUS);
|
||||
}
|
||||
|
||||
// محیطِ مطب شخصی: نوبت هم باید در همان مطب شخصی باشد (clinic == null).
|
||||
if ($clinic !== null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ctxDoctor = $this->doctorRepo->findByUuid($dbUuid);
|
||||
if ($ctxDoctor === null || $ctxDoctor->getId() !== $doctor->getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$relation = $this->secretaryRepo->findActiveBySecretaryForDoctor($user, $doctor);
|
||||
|
||||
return $relation !== null && $this->secretaryPermissions->can($relation, self::RESOURCE, self::ACTION_UPDATE_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* کلینیکی که این کاربر در آن اجازهٔ دیدن نوبتهای این پزشک را دارد، یا null.
|
||||
* برای لیستهایی که باید به یک محیط محدود شوند (نه تکنوبت).
|
||||
|
||||
Reference in New Issue
Block a user