query->get('page', 1)); $limit = min(100, max(1, (int) $request->query->get('limit', 15))); $search = trim((string) $request->query->get('search', '')); $status = trim((string) $request->query->get('status', '')); $date = trim((string) $request->query->get('date', '')); $qb = $this->em->createQueryBuilder() ->select( 'a.uuid, a.slotStart, a.slotEnd, a.status, a.createdAt', 'd.uuid as doctor_uuid, d.name as doctor_name', 'u.mobileNumber as patient_mobile, u.realName as patient_name', 'c.name as clinic_name' ) ->from(Appointment::class, 'a') ->join('a.doctor', 'd') ->join('a.user', 'u') ->leftJoin('App\Clinic\Entity\Clinic', 'c', 'WITH', 'd MEMBER OF c.doctors') ->orderBy('a.slotStart', 'DESC'); $roles = $user->getRoles(); if (in_array('ROLE_ADMIN', $roles, true)) { // Admin voit tout } elseif (in_array('ROLE_CLINIC', $roles, true)) { $clinic = $this->clinicRepo->findByUser($user); if ($clinic === null) { return $this->paginated([], 0, $page, $limit); } $qb->andWhere(':clinic MEMBER OF d.clinics') ->setParameter('clinic', $clinic); } elseif (in_array('ROLE_DOCTOR', $roles, true)) { $doctor = $this->doctorRepo->findByUser($user); if ($doctor === null) { return $this->paginated([], 0, $page, $limit); } $qb->andWhere('a.doctor = :doctor') ->setParameter('doctor', $doctor); } elseif (in_array('ROLE_SECRETARY', $roles, true)) { $rel = $this->secretaryRepo->findActiveBySecretary($user); if ($rel === null) { return $this->paginated([], 0, $page, $limit); } $canView = (bool) ($rel->getPermissions()['resources']['appointments']['view'] ?? false); if (!$canView) { return $this->paginated([], 0, $page, $limit); } $qb->andWhere('a.doctor = :doctor') ->setParameter('doctor', $rel->getDoctor()); } else { return $this->paginated([], 0, $page, $limit); } if ($search !== '') { $qb->andWhere('u.mobileNumber LIKE :s OR d.name LIKE :s OR u.realName LIKE :s') ->setParameter('s', '%' . $search . '%'); } if ($status !== '') { $qb->andWhere('a.status = :status')->setParameter('status', $status); } if ($date !== '') { $dayStart = strtotime($date . ' 00:00:00'); $dayEnd = strtotime($date . ' 23:59:59'); if ($dayStart && $dayEnd) { $qb->andWhere('a.slotStart >= :dayStart AND a.slotStart <= :dayEnd') ->setParameter('dayStart', $dayStart) ->setParameter('dayEnd', $dayEnd); } } $total = (clone $qb)->select('COUNT(a.id)')->getQuery()->getSingleScalarResult(); $rows = $qb->setFirstResult(($page - 1) * $limit)->setMaxResults($limit) ->getQuery()->getArrayResult(); $items = array_map(fn(array $a) => [ 'uuid' => $a['uuid'], 'patient_name' => $a['patient_name'] ?? '', 'patient_mobile' => $a['patient_mobile'], 'doctor_name' => $a['doctor_name'], 'clinic_name' => $a['clinic_name'] ?? null, 'appointment_date' => date('Y-m-d', (int) $a['slotStart']), 'appointment_time' => date('H:i', (int) $a['slotStart']), 'slot_start' => (int) $a['slotStart'], 'status' => $a['status'], 'amount' => 0, 'created_at' => date('c', (int) $a['createdAt']), ], $rows); return $this->paginated($items, (int) $total, $page, $limit); } }