63 lines
2.4 KiB
Kotlin

package roomescape.time.business
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import roomescape.reservation.infrastructure.persistence.ReservationEntity
import roomescape.reservation.infrastructure.persistence.ReservationRepository
import roomescape.time.exception.TimeErrorCode
import roomescape.time.exception.TimeException
import roomescape.time.infrastructure.persistence.TimeEntity
import roomescape.time.infrastructure.persistence.TimeRepository
import roomescape.time.web.*
import java.time.LocalDate
import java.time.LocalTime
@Service
class TimeService(
private val timeRepository: TimeRepository,
private val reservationRepository: ReservationRepository
) {
@Transactional(readOnly = true)
fun findById(id: Long): TimeEntity = timeRepository.findByIdOrNull(id)
?: throw TimeException(TimeErrorCode.TIME_NOT_FOUND)
@Transactional(readOnly = true)
fun findTimes(): TimeRetrieveListResponse = timeRepository.findAll()
.toResponse()
@Transactional
fun createTime(request: TimeCreateRequest): TimeCreateResponse {
val startAt: LocalTime = request.startAt
if (timeRepository.existsByStartAt(startAt)) {
throw TimeException(TimeErrorCode.TIME_DUPLICATED)
}
val time: TimeEntity = request.toEntity()
return timeRepository.save(time).toCreateResponse()
}
@Transactional
fun deleteTime(id: Long) {
val time: TimeEntity = findById(id)
val reservations: List<ReservationEntity> = reservationRepository.findAllByTime(time)
if (reservations.isNotEmpty()) {
throw TimeException(TimeErrorCode.TIME_ALREADY_RESERVED)
}
timeRepository.delete(time)
}
@Transactional(readOnly = true)
fun findTimesWithAvailability(date: LocalDate, themeId: Long): TimeWithAvailabilityListResponse {
val allTimes = timeRepository.findAll()
val reservations: List<ReservationEntity> = reservationRepository.findByDateAndThemeId(date, themeId)
return TimeWithAvailabilityListResponse(allTimes.map { time ->
val isAvailable: Boolean = reservations.none { reservation -> reservation.time.id == time.id }
TimeWithAvailabilityResponse(time.id!!, time.startAt, isAvailable)
})
}
}