-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FU-357] 날짜별 스케줄 검증로직 개선 및 리팩터링 (#91)
* FU-357 feat: 날짜별 스케줄 상태 별 스케줄 충돌 검증 - 예약오픈 <-> 예약중지 간 충돌 불가 - 예약확정 <-> 예약오픈,예약중지 간 충돌 가능 * FU-357 feat: 날짜별 스케줄과 기본스케줄 단위 일치 보장 * FU-357 refactor: 날짜별 스케줄 검증 전담 클래스 분리 서비스 클래스를 간결하게 관리하고, 단일 책임 원칙(SRP)을 따르기 위해 검증 전담 클래스를 분리하였음 * FU-357 refactor: 스케줄 충돌 검증 코드 리팩터링 및 가독성 개선
- Loading branch information
Showing
9 changed files
with
274 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
src/main/java/com/foru/freebe/schedule/service/DailyScheduleValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.foru.freebe.schedule.service; | ||
|
||
import java.time.Clock; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import com.foru.freebe.errors.errorcode.ScheduleErrorCode; | ||
import com.foru.freebe.errors.exception.RestApiException; | ||
import com.foru.freebe.member.entity.Member; | ||
import com.foru.freebe.member.entity.ScheduleUnit; | ||
import com.foru.freebe.schedule.dto.DailyScheduleRequest; | ||
import com.foru.freebe.schedule.entity.DailySchedule; | ||
import com.foru.freebe.schedule.entity.ScheduleStatus; | ||
import com.foru.freebe.schedule.repository.DailyScheduleRepository; | ||
|
||
import jakarta.transaction.Transactional; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional | ||
public class DailyScheduleValidator { | ||
private final Clock clock; | ||
private final DailyScheduleRepository dailyScheduleRepository; | ||
|
||
public void validateTimeRange(LocalTime startTime, LocalTime endTime) { | ||
if (startTime.isAfter(endTime) || startTime.equals(endTime)) { | ||
throw new RestApiException(ScheduleErrorCode.START_TIME_AFTER_END_TIME); | ||
} | ||
} | ||
|
||
public void validateScheduleUnit(ScheduleUnit scheduleUnit, LocalTime startTime, LocalTime endTime) { | ||
switch (scheduleUnit) { | ||
case SIXTY_MINUTES -> { | ||
if (startTime.getMinute() != 0 || endTime.getMinute() != 0) { | ||
throw new RestApiException(ScheduleErrorCode.INVALID_SCHEDULE_UNIT); | ||
} | ||
} | ||
case THIRTY_MINUTES -> { | ||
if (startTime.getMinute() != 0 && startTime.getMinute() != 30) { | ||
throw new RestApiException(ScheduleErrorCode.INVALID_SCHEDULE_UNIT); | ||
} else if (endTime.getMinute() != 0 && endTime.getMinute() != 30) { | ||
throw new RestApiException(ScheduleErrorCode.INVALID_SCHEDULE_UNIT); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void validateScheduleInFuture(DailyScheduleRequest request) { | ||
LocalDateTime requestDateTime = request.getDate().atTime(request.getStartTime()); | ||
|
||
if (requestDateTime.isBefore(LocalDateTime.now(clock))) { | ||
throw new RestApiException(ScheduleErrorCode.DAILY_SCHEDULE_IN_PAST); | ||
} | ||
} | ||
|
||
public void validateConflictingSchedules(Member member, DailyScheduleRequest request) { | ||
List<ScheduleStatus> scheduleStatuses = determineConflictingStatuses(request.getScheduleStatus()); | ||
|
||
List<DailySchedule> overlappingSchedules = dailyScheduleRepository.findConflictingSchedulesByStatuses(member, | ||
request.getDate(), request.getStartTime(), request.getEndTime(), scheduleStatuses); | ||
|
||
if (!overlappingSchedules.isEmpty()) { | ||
throw new RestApiException(ScheduleErrorCode.DAILY_SCHEDULE_OVERLAP); | ||
} | ||
} | ||
|
||
public void validateConflictingSchedules(Member member, DailyScheduleRequest request, Long scheduleId) { | ||
List<ScheduleStatus> scheduleStatuses = determineConflictingStatuses(request.getScheduleStatus()); | ||
|
||
List<DailySchedule> conflictingSchedules = dailyScheduleRepository.findConflictingSchedulesByStatuses(member, | ||
request.getDate(), request.getStartTime(), request.getEndTime(), scheduleStatuses); | ||
|
||
if (conflictingSchedules.isEmpty() || isSelfConflictOnly(scheduleId, conflictingSchedules)) { | ||
return; | ||
} | ||
|
||
throw new RestApiException(ScheduleErrorCode.DAILY_SCHEDULE_OVERLAP); | ||
} | ||
|
||
private List<ScheduleStatus> determineConflictingStatuses(ScheduleStatus scheduleStatus) { | ||
if (scheduleStatus == ScheduleStatus.CONFIRMED) { | ||
return List.of(ScheduleStatus.CONFIRMED); | ||
} else { | ||
return List.of(ScheduleStatus.OPEN, ScheduleStatus.CLOSED); | ||
} | ||
} | ||
|
||
private boolean isSelfConflictOnly(Long scheduleId, List<DailySchedule> conflictingSchedules) { | ||
return conflictingSchedules.size() == 1 && conflictingSchedules.get(0).getId().equals(scheduleId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.