-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FU-357] 날짜별 스케줄 검증로직 개선 및 리팩터링 #91
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어떤 의미로 조건을 달아준건지 헷갈려서 설명 부탁해도 될까??🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
findConflictingSchedulesByStatuses
는 추가하려는 날짜별 스케줄과 기존에 등록되어 있는 날짜별 스케줄 간의 충돌 여부를 검증하기 위해서 작성했어! 위 쿼리는 충돌하는 스케줄을 모두 조회해오는 용도이구 충돌은 아래 두 기준을 모두 만족했을 때 발생해!너가 물어봐준 조건절은 (2)번에 해당하는 데이터를 필터링 하는건데, 시간대가 겹친다는 건 이런 경우야
추가 오픈
1월 23일 10:00 ~ 12:00예약 중지
1월 23일 09:00 ~ 11:00즉, 추가하려는 스케줄의 시작시간은 기존 스케줄의 종료시간보다 이르면서, 종료시간은 기존 스케줄의 시작시간보다 늦는 상황이야
이렇게 하면 충돌하는 시간대를 찾을 수 있더라구!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
예시까지 들어서 설명해줘서 고마워!!ㅎㅎ
22번째 라인에서
ds.startTime < :endTime
까지 읽고 겹치는 부분이겠다 싶었는데 뒤에 따라오는AND ds.endTime > :startTime
이 부분을 읽고 다른의도가 있는건가? 다른 반례가 있어서 세팅해놓은건가? 싶었거든!ds.startTime < :endTime
여기까지만 쿼리문으로 줘도 충분히 말해준 2번 조건을 충족하지 않을까 싶었어!이 부분에 대해서도 의견 부탁해!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ds.startTime < :endTime
이 조건만으로는 시간대가 겹치지 않는 스케줄까지도 조회할 가능성이 있어!09:00
~ 10:0011:00
위와 같은 상황처럼 충돌하지 않는 스케줄도 가져오게 되거든 🫨