Skip to content

Commit

Permalink
[DEV-49] 편입 졸업 계산 로직 작성 (#294)
Browse files Browse the repository at this point in the history
* feat: 편입정보 파싱 및 인정학점 추출

* feat: 편입 졸업 학점 적용

* feat: 편입교양, 편입기독교 추가

* feat: 편입생 인정 학점을 제외한 학점 반영

* feat: 편입생 인정 학점을 적용하고 편입생은 채플 1회 수강으로 변경
completed_credit의  total_credit 타입을 int->double

* feat: 졸업 요건 검사하여 취득학점 계산

* feat: 편입 비로그인 검사

* fix: 편입생 자유선택 학점계산 수정

* test: 편입 기능 추가에 따른 테스트 코트 추가

* test: TakenLectureInventory 기독교 과목 테스트 코드 추가

* refactor: 편입학점 인정 로직 수정

* refactor: 익명유저 졸업 검사 로직 수정

* refactor: 코드스멜 제거

* test: 편입생의 자유선택 졸업 결과를 생성 테스트

* refactor: 코드스멜제거

* refactor: 편입생 전공 과목 처리 로직 변경

---------

Co-authored-by: 5uhwann <[email protected]>
  • Loading branch information
tiemo0708 and 5uhwann authored Dec 22, 2024
1 parent b6d1bae commit 7e19cda
Show file tree
Hide file tree
Showing 45 changed files with 1,047 additions and 398 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
public class CompletedCreditResponse {

private String category;
private int totalCredit;
private double totalCredit;
private double takenCredit;
private boolean completed;

@Builder
private CompletedCreditResponse(String category, int totalCredit, double takenCredit,
private CompletedCreditResponse(String category, double totalCredit, double takenCredit,
boolean completed) {
this.category = category;
this.totalCredit = totalCredit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult;
import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -47,23 +48,22 @@ public void generateOrModifyCompletedCredit(User user) {
);
CompletedCredit chapelCompletedCreditModel = createOrUpdateChapelCompletedCreditModel(
completedCredits,
graduationResult
graduationResult,
user
);
CompletedCredit normalCultureCompletedCreditModel = createOrUpdateNormalCultureCompletedCreditModel(
completedCredits, graduationResult);
CompletedCredit freeElectiveCompletedCreditModel = createOrUpdateFreeElectiveCompletedCreditModel(
completedCredits, graduationResult);

ArrayList<CompletedCredit> allCompletedCreditModels = new ArrayList<>(
updatedCompletedCredits);
ArrayList<CompletedCredit> allCompletedCreditModels = new ArrayList<>(updatedCompletedCredits);
allCompletedCreditModels.addAll(
List.of(chapelCompletedCreditModel, normalCultureCompletedCreditModel,
List.of(
chapelCompletedCreditModel,
normalCultureCompletedCreditModel,
freeElectiveCompletedCreditModel
));
generateOrModifyCompletedCreditPort.generateOrModifyCompletedCredits(
user,
allCompletedCreditModels
);
generateOrModifyCompletedCreditPort.generateOrModifyCompletedCredits(user, allCompletedCreditModels);
}

private List<CompletedCredit> createGeneralCompletedCreditModel(
Expand Down Expand Up @@ -102,19 +102,27 @@ private CompletedCredit createCompletedCreditModel(

private CompletedCredit createOrUpdateChapelCompletedCreditModel(
List<CompletedCredit> completedCredits,
GraduationResult graduationResult
GraduationResult graduationResult,
User user
) {
Optional<CompletedCredit> chapelCompletedCredit = findCompletedCreditByCategory(
completedCredits, CHAPEL);

double totalCredit = user.getStudentCategory() == StudentCategory.TRANSFER
? 0.5
: (double) GRADUATION_COUNT / 2;

return chapelCompletedCredit.map(
completedCredit -> updateCompletedCredit(completedCredit, GRADUATION_COUNT / 2,
graduationResult.getChapelResult()
.getTakenChapelCredit()
completedCredit -> updateCompletedCredit(
completedCredit,
totalCredit,
graduationResult.getChapelResult().getTakenChapelCredit()
))
.orElseGet(() -> CompletedCredit.createChapelCompletedCreditModel(
graduationResult.getChapelResult()));
graduationResult.getChapelResult(), user));
}


private CompletedCredit createOrUpdateNormalCultureCompletedCreditModel(
List<CompletedCredit> completedCredits,
GraduationResult graduationResult
Expand Down Expand Up @@ -143,13 +151,15 @@ private CompletedCredit createOrUpdateFreeElectiveCompletedCreditModel(
completedCredits,
FREE_ELECTIVE
);

int finalTakenCredit = graduationResult.getFreeElectiveGraduationResult()
.getTakenCredit();
return freeElectiveCompletedCredit.map(
completedCredit -> updateCompletedCredit(
completedCredit,
graduationResult.getFreeElectiveGraduationResult()
.getTotalCredit(),
graduationResult.getFreeElectiveGraduationResult()
.getTakenCredit()
finalTakenCredit
))
.orElseGet(() -> CompletedCredit.createFreeElectiveCompletedCreditModel(
graduationResult.getFreeElectiveGraduationResult()));
Expand All @@ -166,7 +176,7 @@ private Optional<CompletedCredit> findCompletedCreditByCategory(

private CompletedCredit updateCompletedCredit(
CompletedCredit completedCredit,
int totalCredit, double takenCredit
double totalCredit, double takenCredit
) {
completedCredit.updateCredit(totalCredit, takenCredit);
return completedCredit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.FreeElectiveGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.NormalCultureGraduationResult;
import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;
import lombok.Builder;
import lombok.Getter;

Expand All @@ -17,36 +19,42 @@ public class CompletedCredit {

private final Long id;
private final GraduationCategory graduationCategory;
private int totalCredit;
private double totalCredit;
private double takenCredit;

@Builder
private CompletedCredit(Long id, GraduationCategory graduationCategory, int totalCredit,
private CompletedCredit(Long id, GraduationCategory graduationCategory, double totalCredit,
double takenCredit) {
this.id = id;
this.graduationCategory = graduationCategory;
this.totalCredit = totalCredit;
this.takenCredit = takenCredit;
}

public static CompletedCredit from(DetailGraduationResult detailGraduationResults) {
public CompletedCredit from(DetailGraduationResult detailGraduationResults) {
return CompletedCredit.builder()
.graduationCategory(detailGraduationResults.getGraduationCategory())
.totalCredit(detailGraduationResults.getTotalCredit())
.takenCredit(detailGraduationResults.getTakenCredit())
.build();
}

public static CompletedCredit createChapelCompletedCreditModel(ChapelResult chapelResult) {
public static CompletedCredit createChapelCompletedCreditModel(ChapelResult chapelResult, User user) {
double totalCredit = user.getStudentCategory() == StudentCategory.TRANSFER
? 0.5 // 편입생일 경우 채플 이수 요건은 1회
: (double) ChapelResult.GRADUATION_COUNT / 2; // 일반 학생일 경우 기본 채플 이수 요건

return CompletedCredit.builder()
.graduationCategory(CHAPEL)
.totalCredit(ChapelResult.GRADUATION_COUNT / 2)
.takenCredit(chapelResult.getTakenChapelCredit())
.build();
.graduationCategory(CHAPEL)
.totalCredit(totalCredit)
.takenCredit(chapelResult.getTakenChapelCredit())
.build();
}


public static CompletedCredit createNormalCultureCompletedCreditModel(
NormalCultureGraduationResult normalCultureGraduationResult) {
NormalCultureGraduationResult normalCultureGraduationResult
) {
return CompletedCredit.builder()
.graduationCategory(NORMAL_CULTURE)
.totalCredit(normalCultureGraduationResult.getTotalCredit())
Expand All @@ -63,7 +71,7 @@ public static CompletedCredit createFreeElectiveCompletedCreditModel(
.build();
}

public void updateCredit(int totalCredit, double takenCredit) {
public void updateCredit(double totalCredit, double takenCredit) {
this.totalCredit = totalCredit;
this.takenCredit = takenCredit;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public class CompletedCreditJpaEntity {
@Enumerated(value = EnumType.STRING)
private GraduationCategory graduationCategory;

private int totalCredit;
private double totalCredit;

private double takenCredit;

@Builder
private CompletedCreditJpaEntity(Long id, UserJpaEntity userJpaEntity,
GraduationCategory graduationCategory,
int totalCredit, double takenCredit) {
double totalCredit, double takenCredit) {
this.id = id;
this.userJpaEntity = userJpaEntity;
this.graduationCategory = graduationCategory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

import com.plzgraduate.myongjigraduatebe.core.meta.UseCase;
import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.ChapelResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DefaultGraduationRequirementType;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.*;
import com.plzgraduate.myongjigraduatebe.lecture.application.port.FindBasicAcademicalCulturePort;
import com.plzgraduate.myongjigraduatebe.takenlecture.application.usecase.find.FindTakenLectureUseCase;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
Expand All @@ -34,8 +29,9 @@ class CalculateGraduationService implements CalculateGraduationUseCase {
private final CalculateMajorGraduationService calculateMajorGraduationService;
private final UpdateStudentInformationUseCase updateStudentInformationUseCase;


@Override
public GraduationResult calculateGraduation(User user) {
public GraduationResult calculateGraduation(User user) {
GraduationRequirement graduationRequirement = determineGraduationRequirement(user);
TakenLectureInventory takenLectureInventory = findTakenLectureUseCase.findTakenLectures(
user.getId()
Expand All @@ -52,13 +48,46 @@ public GraduationResult calculateGraduation(User user) {
chapelResult,
detailGraduationResults,
takenLectureInventory,
graduationRequirement
graduationRequirement,
user
);
handleDuplicatedTakenCredit(user, graduationResult);
updateUserGraduationInformation(user, graduationResult);
return graduationResult;
}

DetailGraduationResult generateTransferChristianDetailGraduationResult(
User user,
GraduationRequirement graduationRequirement,
TakenLectureInventory takenLectureInventory
) {
double christianCreditRequirement = graduationRequirement.getChristianCredit();
double totalTakenCredits = calculateChristianTakenCredits(user, takenLectureInventory) +
user.getTransferCredit().getChristianLecture();

if (totalTakenCredits > christianCreditRequirement) {
totalTakenCredits = christianCreditRequirement;
}

return DetailGraduationResult.create(
GraduationCategory.TRANSFER_CHRISTIAN,
graduationRequirement.getChristianCredit(),
List.of(DetailCategoryResult.builder()
.takenCredits((int) totalTakenCredits)
.isCompleted(totalTakenCredits >= graduationRequirement.getChristianCredit())
.build()
)
);
}

private double calculateChristianTakenCredits(User user, TakenLectureInventory takenLectureInventory) {
if (!user.getAuthId().equals("anonymous")) {
takenLectureInventory = findTakenLectureUseCase.findTakenLectures(user.getId());
}
return takenLectureInventory.calculateChristianCredits();

}

GraduationRequirement determineGraduationRequirement(User user) {
College userCollage = College.findBelongingCollege(user.getPrimaryMajor());
DefaultGraduationRequirementType defaultGraduationRequirement =
Expand All @@ -77,21 +106,26 @@ List<DetailGraduationResult> generateDetailGraduationResults(
TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement
) {
List<DetailGraduationResult> detailGraduationResults = new ArrayList<>(
List.of(
List<DetailGraduationResult> detailGraduationResults = new ArrayList<>();
if (user.getStudentCategory() == StudentCategory.TRANSFER) {
detailGraduationResults.add(
generateTransferChristianDetailGraduationResult(user, graduationRequirement, takenLectureInventory)
);
} else {
detailGraduationResults.addAll(List.of(
generateCommonCultureDetailGraduationResult(
user, takenLectureInventory, graduationRequirement
),
generateCoreCultureDetailGraduationResult(
user, takenLectureInventory, graduationRequirement
)
)
);
detailGraduationResults.addAll(
generateBasicAcademicalDetailGraduationResult(
user, takenLectureInventory, graduationRequirement
)
);
));
detailGraduationResults.addAll(
generateBasicAcademicalDetailGraduationResult(
user, takenLectureInventory, graduationRequirement
)
);
}
detailGraduationResults.addAll(
generateMajorDetailGraduationResult(
user, takenLectureInventory, graduationRequirement
Expand Down Expand Up @@ -147,14 +181,15 @@ GraduationResult generateGraduationResult(
ChapelResult chapelResult,
List<DetailGraduationResult> detailGraduationResults,
TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement
GraduationRequirement graduationRequirement,
User user
) {
GraduationResult graduationResult = GraduationResult.create(
chapelResult,
detailGraduationResults
);
graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement);
graduationResult.checkGraduated(graduationRequirement);
graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement, user);
graduationResult.checkGraduated(graduationRequirement, user);
return graduationResult;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.plzgraduate.myongjigraduatebe.lecture.application.port.FindLecturePort;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -36,7 +37,7 @@ public GraduationResult checkGraduationRequirement(
takenLecture.getSemester()
)
).collect(Collectors.toSet());

TakenLectureInventory takenLectureInventoryWithDuplicateCode = TakenLectureInventory.from(
takenLectureWithDuplicateCode);

Expand All @@ -45,22 +46,23 @@ public GraduationResult checkGraduationRequirement(

ChapelResult chapelResult =
calculateGraduationService.generateChapelResult(takenLectureInventoryWithDuplicateCode);
if (anonymous.getStudentCategory() == StudentCategory.TRANSFER) {
chapelResult.checkAnonymousTransferUserChapelCount();
}

List<DetailGraduationResult> detailGraduationResults = calculateGraduationService.generateDetailGraduationResults(
anonymous,
takenLectureInventoryWithDuplicateCode,
graduationRequirement
);

GraduationResult graduationResult = calculateGraduationService.generateGraduationResult(
chapelResult,
detailGraduationResults,
takenLectureInventoryWithDuplicateCode,
graduationRequirement
graduationRequirement,
anonymous
);

calculateGraduationService.handleDuplicatedTakenCredit(anonymous, graduationResult);

return graduationResult;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class ChapelResult {

public static final String CHAPEL_LECTURE_CODE = "KMA02101";
public static final int GRADUATION_COUNT = 4;
public static final int ANONYMOUS_TRANSFER_USER_GRADUATION_COUNT = 1;
public static final double CHAPEL_CREDIT = 0.5;

private final int takenCount;
Expand Down Expand Up @@ -43,4 +44,8 @@ public void checkCompleted() {
public double getTakenChapelCredit() {
return takenCount * CHAPEL_CREDIT;
}

public void checkAnonymousTransferUserChapelCount() {
isCompleted = takenCount == ANONYMOUS_TRANSFER_USER_GRADUATION_COUNT;
}
}
Loading

0 comments on commit 7e19cda

Please sign in to comment.