diff --git a/src/main/kotlin/dsm/pick2024/domain/application/service/ApplicationService.kt b/src/main/kotlin/dsm/pick2024/domain/application/service/ApplicationService.kt index d58d7aa0..4e86323f 100644 --- a/src/main/kotlin/dsm/pick2024/domain/application/service/ApplicationService.kt +++ b/src/main/kotlin/dsm/pick2024/domain/application/service/ApplicationService.kt @@ -9,6 +9,7 @@ import dsm.pick2024.domain.application.port.`in`.ApplicationUseCase import dsm.pick2024.domain.application.port.out.ExistsApplicationPort import dsm.pick2024.domain.application.port.out.SaveApplicationPort import dsm.pick2024.domain.application.presentation.dto.request.ApplicationRequest +import dsm.pick2024.domain.attendance.domain.service.AttendanceService import dsm.pick2024.domain.fcm.dto.request.FcmRequest import dsm.pick2024.domain.main.port.`in`.MainUseCase import dsm.pick2024.domain.outbox.domain.Outbox @@ -27,7 +28,8 @@ class ApplicationService( private val userFacadeUseCase: UserFacadeUseCase, private val adminFinderUseCase: AdminFinderUseCase, private val saveOutboxPort: SaveOutboxPort, - private val mainUseCase: MainUseCase + private val mainUseCase: MainUseCase, + private val attendanceService: AttendanceService ) : ApplicationUseCase { @Transactional @@ -37,6 +39,12 @@ class ApplicationService( throw AlreadyApplyingForPicnicException } + attendanceService.checkApplicationTime( + applicationType = request.applicationType, + start = request.start, + end = request.end + ) + saveApplicationPort.save( Application( userName = user.name, diff --git a/src/main/kotlin/dsm/pick2024/domain/attendance/domain/service/AttendanceService.kt b/src/main/kotlin/dsm/pick2024/domain/attendance/domain/service/AttendanceService.kt index def988fa..8718e2d8 100644 --- a/src/main/kotlin/dsm/pick2024/domain/attendance/domain/service/AttendanceService.kt +++ b/src/main/kotlin/dsm/pick2024/domain/attendance/domain/service/AttendanceService.kt @@ -3,6 +3,7 @@ package dsm.pick2024.domain.attendance.domain.service import dsm.pick2024.domain.application.enums.ApplicationType import dsm.pick2024.domain.attendance.domain.Attendance import dsm.pick2024.domain.attendance.enums.AttendanceStatus +import dsm.pick2024.domain.attendance.exception.InvalidPeriodException import org.springframework.stereotype.Component import java.time.LocalTime @@ -14,7 +15,7 @@ class AttendanceService { LocalTime.of(8, 40) to LocalTime.of(9, 40), // 1교시 LocalTime.of(9, 40) to LocalTime.of(10, 40), // 2교시 LocalTime.of(10, 40) to LocalTime.of(11, 40), // 3교시 - LocalTime.of(12, 40) to LocalTime.of(13, 30), // 4교시 + LocalTime.of(11, 40) to LocalTime.of(13, 30), // 4교시 LocalTime.of(13, 30) to LocalTime.of(14, 40), // 5교시 LocalTime.of(14, 30) to LocalTime.of(15, 30), // 6교시 LocalTime.of(15, 30) to LocalTime.of(16, 30), // 7교시 @@ -29,17 +30,70 @@ class AttendanceService { } // 교시 혹은 시간을 기반으로 교시 목록을 반환하는 함수 - fun translateApplication(start: String, end: String?, applicationType: ApplicationType): List { + fun translateApplication(start: String, end: String, applicationType: ApplicationType): Pair { return when (applicationType) { - ApplicationType.PERIOD -> listOf(start, end!!) + ApplicationType.PERIOD -> Pair(start, end) ApplicationType.TIME -> { val startTime = LocalTime.parse(start) - val endTime = end?.let { LocalTime.parse(it) } + val endTime = LocalTime.parse(end) getMatchPeriods(startTime, endTime) } } } + fun checkApplicationTime(applicationType: ApplicationType, start: String, end: String) { + when (applicationType) { + ApplicationType.TIME -> { + val startTime = LocalTime.parse(start) + val endTime = LocalTime.parse(end) + if (startTime > endTime || + endTime > LocalTime.of(20, 30) || + startTime < LocalTime.of(8, 30) + ) { + throw InvalidPeriodException + } + } + ApplicationType.PERIOD -> { + val startPeriod = start.replace("교시", "").toIntOrNull() ?: throw InvalidPeriodException + val endPeriod = end.replace("교시", "").toIntOrNull() ?: throw InvalidPeriodException + if (startPeriod > endPeriod || startPeriod < 1 || endPeriod > 10) { + throw InvalidPeriodException + } + } + } + } + + fun checkEarlyReturnTime(applicationType: ApplicationType, start: String) { + when (applicationType) { + ApplicationType.TIME -> { + val startTime = LocalTime.parse(start) + if (startTime < LocalTime.of(8, 30)) { + throw InvalidPeriodException + } + } + ApplicationType.PERIOD -> { + val startPeriod = start.replace("교시", "").toInt() + if (startPeriod < 1 || startPeriod > 10) { + throw InvalidPeriodException + } + } + } + } + + fun translateEarlyReturn(start: String, applicationType: ApplicationType): String { + return when (applicationType) { + ApplicationType.PERIOD -> start + ApplicationType.TIME -> { + val startTime = LocalTime.parse(start) + val startIndex = periods.indexOfFirst { (start, endAt) -> + startTime >= start && startTime < endAt + } + if (startIndex == -1) throw InvalidPeriodException + periodNames[startIndex] + } + } + } + // 주어진 교시 혹은 시간에 해당하는 출석 상태를 업데이트하는 함수 fun updateAttendanceToApplication( start: String, @@ -113,27 +167,16 @@ class AttendanceService { return updateAttendance } - fun translateEarlyReturn(start: String, applicationType: ApplicationType): List { - return when (applicationType) { - ApplicationType.PERIOD -> { - val startIndex = periodNames.indexOf(start).coerceAtLeast(0) - periodNames.subList(startIndex, periodNames.size) - } - ApplicationType.TIME -> { - val startTime = LocalTime.parse(start) - getMatchPeriods(startTime, null) - } + private fun getMatchPeriods(startTime: LocalTime, endTime: LocalTime): Pair { + val startIndex = periods.indexOfFirst { (start, endAt) -> + startTime in start..endAt + } + val endIndex = periods.indexOfFirst { (start, endAt) -> + endTime in start..endAt } - } - private fun getMatchPeriods(startTime: LocalTime, endTime: LocalTime?): List { - return periods - .mapIndexed { index, period -> - if ((startTime < period.second) && (endTime == null || endTime > period.first)) { - periodNames[index] - } else { - null - } - }.filterNotNull() + if (startIndex == -1 || endIndex == -1) throw InvalidPeriodException + + return periodNames[startIndex] to periodNames[endIndex] } } diff --git a/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/CreateEarlyReturnService.kt b/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/CreateEarlyReturnService.kt index c2e3a718..5898b609 100644 --- a/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/CreateEarlyReturnService.kt +++ b/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/CreateEarlyReturnService.kt @@ -6,6 +6,7 @@ import dsm.pick2024.domain.application.enums.ApplicationKind import dsm.pick2024.domain.application.enums.Status import dsm.pick2024.domain.application.port.out.ExistsApplicationPort import dsm.pick2024.domain.application.port.out.SaveApplicationPort +import dsm.pick2024.domain.attendance.domain.service.AttendanceService import dsm.pick2024.domain.earlyreturn.exception.AlreadyApplyingForEarlyReturnException import dsm.pick2024.domain.earlyreturn.port.`in`.CreateEarlyReturnUseCase import dsm.pick2024.domain.earlyreturn.presentation.dto.request.CreateEarlyReturnRequest @@ -24,7 +25,8 @@ class CreateEarlyReturnService( private val userFacadeUseCase: UserFacadeUseCase, private val adminFinderUseCase: AdminFinderUseCase, private val outboxFacadeUseCase: OutboxFacadeUseCase, - private val mainUseCase: MainUseCase + private val mainUseCase: MainUseCase, + private val attendanceService: AttendanceService ) : CreateEarlyReturnUseCase { @Transactional override fun createEarlyReturn(request: CreateEarlyReturnRequest) { @@ -34,6 +36,8 @@ class CreateEarlyReturnService( throw AlreadyApplyingForEarlyReturnException } + attendanceService.checkEarlyReturnTime(request.applicationType, request.start) + saveApplicationPort.save( Application( userName = user.name, diff --git a/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/processor/EarlyReturnApprovalProcessor.kt b/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/processor/EarlyReturnApprovalProcessor.kt index a53d4ab8..1e5b9a00 100644 --- a/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/processor/EarlyReturnApprovalProcessor.kt +++ b/src/main/kotlin/dsm/pick2024/domain/earlyreturn/service/processor/EarlyReturnApprovalProcessor.kt @@ -53,7 +53,7 @@ class EarlyReturnApprovalProcessor( return ApplicationStory( reason = application.reason, userName = application.userName, - start = start.first(), + start = start, date = application.date, type = Type.EARLY_RETURN, userId = application.userId