fix: resolve calendar crash and enhance appointment management
- Fixed calendar crash due to invalid array length in PersianCalendar.tsx by changing locale to 'en-u-ca-persian'. - Added Persian weekday display in DateNavigator with appropriate styling and logic. - Updated empty slot message to indicate when a day is off. - Made patient name a required field in appointment creation and implemented find-or-create logic for patients in both admin and user endpoints. - Corrected mobile number display to show the patient's number instead of the doctor's in appointment listings. - Ensured booked appointments are displayed correctly in the schedule view. - Removed unnecessary operations column from the appointments table view.
This commit is contained in:
@@ -24,6 +24,63 @@ class MyAppointmentsController extends BaseController
|
||||
private readonly DoctorSecretaryRepository $secretaryRepo,
|
||||
) {}
|
||||
|
||||
#[Route('/api/v1/my/appointment', methods: ['POST'])]
|
||||
#[IsGranted('IS_AUTHENTICATED_FULLY')]
|
||||
public function createAppointment(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$roles = $user->getRoles();
|
||||
$allowed = ['ROLE_DOCTOR', 'ROLE_CLINIC', 'ROLE_SECRETARY', 'ROLE_ADMIN'];
|
||||
if (!array_intersect($allowed, $roles)) {
|
||||
return $this->error('FORBIDDEN', 'دسترسی ندارید', 403);
|
||||
}
|
||||
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$doctorUuid = trim($data['doctor_uuid'] ?? '');
|
||||
$slotStart = (int) ($data['slot_start'] ?? 0);
|
||||
$slotEnd = (int) ($data['slot_end'] ?? 0);
|
||||
$mobile = trim($data['patient_mobile'] ?? '');
|
||||
$patientName = trim($data['patient_name'] ?? '');
|
||||
|
||||
if (empty($doctorUuid) || $slotStart <= 0 || $slotEnd <= $slotStart || empty($mobile) || empty($patientName)) {
|
||||
return $this->error('VALIDATION', 'همه فیلدها الزامی است', 422);
|
||||
}
|
||||
|
||||
$doctor = $this->doctorRepo->findByUuid($doctorUuid);
|
||||
if (!$doctor) return $this->error('DOCTOR_NOT_FOUND', 'پزشک یافت نشد', 404);
|
||||
|
||||
$patient = $this->em->getRepository(User::class)->findOneBy(['mobileNumber' => $mobile]);
|
||||
if (!$patient) {
|
||||
$patient = new User($mobile);
|
||||
$patient->setRealName($patientName);
|
||||
$patient->setRoles(['ROLE_USER']);
|
||||
$this->em->persist($patient);
|
||||
}
|
||||
|
||||
$conflict = $this->em->createQueryBuilder()
|
||||
->select('COUNT(a.id)')->from(Appointment::class, 'a')
|
||||
->where('a.doctor = :doctor')
|
||||
->andWhere('a.slotStart < :end AND a.slotEnd > :start')
|
||||
->andWhere("a.status NOT IN ('cancelled_by_doctor','cancelled_by_user','cancelled_by_admin','auto_cancel_unpaid')")
|
||||
->setParameter('doctor', $doctor)
|
||||
->setParameter('start', $slotStart)
|
||||
->setParameter('end', $slotEnd)
|
||||
->getQuery()->getSingleScalarResult();
|
||||
|
||||
if ($conflict > 0) return $this->error('SLOT_TAKEN', 'این نوبت قبلاً رزرو شده است', 409);
|
||||
|
||||
$appointment = new Appointment($doctor, $patient, $slotStart, $slotEnd);
|
||||
if (!empty($data['note'])) $appointment->setNote($data['note']);
|
||||
$this->em->persist($appointment);
|
||||
$this->em->flush();
|
||||
|
||||
return $this->success([
|
||||
'uuid' => $appointment->getUuid(),
|
||||
'slot_start' => $slotStart,
|
||||
'slot_end' => $slotEnd,
|
||||
'status' => $appointment->getStatus(),
|
||||
], 201);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/my/appointments', methods: ['GET'])]
|
||||
#[IsGranted('IS_AUTHENTICATED_FULLY')]
|
||||
public function myAppointments(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
|
||||
Reference in New Issue
Block a user