diff --git a/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationRequest.java b/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationRequest.java index 548b5b79..6257d56f 100644 --- a/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationRequest.java +++ b/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationRequest.java @@ -15,7 +15,6 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReservationRequest { - @Future private LocalDateTime startAt; @Future diff --git a/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationUpdateRequest.java b/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationUpdateRequest.java index dd8bd8a4..6da5b18a 100644 --- a/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationUpdateRequest.java +++ b/src/main/java/com/newfit/reservation/domains/reservation/dto/request/ReservationUpdateRequest.java @@ -17,8 +17,9 @@ public class ReservationUpdateRequest { @Min(1) private Long equipmentGymId; - @Future + private LocalDateTime startAt; + @Future private LocalDateTime endAt; } diff --git a/src/main/java/com/newfit/reservation/domains/reservation/repository/ReservationRepository.java b/src/main/java/com/newfit/reservation/domains/reservation/repository/ReservationRepository.java index 3d91d4d5..f03d5ba3 100644 --- a/src/main/java/com/newfit/reservation/domains/reservation/repository/ReservationRepository.java +++ b/src/main/java/com/newfit/reservation/domains/reservation/repository/ReservationRepository.java @@ -39,4 +39,17 @@ List findAllByAuthorityIdAndStartAtAndEndAt(@Param("authorityId") L List findAllByEquipmentGymIdIdAndStartAtAndEndAt(@Param("equipmentGymId") Long equipmentGymId, @Param("startAt") LocalDateTime startAt, @Param("endAt") LocalDateTime endAt); + + @Query(value = "select r.* from Reservation r " + + "join authority a " + + "on a.id=:authorityId " + + "where ( " + + "(:startAt BETWEEN r.start_at AND r.end_at) " + + "OR (:endAt BETWEEN r.start_at AND r.end_at) " + + "OR (:startAt <= r.start_at AND r.end_at <= :endAt)) " + + "AND (r.id <> :reservationId);", nativeQuery = true) + List findAllByAuthorityIdAndStartAtAndEndAtExcludingCurrent(@Param("authorityId") Long authorityId, + @Param("startAt") LocalDateTime startAt, + @Param("endAt") LocalDateTime endAt, + @Param("reservationId") Long reservationId); } diff --git a/src/main/java/com/newfit/reservation/domains/reservation/service/ReservationService.java b/src/main/java/com/newfit/reservation/domains/reservation/service/ReservationService.java index 118d414f..e8ac0afb 100644 --- a/src/main/java/com/newfit/reservation/domains/reservation/service/ReservationService.java +++ b/src/main/java/com/newfit/reservation/domains/reservation/service/ReservationService.java @@ -49,6 +49,7 @@ public void reserve(Long authorityId, LocalDateTime endAt = request.getEndAt(); validateTime(startAt, endAt, authority); + validateMyReservationOverlap(authority, startAt, endAt); EquipmentGym equipmentGym = equipmentGymRepository.findAvailableByEquipmentGymIdAndStartAtAndEndAt( equipmentGymId, startAt, endAt) @@ -58,12 +59,6 @@ public void reserve(Long authorityId, reservationRepository.save(reservation); } - private void validateLastTagAt(Authority authority) { - LocalDateTime tagAt = authority.getTagAt(); - if (tagAt.isBefore(now().minusHours(2))) - throw new CustomException(EXPIRED_TAG); - } - @Transactional(readOnly = true) public ReservationListResponse listReservation(Long equipmentGymId) { EquipmentGym equipmentGym = equipmentGymRepository.findById(equipmentGymId) @@ -87,6 +82,7 @@ public void update(Long reservationId, ReservationUpdateRequest request) { LocalDateTime endAt = request.getEndAt(); validateTime(startAt, endAt, authority); + validateMyReservationOverlapExcludingCurrent(authority, startAt, endAt, reservationId); if (equipmentGymId == null) { targetReservation.updateTime(startAt, endAt); @@ -114,13 +110,24 @@ private void validateUpdateTime(Long equipmentGymId, LocalDateTime startAt, Loca } private void validateTime(LocalDateTime startAt, LocalDateTime endAt, Authority authority) { + validateStartAtLowerBound(startAt); validateLastTagAt(authority); validateReservationIn2Hours(startAt, endAt); Gym gym = authority.getGym(); gym.checkBusinessHour(startAt, endAt); + } - validateMyReservationOverlap(authority, startAt, endAt); + private void validateStartAtLowerBound(LocalDateTime startAt) { + if (startAt.isBefore(now().minusMinutes(1))) { + throw new CustomException(INVALID_RESERVATION_REQUEST); + } + } + + private void validateLastTagAt(Authority authority) { + LocalDateTime tagAt = authority.getTagAt(); + if (tagAt.isBefore(now().minusHours(2))) + throw new CustomException(EXPIRED_TAG); } private void validateMyReservationOverlap(Authority authority, LocalDateTime startAt, LocalDateTime endAt) { @@ -131,6 +138,17 @@ private void validateMyReservationOverlap(Authority authority, LocalDateTime sta } } + private void validateMyReservationOverlapExcludingCurrent(Authority authority, LocalDateTime startAt, + LocalDateTime endAt, + Long reservationId) { + List reservations = reservationRepository.findAllByAuthorityIdAndStartAtAndEndAtExcludingCurrent( + authority.getId(), + startAt, endAt, reservationId); + if (!reservations.isEmpty()) { + throw new CustomException(INVALID_RESERVATION_REQUEST); + } + } + public void delete(Long reservationId) { reservationRepository.deleteById(reservationId); }