generated from pricelees/issue-pr-template
[#52] 만료 예약 / 일정 스케쥴링 작업 추가 및 동시성 처리를 위한 일부 코드 수정 #53
@ -18,6 +18,8 @@ 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 java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
private val log: KLogger = KotlinLogging.logger {}
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
@ -43,9 +45,16 @@ class ScheduleService(
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
fun getStoreScheduleByDate(storeId: Long, date: LocalDate): ScheduleWithThemeListResponse {
|
fun getStoreScheduleByDate(storeId: Long, date: LocalDate): ScheduleWithThemeListResponse {
|
||||||
log.info { "[ScheduleService.getStoreScheduleByDate] 매장 일정 조회: storeId=${storeId}, date=$date" }
|
log.info { "[ScheduleService.getStoreScheduleByDate] 매장 일정 조회: storeId=${storeId}, date=$date" }
|
||||||
|
val currentDate = LocalDate.now()
|
||||||
|
|
||||||
|
if (date.isBefore(currentDate)) {
|
||||||
|
log.warn { "[ScheduleService.getStoreScheduleByDate] 이전 날짜 선택으로 인한 실패: date=${date}" }
|
||||||
|
throw ScheduleException(ScheduleErrorCode.PAST_DATE_TIME)
|
||||||
|
}
|
||||||
|
|
||||||
val schedules: List<ScheduleOverview> =
|
val schedules: List<ScheduleOverview> =
|
||||||
scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date)
|
scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date)
|
||||||
|
.filter { it.date.isAfter(date) || (it.date.isEqual(date) && it.time.isAfter(LocalTime.now())) }
|
||||||
|
|
||||||
return schedules.toResponse()
|
return schedules.toResponse()
|
||||||
.also {
|
.also {
|
||||||
|
|||||||
@ -17,8 +17,8 @@ interface ScheduleRepository : JpaRepository<ScheduleEntity, Long> {
|
|||||||
WHERE
|
WHERE
|
||||||
s.storeId = :storeId
|
s.storeId = :storeId
|
||||||
AND s.date = :date
|
AND s.date = :date
|
||||||
AND s.themeId = :themeId
|
|
||||||
AND s.time = :time
|
AND s.time = :time
|
||||||
|
AND s.themeId = :themeId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun existsDuplicate(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime): Boolean
|
fun existsDuplicate(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime): Boolean
|
||||||
@ -41,11 +41,13 @@ interface ScheduleRepository : JpaRepository<ScheduleEntity, Long> {
|
|||||||
FROM
|
FROM
|
||||||
ScheduleEntity s
|
ScheduleEntity s
|
||||||
JOIN
|
JOIN
|
||||||
ThemeEntity t ON t._id = s.themeId and (:themeId IS NULL OR t._id = :themeId)
|
ThemeEntity t ON t._id = s.themeId
|
||||||
JOIN
|
JOIN
|
||||||
StoreEntity st ON st._id = s.storeId and st._id = :storeId
|
StoreEntity st ON st._id = s.storeId
|
||||||
WHERE
|
WHERE
|
||||||
s.date = :date
|
s.storeId = :storeId
|
||||||
|
AND s.date = :date
|
||||||
|
AND (:themeId IS NULL OR t._id = :themeId)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
fun findStoreSchedulesWithThemeByDate(
|
fun findStoreSchedulesWithThemeByDate(
|
||||||
|
|||||||
@ -20,11 +20,12 @@ class ScheduleApiTest(
|
|||||||
) : FunSpecSpringbootTest() {
|
) : FunSpecSpringbootTest() {
|
||||||
init {
|
init {
|
||||||
context("특정 매장 + 날짜의 일정 및 테마 정보를 조회한다.") {
|
context("특정 매장 + 날짜의 일정 및 테마 정보를 조회한다.") {
|
||||||
test("정상 응답") {
|
test("날짜가 오늘이면 현재 시간 이후의 정보만 조회된다.") {
|
||||||
val size = 2
|
val size = 3
|
||||||
val date = LocalDate.now().plusDays(1)
|
val date = LocalDate.now()
|
||||||
val store = dummyInitializer.createStore()
|
val store = dummyInitializer.createStore()
|
||||||
initialize("조회를 위한 같은 날짜의 ${size}개의 일정 생성") {
|
|
||||||
|
initialize("조회를 위한 오늘 날짜의 현재 시간 이후인 ${size}개의 일정, 현재 시간 이전인 1개의 일정 생성") {
|
||||||
for (i in 1..size) {
|
for (i in 1..size) {
|
||||||
dummyInitializer.createSchedule(
|
dummyInitializer.createSchedule(
|
||||||
storeId = store.id,
|
storeId = store.id,
|
||||||
@ -34,6 +35,14 @@ class ScheduleApiTest(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dummyInitializer.createSchedule(
|
||||||
|
storeId = store.id,
|
||||||
|
request = ScheduleFixture.createRequest.copy(
|
||||||
|
date = date,
|
||||||
|
time = LocalTime.now().minusMinutes(1)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
runTest(
|
runTest(
|
||||||
@ -50,6 +59,22 @@ class ScheduleApiTest(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("날짜가 오늘 이전이면 실패한다.") {
|
||||||
|
val store = initialize("매장 생성") {
|
||||||
|
dummyInitializer.createStore()
|
||||||
|
}
|
||||||
|
|
||||||
|
runTest(
|
||||||
|
on = {
|
||||||
|
get("/stores/${store.id}/schedules?date=${LocalDate.now().minusDays(1)}")
|
||||||
|
},
|
||||||
|
expect = {
|
||||||
|
statusCode(HttpStatus.BAD_REQUEST.value())
|
||||||
|
body("code", equalTo(ScheduleErrorCode.PAST_DATE_TIME.errorCode))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context("일정을 ${ScheduleStatus.HOLD} 상태로 변경한다.") {
|
context("일정을 ${ScheduleStatus.HOLD} 상태로 변경한다.") {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user