generated from pricelees/issue-pr-template
refactor: 새로 정의된 커스텀 예외를 Service에 반영
This commit is contained in:
parent
2d4b67ad98
commit
faf6e408b6
@ -2,18 +2,19 @@ package roomescape.reservation.business
|
|||||||
|
|
||||||
import org.springframework.data.jpa.domain.Specification
|
import org.springframework.data.jpa.domain.Specification
|
||||||
import org.springframework.data.repository.findByIdOrNull
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
import org.springframework.http.HttpStatus
|
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import roomescape.common.exception.ErrorType
|
|
||||||
import roomescape.common.exception.RoomescapeException
|
|
||||||
import roomescape.member.business.MemberService
|
import roomescape.member.business.MemberService
|
||||||
|
import roomescape.member.infrastructure.persistence.MemberEntity
|
||||||
|
import roomescape.reservation.exception.ReservationErrorCode
|
||||||
|
import roomescape.reservation.exception.ReservationException
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationRepository
|
import roomescape.reservation.infrastructure.persistence.ReservationRepository
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationSearchSpecification
|
import roomescape.reservation.infrastructure.persistence.ReservationSearchSpecification
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationStatus
|
import roomescape.reservation.infrastructure.persistence.ReservationStatus
|
||||||
import roomescape.reservation.web.*
|
import roomescape.reservation.web.*
|
||||||
import roomescape.theme.business.ThemeService
|
import roomescape.theme.business.ThemeService
|
||||||
|
import roomescape.theme.infrastructure.persistence.ThemeEntity
|
||||||
import roomescape.time.business.TimeService
|
import roomescape.time.business.TimeService
|
||||||
import roomescape.time.infrastructure.persistence.TimeEntity
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@ -34,7 +35,6 @@ class ReservationService(
|
|||||||
.confirmed()
|
.confirmed()
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
||||||
return ReservationRetrieveListResponse(findAllReservationByStatus(spec))
|
return ReservationRetrieveListResponse(findAllReservationByStatus(spec))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,17 +56,18 @@ class ReservationService(
|
|||||||
reservationRepository.deleteById(reservationId)
|
reservationRepository.deleteById(reservationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addReservation(request: ReservationCreateWithPaymentRequest, memberId: Long): ReservationEntity {
|
fun createConfirmedReservation(
|
||||||
validateIsReservationExist(request.themeId, request.timeId, request.date)
|
request: ReservationCreateWithPaymentRequest,
|
||||||
return getReservationForSave(
|
memberId: Long
|
||||||
request.timeId,
|
): ReservationEntity {
|
||||||
request.themeId,
|
val themeId = request.themeId
|
||||||
request.date,
|
val timeId = request.timeId
|
||||||
memberId,
|
val date: LocalDate = request.date
|
||||||
ReservationStatus.CONFIRMED
|
validateIsReservationExist(themeId, timeId, date)
|
||||||
).also {
|
|
||||||
reservationRepository.save(it)
|
val reservation: ReservationEntity = createEntity(timeId, themeId, date, memberId, ReservationStatus.CONFIRMED)
|
||||||
}
|
|
||||||
|
return reservationRepository.save(reservation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createReservationByAdmin(request: AdminReservationCreateRequest): ReservationRetrieveResponse {
|
fun createReservationByAdmin(request: AdminReservationCreateRequest): ReservationRetrieveResponse {
|
||||||
@ -98,12 +99,12 @@ class ReservationService(
|
|||||||
date: LocalDate,
|
date: LocalDate,
|
||||||
memberId: Long,
|
memberId: Long,
|
||||||
status: ReservationStatus
|
status: ReservationStatus
|
||||||
): ReservationRetrieveResponse = getReservationForSave(timeId, themeId, date, memberId, status)
|
): ReservationRetrieveResponse = createEntity(timeId, themeId, date, memberId, status)
|
||||||
.also {
|
.also {
|
||||||
reservationRepository.save(it)
|
reservationRepository.save(it)
|
||||||
}.toRetrieveResponse()
|
}.toRetrieveResponse()
|
||||||
|
|
||||||
private fun validateMemberAlreadyReserve(themeId: Long?, timeId: Long?, date: LocalDate?, memberId: Long?) {
|
private fun validateMemberAlreadyReserve(themeId: Long, timeId: Long, date: LocalDate, memberId: Long) {
|
||||||
val spec: Specification<ReservationEntity> = ReservationSearchSpecification()
|
val spec: Specification<ReservationEntity> = ReservationSearchSpecification()
|
||||||
.sameMemberId(memberId)
|
.sameMemberId(memberId)
|
||||||
.sameThemeId(themeId)
|
.sameThemeId(themeId)
|
||||||
@ -112,7 +113,7 @@ class ReservationService(
|
|||||||
.build()
|
.build()
|
||||||
|
|
||||||
if (reservationRepository.exists(spec)) {
|
if (reservationRepository.exists(spec)) {
|
||||||
throw RoomescapeException(ErrorType.HAS_RESERVATION_OR_WAITING, HttpStatus.BAD_REQUEST)
|
throw ReservationException(ReservationErrorCode.ALREADY_RESERVE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ class ReservationService(
|
|||||||
.build()
|
.build()
|
||||||
|
|
||||||
if (reservationRepository.exists(spec)) {
|
if (reservationRepository.exists(spec)) {
|
||||||
throw RoomescapeException(ErrorType.RESERVATION_DUPLICATED, HttpStatus.CONFLICT)
|
throw ReservationException(ReservationErrorCode.RESERVATION_DUPLICATED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,24 +138,20 @@ class ReservationService(
|
|||||||
val request = LocalDateTime.of(requestDate, requestTime.startAt)
|
val request = LocalDateTime.of(requestDate, requestTime.startAt)
|
||||||
|
|
||||||
if (request.isBefore(now)) {
|
if (request.isBefore(now)) {
|
||||||
throw RoomescapeException(
|
throw ReservationException(ReservationErrorCode.PAST_REQUEST_DATETIME)
|
||||||
ErrorType.RESERVATION_PERIOD_IN_PAST,
|
|
||||||
"[now: $now | request: $request]",
|
|
||||||
HttpStatus.BAD_REQUEST
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getReservationForSave(
|
private fun createEntity(
|
||||||
timeId: Long,
|
timeId: Long,
|
||||||
themeId: Long,
|
themeId: Long,
|
||||||
date: LocalDate,
|
date: LocalDate,
|
||||||
memberId: Long,
|
memberId: Long,
|
||||||
status: ReservationStatus
|
status: ReservationStatus
|
||||||
): ReservationEntity {
|
): ReservationEntity {
|
||||||
val time = timeService.findById(timeId)
|
val time: TimeEntity = timeService.findById(timeId)
|
||||||
val theme = themeService.findById(themeId)
|
val theme: ThemeEntity = themeService.findById(themeId)
|
||||||
val member = memberService.findById(memberId)
|
val member: MemberEntity = memberService.findById(memberId)
|
||||||
|
|
||||||
validateDateAndTime(date, time)
|
validateDateAndTime(date, time)
|
||||||
|
|
||||||
@ -191,58 +188,54 @@ class ReservationService(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (startFrom.isAfter(endAt)) {
|
if (startFrom.isAfter(endAt)) {
|
||||||
throw RoomescapeException(
|
throw ReservationException(ReservationErrorCode.INVALID_SEARCH_DATE_RANGE)
|
||||||
ErrorType.INVALID_DATE_RANGE,
|
|
||||||
"[startFrom: $startFrom, endAt: $endAt", HttpStatus.BAD_REQUEST
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
fun findReservationsByMemberId(memberId: Long): MyReservationRetrieveListResponse {
|
fun findReservationsByMemberId(memberId: Long): MyReservationRetrieveListResponse {
|
||||||
return MyReservationRetrieveListResponse(reservationRepository.findAllById(memberId))
|
return MyReservationRetrieveListResponse(reservationRepository.findAllByMemberId(memberId))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun confirmWaiting(reservationId: Long, memberId: Long) {
|
fun confirmWaiting(reservationId: Long, memberId: Long) {
|
||||||
validateIsMemberAdmin(memberId)
|
validateIsMemberAdmin(memberId)
|
||||||
if (reservationRepository.isExistConfirmedReservation(reservationId)) {
|
if (reservationRepository.isExistConfirmedReservation(reservationId)) {
|
||||||
throw RoomescapeException(ErrorType.RESERVATION_DUPLICATED, HttpStatus.CONFLICT)
|
throw ReservationException(ReservationErrorCode.CONFIRMED_RESERVATION_ALREADY_EXISTS)
|
||||||
}
|
}
|
||||||
reservationRepository.updateStatusByReservationId(reservationId, ReservationStatus.CONFIRMED_PAYMENT_REQUIRED)
|
reservationRepository.updateStatusByReservationId(reservationId, ReservationStatus.CONFIRMED_PAYMENT_REQUIRED)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteWaiting(reservationId: Long, memberId: Long) {
|
fun deleteWaiting(reservationId: Long, memberId: Long) {
|
||||||
reservationRepository.findByIdOrNull(reservationId)?.takeIf {
|
val reservation: ReservationEntity = findReservationOrThrow(reservationId)
|
||||||
it.isWaiting() && it.isSameMember(memberId)
|
if (!reservation.isWaiting()) {
|
||||||
}?.let {
|
throw ReservationException(ReservationErrorCode.ALREADY_CONFIRMED)
|
||||||
reservationRepository.delete(it)
|
}
|
||||||
} ?: throw throwReservationNotFound(reservationId)
|
if (!reservation.isReservedBy(memberId)) {
|
||||||
|
throw ReservationException(ReservationErrorCode.NOT_RESERVATION_OWNER)
|
||||||
|
}
|
||||||
|
reservationRepository.delete(reservation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rejectWaiting(reservationId: Long, memberId: Long) {
|
fun rejectWaiting(reservationId: Long, memberId: Long) {
|
||||||
validateIsMemberAdmin(memberId)
|
validateIsMemberAdmin(memberId)
|
||||||
reservationRepository.findByIdOrNull(reservationId)?.takeIf {
|
val reservation: ReservationEntity = findReservationOrThrow(reservationId)
|
||||||
it.isWaiting()
|
|
||||||
}?.let {
|
if (!reservation.isWaiting()) {
|
||||||
reservationRepository.delete(it)
|
throw ReservationException(ReservationErrorCode.ALREADY_CONFIRMED)
|
||||||
} ?: throw throwReservationNotFound(reservationId)
|
}
|
||||||
|
reservationRepository.delete(reservation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateIsMemberAdmin(memberId: Long) {
|
private fun validateIsMemberAdmin(memberId: Long) {
|
||||||
memberService.findById(memberId).takeIf {
|
val member: MemberEntity = memberService.findById(memberId)
|
||||||
it.isAdmin()
|
if (member.isAdmin()) {
|
||||||
} ?: throw RoomescapeException(
|
return
|
||||||
ErrorType.PERMISSION_DOES_NOT_EXIST,
|
}
|
||||||
"[memberId: $memberId]",
|
throw ReservationException(ReservationErrorCode.NO_PERMISSION)
|
||||||
HttpStatus.FORBIDDEN
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun throwReservationNotFound(reservationId: Long?): RoomescapeException {
|
private fun findReservationOrThrow(reservationId: Long): ReservationEntity {
|
||||||
return RoomescapeException(
|
return reservationRepository.findByIdOrNull(reservationId)
|
||||||
ErrorType.RESERVATION_NOT_FOUND,
|
?: throw ReservationException(ReservationErrorCode.RESERVATION_NOT_FOUND)
|
||||||
"[reservationId: $reservationId]",
|
|
||||||
HttpStatus.NOT_FOUND
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class ReservationWithPaymentService(
|
|||||||
paymentInfo: PaymentApproveResponse,
|
paymentInfo: PaymentApproveResponse,
|
||||||
memberId: Long
|
memberId: Long
|
||||||
): ReservationRetrieveResponse {
|
): ReservationRetrieveResponse {
|
||||||
val reservation: ReservationEntity = reservationService.addReservation(request, memberId)
|
val reservation: ReservationEntity = reservationService.createConfirmedReservation(request, memberId)
|
||||||
|
|
||||||
return paymentService.createPayment(paymentInfo, reservation)
|
return paymentService.createPayment(paymentInfo, reservation)
|
||||||
.reservation
|
.reservation
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class ReservationEntity(
|
|||||||
fun isWaiting(): Boolean = reservationStatus == ReservationStatus.WAITING
|
fun isWaiting(): Boolean = reservationStatus == ReservationStatus.WAITING
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
fun isSameMember(memberId: Long): Boolean {
|
fun isReservedBy(memberId: Long): Boolean {
|
||||||
return this.member.id == memberId
|
return this.member.id == memberId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,5 +59,5 @@ interface ReservationRepository
|
|||||||
ON p.reservation = r
|
ON p.reservation = r
|
||||||
WHERE r.member.id = :memberId
|
WHERE r.member.id = :memberId
|
||||||
""")
|
""")
|
||||||
fun findAllById(memberId: Long): List<MyReservationRetrieveResponse>
|
fun findAllByMemberId(memberId: Long): List<MyReservationRetrieveResponse>
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user