generated from pricelees/issue-pr-template
[#30] 코드 구조 개선 #31
@ -0,0 +1,34 @@
|
|||||||
|
package roomescape.reservation.implement
|
||||||
|
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
||||||
|
import roomescape.reservation.infrastructure.persistence.ReservationRepository
|
||||||
|
import roomescape.theme.infrastructure.persistence.ThemeEntity
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class ReservationFinder(
|
||||||
|
private val reservationRepository: ReservationRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun isTimeReserved(time: TimeEntity): Boolean {
|
||||||
|
log.debug { "[ReservationFinder.isTimeReserved] 시작: timeId=${time.id}, startAt=${time.startAt}" }
|
||||||
|
|
||||||
|
return reservationRepository.existsByTime(time)
|
||||||
|
.also { log.debug { "[ReservationFinder.isTimeReserved] 완료: isExist=$it, timeId=${time.id}, startAt=${time.startAt}" } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findAllByDateAndTheme(
|
||||||
|
date: LocalDate, theme: ThemeEntity
|
||||||
|
): List<ReservationEntity> {
|
||||||
|
log.debug { "[ReservationFinder.findAllByDateAndTheme] 시작: date=$date, themeId=${theme.id}" }
|
||||||
|
|
||||||
|
return reservationRepository.findAllByDateAndTheme(date, theme)
|
||||||
|
.also { log.debug { "[ReservationFinder.findAllByDateAndTheme] ${it.size}개 조회 완료: date=$date, themeId=${theme.id}" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package roomescape.reservation.implement
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.reservation.infrastructure.persistence.ReservationRepository
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class ReservationValidator(
|
||||||
|
private val reservationRepository: ReservationRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
@ -6,12 +6,14 @@ import org.springframework.data.jpa.repository.Modifying
|
|||||||
import org.springframework.data.jpa.repository.Query
|
import org.springframework.data.jpa.repository.Query
|
||||||
import org.springframework.data.repository.query.Param
|
import org.springframework.data.repository.query.Param
|
||||||
import roomescape.reservation.web.MyReservationRetrieveResponse
|
import roomescape.reservation.web.MyReservationRetrieveResponse
|
||||||
|
import roomescape.theme.infrastructure.persistence.ThemeEntity
|
||||||
import roomescape.time.infrastructure.persistence.TimeEntity
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
||||||
interface ReservationRepository
|
interface ReservationRepository
|
||||||
: JpaRepository<ReservationEntity, Long>, JpaSpecificationExecutor<ReservationEntity> {
|
: JpaRepository<ReservationEntity, Long>, JpaSpecificationExecutor<ReservationEntity> {
|
||||||
fun findAllByTime(time: TimeEntity): List<ReservationEntity>
|
fun findAllByTime(time: TimeEntity): List<ReservationEntity>
|
||||||
|
fun existsByTime(time: TimeEntity): Boolean
|
||||||
|
|
||||||
fun findByDateAndThemeId(date: LocalDate, themeId: Long): List<ReservationEntity>
|
fun findByDateAndThemeId(date: LocalDate, themeId: Long): List<ReservationEntity>
|
||||||
|
|
||||||
@ -20,11 +22,11 @@ interface ReservationRepository
|
|||||||
"""
|
"""
|
||||||
UPDATE ReservationEntity r
|
UPDATE ReservationEntity r
|
||||||
SET r.status = :status
|
SET r.status = :status
|
||||||
WHERE r.id = :id
|
WHERE r._id = :_id
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun updateStatusByReservationId(
|
fun updateStatusByReservationId(
|
||||||
@Param(value = "id") reservationId: Long,
|
@Param(value = "_id") reservationId: Long,
|
||||||
@Param(value = "status") statusForChange: ReservationStatus
|
@Param(value = "status") statusForChange: ReservationStatus
|
||||||
): Int
|
): Int
|
||||||
|
|
||||||
@ -33,28 +35,28 @@ interface ReservationRepository
|
|||||||
SELECT EXISTS (
|
SELECT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM ReservationEntity r2
|
FROM ReservationEntity r2
|
||||||
WHERE r2.id = :id
|
WHERE r2._id = :_id
|
||||||
AND EXISTS (
|
AND EXISTS (
|
||||||
SELECT 1 FROM ReservationEntity r
|
SELECT 1 FROM ReservationEntity r
|
||||||
WHERE r.theme.id = r2.theme.id
|
WHERE r.theme._id = r2.theme._id
|
||||||
AND r.time.id = r2.time.id
|
AND r.time._id = r2.time._id
|
||||||
AND r.date = r2.date
|
AND r.date = r2.date
|
||||||
AND r.status != 'WAITING'
|
AND r.status != 'WAITING'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun isExistConfirmedReservation(@Param("id") reservationId: Long): Boolean
|
fun isExistConfirmedReservation(@Param("_id") reservationId: Long): Boolean
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""
|
"""
|
||||||
SELECT new roomescape.reservation.web.MyReservationRetrieveResponse(
|
SELECT new roomescape.reservation.web.MyReservationRetrieveResponse(
|
||||||
r.id,
|
r._id,
|
||||||
t.name,
|
t.name,
|
||||||
r.date,
|
r.date,
|
||||||
r.time.startAt,
|
r.time.startAt,
|
||||||
r.status,
|
r.status,
|
||||||
(SELECT COUNT (r2) * 1L FROM ReservationEntity r2 WHERE r2.theme = r.theme AND r2.date = r.date AND r2.time = r.time AND r2.id < r.id),
|
(SELECT COUNT (r2) * 1L FROM ReservationEntity r2 WHERE r2.theme = r.theme AND r2.date = r.date AND r2.time = r.time AND r2._id < r._id),
|
||||||
p.paymentKey,
|
p.paymentKey,
|
||||||
p.totalAmount
|
p.totalAmount
|
||||||
)
|
)
|
||||||
@ -62,8 +64,9 @@ interface ReservationRepository
|
|||||||
JOIN r.theme t
|
JOIN r.theme t
|
||||||
LEFT JOIN PaymentEntity p
|
LEFT JOIN PaymentEntity p
|
||||||
ON p.reservation = r
|
ON p.reservation = r
|
||||||
WHERE r.member.id = :memberId
|
WHERE r.member._id = :memberId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun findAllByMemberId(memberId: Long): List<MyReservationRetrieveResponse>
|
fun findAllByMemberId(memberId: Long): List<MyReservationRetrieveResponse>
|
||||||
|
fun findAllByDateAndTheme(date: LocalDate, theme: ThemeEntity): List<ReservationEntity>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package roomescape.theme.business.domain
|
||||||
|
|
||||||
|
import roomescape.time.web.TimeWithAvailabilityResponse
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
|
class TimeWithAvailability(
|
||||||
|
private val timeId: Long,
|
||||||
|
private val startAt: LocalTime,
|
||||||
|
private val date: LocalDate,
|
||||||
|
private val themeId: Long,
|
||||||
|
private val isReservable: Boolean
|
||||||
|
) {
|
||||||
|
fun toResponse() = TimeWithAvailabilityResponse(
|
||||||
|
id = timeId,
|
||||||
|
startAt = startAt,
|
||||||
|
isAvailable = isReservable
|
||||||
|
)
|
||||||
|
}
|
||||||
28
src/main/kotlin/roomescape/theme/implement/ThemeFinder.kt
Normal file
28
src/main/kotlin/roomescape/theme/implement/ThemeFinder.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package roomescape.theme.implement
|
||||||
|
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.theme.exception.ThemeErrorCode
|
||||||
|
import roomescape.theme.exception.ThemeException
|
||||||
|
import roomescape.theme.infrastructure.persistence.ThemeEntity
|
||||||
|
import roomescape.theme.infrastructure.persistence.ThemeRepository
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class ThemeFinder(
|
||||||
|
private val themeRepository: ThemeRepository
|
||||||
|
) {
|
||||||
|
fun findById(id: Long): ThemeEntity {
|
||||||
|
log.debug { "[ThemeFinder.findById] 조회 시작: memberId=$id" }
|
||||||
|
|
||||||
|
return themeRepository.findByIdOrNull(id)
|
||||||
|
?.also { log.debug { "[ThemeFinder.findById] 조회 완료: id=$id, name=${it.name}" } }
|
||||||
|
?: run {
|
||||||
|
log.warn { "[ThemeFinder.findById] 조회 실패: id=$id" }
|
||||||
|
throw ThemeException(ThemeErrorCode.THEME_NOT_FOUND)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,12 @@
|
|||||||
package roomescape.time.business
|
package roomescape.time.business
|
||||||
|
|
||||||
import com.github.f4b6a3.tsid.TsidFactory
|
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
import org.springframework.data.repository.findByIdOrNull
|
|
||||||
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.config.next
|
import roomescape.theme.business.domain.TimeWithAvailability
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
import roomescape.time.implement.TimeFinder
|
||||||
import roomescape.reservation.infrastructure.persistence.ReservationRepository
|
import roomescape.time.implement.TimeWriter
|
||||||
import roomescape.time.exception.TimeErrorCode
|
|
||||||
import roomescape.time.exception.TimeException
|
|
||||||
import roomescape.time.infrastructure.persistence.TimeEntity
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
import roomescape.time.infrastructure.persistence.TimeRepository
|
|
||||||
import roomescape.time.web.*
|
import roomescape.time.web.*
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalTime
|
import java.time.LocalTime
|
||||||
@ -20,87 +15,53 @@ private val log = KotlinLogging.logger {}
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
class TimeService(
|
class TimeService(
|
||||||
private val tsidFactory: TsidFactory,
|
private val timeFinder: TimeFinder,
|
||||||
private val timeRepository: TimeRepository,
|
private val timeWriter: TimeWriter,
|
||||||
private val reservationRepository: ReservationRepository,
|
|
||||||
) {
|
) {
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
fun findById(id: Long): TimeEntity {
|
fun findById(id: Long): TimeEntity {
|
||||||
log.debug { "[TimeService.findById] 시간 조회 시작: timeId=$id" }
|
log.info { "[TimeService.findById] 시작: timeId=$id" }
|
||||||
return timeRepository.findByIdOrNull(id)
|
|
||||||
?.also { log.info { "[TimeService.findById] 시간 조회 완료: timeId=$id" } }
|
return timeFinder.findById(id)
|
||||||
?: run {
|
.also { log.info { "[TimeService.findById] 완료: timeId=$id, startAt=${it.startAt}" } }
|
||||||
log.warn { "[TimeService.findById] 시간 조회 실패: timeId=$id" }
|
|
||||||
throw TimeException(TimeErrorCode.TIME_NOT_FOUND)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
fun findTimes(): TimeRetrieveListResponse {
|
fun findTimes(): TimeRetrieveListResponse {
|
||||||
log.debug { "[TimeService.findTimes] 모든 시간 조회 시작" }
|
log.info { "[TimeService.findTimes] 시작" }
|
||||||
return timeRepository.findAll()
|
|
||||||
.also { log.info { "[TimeService.findTimes] ${it.size}개의 시간 조회 완료" } }
|
return timeFinder.findAll()
|
||||||
.toResponse()
|
.toResponse()
|
||||||
}
|
.also { log.info { "[TimeService.findTimes] 완료. ${it.times.size}개 반환" } }
|
||||||
|
|
||||||
@Transactional
|
|
||||||
fun createTime(request: TimeCreateRequest): TimeCreateResponse {
|
|
||||||
log.debug { "[TimeService.createTime] 시간 생성 시작: startAt=${request.startAt}" }
|
|
||||||
|
|
||||||
val startAt: LocalTime = request.startAt
|
|
||||||
if (timeRepository.existsByStartAt(startAt)) {
|
|
||||||
log.info { "[TimeService.createTime] 시간 생성 실패(시간 중복): startAt=$startAt" }
|
|
||||||
throw TimeException(TimeErrorCode.TIME_DUPLICATED)
|
|
||||||
}
|
|
||||||
|
|
||||||
val time = TimeEntity(
|
|
||||||
_id = tsidFactory.next(),
|
|
||||||
startAt = request.startAt
|
|
||||||
)
|
|
||||||
return timeRepository.save(time)
|
|
||||||
.also { log.info { "[TimeService.createTime] 시간 생성 완료: timeId=${it.id}" } }
|
|
||||||
.toCreateResponse()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
fun deleteTime(id: Long) {
|
|
||||||
log.debug { "[TimeService.deleteTime] 시간 삭제 시작: timeId=$id" }
|
|
||||||
|
|
||||||
val time: TimeEntity = findById(id)
|
|
||||||
|
|
||||||
log.debug { "[TimeService.deleteTime] 시간이 ${time.startAt}인 모든 예약 조회 시작" }
|
|
||||||
val reservations: List<ReservationEntity> = reservationRepository.findAllByTime(time)
|
|
||||||
log.debug { "[TimeService.deleteTime] 시간이 ${time.startAt}인 모든 ${reservations.size} 개의 예약 조회 완료" }
|
|
||||||
|
|
||||||
if (reservations.isNotEmpty()) {
|
|
||||||
log.info { "[TimeService.deleteTime] 시간 삭제 실패(예약이 있는 시간): timeId=$id" }
|
|
||||||
throw TimeException(TimeErrorCode.TIME_ALREADY_RESERVED)
|
|
||||||
}
|
|
||||||
|
|
||||||
timeRepository.delete(time)
|
|
||||||
.also { log.info { "[TimeService.deleteTime] 시간 삭제 완료: timeId=$id" } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
fun findTimesWithAvailability(date: LocalDate, themeId: Long): TimeWithAvailabilityListResponse {
|
fun findTimesWithAvailability(date: LocalDate, themeId: Long): TimeWithAvailabilityListResponse {
|
||||||
log.debug { "[TimeService.findTimesWithAvailability] 예약 가능 시간 조회 시작: date=$date, themeId=$themeId" }
|
log.info { "[TimeService.findTimesWithAvailability] 시작: date=$date, themeId=$themeId" }
|
||||||
|
|
||||||
log.debug { "[TimeService.findTimesWithAvailability] 모든 시간 조회 " }
|
val times: List<TimeWithAvailability> = timeFinder.findAllWithAvailabilityByDateAndThemeId(date, themeId)
|
||||||
val allTimes = timeRepository.findAll()
|
|
||||||
log.debug { "[TimeService.findTimesWithAvailability] ${allTimes.size}개의 시간 조회 완료" }
|
|
||||||
|
|
||||||
log.debug { "[TimeService.findTimesWithAvailability] date=$date, themeId=$themeId 인 모든 예약 조회 시작" }
|
return TimeWithAvailabilityListResponse(times.map { it.toResponse() })
|
||||||
val reservations: List<ReservationEntity> = reservationRepository.findByDateAndThemeId(date, themeId)
|
.also { log.info { "[TimeService.findTimesWithAvailability] ${it.times.size}개 반환: date=$date, themeId=$themeId" } }
|
||||||
log.debug { "[TimeService.findTimesWithAvailability] date=$date, themeId=$themeId 인 ${reservations.size} 개의 예약 조회 완료" }
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun createTime(request: TimeCreateRequest): TimeCreateResponse {
|
||||||
|
val startAt: LocalTime = request.startAt
|
||||||
|
log.info { "[TimeService.createTime] 시작: startAt=${startAt}" }
|
||||||
|
|
||||||
return TimeWithAvailabilityListResponse(allTimes.map { time ->
|
return timeWriter.create(startAt)
|
||||||
val isAvailable: Boolean = reservations.none { reservation -> reservation.time.id == time.id }
|
.toCreateResponse()
|
||||||
TimeWithAvailabilityResponse(time.id!!, time.startAt, isAvailable)
|
.also { log.info { "[TimeService.createTime] 완료: startAt=${startAt}, timeId=${it.id}" } }
|
||||||
}).also {
|
}
|
||||||
log.info {
|
|
||||||
"[TimeService.findTimesWithAvailability] date=$date, themeId=$themeId 에 대한 예약 가능 여부가 담긴 모든 시간 조회 완료"
|
@Transactional
|
||||||
}
|
fun deleteTime(id: Long) {
|
||||||
}
|
log.info { "[TimeService.deleteTime] 시작: timeId=$id" }
|
||||||
|
|
||||||
|
val time: TimeEntity = timeFinder.findById(id)
|
||||||
|
|
||||||
|
timeWriter.delete(time)
|
||||||
|
.also { log.info { "[TimeService.deleteTime] 완료: timeId=$id, startAt=${time.startAt}" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
src/main/kotlin/roomescape/time/implement/TimeFinder.kt
Normal file
60
src/main/kotlin/roomescape/time/implement/TimeFinder.kt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package roomescape.time.implement
|
||||||
|
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.reservation.implement.ReservationFinder
|
||||||
|
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
||||||
|
import roomescape.theme.business.domain.TimeWithAvailability
|
||||||
|
import roomescape.theme.implement.ThemeFinder
|
||||||
|
import roomescape.time.exception.TimeErrorCode
|
||||||
|
import roomescape.time.exception.TimeException
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeRepository
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class TimeFinder(
|
||||||
|
private val timeRepository: TimeRepository,
|
||||||
|
private val reservationFinder: ReservationFinder,
|
||||||
|
private val themeFinder: ThemeFinder
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun findAll(): List<TimeEntity> {
|
||||||
|
log.debug { "[TimeFinder.findAll] 시작" }
|
||||||
|
|
||||||
|
return timeRepository.findAll()
|
||||||
|
.also { log.debug { "[TimeFinder.findAll] ${it.size}개 시간 조회 완료" } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findById(id: Long): TimeEntity {
|
||||||
|
log.debug { "[TimeFinder.findById] 조회 시작: timeId=$id" }
|
||||||
|
|
||||||
|
return timeRepository.findByIdOrNull(id)
|
||||||
|
?.also { log.debug { "[TimeFinder.findById] 조회 완료: timeId=$id, startAt=${it.startAt}" } }
|
||||||
|
?: run {
|
||||||
|
log.warn { "[TimeFinder.findById] 조회 실패: timeId=$id" }
|
||||||
|
throw TimeException(TimeErrorCode.TIME_NOT_FOUND)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findAllWithAvailabilityByDateAndThemeId(
|
||||||
|
date: LocalDate, themeId: Long
|
||||||
|
): List<TimeWithAvailability> {
|
||||||
|
log.debug { "[TimeFinder.findAllWithAvailabilityByDateAndThemeId] 조회 시작: date:$date, themeId=$themeId" }
|
||||||
|
|
||||||
|
val theme = themeFinder.findById(themeId)
|
||||||
|
val reservations: List<ReservationEntity> = reservationFinder.findAllByDateAndTheme(date, theme)
|
||||||
|
val allTimes: List<TimeEntity> = findAll()
|
||||||
|
|
||||||
|
return allTimes.map { time ->
|
||||||
|
val isReservable: Boolean = reservations.any { reservation -> time.id == reservation.id }
|
||||||
|
TimeWithAvailability(time.id!!, time.startAt, date, themeId, isReservable)
|
||||||
|
}.also {
|
||||||
|
log.debug { "[TimeFinder.findAllWithAvailabilityByDateAndThemeId] ${it.size}개 조회 완료: date:$date, themeId=$themeId" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/main/kotlin/roomescape/time/implement/TimeValidator.kt
Normal file
41
src/main/kotlin/roomescape/time/implement/TimeValidator.kt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package roomescape.time.implement
|
||||||
|
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.reservation.implement.ReservationFinder
|
||||||
|
import roomescape.time.exception.TimeErrorCode
|
||||||
|
import roomescape.time.exception.TimeException
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeRepository
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class TimeValidator(
|
||||||
|
private val timeRepository: TimeRepository,
|
||||||
|
private val reservationFinder: ReservationFinder
|
||||||
|
) {
|
||||||
|
fun validateIsAlreadyExists(startAt: LocalTime) {
|
||||||
|
log.debug { "[TimeValidator.validateIsAlreadyExists] 시작: startAt=${startAt}" }
|
||||||
|
|
||||||
|
if (timeRepository.existsByStartAt(startAt)) {
|
||||||
|
log.info { "[TimeValidator.validateIsAlreadyExists] 중복 시간: startAt=$startAt" }
|
||||||
|
throw TimeException(TimeErrorCode.TIME_DUPLICATED)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug { "[TimeValidator.validateIsAlreadyExists] 완료: startAt=${startAt}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validateIsReserved(time: TimeEntity) {
|
||||||
|
log.debug { "[TimeValidator.validateIsReserved] 시작: id=${time.id}, startAt=${time.startAt}" }
|
||||||
|
|
||||||
|
if (reservationFinder.isTimeReserved(time)) {
|
||||||
|
log.info { "[TimeValidator.validateIsReserved] 예약이 있는 시간: timeId=${time.id}, startAt=${time.startAt}" }
|
||||||
|
throw TimeException(TimeErrorCode.TIME_ALREADY_RESERVED)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug { "[TimeValidator.validateIsReserved] 시작: id=${time.id}, startAt=${time.startAt}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/main/kotlin/roomescape/time/implement/TimeWriter.kt
Normal file
37
src/main/kotlin/roomescape/time/implement/TimeWriter.kt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package roomescape.time.implement
|
||||||
|
|
||||||
|
import com.github.f4b6a3.tsid.TsidFactory
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import roomescape.common.config.next
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeEntity
|
||||||
|
import roomescape.time.infrastructure.persistence.TimeRepository
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class TimeWriter(
|
||||||
|
private val timeValidator: TimeValidator,
|
||||||
|
private val timeRepository: TimeRepository,
|
||||||
|
private val tsidFactory: TsidFactory
|
||||||
|
) {
|
||||||
|
fun create(startAt: LocalTime): TimeEntity {
|
||||||
|
log.debug { "[TimeWriter.create] 시작: startAt=$startAt" }
|
||||||
|
timeValidator.validateIsAlreadyExists(startAt)
|
||||||
|
|
||||||
|
val time = TimeEntity(_id = tsidFactory.next(), startAt = startAt)
|
||||||
|
|
||||||
|
return timeRepository.save(time)
|
||||||
|
.also { log.debug { "[TimeWriter.create] 완료: startAt=$startAt, id=${it.id}" } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun delete(time: TimeEntity) {
|
||||||
|
log.debug { "[TimeWriter.delete] 시작: id=${time.id}" }
|
||||||
|
timeValidator.validateIsReserved(time)
|
||||||
|
|
||||||
|
timeRepository.delete(time)
|
||||||
|
.also { log.debug { "[TimeWriter.delete] 완료: id=${time.id}, startAt=${time.startAt}" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user