Opracowałem w apce reprezentującą klinikę funkcjonalność do pobrania w formie JSONA :
[{"doctor":{"id": 3, "name": "Jan Kowalski"} "date": "2021-05-01 15:00:00"}, ...]
doktorów do których można się umówić na wizytę.
Encje prezentują się następująco :
public class Appointment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "doctor_id")
private Doctor doctor;
@ManyToOne
@JoinColumn(name = "patient_id")
private Patient patient;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm")
private LocalDateTime appointmentDate;
private Integer lengthInHours;
private boolean confirmed;
public Appointment(Doctor doctor, Patient patient, LocalDateTime appointmentDate) {
this.doctor = doctor;
this.patient = patient;
this.appointmentDate = appointmentDate;
this.confirmed = false;
this.lengthInHours = 1;
}
}
public class Doctor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nip;
private String firstName;
private String lastName;
private String medicalSpecialization;
private String petSpecialization;
private BigDecimal salaryPerHour;
private boolean active;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String species;
private String breed;
private Integer age;
private String ownerFirstname;
private String ownerLastname;
private String emailAddress;
public class Patient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String species;
private String breed;
private Integer age;
private String ownerFirstname;
private String ownerLastname;
private String emailAddress;
Metoda spełnia swoje zadanie to fakt, ale mam wrażenie że można to zrobić w o wiele prostszy sposób który nie wymagałby tyle kodu. Generalnie zamysł jest taki:
/check
should find top few (configurable parameter) available doctors and date that you can book a visit (availableAppointmentDTO): private DoctorDTO doctorDTO; private LocalDAteTime date;
Obecnie wygląda to tak:
Pokazuje tylko serwis a nie controller jak coś w controllerze jest bezpośrednio tylko wywołanie metody
public List<AvailableAppointmentDTO> getAvailableDoctors(FindMatchingAppointmentsCommand command) {
List<LocalDateTime> dateList = parseDateRange(command.getDateFrom(), command.getDateTo());
List<Doctor> matchingDoctors = doctorRepository.findDoctorByMedicalSpecializationAndPetSpecialization(command.getDoctorSpecialization(), command.getAnimalSpecies());
List<AvailableAppointmentDTO> availableAppointments = new ArrayList<>();
for (Doctor matchingDoctor : matchingDoctors) {
List<Appointment> doctorAppointments = appointmentRepository.findAppointmentByDoctorAndAppointmentDateBetween(matchingDoctor, command.getDateFrom(), command.getDateTo());
List<LocalDateTime> occupiedDates = getOccupiedDates(doctorAppointments);
dateList.removeAll(occupiedDates);
for (LocalDateTime dateTime : dateList) {
availableAppointments.add(new AvailableAppointmentDTO(matchingDoctor.getId(), matchingDoctor.getFirstName(), matchingDoctor.getLastName(), dateTime));
}
}
return availableAppointments;
}
private static List<LocalDateTime> parseDateRange(LocalDateTime dateFrom, LocalDateTime dateTo) {
List<LocalDateTime> dateList = new ArrayList<>();
while (dateFrom.isBefore(dateTo)){
dateList.add(dateFrom);
dateFrom = dateFrom.plusHours(1);
}
return dateList;
}
private List<LocalDateTime> getOccupiedDates(List<Appointment> doctorAppointments) {
return doctorAppointments.stream()
.map(Appointment::getAppointmentDate)
.toList();
}
Ma ktoś jakiś ciekawszy pomysł na tą logikę? pozdrawiam