diff --git a/src/main/java/com/guttery/madii/common/exception/ErrorDetails.java b/src/main/java/com/guttery/madii/common/exception/ErrorDetails.java index bb933ac..08acc1e 100644 --- a/src/main/java/com/guttery/madii/common/exception/ErrorDetails.java +++ b/src/main/java/com/guttery/madii/common/exception/ErrorDetails.java @@ -60,6 +60,7 @@ public enum ErrorDetails { ACHIEVEMENT_NOT_FOUND("P001", HttpStatus.NOT_FOUND.value(), "오늘의 플레이리스트에서 해당 실천을 찾을 수 없습니다."), INVALID_SATISFACTION_ENUM("P002", HttpStatus.BAD_REQUEST.value(), "만족도 ENUM이 유효하지 않습니다. BAD, SO_SO, GOOD, GREAT, EXCELLENT 중 하나여야 합니다."), ACHIEVEMENT_ACHIEVER_NOT_MATCH("P003", HttpStatus.FORBIDDEN.value(), "해당 실천을 만든 사용자가 아닙니다."), + UNFINISHED_JOY_ALREADY_EXISTS_IN_PLAYLIST("P004", HttpStatus.CONFLICT.value(), "미완료 소확행이 이미 플레이리스트에 존재합니다."), FILE_UPLOAD_FAILED("F001", HttpStatus.INTERNAL_SERVER_ERROR.value(), "파일 업로드에 실패했습니다."), diff --git a/src/main/java/com/guttery/madii/domain/achievement/application/service/AchievementServiceHelper.java b/src/main/java/com/guttery/madii/domain/achievement/application/service/AchievementServiceHelper.java index bd00cbf..360924c 100644 --- a/src/main/java/com/guttery/madii/domain/achievement/application/service/AchievementServiceHelper.java +++ b/src/main/java/com/guttery/madii/domain/achievement/application/service/AchievementServiceHelper.java @@ -4,6 +4,8 @@ import com.guttery.madii.common.exception.ErrorDetails; import com.guttery.madii.domain.achievement.domain.model.Achievement; import com.guttery.madii.domain.achievement.domain.repository.AchievementRepository; +import com.guttery.madii.domain.joy.domain.model.Joy; +import com.guttery.madii.domain.user.domain.model.User; import com.guttery.madii.domain.user.domain.model.UserPrincipal; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -27,4 +29,10 @@ public static Achievement findValidAchievement(final AchievementRepository achie return foundAchievement; } + + public static void validateUnfinishedJoyAchievementNotInPlaylist(final AchievementRepository achievementRepository, final Joy joy, final User achiever) { + if (achievementRepository.existsByJoyAndAchieverAndFinishInfo_IsFinishedFalse(joy, achiever)) { + throw CustomException.of(ErrorDetails.UNFINISHED_JOY_ALREADY_EXISTS_IN_PLAYLIST); + } + } } diff --git a/src/main/java/com/guttery/madii/domain/achievement/application/service/JoyPlaylistService.java b/src/main/java/com/guttery/madii/domain/achievement/application/service/JoyPlaylistService.java index 2bda3be..52a97e8 100644 --- a/src/main/java/com/guttery/madii/domain/achievement/application/service/JoyPlaylistService.java +++ b/src/main/java/com/guttery/madii/domain/achievement/application/service/JoyPlaylistService.java @@ -33,6 +33,7 @@ public void addAchievementInPlaylist(final AddAchievementRequest addAchievementR final User user = UserServiceHelper.findExistingUser(userRepository, userPrincipal); final Joy joy = JoyServiceHelper.findExistingJoy(joyRepository, addAchievementRequest.joyId()); final Achievement newAchievement = Achievement.create(user, joy, FinishInfo.createNotFinished()); + AchievementServiceHelper.validateUnfinishedJoyAchievementNotInPlaylist(achievementRepository, joy, user); achievementRepository.save(newAchievement); } @@ -59,4 +60,5 @@ public void moveAchievementInPlaylist(final MoveAchievementToTodayRequest moveAc achievementRepository.delete(foundAchievement); achievementRepository.save(newAchievement); } + } diff --git a/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementQueryDslRepository.java b/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementQueryDslRepository.java index 2abc6c5..a51fc42 100644 --- a/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementQueryDslRepository.java +++ b/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementQueryDslRepository.java @@ -15,5 +15,4 @@ public interface AchievementQueryDslRepository { CalenderDailyJoyAchievementResponse getDailyJoyAchievementInfos(Long userId, LocalDate date); Achievement getJoyAlreadyInPlaylist(Long userId, Long joyId, LocalDate date); - } diff --git a/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementRepository.java b/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementRepository.java index 4402433..a59db83 100644 --- a/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementRepository.java +++ b/src/main/java/com/guttery/madii/domain/achievement/domain/repository/AchievementRepository.java @@ -1,7 +1,12 @@ package com.guttery.madii.domain.achievement.domain.repository; import com.guttery.madii.domain.achievement.domain.model.Achievement; +import com.guttery.madii.domain.joy.domain.model.Joy; +import com.guttery.madii.domain.user.domain.model.User; import org.springframework.data.jpa.repository.JpaRepository; public interface AchievementRepository extends JpaRepository, AchievementQueryDslRepository { + + boolean existsByJoyAndAchieverAndFinishInfo_IsFinishedFalse(Joy joy, User user); + } diff --git a/src/main/java/com/guttery/madii/domain/joy/domain/model/Joy.java b/src/main/java/com/guttery/madii/domain/joy/domain/model/Joy.java index e644a26..2965a21 100644 --- a/src/main/java/com/guttery/madii/domain/joy/domain/model/Joy.java +++ b/src/main/java/com/guttery/madii/domain/joy/domain/model/Joy.java @@ -1,12 +1,29 @@ package com.guttery.madii.domain.joy.domain.model; import com.guttery.madii.common.domain.model.BaseTimeEntity; +import com.guttery.madii.domain.albums.domain.model.SavingJoy; import com.guttery.madii.domain.user.domain.model.User; -import jakarta.persistence.*; +import jakarta.persistence.Access; +import jakarta.persistence.AccessType; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity @@ -24,6 +41,8 @@ public class Joy extends BaseTimeEntity { private Integer joyIconNum; // 소확행 썸네일 아이콘 번호 @Column(length = 30) private String contents; // 소확행 내용 + @OneToMany(mappedBy = "joy", cascade = CascadeType.ALL, orphanRemoval = true) + private List savingJoys; public Joy(User user, JoyType joyType, Integer joyIconNum, String contents) { this.user = user;