Skip to content

Commit 2b09a74

Browse files
committed
fix: 다음날 예외 존재 시 기존 예외 증발 문제 수정
1 parent f5e03fa commit 2b09a74

File tree

3 files changed

+51
-13
lines changed

3 files changed

+51
-13
lines changed

src/main/java/com/back/domain/study/plan/repository/StudyPlanExceptionRepository.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,4 @@ Optional<StudyPlanException> findByPlanIdAndDate(@Param("planId") Long planId,
3838
@Modifying
3939
@Query("DELETE FROM StudyPlanException spe WHERE spe.studyPlan.id = :planId AND spe.exceptionDate > :date")
4040
void deleteByStudyPlanIdAndExceptionDateAfter(@Param("planId") Long planId, @Param("date") LocalDate date);
41-
4241
}

src/main/java/com/back/domain/study/plan/service/StudyPlanService.java

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -571,29 +571,30 @@ private void deleteRepeatPlan(StudyPlan studyPlan, LocalDate selectedDate, Apply
571571
if (exception.getApplyScope() == ApplyScope.FROM_THIS_DATE
572572
&& exception.getExceptionType() == StudyPlanException.ExceptionType.MODIFIED) {
573573

574-
LocalDate nextDate = selectedDate.plusDays(1);
575-
576-
// 다음 날에 이미 예외가 있는지 확인
577-
Optional<StudyPlanException> nextDayException = studyPlanExceptionRepository
578-
.findByPlanIdAndDate(studyPlan.getId(), nextDate);
579-
580-
// 예외가 없을 때만 새로 생성
581-
if (!nextDayException.isPresent()) {
574+
// 다음 빈 날짜 찾기
575+
LocalDate availableDate = findNextAvailableDateForException(
576+
studyPlan,
577+
selectedDate.plusDays(1)
578+
);
579+
580+
// 빈 날짜가 있으면 FROM_THIS_DATE 예외 생성
581+
if (availableDate != null) {
582582
StudyPlanException continuedException = new StudyPlanException();
583583
continuedException.setStudyPlan(studyPlan);
584-
continuedException.setExceptionDate(nextDate);
584+
continuedException.setExceptionDate(availableDate);
585585
continuedException.setExceptionType(StudyPlanException.ExceptionType.MODIFIED);
586586
continuedException.setApplyScope(ApplyScope.FROM_THIS_DATE);
587587

588-
// 기존 수정 내용 복사
588+
// 기존 수정 내용 복사 (날짜는 availableDate로 조정)
589+
long daysDiff = ChronoUnit.DAYS.between(selectedDate, availableDate);
589590
continuedException.setModifiedSubject(exception.getModifiedSubject());
590591
if (exception.getModifiedStartDate() != null) {
591592
continuedException.setModifiedStartDate(
592-
exception.getModifiedStartDate().plusDays(1));
593+
exception.getModifiedStartDate().plusDays(daysDiff));
593594
}
594595
if (exception.getModifiedEndDate() != null) {
595596
continuedException.setModifiedEndDate(
596-
exception.getModifiedEndDate().plusDays(1));
597+
exception.getModifiedEndDate().plusDays(daysDiff));
597598
}
598599
continuedException.setModifiedColor(exception.getModifiedColor());
599600
continuedException.setModifiedRepeatRule(exception.getModifiedRepeatRule());
@@ -719,4 +720,41 @@ private void getByDayInWeekly(StudyPlanRequest.RepeatRuleRequest request, LocalD
719720
}
720721
}
721722

723+
// THIS_ONLY로 FROM_THIS_DATE 예외를 삭제할 때 다음 빈 날짜 찾기 (재귀탐색)
724+
private LocalDate findNextAvailableDateForException(StudyPlan studyPlan, LocalDate startDate) {
725+
LocalDate currentDate = startDate;
726+
LocalDate untilDate = studyPlan.getRepeatRule().getUntilDate();
727+
728+
// untilDate가 있으면 그것을 최대 범위로, 없으면 1년
729+
int maxDays = untilDate != null
730+
? (int) ChronoUnit.DAYS.between(startDate, untilDate) + 1
731+
: 365;
732+
733+
int daysChecked = 0;
734+
735+
while (daysChecked < maxDays) {
736+
// untilDate 체크
737+
if (untilDate != null && currentDate.isAfter(untilDate)) {
738+
return null;
739+
}
740+
741+
// 해당 날짜에 반복이 발생하는지 확인
742+
if (shouldRepeatOnDate(studyPlan, currentDate)) {
743+
// 해당 날짜에 예외가 있는지 확인
744+
Optional<StudyPlanException> exception = studyPlanExceptionRepository
745+
.findByPlanIdAndDate(studyPlan.getId(), currentDate);
746+
747+
if (!exception.isPresent()) {
748+
return currentDate; // 빈 날짜 찾음
749+
}
750+
}
751+
752+
currentDate = currentDate.plusDays(1);
753+
daysChecked++;
754+
}
755+
756+
// 1년 동안 빈 날짜를 찾지 못한 경우 예외 발생
757+
throw new CustomException(ErrorCode.PLAN_TOO_MANY_EXCEPTIONS);
758+
}
759+
722760
}

src/main/java/com/back/global/exception/ErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public enum ErrorCode {
4646
INVALID_TIME_RANGE(HttpStatus.BAD_REQUEST, "PLAN_006", "시작 시간은 종료 시간보다 빨라야 합니다."),
4747
PLAN_TIME_CONFLICT(HttpStatus.CONFLICT, "PLAN_007", "이미 존재하는 학습 계획과 시간이 겹칩니다. 기존 종료 시간과 겹치는 경우는 제외됩니다."),
4848
PLAN_CANNOT_UPDATE(HttpStatus.BAD_REQUEST, "PLAN_008", "수정 스위치 로직 탈출. 어떤 경우인지 파악이 필요합니다."),
49+
PLAN_TOO_MANY_EXCEPTIONS(HttpStatus.BAD_REQUEST, "PLAN_009", "변경사항이 비정상적으로 많아 요청이 거절되었습니다."),
4950
REPEAT_INVALID_UNTIL_DATE(HttpStatus.BAD_REQUEST, "REPEAT_001", "반복 계획의 종료 날짜는 시작 날짜 이전일 수 없습니다."),
5051
REPEAT_BYDAY_REQUIRED(HttpStatus.BAD_REQUEST, "REPEAT_002", "주간 반복 계획의 경우 요일(byDay) 정보가 필요합니다."),
5152

0 commit comments

Comments
 (0)