generated from pricelees/issue-pr-template
feat: 결제 & 예약 확정 과정에서 필요한 검증 로직 추가
This commit is contained in:
parent
985efbe0a3
commit
6be9ae7efe
@ -0,0 +1,76 @@
|
||||
package com.sangdol.roomescape.order.business
|
||||
|
||||
import com.sangdol.common.utils.KoreaDateTime
|
||||
import com.sangdol.roomescape.order.exception.OrderErrorCode
|
||||
import com.sangdol.roomescape.order.exception.OrderException
|
||||
import com.sangdol.roomescape.order.infrastructure.persistence.PaymentAttemptRepository
|
||||
import com.sangdol.roomescape.reservation.dto.ReservationStateResponse
|
||||
import com.sangdol.roomescape.reservation.infrastructure.persistence.ReservationStatus
|
||||
import com.sangdol.roomescape.schedule.dto.ScheduleStateResponse
|
||||
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleStatus
|
||||
import io.github.oshai.kotlinlogging.KLogger
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
|
||||
private val log: KLogger = KotlinLogging.logger {}
|
||||
|
||||
@Component
|
||||
class OrderValidator(
|
||||
private val paymentAttemptRepository: PaymentAttemptRepository
|
||||
) {
|
||||
fun validateCanConfirm(
|
||||
reservation: ReservationStateResponse,
|
||||
schedule: ScheduleStateResponse
|
||||
) {
|
||||
if (paymentAttemptRepository.isSuccessAttemptExists(reservation.id)) {
|
||||
log.info { "[validateCanConfirm] 이미 결제 완료된 예약: id=${reservation.id}" }
|
||||
throw OrderException(OrderErrorCode.BOOKING_ALREADY_COMPLETED)
|
||||
}
|
||||
|
||||
validateReservationStatus(reservation)
|
||||
validateScheduleStatus(schedule)
|
||||
}
|
||||
|
||||
private fun validateReservationStatus(reservation: ReservationStateResponse) {
|
||||
when (reservation.status) {
|
||||
ReservationStatus.CONFIRMED -> {
|
||||
log.info { "[validateCanConfirm] 이미 확정된 예약: id=${reservation.id}" }
|
||||
throw OrderException(OrderErrorCode.BOOKING_ALREADY_COMPLETED)
|
||||
}
|
||||
ReservationStatus.EXPIRED -> {
|
||||
log.info { "[validateCanConfirm] 만료된 예약 예약: id=${reservation.id}" }
|
||||
throw OrderException(OrderErrorCode.EXPIRED_RESERVATION)
|
||||
}
|
||||
ReservationStatus.CANCELED -> {
|
||||
log.info { "[validateCanConfirm] 취소된 예약 예약: id=${reservation.id}" }
|
||||
throw OrderException(OrderErrorCode.CANCELED_RESERVATION)
|
||||
}
|
||||
ReservationStatus.PENDING -> {
|
||||
val pendingExpiredAt = reservation.createdAt.plusSeconds(5 * 60)
|
||||
val now = Instant.now()
|
||||
|
||||
if (now.isAfter(pendingExpiredAt)) {
|
||||
log.info { "[validateCanConfirm] Pending 예약 시간 내 미결제로 인한 실패: id=${reservation.id}, expiredAt=${pendingExpiredAt}, now=${now}" }
|
||||
throw OrderException(OrderErrorCode.BOOKING_PAYMENT_TIMEOUT)
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateScheduleStatus(schedule: ScheduleStateResponse) {
|
||||
if (schedule.status != ScheduleStatus.HOLD) {
|
||||
log.info { "[validateScheduleStatus] 일정 상태 오류: status=${schedule.status}" }
|
||||
throw OrderException(OrderErrorCode.EXPIRED_RESERVATION)
|
||||
}
|
||||
|
||||
val scheduleDateTime = LocalDateTime.of(schedule.date, schedule.startFrom)
|
||||
val nowDateTime = KoreaDateTime.now()
|
||||
if (scheduleDateTime.isBefore(nowDateTime)) {
|
||||
log.info { "[validateScheduleStatus] 과거 시간인 일정으로 인한 실패: scheduleDateTime=${scheduleDateTime}(KST), now=${nowDateTime}(KST)" }
|
||||
throw OrderException(OrderErrorCode.PAST_SCHEDULE)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user