feat: add clinic status management with active/inactive toggle and update related API endpoints

This commit is contained in:
hamed
2026-06-10 21:29:29 +03:30
parent b0d6ecbd96
commit c41d03b5c5
6 changed files with 555 additions and 134 deletions
@@ -428,6 +428,86 @@ class AdminApiController extends BaseController
return $this->success(['uuid' => $doctor->getUuid()], 201);
}
// ── Clinics ───────────────────────────────────────────────────────────────
#[Route('/api/v1/admin/clinics', methods: ['GET'])]
public function clinicsList(Request $request): JsonResponse
{
$page = max(1, (int) $request->query->get('page', 1));
$limit = min(100, max(5, (int) $request->query->get('limit', 15)));
$search = trim((string) $request->query->get('search', ''));
$status = $request->query->get('status', '');
$conn = $this->em->getConnection();
$where = ['1=1'];
$params = [];
if ($search !== '') {
$where[] = '(c.name LIKE :s OR c.telephone LIKE :s)';
$params['s'] = '%' . $search . '%';
}
if ($status !== '') {
$where[] = 'c.is_active = :active';
$params['active'] = $status === '1' ? 1 : 0;
}
$whereStr = implode(' AND ', $where);
$total = (int) $conn->fetchOne(
"SELECT COUNT(*) FROM clinics c WHERE $whereStr",
$params
);
$offset = ($page - 1) * $limit;
$rows = $conn->fetchAllAssociative(
"SELECT c.uuid, c.name, c.telephone, c.clinic_logo, c.is_active, c.created_at,
COUNT(DISTINCT cd.doctor_id) as doctors_count
FROM clinics c
LEFT JOIN clinic_doctors cd ON cd.clinic_id = c.id
WHERE $whereStr
GROUP BY c.id
ORDER BY c.created_at DESC
LIMIT $limit OFFSET $offset",
$params
);
$items = array_map(fn(array $c) => [
'uuid' => $c['uuid'],
'name' => $c['name'],
'phone' => $c['telephone'],
'logo' => $c['clinic_logo'],
'is_active' => (bool) $c['is_active'],
'doctors_count' => (int) $c['doctors_count'],
'created_at' => (int) $c['created_at'],
], $rows);
return $this->paginated($items, $total, $page, $limit);
}
#[Route('/api/v1/admin/clinic/{uuid}/status', methods: ['PATCH'])]
public function toggleClinicStatus(string $uuid): JsonResponse
{
$clinic = $this->em->getRepository(Clinic::class)->findOneBy(['uuid' => $uuid]);
if (!$clinic) return $this->error('CLINIC_NOT_FOUND', 'کلینیک یافت نشد', 404);
$clinic->setIsActive(!$clinic->isActive());
$this->em->flush();
return $this->success(['is_active' => $clinic->isActive()]);
}
#[Route('/api/v1/admin/clinic/{uuid}', methods: ['DELETE'])]
public function deleteClinic(string $uuid): JsonResponse
{
$clinic = $this->em->getRepository(Clinic::class)->findOneBy(['uuid' => $uuid]);
if (!$clinic) return $this->error('CLINIC_NOT_FOUND', 'کلینیک یافت نشد', 404);
$this->em->remove($clinic);
$this->em->flush();
return $this->success(null);
}
// ── Appointments ──────────────────────────────────────────────────────────
#[OA\Get(
+17 -3
View File
@@ -64,6 +64,9 @@ class Clinic
#[ORM\Column(name: 'representation_id', type: 'integer', nullable: true)]
private ?int $representationId = null;
#[ORM\Column(name: 'is_active', type: 'boolean')]
private bool $isActive = true;
#[ORM\Column(name: 'images_clinic', type: 'json', nullable: true)]
private ?array $imagesClinic = null;
@@ -134,6 +137,7 @@ class Clinic
public function getCityId(): ?int { return $this->cityId; }
public function getProvinceId(): ?int { return $this->provinceId; }
public function getRepresentationId(): ?int { return $this->representationId; }
public function isActive(): bool { return $this->isActive; }
public function getImagesClinic(): ?array { return $this->imagesClinic; }
public function getClinicLogo(): ?string { return $this->clinicLogo; }
public function getCreatedAt(): int { return $this->createdAt; }
@@ -154,6 +158,7 @@ class Clinic
public function setCityId(?int $v): self { $this->cityId = $v; $this->touch(); return $this; }
public function setProvinceId(?int $v): self { $this->provinceId = $v; $this->touch(); return $this; }
public function setRepresentationId(?int $v): self { $this->representationId = $v; $this->touch(); return $this; }
public function setIsActive(bool $v): self { $this->isActive = $v; $this->touch(); return $this; }
public function setImagesClinic(?array $v): self { $this->imagesClinic = $v; $this->touch(); return $this; }
public function setClinicLogo(?string $v): self { $this->clinicLogo = $v; $this->touch(); return $this; }
@@ -164,7 +169,11 @@ class Clinic
return [
'id' => (string) $this->id,
'uuid' => $this->uuid,
'name' => $this->name,
'title' => $this->name,
'is_active' => $this->isActive,
'phone' => $this->telephone,
'logo' => $this->clinicLogo,
'images_clinic' => $this->imagesClinic ?? [],
'clinic_logo' => $this->clinicLogo,
'phone_number' => $this->telephone,
@@ -202,14 +211,19 @@ class Clinic
return [
'id' => (string) $this->id,
'uuid' => $this->uuid,
'name' => $this->name,
'title' => $this->name,
'images_clinic' => $this->imagesClinic ?? [],
'clinic_logo' => $this->clinicLogo ?? [],
'phone' => $this->telephone,
'phone_number' => $this->telephone,
'logo' => $this->clinicLogo,
'clinic_logo' => $this->clinicLogo,
'images_clinic' => $this->imagesClinic ?? [],
'doctors_count' => $this->doctors->count(),
'is_active' => $this->isActive,
'created_at' => $this->createdAt,
'specialties' => array_map(fn(Specialty $s) => [
'uuid' => $s->getUuid(), 'id' => (string) $s->getId(), 'name' => $s->getName(),
], $this->specialties->toArray()),
'doctors' => $this->doctors->count(),
'24_7' => $this->is247,
];
}