Skip to content

Commit

Permalink
Merge pull request #108 from wafflestudio/feat/DTO
Browse files Browse the repository at this point in the history
Feat/dto
  • Loading branch information
gs18113 authored Jan 16, 2025
2 parents d381f82 + 1b421de commit c268a53
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 127 deletions.
24 changes: 24 additions & 0 deletions src/main/kotlin/com/example/toyTeam6Airbnb/ValidatePageable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,33 @@ package com.example.toyTeam6Airbnb

import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.http.HttpStatus
import org.springframework.http.HttpStatusCode

fun validatePageable(pageable: Pageable): Pageable {
return PageRequest.of(pageable.pageNumber, pageable.pageSize)
}

fun validateSortedPageable(pageable: Pageable): Pageable {
val allowedSortProperties = listOf("createdAt", "rating")
pageable.sort.forEach { order ->
if (order.property !in allowedSortProperties) {
throw WrongSortingException()
}
}
return PageRequest.of(pageable.pageNumber, pageable.pageSize, pageable.sort)
}

sealed class PageableException(
errorCode: Int,
httpStatusCode: HttpStatusCode,
msg: String,
cause: Throwable? = null
) : DomainException(errorCode, httpStatusCode, msg, cause)

class WrongSortingException : PageableException(
errorCode = 6001,
httpStatusCode = HttpStatus.BAD_REQUEST,
msg = "Wrong form of sorting"
)
// 이후에 rating, review, price 등의 정렬 기준이 추가될 경우 함수를 추가하여 처리할 수 있습니다.
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
package com.example.toyTeam6Airbnb.reservation.controller

import com.example.toyTeam6Airbnb.reservation.persistence.ReservationEntity
import java.time.Instant
import java.time.LocalDate

data class Reservation(
val id: Long,
val userId: Long,
val roomId: Long,
val reviewId: Long?,
val startDate: LocalDate,
val endDate: LocalDate,
val totalPrice: Double,
val numberOfGuests: Int,
val createdAt: Instant,
val updatedAt: Instant
val reservationId: Long
) {
companion object {
fun fromEntity(entity: ReservationEntity): Reservation {
return Reservation(
id = entity.id!!,
userId = entity.user.id!!,
roomId = entity.room.id!!,
reviewId = entity.review?.id,
startDate = entity.startDate,
endDate = entity.endDate,
totalPrice = entity.totalPrice,
createdAt = entity.createdAt,
updatedAt = entity.updatedAt,
numberOfGuests = entity.numberOfGuests
reservationId = entity.id!!
)
}
}
}

data class ReservationDTO(
val id: Long,
val userId: Long,
data class ReservationDetails(
val reservationId: Long,
val roomId: Long,
val startDate: LocalDate,
val endDate: LocalDate,
val place: String,
val numberOfGuests: Int
// val imageUrl: String,
) {
companion object {
fun fromEntity(entity: ReservationEntity): ReservationDTO {
return ReservationDTO(
id = entity.id!!,
userId = entity.user.id!!,
fun fromEntity(entity: ReservationEntity): ReservationDetails {
return ReservationDetails(
reservationId = entity.id!!,
roomId = entity.room.id!!,
startDate = entity.startDate,
endDate = entity.endDate,
place = entity.room.address.sido,
numberOfGuests = entity.numberOfGuests
// imageUrl = entity.room.imageUrl
)
}
}
}

data class ReservationDTO(
val reservationId: Long,
val place: String,
val startDate: LocalDate,
val endDate: LocalDate
// val imageUrl: String,
) {
companion object {
fun fromEntity(entity: ReservationEntity): ReservationDTO {
return ReservationDTO(
reservationId = entity.id!!,
place = entity.room.address.sido,
startDate = entity.startDate,
endDate = entity.endDate
// imageUrl = entity.room.imageUrl
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ReservationController(
fun getReservation(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@PathVariable reservationId: Long
): ResponseEntity<Reservation> {
): ResponseEntity<ReservationDetails> {
val reservation = reservationService.getReservation(principalDetails.getUser().id!!, reservationId)

return ResponseEntity.ok(reservation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.example.toyTeam6Airbnb.reservation.service

import com.example.toyTeam6Airbnb.reservation.controller.Reservation
import com.example.toyTeam6Airbnb.reservation.controller.ReservationDTO
import com.example.toyTeam6Airbnb.reservation.controller.ReservationDetails
import com.example.toyTeam6Airbnb.reservation.controller.RoomAvailabilityResponse
import com.example.toyTeam6Airbnb.user.controller.User
import org.springframework.data.domain.Page
Expand Down Expand Up @@ -35,7 +36,7 @@ interface ReservationService {
fun getReservation(
userId: Long,
reservationId: Long
): Reservation
): ReservationDetails

fun getReservationsByUser(
viewerId: Long?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.example.toyTeam6Airbnb.reservation.ReservationUnavailable
import com.example.toyTeam6Airbnb.reservation.ZeroGuests
import com.example.toyTeam6Airbnb.reservation.controller.Reservation
import com.example.toyTeam6Airbnb.reservation.controller.ReservationDTO
import com.example.toyTeam6Airbnb.reservation.controller.ReservationDetails
import com.example.toyTeam6Airbnb.reservation.controller.RoomAvailabilityResponse
import com.example.toyTeam6Airbnb.reservation.persistence.ReservationEntity
import com.example.toyTeam6Airbnb.reservation.persistence.ReservationRepository
Expand Down Expand Up @@ -129,11 +130,11 @@ class ReservationServiceImpl(
override fun getReservation(
userId: Long,
reservationId: Long
): Reservation {
): ReservationDetails {
val reservationEntity = reservationRepository.findByIdOrNull(reservationId) ?: throw ReservationNotFound()
if (reservationEntity.user.id != userId) throw ReservationPermissionDenied()

return Reservation.fromEntity(reservationEntity)
return ReservationDetails.fromEntity(reservationEntity)
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.example.toyTeam6Airbnb.user.UserNotFoundException
import com.example.toyTeam6Airbnb.user.controller.User
import com.example.toyTeam6Airbnb.user.persistence.UserRepository
import com.example.toyTeam6Airbnb.validatePageable
import com.example.toyTeam6Airbnb.validateSortedPageable
import org.springframework.dao.DataIntegrityViolationException
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
Expand Down Expand Up @@ -68,7 +69,7 @@ class ReviewServiceImpl(
override fun getReviewsByRoom(roomId: Long, pageable: Pageable): Page<ReviewByRoomDTO> {
roomRepository.findByIdOrNull(roomId) ?: throw RoomNotFoundException()

val reviewEntities = reviewRepository.findAllByRoomId(roomId, validatePageable(pageable))
val reviewEntities = reviewRepository.findAllByRoomId(roomId, validateSortedPageable(pageable))

val reviews = reviewEntities.map { ReviewByRoomDTO.fromEntity(it) }
return reviews
Expand Down
66 changes: 40 additions & 26 deletions src/main/kotlin/com/example/toyTeam6Airbnb/room/controller/Room.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,72 +8,86 @@ import com.example.toyTeam6Airbnb.room.persistence.RoomType
import java.time.Instant

data class Room(
val id: Long,
val hostId: Long,
val name: String,
val description: String,
val type: RoomType,
val address: Address,
val price: Price,
val maxOccupancy: Int,
val rating: Double
val roomId: Long,
val roomName: String,
val roomType: RoomType,
val sido: String,
val price: Double,
val averageRating: Double
// val imageUrl: String //대표 이미지 1개만 return
) {
companion object {
fun fromEntity(entity: RoomEntity): Room {
var averageRating = entity.reviews.map { it.rating }.average()
if (averageRating.isNaN()) averageRating = 0.0

return Room(
id = entity.id!!,
hostId = entity.host.id!!,
name = entity.name,
description = entity.description,
type = entity.type,
address = entity.address,
price = entity.price,
maxOccupancy = entity.maxOccupancy,
rating = averageRating
roomId = entity.id!!,
roomName = entity.name,
roomType = entity.type,
sido = entity.address.sido,
price = entity.price.perNight,
averageRating = averageRating
// imageUrl = entity.images.firstOrNull()?.url ?: ""
)
}
}
}

data class RoomDetailsDTO(
val id: Long,
val roomId: Long,
val hostId: Long,
val name: String,
val hostName: String?,
val roomName: String,
val description: String,
val type: RoomType,
val roomType: RoomType,
val address: Address,
val roomDetails: RoomDetails,
val price: Price,
val maxOccupancy: Int,
val rating: Double,
val averageRating: Double,
val reviewCount: Int,
val isSuperHost: Boolean,
val createdAt: Instant,
val updatedAt: Instant
// val imageUrl: List<String>, //방에 대한 모든 image url 전달
) {
companion object {
fun fromEntity(entity: RoomEntity): RoomDetailsDTO {
var averageRating = entity.reviews.map { it.rating }.average()
if (averageRating.isNaN()) averageRating = 0.0

return RoomDetailsDTO(
id = entity.id!!,
roomId = entity.id!!,
hostId = entity.host.id!!,
name = entity.name,
hostName = entity.host.profile?.nickname,
roomName = entity.name,
description = entity.description,
type = entity.type,
roomType = entity.type,
address = entity.address,
roomDetails = entity.roomDetails,
price = entity.price,
maxOccupancy = entity.maxOccupancy,
rating = averageRating,
averageRating = averageRating,
reviewCount = entity.reviews.size,
isSuperHost = entity.host.isSuperhost(),
createdAt = entity.createdAt,
updatedAt = entity.updatedAt
// imageUrl = entity.images.map { imageService(it.url) }
)
}
}
}

data class RoomShortDTO(
val roomId: Long
// val imageUrl: String, // 이미지가 여러 개면 List<String> 형태로 여러 개의 cloudfront url 전달
) {
companion object {
fun fromEntity(entity: RoomEntity): RoomShortDTO {
return RoomShortDTO(
roomId = entity.id!!
// imageUrl = entity.images.map { imageService(it.url) }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ class RoomController(
fun createRoom(
@RequestBody request: CreateRoomRequest,
@AuthenticationPrincipal principalDetails: PrincipalDetails
): ResponseEntity<RoomDetailsDTO> {
): ResponseEntity<RoomShortDTO> {
val room = roomService.createRoom(
hostId = User.fromEntity(principalDetails.getUser()).id,
name = request.name,
name = request.roomName,
description = request.description,
type = request.type,
type = request.roomType,
address = request.address,
roomDetails = request.roomDetails,
price = request.price,
Expand Down Expand Up @@ -75,13 +75,13 @@ class RoomController(
@AuthenticationPrincipal principalDetails: PrincipalDetails,
@PathVariable roomId: Long,
@RequestBody request: UpdateRoomRequest
): ResponseEntity<RoomDetailsDTO> {
): ResponseEntity<RoomShortDTO> {
val updatedRoom = roomService.updateRoom(
User.fromEntity(principalDetails.getUser()).id,
roomId,
request.name,
request.roomName,
request.description,
request.type,
request.roomType,
request.address,
request.roomDetails,
request.price,
Expand All @@ -107,8 +107,8 @@ class RoomController(
@GetMapping("/rooms/main/search")
@Operation(summary = "방 검색", description = "방을 검색합니다(페이지네이션 적용)")
fun searchRooms(
@RequestParam(required = false) name: String?,
@RequestParam(required = false) type: RoomType?,
@RequestParam(required = false) roomName: String?,
@RequestParam(required = false) roomType: RoomType?,
@RequestParam(required = false) minPrice: Double?,
@RequestParam(required = false) maxPrice: Double?,
@RequestParam(required = false) sido: String?,
Expand All @@ -122,7 +122,7 @@ class RoomController(
pageable: Pageable
): ResponseEntity<Page<Room>> {
val address = AddressSearchDTO(sido, sigungu, street, detail)
val rooms = roomService.searchRooms(name, type, minPrice, maxPrice, address, maxOccupancy, rating, startDate, endDate, pageable)
val rooms = roomService.searchRooms(roomName, roomType, minPrice, maxPrice, address, maxOccupancy, rating, startDate, endDate, pageable)
return ResponseEntity.ok(rooms)
}
}
Expand All @@ -135,19 +135,19 @@ data class AddressSearchDTO(
)

data class CreateRoomRequest(
val name: String,
val roomName: String,
val description: String,
val type: RoomType,
val roomType: RoomType,
val address: Address,
val roomDetails: RoomDetails,
val price: Price,
val maxOccupancy: Int
)

data class UpdateRoomRequest(
val name: String,
val roomName: String,
val description: String,
val type: RoomType,
val roomType: RoomType,
val address: Address,
val roomDetails: RoomDetails,
val price: Price,
Expand Down
Loading

0 comments on commit c268a53

Please sign in to comment.