From cbd6d373bbbe5adeac03de30198127c67a3ff5db Mon Sep 17 00:00:00 2001 From: Matthias Engelien Date: Sun, 15 Sep 2024 12:41:39 +0200 Subject: [PATCH] refactoring --- .../etecture/ga/api/GarageApiController.java | 10 +++- .../de/etecture/ga/model/Appointment.java | 16 +++++- .../java/de/etecture/ga/model/Garage.java | 5 ++ .../ga/service/AppointmentService.java | 49 +++++++++++++------ .../ga/service/GarageImportService.java | 1 - 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/main/java/de/etecture/ga/api/GarageApiController.java b/src/main/java/de/etecture/ga/api/GarageApiController.java index f4b16d2..87880e0 100644 --- a/src/main/java/de/etecture/ga/api/GarageApiController.java +++ b/src/main/java/de/etecture/ga/api/GarageApiController.java @@ -71,7 +71,15 @@ public class GarageApiController implements WerkstattApi { @Override public ResponseEntity> getTerminvorschlaege(String werkstattId, @NotNull @Valid String leistungsId, @Valid String von, @Valid String bis) { - // TODO Auto-generated method stub + Assert.isTrue(NumberUtils.isParsable(werkstattId), "werkstattId ungültig"); + + long garageId = Long.parseLong(werkstattId); + Optional serviceId = NumberUtils.isParsable(leistungsId) ? Optional.of(Long.parseLong(leistungsId)) + : Optional.empty(); + Optional appointmentsFrom = Optional.ofNullable(parseDate(von)); + Optional appointmentsTill = Optional.ofNullable(parseDate(bis)); + + return WerkstattApi.super.getTerminvorschlaege(werkstattId, leistungsId, von, bis); } diff --git a/src/main/java/de/etecture/ga/model/Appointment.java b/src/main/java/de/etecture/ga/model/Appointment.java index 1362d4d..be767be 100644 --- a/src/main/java/de/etecture/ga/model/Appointment.java +++ b/src/main/java/de/etecture/ga/model/Appointment.java @@ -11,13 +11,16 @@ import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.data.relational.core.mapping.Column; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @Data @Accessors(fluent = true, chain = true) -public class Appointment { +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +public class Appointment implements Comparable{ @Id + @EqualsAndHashCode.Include private Long id; @Column("GARAGE_ID") @@ -26,12 +29,15 @@ public class Appointment { @Column("SERVICE_ID") private AggregateReference serviceId; + @EqualsAndHashCode.Include private String serviceCode; private String serviceName; + @EqualsAndHashCode.Include private Date appointmentTime; + @EqualsAndHashCode.Include private Integer slot = 1; private Duration duration = Duration.ZERO; @@ -45,4 +51,12 @@ public class Appointment { public LocalDateTime appointmentEnd() { return this.appointmentStart().plus(this.duration()); } + + + @Override + public int compareTo(Appointment o) { + if(o == null || o.appointmentTime() == null) return 1; + + return this.appointmentTime().compareTo(o.appointmentTime()); + } } diff --git a/src/main/java/de/etecture/ga/model/Garage.java b/src/main/java/de/etecture/ga/model/Garage.java index cc609b4..fe33fc0 100644 --- a/src/main/java/de/etecture/ga/model/Garage.java +++ b/src/main/java/de/etecture/ga/model/Garage.java @@ -2,6 +2,7 @@ package de.etecture.ga.model; import java.time.Duration; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.springframework.data.annotation.Id; @@ -40,6 +41,10 @@ public class Garage { } return this; } + + public List appointmentsSorted() { + return this.appointments.stream().sorted().toList(); + } public Garage addService(MDService service) { garageServices.add(createGarageService(service, null)); diff --git a/src/main/java/de/etecture/ga/service/AppointmentService.java b/src/main/java/de/etecture/ga/service/AppointmentService.java index 81791d7..90e7744 100644 --- a/src/main/java/de/etecture/ga/service/AppointmentService.java +++ b/src/main/java/de/etecture/ga/service/AppointmentService.java @@ -62,6 +62,7 @@ public class AppointmentService { public Optional createAppointment(long garageId, long serviceId, Date from, Date till) { + // validate input Optional garage = garageService.getGarage(garageId); if (garage.isEmpty()) throw new IllegalArgumentException("GarageId not valid"); @@ -73,8 +74,25 @@ public class AppointmentService { if (service.isEmpty() || garageService.isEmpty()) throw new IllegalArgumentException("serviceId not valid"); + // check appointment times + LocalDateTime validAppointmentTime = getValidAppointmentTime(from, till, garage); + + // create appointment + if (validAppointmentTime != null) { + Appointment appointment = createAppointmentObj(garage, service, garageService, validAppointmentTime); + + return Optional.of(repository.save(appointment)); + + } else { + return Optional.empty(); + } + } + + private LocalDateTime getValidAppointmentTime(Date from, Date till, Optional garage) { + LocalDateTime fromDateTime = Instant.ofEpochMilli(from.getTime()).atZone(ZoneId.systemDefault()) .toLocalDateTime(); + fromDateTime = roundUpToQuarter(fromDateTime); LocalDateTime tillDateTime = Instant.ofEpochMilli(till.getTime()).atZone(ZoneId.systemDefault()) .toLocalDateTime(); @@ -87,17 +105,16 @@ public class AppointmentService { fromDateTime = fromDateTime.plusMinutes(15); } - if (validAppointmentTime != null) { - Appointment appointment = new Appointment().garageId(AggregateReference.to(garage.get().id())) - .appointmentTime(Date.from(validAppointmentTime.atZone(ZoneId.systemDefault()).toInstant())) - .serviceId(AggregateReference.to(service.get().id())).serviceCode(service.get().code()) - .serviceName(service.get().name()).duration(garageService.get().duration()); + return validAppointmentTime; + } - return Optional.of(repository.save(appointment)); + private LocalDateTime roundUpToQuarter(LocalDateTime datetime) { - } else { - return Optional.empty(); - } + if (datetime.getMinute() % 15 == 0) + return datetime; + + int minutesToAdd = 15 - (datetime.getMinute() % 15); + return datetime.plusMinutes(minutesToAdd).truncatedTo(ChronoUnit.MINUTES); } private boolean isSlotAvailable(Garage garage, LocalDateTime time) { @@ -110,12 +127,12 @@ public class AppointmentService { return appointments < garage.maxAppointments(); } - private LocalDateTime roundUpToQuarter(LocalDateTime datetime) { - - if (datetime.getMinute() % 15 == 0) - return datetime; - - int minutesToAdd = 15 - (datetime.getMinute() % 15); - return datetime.plusMinutes(minutesToAdd).truncatedTo(ChronoUnit.MINUTES); + private Appointment createAppointmentObj(Optional garage, Optional service, + Optional garageService, LocalDateTime validAppointmentTime) { + Appointment appointment = new Appointment().garageId(AggregateReference.to(garage.get().id())) + .appointmentTime(Date.from(validAppointmentTime.atZone(ZoneId.systemDefault()).toInstant())) + .serviceId(AggregateReference.to(service.get().id())).serviceCode(service.get().code()) + .serviceName(service.get().name()).duration(garageService.get().duration()); + return appointment; } } diff --git a/src/main/java/de/etecture/ga/service/GarageImportService.java b/src/main/java/de/etecture/ga/service/GarageImportService.java index fc81380..3110117 100644 --- a/src/main/java/de/etecture/ga/service/GarageImportService.java +++ b/src/main/java/de/etecture/ga/service/GarageImportService.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import de.etecture.ga.model.Appointment; import de.etecture.ga.model.Garage;