generated from pricelees/issue-pr-template
78 lines
3.2 KiB
Kotlin
78 lines
3.2 KiB
Kotlin
package roomescape.schedule.business
|
|
|
|
import ScheduleException
|
|
import io.github.oshai.kotlinlogging.KLogger
|
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
|
import org.springframework.stereotype.Component
|
|
import roomescape.schedule.exception.ScheduleErrorCode
|
|
import roomescape.schedule.infrastructure.persistence.ScheduleEntity
|
|
import roomescape.schedule.infrastructure.persistence.ScheduleRepository
|
|
import roomescape.schedule.infrastructure.persistence.ScheduleStatus
|
|
import roomescape.schedule.web.ScheduleCreateRequest
|
|
import roomescape.schedule.web.ScheduleUpdateRequest
|
|
import java.time.LocalDate
|
|
import java.time.LocalDateTime
|
|
import java.time.LocalTime
|
|
|
|
private val log: KLogger = KotlinLogging.logger {}
|
|
|
|
@Component
|
|
class ScheduleValidator(
|
|
private val scheduleRepository: ScheduleRepository
|
|
) {
|
|
fun validateCanDelete(schedule: ScheduleEntity) {
|
|
val status: ScheduleStatus = schedule.status
|
|
|
|
if (status !in listOf(ScheduleStatus.AVAILABLE, ScheduleStatus.BLOCKED)) {
|
|
log.info { "[ScheduleValidator.validateCanDelete] 삭제 실패: id=${schedule.id} / status=${status}" }
|
|
throw ScheduleException(ScheduleErrorCode.SCHEDULE_IN_USE)
|
|
}
|
|
}
|
|
|
|
fun validateCanUpdate(schedule: ScheduleEntity, request: ScheduleUpdateRequest) {
|
|
val date: LocalDate = schedule.date
|
|
val time: LocalTime = request.time ?: schedule.time
|
|
|
|
validateNotInPast(date, time)
|
|
}
|
|
|
|
fun validateCanCreate(storeId: Long, request: ScheduleCreateRequest) {
|
|
val date: LocalDate = request.date
|
|
val time: LocalTime = request.time
|
|
val themeId: Long = request.themeId
|
|
|
|
validateAlreadyExists(storeId, date, themeId, time)
|
|
validateNotInPast(date, time)
|
|
validateTimeNotConflict(storeId, request.date, request.themeId, request.time)
|
|
}
|
|
|
|
private fun validateAlreadyExists(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime) {
|
|
if (scheduleRepository.existsDuplicate(storeId, date, themeId, time)) {
|
|
log.info {
|
|
"[ScheduleValidator.validateAlreadyExists] 동일한 날짜, 테마, 시간 존재로 인한 실패: date=${date} / themeId=${themeId} / time=${time}"
|
|
}
|
|
throw ScheduleException(ScheduleErrorCode.SCHEDULE_ALREADY_EXISTS)
|
|
}
|
|
}
|
|
|
|
private fun validateNotInPast(date: LocalDate, time: LocalTime) {
|
|
val dateTime = LocalDateTime.of(date, time)
|
|
|
|
if (dateTime.isBefore(LocalDateTime.now())) {
|
|
log.info {
|
|
"[ScheduleValidator.validateDateTime] 이전 시간 선택으로 인한 실패: date=${date} / time=${time}"
|
|
}
|
|
throw ScheduleException(ScheduleErrorCode.PAST_DATE_TIME)
|
|
}
|
|
}
|
|
|
|
private fun validateTimeNotConflict(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime) {
|
|
scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date, themeId)
|
|
.firstOrNull { it.containsTime(time) }
|
|
?.let {
|
|
log.info { "[ScheduleValidator.validateTimeNotConflict] 시간이 겹치는 일정 존재: conflictSchedule(Id=${it.id}, time=${it.time}~${it.getEndAt()})" }
|
|
throw ScheduleException(ScheduleErrorCode.SCHEDULE_TIME_CONFLICT)
|
|
}
|
|
}
|
|
}
|