feat: enhance DoctorAddress entity to support clinic addresses and types
- Added `clinic_id` and `type` fields to `DoctorAddress` entity to differentiate between personal and clinic addresses. - Updated constructor to support creation of addresses for both doctors and clinics. - Modified repository methods to handle new address types and added methods for counting and finding addresses by clinic. - Implemented migration to update the database schema accordingly. - Removed deprecated endpoint for creating addresses from clinics and updated related controller methods. - Added new endpoints for managing clinic addresses, including CRUD operations. - Updated frontend components to handle new address types and display accordingly.
This commit is contained in:
@@ -7,6 +7,8 @@ use App\Auth\Repository\UserRepository;
|
||||
use App\Clinic\Entity\Clinic;
|
||||
use App\Clinic\Repository\ClinicRepository;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Doctor\Entity\DoctorAddress;
|
||||
use App\Doctor\Repository\DoctorAddressRepository;
|
||||
use App\Doctor\Repository\DoctorRepository;
|
||||
use App\DoctorService\Repository\DoctorServiceRepository;
|
||||
use App\Insurance\Repository\InsuranceRepository;
|
||||
@@ -28,16 +30,17 @@ use Symfony\Component\Uid\Uuid;
|
||||
class ClinicController extends BaseController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClinicRepository $clinicRepo,
|
||||
private readonly DoctorRepository $doctorRepo,
|
||||
private readonly SpecialtyRepository $specialtyRepo,
|
||||
private readonly ClinicRepository $clinicRepo,
|
||||
private readonly DoctorRepository $doctorRepo,
|
||||
private readonly DoctorAddressRepository $addressRepo,
|
||||
private readonly SpecialtyRepository $specialtyRepo,
|
||||
private readonly DoctorServiceRepository $serviceRepo,
|
||||
private readonly InsuranceRepository $insuranceRepo,
|
||||
private readonly ProvinceRepository $provinceRepo,
|
||||
private readonly CityRepository $cityRepo,
|
||||
private readonly UserRepository $userRepo,
|
||||
private readonly FileValidatorService $fileValidator,
|
||||
private readonly string $projectDir,
|
||||
private readonly InsuranceRepository $insuranceRepo,
|
||||
private readonly ProvinceRepository $provinceRepo,
|
||||
private readonly CityRepository $cityRepo,
|
||||
private readonly UserRepository $userRepo,
|
||||
private readonly FileValidatorService $fileValidator,
|
||||
private readonly string $projectDir,
|
||||
) {}
|
||||
|
||||
#[OA\Post(
|
||||
@@ -535,4 +538,109 @@ class ClinicController extends BaseController
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, $e->getMessage(), 422);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Clinic Addresses ─────────────────────────────────────────────────────
|
||||
|
||||
#[Route('/api/v1/clinic/{clinicUuid}/addresses', methods: ['GET'])]
|
||||
public function listAddresses(string $clinicUuid): JsonResponse
|
||||
{
|
||||
$clinic = $this->clinicRepo->findByUuid($clinicUuid);
|
||||
if ($clinic === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'کلینیک یافت نشد', 404);
|
||||
}
|
||||
|
||||
$addresses = $this->addressRepo->findBy(['clinicId' => $clinic->getId()]);
|
||||
|
||||
return $this->success(['data' => array_map(fn(DoctorAddress $a) => $a->toArray(), $addresses)]);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/clinic/{clinicUuid}/address', methods: ['POST'])]
|
||||
#[IsGranted('IS_AUTHENTICATED_FULLY')]
|
||||
public function createAddress(string $clinicUuid, Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$clinic = $this->clinicRepo->findByUuid($clinicUuid);
|
||||
if ($clinic === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'کلینیک یافت نشد', 404);
|
||||
}
|
||||
|
||||
if ($clinic->getUser()->getId() !== $user->getId() && !$user->hasRole('ROLE_ADMIN')) {
|
||||
return $this->error(ErrorCodes::ERR_AUTH_006, 'دسترسی ممنوع', 403);
|
||||
}
|
||||
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$address = DoctorAddress::forClinic($clinic->getId());
|
||||
$this->hydrateClinicAddress($address, $data);
|
||||
$this->addressRepo->save($address);
|
||||
|
||||
return $this->success(['data' => $address->toArray()], 201);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/clinic/{clinicUuid}/address/{addressUuid}', methods: ['PATCH'])]
|
||||
#[IsGranted('IS_AUTHENTICATED_FULLY')]
|
||||
public function updateAddress(string $clinicUuid, string $addressUuid, Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$clinic = $this->clinicRepo->findByUuid($clinicUuid);
|
||||
if ($clinic === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'کلینیک یافت نشد', 404);
|
||||
}
|
||||
|
||||
if ($clinic->getUser()->getId() !== $user->getId() && !$user->hasRole('ROLE_ADMIN')) {
|
||||
return $this->error(ErrorCodes::ERR_AUTH_006, 'دسترسی ممنوع', 403);
|
||||
}
|
||||
|
||||
$address = $this->addressRepo->findByUuidAndClinic($addressUuid, $clinic->getId());
|
||||
if ($address === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'آدرس یافت نشد', 404);
|
||||
}
|
||||
|
||||
$data = json_decode($request->getContent(), true) ?? [];
|
||||
$this->hydrateClinicAddress($address, $data);
|
||||
$this->addressRepo->save($address);
|
||||
|
||||
return $this->success(['data' => $address->toArray()]);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/clinic/{clinicUuid}/address/{addressUuid}', methods: ['DELETE'])]
|
||||
#[IsGranted('IS_AUTHENTICATED_FULLY')]
|
||||
public function deleteAddress(string $clinicUuid, string $addressUuid, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$clinic = $this->clinicRepo->findByUuid($clinicUuid);
|
||||
if ($clinic === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'کلینیک یافت نشد', 404);
|
||||
}
|
||||
|
||||
if ($clinic->getUser()->getId() !== $user->getId() && !$user->hasRole('ROLE_ADMIN')) {
|
||||
return $this->error(ErrorCodes::ERR_AUTH_006, 'دسترسی ممنوع', 403);
|
||||
}
|
||||
|
||||
$address = $this->addressRepo->findByUuidAndClinic($addressUuid, $clinic->getId());
|
||||
if ($address === null) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'آدرس یافت نشد', 404);
|
||||
}
|
||||
|
||||
$remaining = $this->addressRepo->countByClinic($clinic->getId());
|
||||
if ($remaining <= 1) {
|
||||
return $this->error(ErrorCodes::ERR_CONFLICT_001, 'کلینیک باید حداقل یک آدرس داشته باشد', 409);
|
||||
}
|
||||
|
||||
$this->addressRepo->remove($address);
|
||||
|
||||
return $this->success(['message' => 'آدرس با موفقیت حذف شد']);
|
||||
}
|
||||
|
||||
private function hydrateClinicAddress(DoctorAddress $address, array $data): void
|
||||
{
|
||||
if (array_key_exists('name', $data)) $address->setName($data['name']);
|
||||
if (array_key_exists('address', $data)) $address->setAddress($data['address']);
|
||||
if (array_key_exists('telephone', $data)) $address->setTelephone($data['telephone']);
|
||||
if (array_key_exists('latitude', $data)) $address->setLatitude($data['latitude'] !== null ? (float) $data['latitude'] : null);
|
||||
if (array_key_exists('longitude', $data)) $address->setLongitude($data['longitude'] !== null ? (float) $data['longitude'] : null);
|
||||
|
||||
if (array_key_exists('city_id', $data)) {
|
||||
$address->setCity($data['city_id'] !== null ? $this->cityRepo->find((int) $data['city_id']) : null);
|
||||
}
|
||||
if (array_key_exists('province_id', $data)) {
|
||||
$address->setProvince($data['province_id'] !== null ? $this->provinceRepo->find((int) $data['province_id']) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user