diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateGraduationService.java index 1a6466b3..15bfb9fa 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateGraduationService.java @@ -4,6 +4,7 @@ import static com.plzgraduate.myongjigraduatebe.graduation.domain.service.major.MajorGraduationCategory.PRIMARY; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -27,7 +28,9 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.service.GraduationManager; import com.plzgraduate.myongjigraduatebe.graduation.domain.service.major.MajorManager; import com.plzgraduate.myongjigraduatebe.graduation.domain.service.submajor.SubMajorManager; +import com.plzgraduate.myongjigraduatebe.lecture.application.port.FindBasicAcademicalCulturePort; import com.plzgraduate.myongjigraduatebe.lecture.application.port.FindMajorPort; +import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; import com.plzgraduate.myongjigraduatebe.lecture.domain.model.MajorLecture; import com.plzgraduate.myongjigraduatebe.takenlecture.application.usecase.find.FindTakenLectureUseCase; import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; @@ -45,6 +48,7 @@ class CalculateGraduationService implements CalculateGraduationUseCase { private final FindMajorPort findMajorPort; + private final FindBasicAcademicalCulturePort findBasicAcademicalCulturePort; private final FindTakenLectureUseCase findTakenLectureUseCase; private final CalculateCommonCultureGraduationUseCase calculateCommonCultureGraduationUseCase; @@ -68,10 +72,21 @@ public GraduationResult calculateGraduation(User user) { GraduationResult graduationResult = generateGraduationResult(chapelResult, detailGraduationResults, takenLectureInventory, graduationRequirement); + handleDuplicatedTakenCredit(user, graduationResult); updateUserGraduationInformation(user, graduationResult); return graduationResult; } + private void handleDuplicatedTakenCredit(User user, GraduationResult graduationResult) { + if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { + int duplicatedBasicAcademicalCultureCredit = + findBasicAcademicalCulturePort.findDuplicatedLecturesBetweenMajors(user).stream() + .mapToInt(basicAcademicalCulture -> basicAcademicalCulture.getLecture().getCredit()) + .sum(); + graduationResult.deductDuplicatedCredit(duplicatedBasicAcademicalCultureCredit); + } + } + private GraduationRequirement determineGraduationRequirement(User user) { College userCollage = College.findBelongingCollege(user.getPrimaryMajor()); DefaultGraduationRequirementType defaultGraduationRequirement = DefaultGraduationRequirementType.determineGraduationRequirement( @@ -91,13 +106,12 @@ private List generateDetailGraduationResults(User user, generateCommonCultureDetailGraduationResult( user, takenLectureInventory, graduationRequirement), generateCoreCultureDetailGraduationResult( - user, takenLectureInventory, graduationRequirement), - generteBasicAcademicalDetailGraduationResult( user, takenLectureInventory, graduationRequirement) )); detailGraduationResults.addAll( generatePrimaryMajorDetailGraduations(user, takenLectureInventory, graduationRequirement)); - + detailGraduationResults.addAll(generateBasicAcademicalDetailGraduationResult( + user, takenLectureInventory, graduationRequirement)); if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { detailGraduationResults.addAll( generateDualMajorDetailGraduations(user, takenLectureInventory, graduationRequirement)); @@ -122,10 +136,39 @@ private DetailGraduationResult generateCoreCultureDetailGraduationResult(User us graduationRequirement); } - private DetailGraduationResult generteBasicAcademicalDetailGraduationResult(User user, + private List generateBasicAcademicalDetailGraduationResult(User user, TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - return calculatePrimaryBasicAcademicalCultureDetailGraduationUseCase.calculateDetailGraduation(user, - takenLectureInventory, graduationRequirement); + if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { + TakenLectureInventory copiedTakenLectureForPrimaryBasicAcademicalCulture = takenLectureInventory.copy(); + TakenLectureInventory copiedTakenLectureForDualBasicAcademicalCulture = takenLectureInventory.copy(); + DetailGraduationResult primaryBasicAcademicalCultureDetailGraduationResult = calculatePrimaryBasicAcademicalCultureDetailGraduationUseCase.calculateDetailGraduation( + user, copiedTakenLectureForPrimaryBasicAcademicalCulture, graduationRequirement); + DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult = calculateDualBasicAcademicalCultureDetailGraduationUseCase.calculateDetailGraduation( + user, copiedTakenLectureForDualBasicAcademicalCulture, graduationRequirement); + syncOriginalTakenLectureInventory(takenLectureInventory, + primaryBasicAcademicalCultureDetailGraduationResult, + dualBasicAcademicalCultureDetailGraduationResult); + return List.of(primaryBasicAcademicalCultureDetailGraduationResult, + dualBasicAcademicalCultureDetailGraduationResult); + } + DetailGraduationResult primaryBasicAcademicalCultureGraduationResult = calculatePrimaryBasicAcademicalCultureDetailGraduationUseCase.calculateDetailGraduation( + user, takenLectureInventory, graduationRequirement); + return List.of(primaryBasicAcademicalCultureGraduationResult); + } + + private void syncOriginalTakenLectureInventory(TakenLectureInventory originalTakenLectureInventory, + DetailGraduationResult primaryBasicAcademicalCultureDetailGraduationResult, + DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult) { + List primaryBasicAcademicalCultureTakenLectures = primaryBasicAcademicalCultureDetailGraduationResult.getDetailCategory() + .get(0) + .getTakenLectures(); + List dualBasicAcademicalCultureTakenLectures = dualBasicAcademicalCultureDetailGraduationResult.getDetailCategory() + .get(0) + .getTakenLectures(); + Set basicAcademicalCultureTakenLectures = new HashSet<>(); + basicAcademicalCultureTakenLectures.addAll(primaryBasicAcademicalCultureTakenLectures); + basicAcademicalCultureTakenLectures.addAll(dualBasicAcademicalCultureTakenLectures); + originalTakenLectureInventory.handleFinishedLectures(basicAcademicalCultureTakenLectures); } private List generatePrimaryMajorDetailGraduations(User user, @@ -154,10 +197,8 @@ private List generateDualMajorDetailGraduations(User use dualMajorDetailGraduationResult); DetailGraduationResult dualElectiveMajorDetailGraduationResult = calculateDualElectiveMajorDetailGraduationUseCase.isolateDualElectiveMajorDetailGraduation( dualMajorDetailGraduationResult); - DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult = calculateDualBasicAcademicalCultureDetailGraduationUseCase.calculateDetailGraduation( - user, takenLectureInventory, graduationRequirement); - return List.of(dualMandatoryMajorDetailGraduationResult, dualElectiveMajorDetailGraduationResult, - dualBasicAcademicalCultureDetailGraduationResult); + + return List.of(dualMandatoryMajorDetailGraduationResult, dualElectiveMajorDetailGraduationResult); } private DetailGraduationResult generateSubMajorDetailGraduationResult(User user, diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResult.java index dd49193d..cf7929e7 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResult.java @@ -59,6 +59,10 @@ public void checkGraduated(GraduationRequirement graduationRequirement) { && normalCultureGraduationResult.isCompleted() && freeElectiveGraduationResult.isCompleted(); } + public void deductDuplicatedCredit(int duplicatedCredit) { + this.takenCredit -= duplicatedCredit; + } + private void addUpTotalCredit(int originTotalCredit) { int combinedScore = detailGraduationResults.stream() .mapToInt(DetailGraduationResult::getTotalCredit) diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventory.java index 9158e7d5..83a089c4 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventory.java @@ -1,9 +1,12 @@ package com.plzgraduate.myongjigraduatebe.takenlecture.domain.model; import java.util.Collections; +import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; +import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; + import lombok.Builder; public class TakenLectureInventory { @@ -19,6 +22,10 @@ public Set getTakenLectures() { return Collections.unmodifiableSet(takenLecture); } + public TakenLectureInventory copy() { + return TakenLectureInventory.from(new HashSet<>(takenLecture)); + } + public Set getCultureLectures() { return takenLecture.stream() .filter(taken -> taken.getLecture().isCulture()) @@ -35,12 +42,20 @@ public void handleFinishedTakenLectures(Set finishedTakenLecture) takenLecture.removeAll(finishedTakenLecture); } + public void handleFinishedLectures(Set finishedBasicAcademicalCultureLecture) { + takenLecture.removeAll( + takenLecture.stream() + .filter(taken -> finishedBasicAcademicalCultureLecture.contains(taken.getLecture())) + .collect(Collectors.toSet()) + ); + } + public int calculateTotalCredit() { int totalCredit = this.takenLecture .stream() .mapToInt(takenLecture -> takenLecture.getLecture().getCredit()) .sum(); - if(checkChapelCountIsFour(this.takenLecture)) { + if (checkChapelCountIsFour(this.takenLecture)) { totalCredit += 2; } return totalCredit; diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventoryTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventoryTest.java index 56ac0923..1a8b7f03 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventoryTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLectureInventoryTest.java @@ -1,6 +1,6 @@ package com.plzgraduate.myongjigraduatebe.takenlecture.domain.model; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import java.util.HashSet; import java.util.Map; @@ -18,36 +18,23 @@ class TakenLectureInventoryTest { private final User user = UserFixture.경영학과_19학번_ENG34(); private final Map mockLectureMap = LectureFixture.getMockLectureMap(); - private final TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(new HashSet<>(Set.of( - TakenLecture.of(user, mockLectureMap.get("KMA00101"), 2019, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02102"), 2019, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02122"), 2019, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02104"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02141"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02106"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02107"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02123"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02124"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02108"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02109"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02125"), 2023, Semester.FIRST), - TakenLecture.of(user, mockLectureMap.get("KMA02126"), 2023, Semester.FIRST) - ))); @DisplayName("수강과목 목록에서 교양 수강과목 목록을 반환한다.") @Test void getTakenCultureLectures() { //given //when + TakenLectureInventory takenLectureInventory = getTakenLectureInventory(); Set cultureLectures = takenLectureInventory.getCultureLectures(); //then assertThat(cultureLectures).hasSize(takenLectureInventory.getTakenLectures().size()); } - @DisplayName("수강과목 목록에서 처리 완료된 과목을 제거한다.") + @DisplayName("수강과목 목록에서 처리 완료된 수강과목들을 제거한다.") @Test void handleFinishedTakenLectures() { //given + TakenLectureInventory takenLectureInventory = getTakenLectureInventory(); int beforeHandleSize = takenLectureInventory.getTakenLectures().size(); Set finishedTakenLecture = new HashSet<>(Set.of( TakenLecture.of(user, mockLectureMap.get("KMA00101"), 2019, Semester.FIRST), @@ -84,4 +71,41 @@ void calculateTotalCredit() { //then assertThat(calculatedCredit).isEqualTo(4); } + + @DisplayName("수강과목 목록에서 처리 완료된 과목을 제거한다.") + @Test + void handleFinishedLectures() { + //given + TakenLectureInventory takenLectureInventory = getTakenLectureInventory(); + int beforeHandleSize = takenLectureInventory.getTakenLectures().size(); + Set finishedLectures = new HashSet<>(Set.of( + mockLectureMap.get("KMA00101"), + mockLectureMap.get("KMA02102") + )); + + //when + takenLectureInventory.handleFinishedLectures(finishedLectures); + + //then + assertThat(takenLectureInventory.getTakenLectures()) + .hasSize(beforeHandleSize - finishedLectures.size()); + } + + private TakenLectureInventory getTakenLectureInventory() { + return TakenLectureInventory.from(new HashSet<>(Set.of( + TakenLecture.of(user, mockLectureMap.get("KMA00101"), 2019, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02102"), 2019, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02122"), 2019, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02104"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02141"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02106"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02107"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02123"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02124"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02108"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02109"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02125"), 2023, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("KMA02126"), 2023, Semester.FIRST) + ))); + } }