11package com .back .domain .study .plan .service ;
22
3- import com .back .domain .study .plan .dto .StudyPlanDeleteRequest ;
43import com .back .domain .study .plan .dto .StudyPlanRequest ;
54import com .back .domain .study .plan .dto .StudyPlanResponse ;
65import com .back .domain .study .plan .entity .*;
@@ -69,19 +68,9 @@ private RepeatRule createRepeatRule(StudyPlanRequest.RepeatRuleRequest request,
6968 repeatRule .setStudyPlan (studyPlan );
7069 repeatRule .setFrequency (request .getFrequency ());
7170 repeatRule .setRepeatInterval (request .getIntervalValue () != null ? request .getIntervalValue () : 1 );
71+ // byDay 설정 (WEEKLY인 경우에만 의미 있음)
72+ getByDayInWeekly (request , studyPlan , repeatRule );
7273
73- // byDay 설정 (WEEKLY 인 경우에만)
74- if (request .getFrequency () == Frequency .WEEKLY ) {
75- // 1. byDay가 없으면 시작일 요일을 자동으로 설정 (현재 구현 의도 반영)
76- if (request .getByDay () == null || request .getByDay ().isEmpty ()) {
77- String startDayOfWeek = studyPlan .getStartDate ().getDayOfWeek ().name ().substring (0 , 3 );
78- // *가정: RepeatRule.byDay는 List<String> 타입으로 가정
79- repeatRule .setByDay (List .of (startDayOfWeek ));
80- } else {
81- // 2. byDay가 있다면 요청 값을 사용 (List<String> to List<String> 매핑 확인)
82- repeatRule .setByDay (request .getByDay ());
83- }
84- }
8574 // untilDate 설정 및 검증
8675 LocalDate untilDate ;
8776
@@ -335,6 +324,10 @@ public StudyPlanResponse updateStudyPlan(Long userId, Long planId, StudyPlanRequ
335324
336325 switch (updateType ) {
337326 case ORIGINAL_PLAN_UPDATE :
327+ // 요청에 반복 규칙이 있으면 반복 규칙 수정 후 원본 계획 수정
328+ if (request .getRepeatRule () != null ) {
329+ updateRepeatRule (originalPlan .getRepeatRule (), request .getRepeatRule (), originalPlan );
330+ }
338331 return updateOriginalPlan (originalPlan , request );
339332
340333 case REPEAT_INSTANCE_CREATE :
@@ -390,11 +383,6 @@ private StudyPlanResponse updateOriginalPlan(StudyPlan originalPlan, StudyPlanRe
390383 if (request .getEndDate () != null ) originalPlan .setEndDate (request .getEndDate ());
391384 if (request .getColor () != null ) originalPlan .setColor (request .getColor ());
392385
393- // 요청에 반복 규칙이 있고 원본 반복성 계획인 경우에만 반복 규칙 수정
394- if (request .getRepeatRule () != null && originalPlan .getRepeatRule () != null ) {
395- updateRepeatRule (originalPlan .getRepeatRule (), request .getRepeatRule ());
396- }
397-
398386 StudyPlan savedPlan = studyPlanRepository .save (originalPlan );
399387 return new StudyPlanResponse (savedPlan );
400388 }
@@ -412,7 +400,7 @@ private StudyPlanResponse createRepeatException(StudyPlan originalPlan, StudyPla
412400 exception .setStudyPlan (originalPlan );
413401 exception .setExceptionDate (exceptionDate );
414402 exception .setExceptionType (StudyPlanException .ExceptionType .MODIFIED );
415- exception .setApplyScope (applyScope ); // 파라미터로 받은 applyScope
403+ exception .setApplyScope (applyScope );
416404
417405 // 수정된 내용 설정
418406 if (request .getSubject () != null ) exception .setModifiedSubject (request .getSubject ());
@@ -422,24 +410,10 @@ private StudyPlanResponse createRepeatException(StudyPlan originalPlan, StudyPla
422410
423411 // 반복 규칙 수정. 요청에 반복 규칙이 있으면 설정
424412 if (request .getRepeatRule () != null ) {
425- RepeatRuleEmbeddable embeddable = new RepeatRuleEmbeddable ();
426- embeddable .setFrequency (request .getRepeatRule ().getFrequency ());
427- embeddable .setIntervalValue (request .getRepeatRule ().getIntervalValue ());
428- embeddable .setByDay (request .getRepeatRule ().getByDay ());
429-
430- if (request .getRepeatRule ().getUntilDate () != null && !request .getRepeatRule ().getUntilDate ().isEmpty ()) {
431- try {
432- LocalDate untilDate = LocalDate .parse (request .getRepeatRule ().getUntilDate ());
433- embeddable .setUntilDate (untilDate );
434- } catch (Exception e ) {
435- throw new CustomException (ErrorCode .INVALID_DATE_FORMAT );
436- }
437- }
438-
413+ RepeatRuleEmbeddable embeddable = createRepeatRuleEmbeddable (request .getRepeatRule (), request .getStartDate ());
439414 exception .setModifiedRepeatRule (embeddable );
440415 }
441416
442-
443417 studyPlanExceptionRepository .save (exception );
444418 return createVirtualPlanForDate (originalPlan , exceptionDate );
445419 }
@@ -458,38 +432,26 @@ private StudyPlanResponse updateExistingException(StudyPlan originalPlan, StudyP
458432 if (request .getEndDate () != null ) existingException .setModifiedEndDate (request .getEndDate ());
459433 if (request .getColor () != null ) existingException .setModifiedColor (request .getColor ());
460434
461- // ApplyScope도 업데이트 (사용자가 범위를 변경할 수 있음)
435+ // ApplyScope도 업데이트
462436 existingException .setApplyScope (applyScope );
463437
464438 // 반복 규칙 수정사항 있으면 예외 안에 추가 (embeddable)
465439 if (request .getRepeatRule () != null ) {
466- RepeatRuleEmbeddable embeddable = new RepeatRuleEmbeddable ();
467- embeddable .setFrequency (request .getRepeatRule ().getFrequency ());
468- embeddable .setIntervalValue (request .getRepeatRule ().getIntervalValue ());
469- embeddable .setByDay (request .getRepeatRule ().getByDay ());
470-
471- if (request .getRepeatRule ().getUntilDate () != null && !request .getRepeatRule ().getUntilDate ().isEmpty ()) {
472- try {
473- LocalDate untilDate = LocalDate .parse (request .getRepeatRule ().getUntilDate ());
474- embeddable .setUntilDate (untilDate );
475- } catch (Exception e ) {
476- throw new CustomException (ErrorCode .INVALID_DATE_FORMAT );
477- }
478- }
479-
440+ RepeatRuleEmbeddable embeddable = createRepeatRuleEmbeddable (request .getRepeatRule (), request .getStartDate ());
480441 existingException .setModifiedRepeatRule (embeddable );
481442 }
482443
483444 studyPlanExceptionRepository .save (existingException );
484445 return createVirtualPlanForDate (originalPlan , exceptionDate );
485446 }
486447
487-
488448 // 원본의 반복 룰 수정 (엔티티)
489- private void updateRepeatRule (RepeatRule repeatRule , StudyPlanRequest .RepeatRuleRequest request ) {
449+ private void updateRepeatRule (RepeatRule repeatRule , StudyPlanRequest .RepeatRuleRequest request , StudyPlan studyPlan ) {
490450 if (request .getFrequency () != null ) repeatRule .setFrequency (request .getFrequency ());
491451 if (request .getIntervalValue () != null ) repeatRule .setRepeatInterval (request .getIntervalValue ());
492- if (request .getByDay () != null ) repeatRule .setByDay (request .getByDay ());
452+
453+ // byDay 자동 설정 (기존 메서드 재사용)
454+ getByDayInWeekly (request , studyPlan , repeatRule );
493455
494456 if (request .getUntilDate () != null && !request .getUntilDate ().isEmpty ()) {
495457 try {
@@ -501,6 +463,27 @@ private void updateRepeatRule(RepeatRule repeatRule, StudyPlanRequest.RepeatRule
501463 }
502464 }
503465
466+ // RepeatRuleEmbeddable 생성 헬퍼 메서드 (중복 코드 제거)
467+ private RepeatRuleEmbeddable createRepeatRuleEmbeddable (StudyPlanRequest .RepeatRuleRequest request , LocalDateTime startDate ) {
468+ RepeatRuleEmbeddable embeddable = new RepeatRuleEmbeddable ();
469+ embeddable .setFrequency (request .getFrequency ());
470+ embeddable .setIntervalValue (request .getIntervalValue ());
471+
472+ // byDay 자동 설정 (오버로딩된 메서드 사용)
473+ getByDayInWeekly (request , startDate , embeddable );
474+
475+ if (request .getUntilDate () != null && !request .getUntilDate ().isEmpty ()) {
476+ try {
477+ LocalDate untilDate = LocalDate .parse (request .getUntilDate ());
478+ embeddable .setUntilDate (untilDate );
479+ } catch (Exception e ) {
480+ throw new CustomException (ErrorCode .INVALID_DATE_FORMAT );
481+ }
482+ }
483+
484+ return embeddable ;
485+ }
486+
504487 // ==================== 삭제 ===================
505488 @ Transactional
506489 public void deleteStudyPlan (Long userId , Long planId , LocalDate selectedDate , ApplyScope applyScope ) {
@@ -617,5 +600,30 @@ private void validateRepeatRuleDate(StudyPlan studyPlan, LocalDate untilDate) {
617600 throw new CustomException (ErrorCode .REPEAT_INVALID_UNTIL_DATE );
618601 }
619602 }
603+ // WEEKLY인 경우 빈 byDay 처리 메서드 (RepeatRule용)
604+ private void getByDayInWeekly (StudyPlanRequest .RepeatRuleRequest request , StudyPlan studyPlan , RepeatRule repeatRule ) {
605+ // byDay 설정 (WEEKLY 인 경우에만)
606+ if (request .getFrequency () == Frequency .WEEKLY ) {
607+ // 1. byDay가 없으면 시작일 요일을 자동으로 설정
608+ if (request .getByDay () == null || request .getByDay ().isEmpty ()) {
609+ DayOfWeek startDay = DayOfWeek .valueOf (studyPlan .getStartDate ().getDayOfWeek ().name ().substring (0 ,3 ));
610+ repeatRule .setByDay (List .of (startDay ));
611+ } else {
612+ // 2. byDay가 있다면 요청 값을 사용
613+ repeatRule .setByDay (request .getByDay ());
614+ }
615+ }
616+ }
617+ // WEEKLY인 경우 빈 byDay 처리 메서드 (RepeatRuleEmbeddable용 - 오버로딩)
618+ private void getByDayInWeekly (StudyPlanRequest .RepeatRuleRequest request , LocalDateTime startDate , RepeatRuleEmbeddable embeddable ) {
619+ if (request .getFrequency () == Frequency .WEEKLY ) {
620+ if (request .getByDay () == null || request .getByDay ().isEmpty ()) {
621+ DayOfWeek startDay = DayOfWeek .valueOf (startDate .getDayOfWeek ().name ().substring (0 , 3 ));
622+ embeddable .setByDay (List .of (startDay ));
623+ } else {
624+ embeddable .setByDay (request .getByDay ());
625+ }
626+ }
627+ }
620628
621629}
0 commit comments