147 lines
6.7 KiB
Java
147 lines
6.7 KiB
Java
package com.mirna.hospitalmanagementapi.application.services;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import com.mirna.hospitalmanagementapi.application.usecase.consultation.FindConsultationByIdUseCase;
|
|
import com.mirna.hospitalmanagementapi.application.usecase.consultation.SaveConsultationUseCase;
|
|
import com.mirna.hospitalmanagementapi.application.usecase.doctor.FindDoctorByIdUseCase;
|
|
import com.mirna.hospitalmanagementapi.application.usecase.doctor.FindOneFreeDoctorBySpecialtyUseCase;
|
|
import com.mirna.hospitalmanagementapi.application.usecase.patient.FindPatientByIdUseCase;
|
|
import com.mirna.hospitalmanagementapi.domain.dtos.consultation.ConsultationCanceledDTO;
|
|
import com.mirna.hospitalmanagementapi.domain.dtos.consultation.ConsultationDTO;
|
|
import com.mirna.hospitalmanagementapi.domain.entities.Consultation;
|
|
import com.mirna.hospitalmanagementapi.domain.entities.Doctor;
|
|
import com.mirna.hospitalmanagementapi.domain.entities.Patient;
|
|
import com.mirna.hospitalmanagementapi.domain.exceptions.ConsultationValidationException;
|
|
import com.mirna.hospitalmanagementapi.domain.services.ConsultationService;
|
|
import com.mirna.hospitalmanagementapi.domain.services.DoctorScheduleService;
|
|
import com.mirna.hospitalmanagementapi.domain.repositories.ConsultationRepository;
|
|
|
|
import jakarta.persistence.EntityNotFoundException;
|
|
import java.time.LocalTime;
|
|
import java.time.OffsetDateTime;
|
|
import java.time.ZoneOffset;
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
@Service
|
|
public class ConsultationServiceImpl implements ConsultationService {
|
|
|
|
@Autowired
|
|
private SaveConsultationUseCase saveConsultation;
|
|
|
|
@Autowired
|
|
private FindConsultationByIdUseCase findConsultationById;
|
|
|
|
@Autowired
|
|
private ConsultationRepository consultationRepository;
|
|
|
|
@Autowired
|
|
private FindPatientByIdUseCase findPatientById;
|
|
|
|
@Autowired
|
|
private FindDoctorByIdUseCase findDoctorById;
|
|
|
|
@Autowired
|
|
private FindOneFreeDoctorBySpecialtyUseCase findOneFreeDoctorBySpecialty;
|
|
|
|
@Autowired
|
|
private DoctorScheduleService doctorScheduleService;
|
|
|
|
private static final ZoneOffset BANGKOK_ZONE_OFFSET = ZoneOffset.ofHours(7);
|
|
|
|
@Override
|
|
@Transactional
|
|
public Consultation addConsultation(ConsultationDTO consultationDTO) throws ConsultationValidationException {
|
|
Patient patient = validatePatient(consultationDTO.patientId(), consultationDTO.consultationDate());
|
|
Doctor doctor = validateAndFindDoctor(consultationDTO);
|
|
validatePatientAndDoctorAvailability(patient, doctor, consultationDTO.consultationDate());
|
|
|
|
Consultation consultation = new Consultation(patient, doctor, consultationDTO.consultationDate());
|
|
|
|
return saveConsultation.execute(consultation);
|
|
}
|
|
|
|
private Patient validatePatient(Long patientId, OffsetDateTime consultationDate) throws ConsultationValidationException {
|
|
if (patientId == null) {
|
|
throw new ConsultationValidationException("Patient ID cannot be null");
|
|
}
|
|
|
|
Patient patient = findPatientById.execute(patientId);
|
|
|
|
if (patient == null) {
|
|
throw new ConsultationValidationException("This patient is not found");
|
|
}
|
|
if (!patient.getActive()) {
|
|
throw new ConsultationValidationException("This patient is not active");
|
|
}
|
|
|
|
OffsetDateTime consultationDateInBkkZone = consultationDate.withOffsetSameInstant(BANGKOK_ZONE_OFFSET);
|
|
OffsetDateTime startOfDay = consultationDateInBkkZone.with(LocalTime.MIN);
|
|
OffsetDateTime endOfDay = consultationDateInBkkZone.with(LocalTime.MAX);
|
|
|
|
// แก้ไขบรรทัดนี้: ส่งพารามิเตอร์ที่ถูกต้องไปยัง Repository
|
|
if (consultationRepository.findConsultationByPatientAndDate(patient.getId(), startOfDay, endOfDay) != null) {
|
|
throw new ConsultationValidationException("This patient is not free on this date");
|
|
}
|
|
return patient;
|
|
}
|
|
|
|
private Doctor validateAndFindDoctor(ConsultationDTO consultationDTO) throws ConsultationValidationException {
|
|
Doctor doctor = null;
|
|
OffsetDateTime consultationDateInBkkZone = consultationDTO.consultationDate().withOffsetSameInstant(BANGKOK_ZONE_OFFSET);
|
|
|
|
if (consultationDTO.doctorId() != null) {
|
|
doctor = findDoctorById.execute(consultationDTO.doctorId());
|
|
} else if (consultationDTO.specialty() != null) {
|
|
doctor = findOneFreeDoctorBySpecialty.execute(consultationDTO.specialty(), consultationDateInBkkZone);
|
|
} else {
|
|
throw new ConsultationValidationException("At least the specialty or doctor ID must be filled in");
|
|
}
|
|
|
|
if (doctor == null) {
|
|
throw new ConsultationValidationException("No doctors found at the requested time or specialty.");
|
|
}
|
|
return doctor;
|
|
}
|
|
|
|
private void validatePatientAndDoctorAvailability(Patient patient, Doctor doctor, OffsetDateTime consultationDate) throws ConsultationValidationException {
|
|
OffsetDateTime consultationDateInBkkZone = consultationDate.withOffsetSameInstant(BANGKOK_ZONE_OFFSET);
|
|
|
|
OffsetDateTime startOfDay = consultationDateInBkkZone.with(LocalTime.MIN);
|
|
OffsetDateTime endOfDay = consultationDateInBkkZone.with(LocalTime.MAX);
|
|
|
|
// แก้ไขบรรทัดนี้: ส่งพารามิเตอร์ที่ถูกต้องไปยัง Repository
|
|
if (consultationRepository.findConsultationByDoctorAndDate(doctor.getId(), startOfDay, endOfDay) != null) {
|
|
throw new ConsultationValidationException("This doctor is not free on this date");
|
|
}
|
|
|
|
boolean isDoctorAvailable = doctorScheduleService.isDoctorAvailable(
|
|
doctor.getId(),
|
|
consultationDateInBkkZone.getDayOfWeek(),
|
|
consultationDateInBkkZone.toLocalTime()
|
|
);
|
|
|
|
if (!isDoctorAvailable) {
|
|
throw new ConsultationValidationException("The selected doctor is not on duty at the requested time.");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Consultation findConsultationById(Long id) {
|
|
Consultation consultation = findConsultationById.execute(id);
|
|
|
|
if (consultation == null)
|
|
throw new EntityNotFoundException("No existing consultation with this id");
|
|
|
|
return consultation;
|
|
}
|
|
|
|
@Override
|
|
public Consultation cancelConsultation(ConsultationCanceledDTO consultationCanceledDTO) {
|
|
Consultation consultation = this.findConsultationById(consultationCanceledDTO.consultationId());
|
|
consultation.setCanceled(true);
|
|
consultation.setReasonCancellation(consultationCanceledDTO.reasonCancellation());
|
|
return saveConsultation.execute(consultation);
|
|
}
|
|
} |