diff --git a/src/main/java/ybe/mini/travelserver/domain/reservation_room/repository/ReservationRoomRepository.java b/src/main/java/ybe/mini/travelserver/domain/reservation_room/repository/ReservationRoomRepository.java index 3cb296f..5fda357 100644 --- a/src/main/java/ybe/mini/travelserver/domain/reservation_room/repository/ReservationRoomRepository.java +++ b/src/main/java/ybe/mini/travelserver/domain/reservation_room/repository/ReservationRoomRepository.java @@ -3,10 +3,18 @@ import org.springframework.data.jpa.repository.JpaRepository; import ybe.mini.travelserver.domain.reservation.entity.Reservation; import ybe.mini.travelserver.domain.reservation_room.entity.ReservationRoom; +import ybe.mini.travelserver.domain.room.entity.Room; +import java.time.LocalDate; import java.util.List; public interface ReservationRoomRepository extends JpaRepository { List findAllByReservation(Reservation reservation); + + List findAllByRoomAndCheckInBetweenAndCheckOutBetween( + Room room, + LocalDate checkInDate1, LocalDate checkOutDate1, + LocalDate checkInDate2, LocalDate checkOutDate2 + ); } diff --git a/src/main/java/ybe/mini/travelserver/domain/room/controller/RoomController.java b/src/main/java/ybe/mini/travelserver/domain/room/controller/RoomController.java index 685a80d..14983e4 100644 --- a/src/main/java/ybe/mini/travelserver/domain/room/controller/RoomController.java +++ b/src/main/java/ybe/mini/travelserver/domain/room/controller/RoomController.java @@ -2,10 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import ybe.mini.travelserver.domain.room.dto.RoomGetResponseFromAPI; import ybe.mini.travelserver.domain.room.service.RoomService; import ybe.mini.travelserver.global.common.ResponseDto; @@ -20,8 +17,12 @@ public class RoomController { private final RoomService roomService; @GetMapping("/{accommodationId}") - public ResponseDto> getRooms(@PathVariable Long accommodationId) { - List rooms = roomService.bringRoomsFromAPI(accommodationId); + public ResponseDto> getRooms( + @PathVariable Long accommodationId, + @RequestParam(value = "check-in") String checkIn, + @RequestParam(value = "check-out") String checkOut + ) { + List rooms = roomService.bringRoomsFromAPI(accommodationId, checkIn, checkOut); return new ResponseDto<>(HttpStatus.OK.value(), rooms); } } diff --git a/src/main/java/ybe/mini/travelserver/domain/room/dto/RoomGetResponseFromAPI.java b/src/main/java/ybe/mini/travelserver/domain/room/dto/RoomGetResponseFromAPI.java index d16e99d..70868a1 100644 --- a/src/main/java/ybe/mini/travelserver/domain/room/dto/RoomGetResponseFromAPI.java +++ b/src/main/java/ybe/mini/travelserver/domain/room/dto/RoomGetResponseFromAPI.java @@ -26,4 +26,17 @@ public static RoomGetResponseFromAPI fromEntity(Room room) { room.getStock() ); } + + @Builder + public static RoomGetResponseFromAPI fromEntity(Room room, Integer stock) { + return new RoomGetResponseFromAPI( + room.getCapacity(), + room.getDescription(), + room.getPrice(), + room.getImage(), + room.getName(), + room.getRoomTypeId(), + stock + ); + } } diff --git a/src/main/java/ybe/mini/travelserver/domain/room/service/RoomService.java b/src/main/java/ybe/mini/travelserver/domain/room/service/RoomService.java index 1450373..517de79 100644 --- a/src/main/java/ybe/mini/travelserver/domain/room/service/RoomService.java +++ b/src/main/java/ybe/mini/travelserver/domain/room/service/RoomService.java @@ -2,23 +2,49 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ybe.mini.travelserver.domain.reservation_room.entity.ReservationRoom; +import ybe.mini.travelserver.domain.reservation_room.repository.ReservationRoomRepository; import ybe.mini.travelserver.domain.room.dto.RoomGetResponseFromAPI; import ybe.mini.travelserver.domain.room.entity.Room; +import ybe.mini.travelserver.domain.room.repository.RoomRepository; import ybe.mini.travelserver.global.api.TourAPIService; +import ybe.mini.travelserver.global.util.Validation; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; + +import static ybe.mini.travelserver.global.util.Validation.validateDateFormat; @Service @RequiredArgsConstructor public class RoomService { private final TourAPIService tourAPIService; + private final ReservationRoomRepository reservationRoomRepository; + private final RoomRepository roomRepository; - public List bringRoomsFromAPI(Long accommodationId) { + @Transactional(readOnly = true) + public List bringRoomsFromAPI(Long accommodationId, String checkIn, String checkOut) { List rooms = tourAPIService.bringRooms(accommodationId); + return rooms.stream() - .map(RoomGetResponseFromAPI::fromEntity) - .toList(); + .map(room -> RoomGetResponseFromAPI.fromEntity( + room, getRestStock(room, validateDateFormat(checkIn), validateDateFormat(checkOut)) + )).toList(); + } + + private Integer getRestStock(Room room, LocalDate checkIn, LocalDate checkOut) { + Optional roomOpt = roomRepository.findByRoomTypeId(room.getRoomTypeId()); + if(roomOpt.isEmpty()) return room.getStock(); + + List reservationRooms = + reservationRoomRepository.findAllByRoomAndCheckInBetweenAndCheckOutBetween( + roomOpt.get(), checkIn, checkOut, checkIn, checkOut + ); + return room.getStock() - reservationRooms.size(); } } diff --git a/src/test/java/ybe/mini/travelserver/domain/room/controller/RoomControllerTest.java b/src/test/java/ybe/mini/travelserver/domain/room/controller/RoomControllerTest.java index e342d11..ac3791f 100644 --- a/src/test/java/ybe/mini/travelserver/domain/room/controller/RoomControllerTest.java +++ b/src/test/java/ybe/mini/travelserver/domain/room/controller/RoomControllerTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; @@ -39,18 +40,18 @@ void getRooms_success() { RoomGetResponseFromAPI.fromEntity(dummyRoom(accommodation)), RoomGetResponseFromAPI.fromEntity(dummyRoom1(accommodation)) ); - given(roomService.bringRoomsFromAPI(accommodation.getId())).willReturn(expectedRooms); + given(roomService.bringRoomsFromAPI(anyLong(), anyString(), anyString())).willReturn(expectedRooms); // when ResponseDto> responseDto = - roomController.getRooms(accommodation.getId()); + roomController.getRooms(accommodation.getId(), "20240102", "20240202"); // then assertNotNull(responseDto); assertEquals(HttpStatus.OK.value(), responseDto.status()); assertEquals(expectedRooms, responseDto.data()); - then(roomService).should().bringRoomsFromAPI(accommodation.getId()); + then(roomService).should().bringRoomsFromAPI(anyLong(), anyString(), anyString()); } } diff --git a/src/test/java/ybe/mini/travelserver/domain/room/service/RoomServiceTest.java b/src/test/java/ybe/mini/travelserver/domain/room/service/RoomServiceTest.java index d1ffb04..2afaa1d 100644 --- a/src/test/java/ybe/mini/travelserver/domain/room/service/RoomServiceTest.java +++ b/src/test/java/ybe/mini/travelserver/domain/room/service/RoomServiceTest.java @@ -7,9 +7,11 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import ybe.mini.travelserver.domain.accommodation.entity.Accommodation; +import ybe.mini.travelserver.domain.reservation_room.repository.ReservationRoomRepository; import ybe.mini.travelserver.domain.room.DummyObjectForControllerAndService; import ybe.mini.travelserver.domain.room.dto.RoomGetResponseFromAPI; import ybe.mini.travelserver.domain.room.entity.Room; +import ybe.mini.travelserver.domain.room.repository.RoomRepository; import ybe.mini.travelserver.global.api.TourAPIService; import java.util.Arrays; @@ -17,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; @@ -27,6 +30,12 @@ class RoomServiceTest extends DummyObjectForControllerAndService { @Mock private TourAPIService tourAPIService; + @Mock + ReservationRoomRepository reservationRoomRepository; + + @Mock + RoomRepository roomRepository; + @InjectMocks private RoomService roomService; @@ -41,10 +50,11 @@ void getRooms_success() { List responseDto = expectedRooms.stream() .map(RoomGetResponseFromAPI::fromEntity) .toList(); - given(tourAPIService.bringRooms(eq(accommodation.getId()))).willReturn(expectedRooms); + given(tourAPIService.bringRooms(anyLong())).willReturn(expectedRooms); // when - List actualRooms = roomService.bringRoomsFromAPI(accommodation.getId()); + List actualRooms = + roomService.bringRoomsFromAPI(accommodation.getId(), "20240101", "20240102"); // then assertNotNull(actualRooms);