diff --git a/src/main/java/roomescape/entity/Reservation.java b/src/main/java/roomescape/entity/Reservation.java index f01ddd5b..90028ec4 100644 --- a/src/main/java/roomescape/entity/Reservation.java +++ b/src/main/java/roomescape/entity/Reservation.java @@ -1,6 +1,7 @@ package roomescape.entity; import java.time.LocalDate; +import java.time.LocalTime; import java.util.Objects; public class Reservation { @@ -15,6 +16,7 @@ public Reservation(Long id, Person person, LocalDate date, Time time) { this.date = date; this.time = time; } + public Reservation(Person person, LocalDate date, Time time) { this.id = 0L; this.person = person; @@ -22,6 +24,13 @@ public Reservation(Person person, LocalDate date, Time time) { this.time = time; } + public void validateReservationDate() { + LocalDate today = LocalDate.now(); + if (today.isAfter(date)) { + throw new IllegalArgumentException("시간이 지난 예약은 예약할 수 없습니다."); + } + } + public Long getId() { return id; } @@ -42,6 +51,10 @@ public Time getTime() { return time; } + public LocalTime getLocalTime() { + return time.getTime(); + } + public Long getTimeId() { return time.getId(); } diff --git a/src/main/java/roomescape/repository/ReservationDao.java b/src/main/java/roomescape/repository/ReservationDao.java index 8edaabea..3a8c7083 100644 --- a/src/main/java/roomescape/repository/ReservationDao.java +++ b/src/main/java/roomescape/repository/ReservationDao.java @@ -67,12 +67,16 @@ public Reservation save(Reservation reservation, Long timeId) { } public List findAll() { - String query = "SELECT r.id as reservation_id, r.name, r.date, t.id as time_id, t.time as time_value FROM reservation as r inner join time as t on r.time_id = t.id"; return jdbcTemplate.query(query, reservationTimeRowMapper); } + public List findByDate(LocalDate date) { + String query = "SELECT r.id as reservation_id, r.name, r.date, t.id as time_id, t.time as time_value FROM reservation as r inner join time as t on r.time_id = t.id where r.date = ?"; + return jdbcTemplate.query(query, reservationTimeRowMapper, date.format(CustomDateTimeFormat.dateFormatter)); + } + public Reservation findById(Long id) { String query = "SELECT * FROM RESERVATION WHERE id = ?"; diff --git a/src/main/java/roomescape/service/ReservationService.java b/src/main/java/roomescape/service/ReservationService.java index 16085f2d..90a40af3 100644 --- a/src/main/java/roomescape/service/ReservationService.java +++ b/src/main/java/roomescape/service/ReservationService.java @@ -7,10 +7,14 @@ import roomescape.repository.ReservationDao; import roomescape.repository.TimeDao; +import java.time.LocalDate; +import java.time.LocalTime; import java.util.List; @Service public class ReservationService { + private static final int RESERVATION_RUNNING_TIME = 60; + private static final int RESERVATION_CLEAN_TIME = 30; private final ReservationDao reservationDao; private final TimeDao timeDao; @@ -30,18 +34,46 @@ public Reservation readReservation(Long id) { return reservationDao.findById(id); } - public Reservation createReservation(Reservation reservation) { - Time time = timeDao.findById(reservation.getTimeId()); + public Reservation createReservation(Reservation reservationDto) { + reservationDto.validateReservationDate(); - Reservation reservationWithTimeInfo = new Reservation( - reservation.getPerson(), - reservation.getDate(), + Time time = timeDao.findById(reservationDto.getTimeId()); + + Reservation currReservation = new Reservation( + reservationDto.getPerson(), + reservationDto.getDate(), time ); - return reservationDao.save(reservationWithTimeInfo, reservation.getTimeId()); + + List savedReservations = reservationDao.findByDate(currReservation.getDate()); + + validateReservationTime(currReservation, savedReservations); + + return reservationDao.save(currReservation, currReservation.getTimeId()); } public void deleteReservation(Long id) { reservationDao.deleteById(id); } + + private void validateReservationTime(Reservation currReservation, List savedReservations) { + LocalTime currReservationTime = currReservation.getLocalTime(); + + List savedTimes = savedReservations + .stream() + .map(Reservation::getLocalTime) + .toList(); + + long reservationLimitTime = RESERVATION_RUNNING_TIME + RESERVATION_CLEAN_TIME; + + boolean conflictExists = savedTimes.stream(). + anyMatch(s -> { + LocalTime upperBound = s.plusMinutes(reservationLimitTime); + return currReservationTime.equals(s) || (currReservationTime.isBefore(upperBound) && currReservationTime.isAfter(s)); + }); + + if (conflictExists) { + throw new IllegalArgumentException("예약 불가능: 1시간 30분 이내의 예약이 이미 존재합니다."); + } + } } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 0ead4768..87377257 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,3 +1,6 @@ insert into time (time) values ('10:00'); +insert into time (time) values ('10:30'); +insert into time (time) values ('11:00'); insert into time (time) values ('12:00'); -insert into reservation (name, date, time_id) values ('sj', '2024-11-27', 1); +insert into time (time) values ('13:00'); +insert into reservation (name, date, time_id) values ('sj', '2025-01-27', 1);