diff --git a/build.gradle b/build.gradle index af34d197..52cd711e 100644 --- a/build.gradle +++ b/build.gradle @@ -77,10 +77,10 @@ jacocoTestReport { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ "com/plzgraduate/myongjigraduatebe/core/**", - "com/plzgraudate/myongjigraduatebe/*Request*", - "com/plzgraudate/myongjigraduatebe/*Command*", - "com/plzgraudate/myongjigraduatebe/*Response*", - "com/plzgraudate/myongjigraduatebe/*Mapper*" + "com/plzgraduate/myongjigraduatebe/*Request*", + "com/plzgraduate/myongjigraduatebe/*Command*", + "com/plzgraduate/myongjigraduatebe/*Response*", + "com/plzgraduate/myongjigraduatebe/*Mapper*" ]) })) } diff --git a/codecov.yml b/codecov.yml index 860f71f7..27b65d93 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,11 @@ codecov: require_ci_to_pass: true + ignore: + - "com/plzgraduate/myongjigraduatebe/core/**" + - "com/plzgraudate/myongjigraduatebe/*Request*" + - "com/plzgraudate/myongjigraduatebe/*Command*" + - "com/plzgraudate/myongjigraduatebe/*Response*" + - "com/plzgraudate/myongjigraduatebe/*Mapper*" comment: layout: "reach,diff,flags,files,footer" diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/api/dto/CompletedCreditResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/api/dto/CompletedCreditResponse.java index aa7fa359..099c0f6c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/api/dto/CompletedCreditResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/api/dto/CompletedCreditResponse.java @@ -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; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditService.java index fafc92c9..62a41392 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditService.java @@ -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; @@ -34,6 +35,7 @@ class GenerateOrModifyCompletedCreditService implements GenerateOrModifyComplete private final CalculateGraduationUseCase calculateGraduationUseCase; + //TODO() @Override public void generateOrModifyCompletedCredit(User user) { List completedCredits = findCompletedCreditPort.findCompletedCredit(user); @@ -42,27 +44,32 @@ public void generateOrModifyCompletedCredit(User user) { List updatedCompletedCredits = createGeneralCompletedCreditModel( completedCredits, - detailGraduationResults); + detailGraduationResults + ); CompletedCredit chapelCompletedCreditModel = createOrUpdateChapelCompletedCreditModel( completedCredits, - graduationResult); + graduationResult, + user + ); CompletedCredit normalCultureCompletedCreditModel = createOrUpdateNormalCultureCompletedCreditModel( completedCredits, graduationResult); CompletedCredit freeElectiveCompletedCreditModel = createOrUpdateFreeElectiveCompletedCreditModel( completedCredits, graduationResult); - ArrayList allCompletedCreditModels = new ArrayList<>( - updatedCompletedCredits); + ArrayList allCompletedCreditModels = new ArrayList<>(updatedCompletedCredits); allCompletedCreditModels.addAll( - List.of(chapelCompletedCreditModel, normalCultureCompletedCreditModel, - freeElectiveCompletedCreditModel)); - generateOrModifyCompletedCreditPort.generateOrModifyCompletedCredits(user, - allCompletedCreditModels); + List.of( + chapelCompletedCreditModel, + normalCultureCompletedCreditModel, + freeElectiveCompletedCreditModel + )); + generateOrModifyCompletedCreditPort.generateOrModifyCompletedCredits(user, allCompletedCreditModels); } private List createGeneralCompletedCreditModel( List completedCredits, - List detailGraduationResults) { + List detailGraduationResults + ) { Map> resultMap = detailGraduationResults.stream() .collect(Collectors.toMap( Function.identity(), @@ -73,14 +80,17 @@ private List createGeneralCompletedCreditModel( )); return resultMap.keySet() .stream() - .map(detailGraduationResult -> createCompletedCreditModel(detailGraduationResult, - resultMap.get(detailGraduationResult))) + .map(detailGraduationResult -> createCompletedCreditModel( + detailGraduationResult, + resultMap.get(detailGraduationResult) + )) .collect(Collectors.toList()); } private CompletedCredit createCompletedCreditModel( DetailGraduationResult detailGraduationResult, - Optional completedCredit) { + Optional completedCredit + ) { return CompletedCredit.builder() .id(completedCredit.map(CompletedCredit::getId) .orElse(null)) @@ -92,59 +102,82 @@ private CompletedCredit createCompletedCreditModel( private CompletedCredit createOrUpdateChapelCompletedCreditModel( List completedCredits, - GraduationResult graduationResult) { + GraduationResult graduationResult, + User user + ) { Optional 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 completedCredits, - GraduationResult graduationResult) { + GraduationResult graduationResult + ) { Optional normalCultureCompletedCredit = findCompletedCreditByCategory( completedCredits, - NORMAL_CULTURE); + NORMAL_CULTURE + ); return normalCultureCompletedCredit.map( - completedCredit -> updateCompletedCredit(completedCredit, + completedCredit -> updateCompletedCredit( + completedCredit, graduationResult.getNormalCultureGraduationResult() .getTotalCredit(), graduationResult.getNormalCultureGraduationResult() - .getTakenCredit())) + .getTakenCredit() + )) .orElseGet(() -> CompletedCredit.createNormalCultureCompletedCreditModel( graduationResult.getNormalCultureGraduationResult())); } private CompletedCredit createOrUpdateFreeElectiveCompletedCreditModel( List completedCredits, - GraduationResult graduationResult) { + GraduationResult graduationResult + ) { Optional freeElectiveCompletedCredit = findCompletedCreditByCategory( completedCredits, - FREE_ELECTIVE); + FREE_ELECTIVE + ); + + int finalTakenCredit = graduationResult.getFreeElectiveGraduationResult() + .getTakenCredit(); return freeElectiveCompletedCredit.map( - completedCredit -> updateCompletedCredit(completedCredit, + completedCredit -> updateCompletedCredit( + completedCredit, graduationResult.getFreeElectiveGraduationResult() .getTotalCredit(), - graduationResult.getFreeElectiveGraduationResult() - .getTakenCredit())) + finalTakenCredit + )) .orElseGet(() -> CompletedCredit.createFreeElectiveCompletedCreditModel( graduationResult.getFreeElectiveGraduationResult())); } private Optional findCompletedCreditByCategory( List completedCredits, - GraduationCategory category) { + GraduationCategory category + ) { return completedCredits.stream() .filter(completedCredit -> completedCredit.getGraduationCategory() == category) .findFirst(); } - private CompletedCredit updateCompletedCredit(CompletedCredit completedCredit, - int totalCredit, double takenCredit) { + private CompletedCredit updateCompletedCredit( + CompletedCredit completedCredit, + double totalCredit, double takenCredit + ) { completedCredit.updateCredit(totalCredit, takenCredit); return completedCredit; } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCredit.java b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCredit.java index bc1c7a30..b3f50117 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCredit.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCredit.java @@ -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; @@ -17,11 +19,11 @@ 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; @@ -29,7 +31,7 @@ private CompletedCredit(Long id, GraduationCategory graduationCategory, int tota this.takenCredit = takenCredit; } - public static CompletedCredit from(DetailGraduationResult detailGraduationResults) { + public CompletedCredit from(DetailGraduationResult detailGraduationResults) { return CompletedCredit.builder() .graduationCategory(detailGraduationResults.getGraduationCategory()) .totalCredit(detailGraduationResults.getTotalCredit()) @@ -37,16 +39,22 @@ public static CompletedCredit from(DetailGraduationResult detailGraduationResult .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()) @@ -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; } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/infrastructure/persistence/entity/CompletedCreditJpaEntity.java b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/infrastructure/persistence/entity/CompletedCreditJpaEntity.java index fab6bfce..436a10f9 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/infrastructure/persistence/entity/CompletedCreditJpaEntity.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/completedcredit/infrastructure/persistence/entity/CompletedCreditJpaEntity.java @@ -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; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java index aa2d75f8..58677dde 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/config/SecurityConfig.java @@ -35,51 +35,31 @@ public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - .csrf() - .disable() - .headers() - .disable() - .formLogin() - .disable() - .httpBasic() - .disable() - .rememberMe() - .disable() - .logout() - .disable() - .exceptionHandling() + http.csrf().disable().headers().disable().formLogin().disable().httpBasic().disable() + .rememberMe().disable().logout().disable().exceptionHandling() .accessDeniedHandler(jwtAccessDeniedHandler) - .authenticationEntryPoint(jwtAuthenticationEntryPoint) - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() + .authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() .antMatchers( API_V1_PREFIX + "/users/sign-up/**", // 회원가입 API_V1_PREFIX + "/auth/sign-in", // 로그인 - API_V1_PREFIX + "/auth/token", //새 토큰 발급 + API_V1_PREFIX + "/auth/token", // 새 토큰 발급 API_V1_PREFIX + "/users/{student-number}/auth-id", // 아이디 찾기 API_V1_PREFIX + "/users/{student-number}/validate", // 유저 검증 API_V1_PREFIX + "/users/password", // 비밀번호 재설정 - API_V1_PREFIX + "/health", //헬스체크 + API_V1_PREFIX + "/health", // 헬스체크 + API_V1_PREFIX + "/graduations/check", // 비로그인 졸업 요건 검사 "/api-docs", "/swagger-custom-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/api-docs/**", "/swagger-ui.html" - ) - .permitAll() - .anyRequest() - .authenticated() - .and() - .cors() - .configurationSource(corsConfigurationSource()) - .and() - .addFilterBefore(tokenAuthenticationFilter(tokenProvider), - UsernamePasswordAuthenticationFilter.class); + ).permitAll().anyRequest().authenticated().and().cors() + .configurationSource(corsConfigurationSource()).and().addFilterBefore( + tokenAuthenticationFilter(tokenProvider), + UsernamePasswordAuthenticationFilter.class + ); return http.build(); } @@ -105,14 +85,15 @@ public PasswordEncoder passwordEncoder() { } @Bean - public AuthenticationManager authenticationManager( - JwtAuthenticationProvider jwtAuthenticationProvider) { + public AuthenticationManager authenticationManager(JwtAuthenticationProvider jwtAuthenticationProvider) { return new ProviderManager(jwtAuthenticationProvider); } @Bean - public JwtAuthenticationProvider jwtAuthenticationProvider(PasswordEncoder passwordEncoder, - FindUserUseCase findUserUseCase) { + public JwtAuthenticationProvider jwtAuthenticationProvider( + PasswordEncoder passwordEncoder, + FindUserUseCase findUserUseCase + ) { return new JwtAuthenticationProvider(passwordEncoder, findUserUseCase); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementApiPresentation.java new file mode 100644 index 00000000..02495c2c --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementApiPresentation.java @@ -0,0 +1,15 @@ +package com.plzgraduate.myongjigraduatebe.graduation.api; + +import com.plzgraduate.myongjigraduatebe.graduation.api.dto.request.CheckGraduationRequirementRequest; +import com.plzgraduate.myongjigraduatebe.graduation.api.dto.response.CheckGraduationRequirementResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import javax.validation.Valid; +import org.springframework.web.bind.annotation.RequestBody; + +@Tag(name = "CheckGraduationRequirement", description = "로그인 없이 졸업 요건을 검사하는 API") +public interface CheckGraduationRequirementApiPresentation { + + CheckGraduationRequirementResponse checkGraduationRequirement( + @Valid @RequestBody CheckGraduationRequirementRequest checkGraduationRequirementRequest + ); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementController.java new file mode 100644 index 00000000..fca7e701 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/CheckGraduationRequirementController.java @@ -0,0 +1,45 @@ +package com.plzgraduate.myongjigraduatebe.graduation.api; + +import com.plzgraduate.myongjigraduatebe.core.meta.WebAdapter; +import com.plzgraduate.myongjigraduatebe.graduation.api.dto.request.CheckGraduationRequirementRequest; +import com.plzgraduate.myongjigraduatebe.graduation.api.dto.response.CheckGraduationRequirementResponse; +import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CheckGraduationRequirementUseCase; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.ParsingAnonymousUseCase; +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.dto.ParsingAnonymousDto; +import com.plzgraduate.myongjigraduatebe.user.api.finduserinformation.dto.response.UserInformationResponse; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +@WebAdapter +@RequestMapping("/api/v1/graduations/check") +@RequiredArgsConstructor +public class CheckGraduationRequirementController implements CheckGraduationRequirementApiPresentation { + + private final ParsingAnonymousUseCase parsingAnonymousUseCase; + private final CheckGraduationRequirementUseCase checkGraduationRequirementUseCase; + + @PostMapping + public CheckGraduationRequirementResponse checkGraduationRequirement( + @Valid @RequestBody CheckGraduationRequirementRequest checkGraduationRequirementRequest + ) { + ParsingAnonymousDto parsingAnonymousDto = parsingAnonymousUseCase.parseAnonymous( + checkGraduationRequirementRequest.getEngLv(), + checkGraduationRequirementRequest.getParsingText() + ); + User anonymous = parsingAnonymousDto.getAnonymous(); + GraduationResult graduationResult = checkGraduationRequirementUseCase.checkGraduationRequirement( + anonymous, + parsingAnonymousDto.getTakenLectureInventory() + ); + + return new CheckGraduationRequirementResponse( + UserInformationResponse.from(anonymous), + graduationResult + ); + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationApiPresentation.java index 55976377..0c77e5de 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationApiPresentation.java @@ -5,16 +5,24 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.RequestParam; -@Tag(name = "Graduations") +@Tag(name = "FindDetailGraduation") public interface FindDetailGraduationApiPresentation { @Operation(summary = "졸업 카테고리 상세 결과 조회", description = "유저의 각 졸업 카테고리 상세 결과를 조회한다.") - @Parameter(name = "graduationCategory", description = "상세 조회하고자 하는 졸업 카테고리") @SecurityRequirement(name = "AccessToken") - DetailGraduationResultResponse getDetailGraduation(@Parameter(hidden = true) @LoginUser Long userId, - @RequestParam GraduationCategory graduationCategory); + DetailGraduationResultResponse getDetailGraduation( + @Parameter(hidden = true) @LoginUser Long userId, + @RequestParam @Schema( + type = "string", allowableValues = { + "COMMON_CULTURE", "CORE_CULTURE", "PRIMARY_MANDATORY_MAJOR", "PRIMARY_ELECTIVE_MAJOR", + "DUAL_MANDATORY_MAJOR", "DUAL_ELECTIVE_MAJOR", "SUB_MAJOR", "PRIMARY_BASIC_ACADEMICAL_CULTURE", + "DUAL_BASIC_ACADEMICAL_CULTURE", "NORMAL_CULTURE", "FREE_ELECTIVE", "CHAPEL" + } + ) GraduationCategory graduationCategory + ); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationController.java index 20d6fcc8..f5f6c45e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationController.java @@ -19,10 +19,15 @@ public class FindDetailGraduationController implements FindDetailGraduationApiPr private final CalculateSingleDetailGraduationUseCase calculateSingleDetailGraduationUseCase; @GetMapping - public DetailGraduationResultResponse getDetailGraduation(@LoginUser Long userId, - @RequestParam GraduationCategory graduationCategory) { + public DetailGraduationResultResponse getDetailGraduation( + @LoginUser Long userId, + @RequestParam GraduationCategory graduationCategory + ) { DetailGraduationResult detailGraduationResult = calculateSingleDetailGraduationUseCase.calculateSingleDetailGraduation( - userId, graduationCategory); + userId, + graduationCategory + ); + return DetailGraduationResultResponse.from(detailGraduationResult); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/request/CheckGraduationRequirementRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/request/CheckGraduationRequirementRequest.java new file mode 100644 index 00000000..69b0b975 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/request/CheckGraduationRequirementRequest.java @@ -0,0 +1,32 @@ +package com.plzgraduate.myongjigraduatebe.graduation.api.dto.request; + +import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; +import io.swagger.v3.oas.annotations.media.Schema; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class CheckGraduationRequirementRequest { + + @NotBlank(message = "영어 레벨을 입력해 주세요.") + @Schema(name = "engLv", example = "ENG34") + private String engLv; + + @NotNull(message = "parsingText는 null 값이 될 수 없습니다.") + @Schema(name = "parsingText", example = "2023/12/08|1/1|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 나경호(60202455), 현학적 - 재학, 이수 - 3, 입학 - 신입학(2020/03/02)|토익 - 715, 영어교과목면제 - 면제없음, 최종학적변동 - 2/1전과(2023/01/27), 전과내역 - 기계공학과|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0|공통교양 16.5, 핵심교양 6, 학문기초교양 6, 일반교양 12, 전공 9, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 7|총 취득학점 - 56.5, 총점 - 230.5, 평균평점 - 4.43|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2020년 2학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P|공통교양|2020년 2학기|교필122|KMA02122|기독교와문화|2|A+|공통교양|2023년 1학기|교필105|KMA02105|발표와토의|3|A0|공통교양|2020년 1학기|교필127|KMA00101|성서와인간이해|2|A+|공통교양|2020년 1학기|교필123|KMA02123|영어3|2|A+|공통교양|2020년 2학기|교필124|KMA02124|영어4|2|A+|공통교양|2020년 1학기|교필125|KMA02125|영어회화3|1|A0|공통교양|2020년 2학기|교필126|KMA02126|영어회화4|1|A+|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2023년 1학기|교선128|KMA02128|글로벌문화|3|A0|핵심교양|2023년 1학기|교선114|KMA02114|민주주의와현대사회|3|A+|학문기초교양|2020년 1학기|기자111|KME02111|물리학1|3|A+|학문기초교양|2020년 1학기|기자101|KME02101|미적분학1|3|A+|일반교양|2020년 2학기|기자112|KME02112|물리학2|3|A+|일반교양|2020년 1학기|기자113|KME02113|물리학실험1|1|A+|일반교양|2020년 2학기|기자114|KME02114|물리학실험2|1|A+|일반교양|2020년 2학기|기자102|KME02102|미적분학2|3|A+|일반교양|2020년 1학기|기자121|KME02121|일반화학|3|A+|일반교양|2020년 1학기|기자122|KME02122|일반화학실험|1|A+|전공1단계|2023년 1학기|데테202|HED01202|R통계분석|3|A+|전공1단계|2023년 1학기|융소102|HEB01102|기초프로그래밍|3|A+|전공1단계|2023년 1학기|데테201|HED01201|자료구조|3|A+|자유선택|2020년 2학기|공과100|JEA00100|공학입문설계|3|A+|자유선택|2020년 1학기|기계207|JEP01207|기계신입생세미나|1|P|자유선택|2020년 2학기|기계209|JEP02209|정역학|3|A+|") + private String parsingText; + + @Builder + public CheckGraduationRequirementRequest(String engLv, String parsingText) { + this.engLv = engLv; + this.parsingText = parsingText; + } + + public EnglishLevel getEngLv() { + return EnglishLevel.valueOf(engLv); + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/CheckGraduationRequirementResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/CheckGraduationRequirementResponse.java new file mode 100644 index 00000000..4aa87094 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/CheckGraduationRequirementResponse.java @@ -0,0 +1,19 @@ +package com.plzgraduate.myongjigraduatebe.graduation.api.dto.response; + +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; +import com.plzgraduate.myongjigraduatebe.user.api.finduserinformation.dto.response.UserInformationResponse; +import lombok.Getter; + +@Getter +public class CheckGraduationRequirementResponse { + + private final UserInformationResponse user; + private final GraduationResult graduationResult; + + public CheckGraduationRequirementResponse( + UserInformationResponse user, GraduationResult graduationResult + ) { + this.user = user; + this.graduationResult = graduationResult; + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/DetailGraduationResultResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/DetailGraduationResultResponse.java index 2c4ecae8..874d5611 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/DetailGraduationResultResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/api/dto/response/DetailGraduationResultResponse.java @@ -19,8 +19,12 @@ public class DetailGraduationResultResponse { private final boolean completed; @Builder - private DetailGraduationResultResponse(int totalCredit, double takenCredit, - List detailCategory, boolean completed) { + private DetailGraduationResultResponse( + int totalCredit, + double takenCredit, + List detailCategory, + boolean completed + ) { this.totalCredit = totalCredit; this.takenCredit = takenCredit; this.detailCategory = detailCategory; @@ -28,15 +32,15 @@ private DetailGraduationResultResponse(int totalCredit, double takenCredit, } public static DetailGraduationResultResponse from( - DetailGraduationResult detailGraduationResult) { + DetailGraduationResult detailGraduationResult + ) { return DetailGraduationResultResponse.builder() .totalCredit(detailGraduationResult.getTotalCredit()) .takenCredit(detailGraduationResult.getTakenCredit()) - .detailCategory(detailGraduationResult.getDetailCategory() - .stream() - .map(DetailGraduationCategoryResultResponse::from) - .collect(Collectors.toList())) - .completed(detailGraduationResult.isCompleted()) - .build(); + .detailCategory( + detailGraduationResult.getDetailCategory().stream() + .map(DetailGraduationCategoryResultResponse::from).collect(Collectors.toList()) + ) + .completed(detailGraduationResult.isCompleted()).build(); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateBasicAcademicalCultureGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateBasicAcademicalCultureGraduationService.java index f6172a9d..1cac7978 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateBasicAcademicalCultureGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateBasicAcademicalCultureGraduationService.java @@ -40,9 +40,11 @@ public boolean supports(GraduationCategory graduationCategory) { } @Override - public DetailGraduationResult calculateSingleDetailGraduation(User user, + public DetailGraduationResult calculateSingleDetailGraduation( + User user, GraduationCategory graduationCategory, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { + TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement + ) { MajorType majorType = MajorType.from(graduationCategory); String userMajor = user.getMajorByMajorType(majorType); Set graduationBasicAcademicalCultureLectures = @@ -51,29 +53,39 @@ public DetailGraduationResult calculateSingleDetailGraduation(User user, determineBasicAcademicalCultureGraduationManager(userMajor); DetailGraduationResult detailGraduationResult = basicAcademicalCultureGraduationManager.createDetailGraduationResult( user, takenLectureInventory, graduationBasicAcademicalCultureLectures, - graduationRequirement.getBasicCreditByMajorType(majorType)); + graduationRequirement.getBasicCreditByMajorType(majorType) + ); detailGraduationResult.assignGraduationCategory(graduationCategory); return detailGraduationResult; } - public List calculateAllDetailGraduation(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { + public List calculateAllDetailGraduation( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { TakenLectureInventory copiedTakenLectureForPrimaryBasicAcademicalCulture = takenLectureInventory.copy(); TakenLectureInventory copiedTakenLectureForDualBasicAcademicalCulture = takenLectureInventory.copy(); DetailGraduationResult primaryBasicAcademicalCultureDetailGraduationResult = calculateSingleDetailGraduation( user, PRIMARY_BASIC_ACADEMICAL_CULTURE, copiedTakenLectureForPrimaryBasicAcademicalCulture, - graduationRequirement); + graduationRequirement + ); DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult = calculateSingleDetailGraduation( user, DUAL_BASIC_ACADEMICAL_CULTURE, copiedTakenLectureForDualBasicAcademicalCulture, - graduationRequirement); - syncOriginalTakenLectureInventory(takenLectureInventory, + graduationRequirement + ); + syncOriginalTakenLectureInventory( + takenLectureInventory, primaryBasicAcademicalCultureDetailGraduationResult, - dualBasicAcademicalCultureDetailGraduationResult); - return List.of(primaryBasicAcademicalCultureDetailGraduationResult, - dualBasicAcademicalCultureDetailGraduationResult); + dualBasicAcademicalCultureDetailGraduationResult + ); + return List.of( + primaryBasicAcademicalCultureDetailGraduationResult, + dualBasicAcademicalCultureDetailGraduationResult + ); } DetailGraduationResult primaryBasicAcademicalCultureGraduationResult = calculateSingleDetailGraduation( user, PRIMARY_BASIC_ACADEMICAL_CULTURE, takenLectureInventory, graduationRequirement); @@ -81,7 +93,8 @@ public List calculateAllDetailGraduation(User user, } private GraduationManager determineBasicAcademicalCultureGraduationManager( - String userMajor) { + String userMajor + ) { return basicAcademicalGraduationManagers.stream() .filter(basicAcademicalManager -> basicAcademicalManager.isSatisfied(userMajor)) .findFirst() @@ -91,7 +104,8 @@ private GraduationManager determineBasicAcademica private void syncOriginalTakenLectureInventory( TakenLectureInventory originalTakenLectureInventory, DetailGraduationResult primaryBasicAcademicalCultureDetailGraduationResult, - DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult) { + DetailGraduationResult dualBasicAcademicalCultureDetailGraduationResult + ) { List primaryBasicAcademicalCultureTakenLectures = primaryBasicAcademicalCultureDetailGraduationResult.getDetailCategory() .get(0) diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCommonCultureGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCommonCultureGraduationService.java index 9c664958..f5d51826 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCommonCultureGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCommonCultureGraduationService.java @@ -30,13 +30,19 @@ public boolean supports(GraduationCategory graduationCategory) { } @Override - public DetailGraduationResult calculateSingleDetailGraduation(User user, + public DetailGraduationResult calculateSingleDetailGraduation( + User user, GraduationCategory graduationCategory, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { Set graduationCommonCultures = findCommonCulturePort.findCommonCulture(user); return commonCultureGraduationManager.createDetailGraduationResult( - user, takenLectureInventory, graduationCommonCultures, - graduationRequirement.getCommonCultureCredit()); + user, + takenLectureInventory, + graduationCommonCultures, + graduationRequirement.getCommonCultureCredit() + ); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCoreCultureGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCoreCultureGraduationService.java index e34df1d7..a7805b9c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCoreCultureGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateCoreCultureGraduationService.java @@ -30,12 +30,18 @@ public boolean supports(GraduationCategory graduationCategory) { } @Override - public DetailGraduationResult calculateSingleDetailGraduation(User user, + public DetailGraduationResult calculateSingleDetailGraduation( + User user, GraduationCategory graduationCategory, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { Set graduationCoreCultures = findCoreCulturePort.findCoreCulture(user); return coreCultureGraduationManager.createDetailGraduationResult( - user, takenLectureInventory, graduationCoreCultures, - graduationRequirement.getCoreCultureCredit()); + user, + takenLectureInventory, + graduationCoreCultures, + graduationRequirement.getCoreCultureCredit() + ); } } 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 a447247c..af467d27 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 @@ -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; @@ -34,89 +29,171 @@ 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()); + user.getId() + ); ChapelResult chapelResult = generateChapelResult(takenLectureInventory); - List detailGraduationResults = generateDetailGraduationResults(user, - takenLectureInventory, graduationRequirement); + List detailGraduationResults = generateDetailGraduationResults( + user, + takenLectureInventory, + graduationRequirement + ); - GraduationResult graduationResult = generateGraduationResult(chapelResult, + GraduationResult graduationResult = generateGraduationResult( + chapelResult, detailGraduationResults, - takenLectureInventory, graduationRequirement); + takenLectureInventory, + graduationRequirement, + user + ); handleDuplicatedTakenCredit(user, graduationResult); updateUserGraduationInformation(user, graduationResult); return graduationResult; } - private GraduationRequirement determineGraduationRequirement(User user) { + 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 = DefaultGraduationRequirementType.determineGraduationRequirement( - userCollage, user); + DefaultGraduationRequirementType defaultGraduationRequirement = + DefaultGraduationRequirementType.determineGraduationRequirement(userCollage, user); return defaultGraduationRequirement.convertToProfitGraduationRequirement(user); } - private ChapelResult generateChapelResult(TakenLectureInventory takenLectureInventory) { + ChapelResult generateChapelResult(TakenLectureInventory takenLectureInventory) { ChapelResult chapelResult = ChapelResult.create(takenLectureInventory); chapelResult.checkCompleted(); return chapelResult; } - private List generateDetailGraduationResults(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - List detailGraduationResults = new ArrayList<>(List.of( - generateCommonCultureDetailGraduationResult( - user, takenLectureInventory, graduationRequirement), - generateCoreCultureDetailGraduationResult( - user, takenLectureInventory, graduationRequirement) - )); - detailGraduationResults.addAll(generateBasicAcademicalDetailGraduationResult( - user, takenLectureInventory, graduationRequirement)); - detailGraduationResults.addAll(generateMajorDetailGraduationResult( - user, takenLectureInventory, graduationRequirement)); + List generateDetailGraduationResults( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + List 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( + generateMajorDetailGraduationResult( + user, takenLectureInventory, graduationRequirement + ) + ); + return detailGraduationResults; } - private DetailGraduationResult generateCommonCultureDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - return calculateCommonCultureGraduationService.calculateSingleDetailGraduation(user, - GraduationCategory.COMMON_CULTURE, takenLectureInventory, graduationRequirement); + private DetailGraduationResult generateCommonCultureDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + return calculateCommonCultureGraduationService.calculateSingleDetailGraduation( + user, GraduationCategory.COMMON_CULTURE, takenLectureInventory, graduationRequirement + ); } - private DetailGraduationResult generateCoreCultureDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - return calculateCoreCultureGraduationService.calculateSingleDetailGraduation(user, - GraduationCategory.CORE_CULTURE, takenLectureInventory, graduationRequirement); + private DetailGraduationResult generateCoreCultureDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + return calculateCoreCultureGraduationService.calculateSingleDetailGraduation( + user, GraduationCategory.CORE_CULTURE, takenLectureInventory, graduationRequirement + ); } - private List generateBasicAcademicalDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - return calculateBasicAcademicalCultureGraduationService.calculateAllDetailGraduation(user, - takenLectureInventory, graduationRequirement); + private List generateBasicAcademicalDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + return calculateBasicAcademicalCultureGraduationService.calculateAllDetailGraduation( + user, takenLectureInventory, graduationRequirement + ); } - private List generateMajorDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - return calculateMajorGraduationService.calculateAllDetailGraduation(user, + private List generateMajorDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + return calculateMajorGraduationService.calculateAllDetailGraduation( + user, takenLectureInventory, - graduationRequirement); + graduationRequirement + ); } - private GraduationResult generateGraduationResult(ChapelResult chapelResult, + GraduationResult generateGraduationResult( + ChapelResult chapelResult, List detailGraduationResults, TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { - GraduationResult graduationResult = GraduationResult.create(chapelResult, - detailGraduationResults); - graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement); - graduationResult.checkGraduated(graduationRequirement); + GraduationRequirement graduationRequirement, + User user + ) { + GraduationResult graduationResult = GraduationResult.create( + chapelResult, + detailGraduationResults + ); + graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement, user); + graduationResult.checkGraduated(graduationRequirement, user); return graduationResult; } - private void handleDuplicatedTakenCredit(User user, GraduationResult graduationResult) { + void handleDuplicatedTakenCredit(User user, GraduationResult graduationResult) { if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { int duplicatedBasicAcademicalCultureCredit = findBasicAcademicalCulturePort.findDuplicatedLecturesBetweenMajors(user) @@ -131,7 +208,8 @@ private void handleDuplicatedTakenCredit(User user, GraduationResult graduationR private void updateUserGraduationInformation(User user, GraduationResult graduationResult) { UpdateStudentInformationCommand updateStudentInformationCommand = UpdateStudentInformationCommand.update( user, - graduationResult); + graduationResult + ); updateStudentInformationUseCase.updateUser(updateStudentInformationCommand); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationService.java index 194e6345..7f0d99eb 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationService.java @@ -31,144 +31,179 @@ @RequiredArgsConstructor public class CalculateMajorGraduationService implements CalculateDetailGraduationUseCase { - private final FindMajorPort findMajorPort; - private final MajorGraduationManager majorGraduationManager; - private final SubMajorGraduationManager subMajorGraduationManager; - - @Override - public boolean supports(GraduationCategory graduationCategory) { - return graduationCategory == PRIMARY_MANDATORY_MAJOR - || graduationCategory == PRIMARY_ELECTIVE_MAJOR - || graduationCategory == DUAL_MANDATORY_MAJOR - || graduationCategory == DUAL_ELECTIVE_MAJOR - || graduationCategory == SUB_MAJOR; - } - - @Override - public DetailGraduationResult calculateSingleDetailGraduation(User user, - GraduationCategory graduationCategory, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - MajorType majorType = MajorType.from(graduationCategory); - - if (majorType == MajorType.SUB) { - return generateSubMajorDetailGraduationResult(user, takenLectureInventory, - graduationRequirement); - } - - DetailGraduationResult majorDetailGraduationResult = generateMajorDetailGraduationResult( - user, - majorType, takenLectureInventory, graduationRequirement); - - boolean isMandatory = graduationCategory.checkMandatoryIfSeperatedByMandatoryAndElective(); - - if (isMandatory) { - DetailCategoryResult majorDetailCategoryResult = separateMandatoryMajor( - graduationCategory, - majorDetailGraduationResult); - return DetailGraduationResult.create(graduationCategory, - majorDetailCategoryResult.getTotalCredits(), List.of(majorDetailCategoryResult)); - } - - DetailCategoryResult majorDetailCategoryResult = separateElectiveMajor(graduationCategory, - majorDetailGraduationResult); - return DetailGraduationResult.create(graduationCategory, - majorDetailCategoryResult.getTotalCredits(), List.of(majorDetailCategoryResult)); - } - - public List calculateAllDetailGraduation(User user, - TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement) { - - DetailGraduationResult primaryMajorDetailGraduationResult = generateMajorDetailGraduationResult( - user, - MajorType.PRIMARY, takenLectureInventory, graduationRequirement); - DetailGraduationResult primaryMandatoryMajorDetailGraduationResult = isolateMandatoryMajorDetailGraduation( - PRIMARY_MANDATORY_MAJOR, primaryMajorDetailGraduationResult); - DetailGraduationResult primaryElectiveMajorDetailGraduationResult = isolateElectiveMajorDetailGraduation( - PRIMARY_ELECTIVE_MAJOR, primaryMajorDetailGraduationResult); - - List majorGraduationResults = new ArrayList<>( - List.of(primaryMandatoryMajorDetailGraduationResult, - primaryElectiveMajorDetailGraduationResult)); - - if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { - DetailGraduationResult dualMajorDetailGraduationResult = generateMajorDetailGraduationResult( - user, - MajorType.DUAL, takenLectureInventory, graduationRequirement); - DetailGraduationResult dualMandatoryMajorDetailGraduationResult = isolateMandatoryMajorDetailGraduation( - DUAL_MANDATORY_MAJOR, dualMajorDetailGraduationResult); - DetailGraduationResult dualElectiveMajorDetailGraduationResult = isolateElectiveMajorDetailGraduation( - DUAL_ELECTIVE_MAJOR, dualMajorDetailGraduationResult); - majorGraduationResults.addAll( - List.of(dualMandatoryMajorDetailGraduationResult, - dualElectiveMajorDetailGraduationResult)); - } - if (user.getStudentCategory() == StudentCategory.SUB_MAJOR) { - majorGraduationResults.add( - generateSubMajorDetailGraduationResult(user, takenLectureInventory, - graduationRequirement)); - } - return majorGraduationResults; - } - - private DetailGraduationResult generateMajorDetailGraduationResult(User user, - MajorType majorType, - TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { - Set graduationMajorLectures = findMajorPort.findMajor( - user.getMajorByMajorType(majorType)); - return majorGraduationManager.createDetailGraduationResult(user, majorType, - takenLectureInventory, graduationMajorLectures, - graduationRequirement.getMajorCreditByMajorType(majorType)); - } - - private DetailGraduationResult generateSubMajorDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { - Set graduationSubMajorLectures = findMajorPort.findMajor(user.getSubMajor()); - return subMajorGraduationManager.createDetailGraduationResult(user, takenLectureInventory, - graduationSubMajorLectures, - graduationRequirement.getSubMajorCredit()); - } - - private DetailGraduationResult isolateMandatoryMajorDetailGraduation( - GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult) { - DetailCategoryResult mandatoryMajorDetailCategoryResult = separateMandatoryMajor( - graduationCategory, majorDetailGraduationResult); - return DetailGraduationResult.create(graduationCategory, - mandatoryMajorDetailCategoryResult.getTotalCredits(), - List.of(mandatoryMajorDetailCategoryResult)); - } - - private DetailGraduationResult isolateElectiveMajorDetailGraduation( - GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult) { - DetailCategoryResult electiveMajorDetailCategoryResult = separateElectiveMajor( - graduationCategory, majorDetailGraduationResult); - return DetailGraduationResult.create(graduationCategory, - electiveMajorDetailCategoryResult.getTotalCredits(), - List.of(electiveMajorDetailCategoryResult)); - } - - private DetailCategoryResult separateMandatoryMajor( - GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult) { - DetailCategoryResult mandatoryMajorDetailCategoryResult = majorDetailGraduationResult.getDetailCategory() - .stream() - .filter(detailCategoryResult -> detailCategoryResult.getDetailCategoryName() - .equals("전공필수")) - .findFirst() - .orElseThrow(() -> new RuntimeException("Not Found DetailCategoryResult(전공 필수)")); - mandatoryMajorDetailCategoryResult.assignDetailCategoryName(graduationCategory.getName()); - return mandatoryMajorDetailCategoryResult; - } - - private DetailCategoryResult separateElectiveMajor( - GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult) { - DetailCategoryResult electiveMajorDetailCategoryResult = majorDetailGraduationResult.getDetailCategory() - .stream() - .filter(detailCategoryResult -> detailCategoryResult.getDetailCategoryName() - .equals("전공선택")) - .findFirst() - .orElseThrow(() -> new RuntimeException("Not Found DetailCategoryResult(전공 선택)")); - electiveMajorDetailCategoryResult.assignDetailCategoryName(graduationCategory.getName()); - return electiveMajorDetailCategoryResult; - } + private final FindMajorPort findMajorPort; + private final MajorGraduationManager majorGraduationManager; + private final SubMajorGraduationManager subMajorGraduationManager; + + @Override + public boolean supports(GraduationCategory graduationCategory) { + return graduationCategory == PRIMARY_MANDATORY_MAJOR + || graduationCategory == PRIMARY_ELECTIVE_MAJOR + || graduationCategory == DUAL_MANDATORY_MAJOR + || graduationCategory == DUAL_ELECTIVE_MAJOR + || graduationCategory == SUB_MAJOR; + } + + @Override + public DetailGraduationResult calculateSingleDetailGraduation( + User user, + GraduationCategory graduationCategory, + TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement + ) { + MajorType majorType = MajorType.from(graduationCategory); + + if (majorType == MajorType.SUB) { + return generateSubMajorDetailGraduationResult(user, takenLectureInventory, + graduationRequirement + ); + } + + DetailGraduationResult majorDetailGraduationResult = generateMajorDetailGraduationResult( + user, + majorType, takenLectureInventory, graduationRequirement + ); + + boolean isMandatory = graduationCategory.checkMandatoryIfSeperatedByMandatoryAndElective(); + + if (isMandatory) { + DetailCategoryResult majorDetailCategoryResult = separateMandatoryMajor( + graduationCategory, + majorDetailGraduationResult + ); + return DetailGraduationResult.create(graduationCategory, + majorDetailCategoryResult.getTotalCredits(), List.of(majorDetailCategoryResult) + ); + } + + DetailCategoryResult majorDetailCategoryResult = separateElectiveMajor( + graduationCategory, + majorDetailGraduationResult + ); + return DetailGraduationResult.create(graduationCategory, + majorDetailCategoryResult.getTotalCredits(), List.of(majorDetailCategoryResult) + ); + } + + public List calculateAllDetailGraduation( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + + DetailGraduationResult primaryMajorDetailGraduationResult = generateMajorDetailGraduationResult( + user, + MajorType.PRIMARY, + takenLectureInventory, + graduationRequirement + ); + DetailGraduationResult primaryMandatoryMajorDetailGraduationResult = isolateMandatoryMajorDetailGraduation( + PRIMARY_MANDATORY_MAJOR, primaryMajorDetailGraduationResult); + DetailGraduationResult primaryElectiveMajorDetailGraduationResult = isolateElectiveMajorDetailGraduation( + PRIMARY_ELECTIVE_MAJOR, primaryMajorDetailGraduationResult); + + List majorGraduationResults = new ArrayList<>( + List.of( + primaryMandatoryMajorDetailGraduationResult, + primaryElectiveMajorDetailGraduationResult + )); + + if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { + DetailGraduationResult dualMajorDetailGraduationResult = generateMajorDetailGraduationResult( + user, + MajorType.DUAL, takenLectureInventory, graduationRequirement + ); + DetailGraduationResult dualMandatoryMajorDetailGraduationResult = isolateMandatoryMajorDetailGraduation( + DUAL_MANDATORY_MAJOR, dualMajorDetailGraduationResult); + DetailGraduationResult dualElectiveMajorDetailGraduationResult = isolateElectiveMajorDetailGraduation( + DUAL_ELECTIVE_MAJOR, dualMajorDetailGraduationResult); + majorGraduationResults.addAll( + List.of( + dualMandatoryMajorDetailGraduationResult, + dualElectiveMajorDetailGraduationResult + )); + } + if (user.getStudentCategory() == StudentCategory.SUB_MAJOR) { + majorGraduationResults.add( + generateSubMajorDetailGraduationResult(user, takenLectureInventory, + graduationRequirement + )); + } + return majorGraduationResults; + } + + private DetailGraduationResult generateMajorDetailGraduationResult( + User user, + MajorType majorType, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + Set graduationMajorLectures = findMajorPort.findMajor( + user.getMajorByMajorType(majorType)); + return majorGraduationManager.createDetailGraduationResult(user, majorType, + takenLectureInventory, graduationMajorLectures, + graduationRequirement.getMajorCreditByMajorType(majorType) + ); + } + + private DetailGraduationResult generateSubMajorDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + GraduationRequirement graduationRequirement + ) { + Set graduationSubMajorLectures = findMajorPort.findMajor(user.getSubMajor()); + return subMajorGraduationManager.createDetailGraduationResult(user, takenLectureInventory, + graduationSubMajorLectures, + graduationRequirement.getSubMajorCredit() + ); + } + + private DetailGraduationResult isolateMandatoryMajorDetailGraduation( + GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult + ) { + DetailCategoryResult mandatoryMajorDetailCategoryResult = separateMandatoryMajor( + graduationCategory, majorDetailGraduationResult); + return DetailGraduationResult.create( + graduationCategory, + mandatoryMajorDetailCategoryResult.getTotalCredits(), + List.of(mandatoryMajorDetailCategoryResult) + ); + } + + private DetailGraduationResult isolateElectiveMajorDetailGraduation( + GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult + ) { + DetailCategoryResult electiveMajorDetailCategoryResult = separateElectiveMajor( + graduationCategory, majorDetailGraduationResult); + return DetailGraduationResult.create( + graduationCategory, + electiveMajorDetailCategoryResult.getTotalCredits(), + List.of(electiveMajorDetailCategoryResult) + ); + } + + private DetailCategoryResult separateMandatoryMajor( + GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult + ) { + DetailCategoryResult mandatoryMajorDetailCategoryResult = majorDetailGraduationResult.getDetailCategory() + .stream() + .filter(detailCategoryResult -> detailCategoryResult.getDetailCategoryName() + .equals("전공필수")) + .findFirst() + .orElseThrow(() -> new RuntimeException("Not Found DetailCategoryResult(전공 필수)")); + mandatoryMajorDetailCategoryResult.assignDetailCategoryName(graduationCategory.getName()); + return mandatoryMajorDetailCategoryResult; + } + + private DetailCategoryResult separateElectiveMajor( + GraduationCategory graduationCategory, DetailGraduationResult majorDetailGraduationResult + ) { + DetailCategoryResult electiveMajorDetailCategoryResult = majorDetailGraduationResult.getDetailCategory() + .stream() + .filter(detailCategoryResult -> detailCategoryResult.getDetailCategoryName() + .equals("전공선택")) + .findFirst() + .orElseThrow(() -> new RuntimeException("Not Found DetailCategoryResult(전공 선택)")); + electiveMajorDetailCategoryResult.assignDetailCategoryName(graduationCategory.getName()); + return electiveMajorDetailCategoryResult; + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CheckGraduationRequirementService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CheckGraduationRequirementService.java new file mode 100644 index 00000000..c0f9d922 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CheckGraduationRequirementService.java @@ -0,0 +1,68 @@ +package com.plzgraduate.myongjigraduatebe.graduation.application.service; + +import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; +import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CheckGraduationRequirementUseCase; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.ChapelResult; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; +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; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class CheckGraduationRequirementService implements CheckGraduationRequirementUseCase { + + private final FindLecturePort findLecturePort; + private final CalculateGraduationService calculateGraduationService; + + @Override + public GraduationResult checkGraduationRequirement( + User anonymous, + TakenLectureInventory takenLectureInventory + ) { + Set takenLectureWithDuplicateCode = takenLectureInventory.getTakenLectures() + .stream() + .map(takenLecture -> TakenLecture.of( + anonymous, + findLecturePort.findLectureById(takenLecture.getLecture().getId()), + takenLecture.getYear(), + takenLecture.getSemester() + ) + ).collect(Collectors.toSet()); + + TakenLectureInventory takenLectureInventoryWithDuplicateCode = TakenLectureInventory.from( + takenLectureWithDuplicateCode); + + GraduationRequirement graduationRequirement = + calculateGraduationService.determineGraduationRequirement(anonymous); + + ChapelResult chapelResult = + calculateGraduationService.generateChapelResult(takenLectureInventoryWithDuplicateCode); + if (anonymous.getStudentCategory() == StudentCategory.TRANSFER) { + chapelResult.checkAnonymousTransferUserChapelCount(); + } + + List detailGraduationResults = calculateGraduationService.generateDetailGraduationResults( + anonymous, + takenLectureInventoryWithDuplicateCode, + graduationRequirement + ); + GraduationResult graduationResult = calculateGraduationService.generateGraduationResult( + chapelResult, + detailGraduationResults, + takenLectureInventoryWithDuplicateCode, + graduationRequirement, + anonymous + ); + calculateGraduationService.handleDuplicatedTakenCredit(anonymous, graduationResult); + return graduationResult; + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CalculateSingleDetailGraduationUseCase.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CalculateSingleDetailGraduationUseCase.java index c09b3a6b..8ee718fb 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CalculateSingleDetailGraduationUseCase.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CalculateSingleDetailGraduationUseCase.java @@ -5,7 +5,8 @@ public interface CalculateSingleDetailGraduationUseCase { - DetailGraduationResult calculateSingleDetailGraduation(Long userId, - GraduationCategory graduationCategory); - + DetailGraduationResult calculateSingleDetailGraduation( + Long userId, + GraduationCategory graduationCategory + ); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CheckGraduationRequirementUseCase.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CheckGraduationRequirementUseCase.java new file mode 100644 index 00000000..4cad6a40 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/usecase/CheckGraduationRequirementUseCase.java @@ -0,0 +1,13 @@ +package com.plzgraduate.myongjigraduatebe.graduation.application.usecase; + +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; +import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; + +public interface CheckGraduationRequirementUseCase { + + GraduationResult checkGraduationRequirement( + User user, + TakenLectureInventory takenLectureInventory + ); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/ChapelResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/ChapelResult.java index 8cf700e7..a3ee3c78 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/ChapelResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/ChapelResult.java @@ -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; @@ -43,4 +44,8 @@ public void checkCompleted() { public double getTakenChapelCredit() { return takenCount * CHAPEL_CREDIT; } + + public void checkAnonymousTransferUserChapelCount() { + isCompleted = takenCount == ANONYMOUS_TRANSFER_USER_GRADUATION_COUNT; + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DefaultGraduationRequirementType.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DefaultGraduationRequirementType.java index 983bf252..241c521e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DefaultGraduationRequirementType.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DefaultGraduationRequirementType.java @@ -35,45 +35,72 @@ public enum DefaultGraduationRequirementType { private final int startEntryYear; private final int endEntryYear; - public static DefaultGraduationRequirementType determineGraduationRequirement(College college, - User user) { + public static DefaultGraduationRequirementType determineGraduationRequirement( + College college, + User user + ) { return Arrays.stream(DefaultGraduationRequirementType.values()) - .filter(gr -> gr.getCollageName() - .equals(college.getName())) - .filter(gr -> gr.getStartEntryYear() <= user.getEntryYear() - && gr.getEndEntryYear() >= user.getEntryYear()) - .findFirst() - .orElseThrow(() -> new NoSuchElementException("일치하는 졸업 요건이 존재하지 않습니다.")); + .filter(gr -> gr.getCollageName().equals(college.getName())) + .filter(gr -> gr.getStartEntryYear() <= user.getEntryYear() + && gr.getEndEntryYear() >= user.getEntryYear()) + .findFirst() + .orElseThrow(() -> new NoSuchElementException("일치하는 졸업 요건이 존재하지 않습니다.")); } public GraduationRequirement convertToProfitGraduationRequirement(User user) { + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + return createTransferGraduationRequirement(user); + } + return createDefaultGraduationRequirement(user); + } + + private GraduationRequirement createDefaultGraduationRequirement(User user) { GraduationRequirement graduationRequirement = GraduationRequirement.builder() - .totalCredit(this.totalCredit) - .primaryMajorCredit(this.majorLectureCredit) - .dualMajorCredit(0) - .subMajorCredit(0) - .primaryBasicAcademicalCultureCredit(this.basicAcademicalLectureCredit) - .dualBasicAcademicalCultureCredit(0) - .commonCultureCredit(this.commonCultureCredit) - .coreCultureCredit(this.coreCultureCredit) - .normalCultureCredit(this.normalLectureCredit) - .freeElectiveCredit(this.freeElectiveLectureCredit) - .build(); + .totalCredit(this.totalCredit) + .primaryMajorCredit(this.majorLectureCredit) + .dualMajorCredit(0) + .subMajorCredit(0) + .primaryBasicAcademicalCultureCredit(this.basicAcademicalLectureCredit) + .dualBasicAcademicalCultureCredit(0) + .commonCultureCredit(this.commonCultureCredit) + .coreCultureCredit(this.coreCultureCredit) + .normalCultureCredit(this.normalLectureCredit) + .freeElectiveCredit(this.freeElectiveLectureCredit) + .build(); checkIsEnglishFreeUserAndTransferCredit(user, graduationRequirement); checkIsMultiMajorUserAndTransferCredit(user, graduationRequirement); + return graduationRequirement; } - private void checkIsEnglishFreeUserAndTransferCredit(User user, - GraduationRequirement graduationRequirement) { + private GraduationRequirement createTransferGraduationRequirement(User user) { + College userCollege = College.findBelongingCollege(user.getPrimaryMajor()); + TransferGraduationRequirementType transferRequirement = + TransferGraduationRequirementType.findByCollegeName(userCollege.getName()); + + return GraduationRequirement.builder() + .totalCredit(this.totalCredit) + .primaryMajorCredit(this.majorLectureCredit) + .normalCultureCredit(transferRequirement.getCombinedCultureCredit()) + .christianCredit(transferRequirement.getChristianCredit()) + .freeElectiveCredit(this.freeElectiveLectureCredit) + .build(); + } + + private void checkIsEnglishFreeUserAndTransferCredit( + User user, + GraduationRequirement graduationRequirement + ) { if (user.getEnglishLevel() == EnglishLevel.FREE) { graduationRequirement.transferEnglishCreditCommonToNormal(); } } - private void checkIsMultiMajorUserAndTransferCredit(User user, - GraduationRequirement graduationRequirement) { + private void checkIsMultiMajorUserAndTransferCredit( + User user, + GraduationRequirement graduationRequirement + ) { if (user.getStudentCategory() == StudentCategory.DUAL_MAJOR) { graduationRequirement.modifyCreditForDualMajor(user); } @@ -81,4 +108,4 @@ private void checkIsMultiMajorUserAndTransferCredit(User user, graduationRequirement.modifyCreditForSubMajor(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailCategoryResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailCategoryResult.java index bc9581c5..0876addf 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailCategoryResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailCategoryResult.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; + import lombok.Builder; import lombok.Getter; @@ -24,9 +25,11 @@ public class DetailCategoryResult { private int freeElectiveLeftCredit; @Builder - private DetailCategoryResult(String detailCategoryName, boolean isCompleted, + private DetailCategoryResult( + String detailCategoryName, boolean isCompleted, boolean isSatisfiedMandatory, - int totalCredits, int takenCredits, int normalLeftCredit, int freeElectiveLeftCredit) { + int totalCredits, int takenCredits, int normalLeftCredit, int freeElectiveLeftCredit + ) { this.detailCategoryName = detailCategoryName; this.isCompleted = isCompleted; this.isSatisfiedMandatory = isSatisfiedMandatory; @@ -36,9 +39,11 @@ private DetailCategoryResult(String detailCategoryName, boolean isCompleted, this.freeElectiveLeftCredit = freeElectiveLeftCredit; } - public static DetailCategoryResult create(String detailCategoryName, + public static DetailCategoryResult create( + String detailCategoryName, boolean isSatisfiedMandatory, - int totalCredits) { + int totalCredits + ) { return DetailCategoryResult.builder() .detailCategoryName(detailCategoryName) .isCompleted(false) @@ -50,6 +55,21 @@ public static DetailCategoryResult create(String detailCategoryName, .build(); } + @Override + public String toString() { + return "DetailCategoryResult{" + + "isSatisfiedMandatory=" + isSatisfiedMandatory + + ", totalCredits=" + totalCredits + + ", takenLectures=" + takenLectures + + ", haveToLectures=" + haveToLectures + + ", detailCategoryName='" + detailCategoryName + '\'' + + ", isCompleted=" + isCompleted + + ", takenCredits=" + takenCredits + + ", normalLeftCredit=" + normalLeftCredit + + ", freeElectiveLeftCredit=" + freeElectiveLeftCredit + + '}'; + } + public void assignDetailCategoryName(String detailCategoryName) { this.detailCategoryName = detailCategoryName; } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailGraduationResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailGraduationResult.java index 1145ee56..c4979daf 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailGraduationResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/DetailGraduationResult.java @@ -14,10 +14,13 @@ public class DetailGraduationResult { private double takenCredit; @Builder - private DetailGraduationResult(GraduationCategory graduationCategory, boolean isCompleted, + private DetailGraduationResult( + GraduationCategory graduationCategory, + boolean isCompleted, int totalCredit, double takenCredit, - List detailCategory) { + List detailCategory + ) { this.graduationCategory = graduationCategory; this.isCompleted = isCompleted; this.totalCredit = totalCredit; @@ -25,9 +28,11 @@ private DetailGraduationResult(GraduationCategory graduationCategory, boolean is this.detailCategory = detailCategory; } - public static DetailGraduationResult create(GraduationCategory graduationCategory, + public static DetailGraduationResult create( + GraduationCategory graduationCategory, int totalCredit, - List detailCategoryResults) { + List detailCategoryResults + ) { return DetailGraduationResult.builder() .graduationCategory(graduationCategory) .isCompleted(checkIsCompleted(detailCategoryResults)) @@ -37,8 +42,10 @@ public static DetailGraduationResult create(GraduationCategory graduationCategor .build(); } - public static DetailGraduationResult createNonCategorizedGraduationResult(int totalCredit, - List detailCategoryResults) { + public static DetailGraduationResult createNonCategorizedGraduationResult( + int totalCredit, + List detailCategoryResults + ) { return DetailGraduationResult.builder() .isCompleted(checkIsCompleted(detailCategoryResults)) .totalCredit(totalCredit) @@ -58,6 +65,17 @@ private static int calculateTakenCredit(List detailCategor .sum(); } + @Override + public String toString() { + return "DetailGraduationResult{" + + "isCompleted=" + isCompleted + + ", totalCredit=" + totalCredit + + ", detailCategory=" + detailCategory + + ", graduationCategory=" + graduationCategory + + ", takenCredit=" + takenCredit + + '}'; + } + public void assignGraduationCategory(GraduationCategory graduationCategory) { this.graduationCategory = graduationCategory; } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResult.java index 0c56eea0..07addd5f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResult.java @@ -4,6 +4,9 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; import java.util.List; + +import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import lombok.Builder; import lombok.Getter; @@ -26,19 +29,19 @@ private FreeElectiveGraduationResult(String categoryName, boolean isCompleted, i public static FreeElectiveGraduationResult create(int totalCredit, TakenLectureInventory takenLectureInventory, - List detailGraduationResults, int leftNormalCultureCredit) { + List detailGraduationResults, int leftNormalCultureCredit, User user) { return FreeElectiveGraduationResult.builder() .categoryName(FREE_ELECTIVE.getName()) .isCompleted(false) .totalCredit(totalCredit) .takenCredit( calculateTakenCredit(takenLectureInventory, detailGraduationResults, - leftNormalCultureCredit)) + leftNormalCultureCredit, user)) .build(); } private static int calculateTakenCredit(TakenLectureInventory takenLectureInventory, - List detailGraduationResults, int leftNormalCultureCredit) { + List detailGraduationResults, int leftNormalCultureCredit, User user) { int remainCreditByDetailGraduationResult = detailGraduationResults.stream() .mapToInt(DetailGraduationResult::getFreeElectiveLeftCredit) .sum(); @@ -49,8 +52,14 @@ private static int calculateTakenCredit(TakenLectureInventory takenLectureInvent .getCredit()) .sum(); + int transferFreeElectiveCredit = 0; + + // 편입생일 경우 추가 학점을 계산 + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + transferFreeElectiveCredit = user.getTransferCredit().getFreeElective(); + } return remainCreditByDetailGraduationResult + remainCreditByTakenLectures - + leftNormalCultureCredit; + + leftNormalCultureCredit+transferFreeElectiveCredit; } public void checkCompleted() { diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationCategory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationCategory.java index db36c59f..0498bd0b 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationCategory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationCategory.java @@ -19,10 +19,7 @@ public enum GraduationCategory { SUB_MAJOR("부전공"), PRIMARY_BASIC_ACADEMICAL_CULTURE("주학문기초교양"), DUAL_BASIC_ACADEMICAL_CULTURE("복수학문기초교양"), - ASSOCIATED_MANDATORY_MAJOR("연계전공필수"), - ASSOCIATED_ELECTIVE_MAJOR("연계전공선택"), - ASSOCIATED_MANDATORY_CULTURE("연계전공교양필수"), - ASSOCIATED_ELECTIVE_CULTURE("연계전공교양선택"), + TRANSFER_CHRISTIAN("편입기독교"), NORMAL_CULTURE("일반교양"), FREE_ELECTIVE("자유선택"), CHAPEL("채플"); @@ -39,4 +36,11 @@ public static GraduationCategory of(String name) { public boolean checkMandatoryIfSeperatedByMandatoryAndElective() { return this == PRIMARY_MANDATORY_MAJOR || this == DUAL_MANDATORY_MAJOR; } + + @Override + public String toString() { + return "GraduationCategory{" + + "name='" + name + '\'' + + '}'; + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationRequirement.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationRequirement.java index dd3f1841..db573e62 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationRequirement.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationRequirement.java @@ -21,14 +21,22 @@ public class GraduationRequirement { private int commonCultureCredit; private int normalCultureCredit; private int freeElectiveCredit; + private final int christianCredit; @Builder - private GraduationRequirement(int totalCredit, int primaryMajorCredit, int dualMajorCredit, + private GraduationRequirement( + int totalCredit, + int primaryMajorCredit, + int dualMajorCredit, int subMajorCredit, - int primaryBasicAcademicalCultureCredit, int dualBasicAcademicalCultureCredit, + int primaryBasicAcademicalCultureCredit, + int dualBasicAcademicalCultureCredit, int commonCultureCredit, int coreCultureCredit, - int normalCultureCredit, int freeElectiveCredit) { + int normalCultureCredit, + int freeElectiveCredit, + int christianCredit + ) { this.totalCredit = totalCredit; this.primaryMajorCredit = primaryMajorCredit; this.dualMajorCredit = dualMajorCredit; @@ -39,6 +47,7 @@ private GraduationRequirement(int totalCredit, int primaryMajorCredit, int dualM this.coreCultureCredit = coreCultureCredit; this.normalCultureCredit = normalCultureCredit; this.freeElectiveCredit = freeElectiveCredit; + this.christianCredit = christianCredit; } public void transferEnglishCreditCommonToNormal() { @@ -54,12 +63,12 @@ public void modifyCreditForSubMajor() { public void modifyCreditForDualMajor(User user) { DualMajorGraduationRequirementType primaryMajorGraduationRequirementType = findBelongingDualMajorGraduationRequirementType( - College.findBelongingCollege(user.getPrimaryMajor()) - .getName()); + College.findBelongingCollege(user.getPrimaryMajor()).getName() + ); DualMajorGraduationRequirementType dualMajorGraduationRequirementType = findBelongingDualMajorGraduationRequirementType( - College.findBelongingCollege(user.getDualMajor()) - .getName()); + College.findBelongingCollege(user.getDualMajor()).getName() + ); primaryMajorCredit = primaryMajorGraduationRequirementType.getMajorCredit(); dualMajorCredit = dualMajorGraduationRequirementType.getMajorCredit(); @@ -69,10 +78,7 @@ public void modifyCreditForDualMajor(User user) { } private int calculateFreeElectiveCreditWithDualMajorStudent() { - int freeElectiveCredit = - totalCredit - commonCultureCredit - coreCultureCredit - primaryMajorCredit - - dualMajorCredit - - primaryBasicAcademicalCultureCredit - dualBasicAcademicalCultureCredit; + int freeElectiveCredit = totalCredit - commonCultureCredit - coreCultureCredit - primaryMajorCredit - dualMajorCredit - primaryBasicAcademicalCultureCredit - dualBasicAcademicalCultureCredit; return Math.max(freeElectiveCredit, 0); } @@ -91,4 +97,20 @@ public int getMajorCreditByMajorType(MajorType majorType) { } return subMajorCredit; } + + @Override + public String toString() { + return "GraduationRequirement{" + + "totalCredit=" + totalCredit + + ", primaryBasicAcademicalCultureCredit=" + primaryBasicAcademicalCultureCredit + + ", coreCultureCredit=" + coreCultureCredit + + ", primaryMajorCredit=" + primaryMajorCredit + + ", dualMajorCredit=" + dualMajorCredit + + ", subMajorCredit=" + subMajorCredit + + ", dualBasicAcademicalCultureCredit=" + dualBasicAcademicalCultureCredit + + ", commonCultureCredit=" + commonCultureCredit + + ", normalCultureCredit=" + normalCultureCredit + + ", freeElectiveCredit=" + freeElectiveCredit + + '}'; + } } 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 7637aace..0e9adcdf 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 @@ -2,6 +2,9 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; import java.util.List; + +import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import lombok.Builder; import lombok.Getter; @@ -17,11 +20,15 @@ public class GraduationResult { private boolean graduated; @Builder - private GraduationResult(ChapelResult chapelResult, + private GraduationResult( + ChapelResult chapelResult, List detailGraduationResults, NormalCultureGraduationResult normalCultureGraduationResult, - FreeElectiveGraduationResult freeElectiveGraduationResult, int totalCredit, int takenCredit, - boolean graduated) { + FreeElectiveGraduationResult freeElectiveGraduationResult, + int totalCredit, + int takenCredit, + boolean graduated + ) { this.chapelResult = chapelResult; this.detailGraduationResults = detailGraduationResults; this.normalCultureGraduationResult = normalCultureGraduationResult; @@ -31,26 +38,24 @@ private GraduationResult(ChapelResult chapelResult, this.graduated = graduated; } - public static GraduationResult create(ChapelResult chapelResult, - List detailGraduationResults) { - return GraduationResult.builder() - .chapelResult(chapelResult) - .detailGraduationResults(detailGraduationResults) - .totalCredit(0) - .takenCredit(0) - .graduated(false) - .build(); + public static GraduationResult create( + ChapelResult chapelResult, List detailGraduationResults + ) { + return GraduationResult.builder().chapelResult(chapelResult) + .detailGraduationResults(detailGraduationResults).totalCredit(0).takenCredit(0) + .graduated(false).build(); } - public void handleLeftTakenLectures(TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { - handleLeftTakenNormaCulture(takenLectureInventory, graduationRequirement); - handleLeftTakenFreeElective(takenLectureInventory, graduationRequirement); + public void handleLeftTakenLectures( + TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement, User user + ) { + handleLeftTakenNormaCulture(takenLectureInventory, graduationRequirement, user); + handleLeftTakenFreeElective(takenLectureInventory, graduationRequirement, user); } - public void checkGraduated(GraduationRequirement graduationRequirement) { + public void checkGraduated(GraduationRequirement graduationRequirement, User user) { addUpTotalCredit(graduationRequirement.getTotalCredit()); - addUpTakenCredit(); + addUpTakenCredit(user); boolean isAllDetailGraduationResultCompleted = detailGraduationResults.stream() .allMatch(DetailGraduationResult::isCompleted); @@ -64,11 +69,10 @@ public void deductDuplicatedCredit(int duplicatedCredit) { } private void addUpTotalCredit(int originTotalCredit) { - int combinedScore = detailGraduationResults.stream() - .mapToInt(DetailGraduationResult::getTotalCredit) - .sum() - + normalCultureGraduationResult.getTotalCredit() - + freeElectiveGraduationResult.getTotalCredit(); + int combinedScore = + detailGraduationResults.stream().mapToInt(DetailGraduationResult::getTotalCredit).sum() + + normalCultureGraduationResult.getTotalCredit() + + freeElectiveGraduationResult.getTotalCredit(); if (originTotalCredit < combinedScore) { this.totalCredit = originTotalCredit; return; @@ -76,32 +80,53 @@ private void addUpTotalCredit(int originTotalCredit) { this.totalCredit = combinedScore; } - private void addUpTakenCredit() { + private void addUpTakenCredit(User user) { this.takenCredit = detailGraduationResults.stream() - .mapToDouble(DetailGraduationResult::getTakenCredit) - .sum() - + normalCultureGraduationResult.getTakenCredit() - + freeElectiveGraduationResult.getTakenCredit(); + .filter(result -> + result.getGraduationCategory() != GraduationCategory.TRANSFER_CHRISTIAN && + result.getGraduationCategory() != GraduationCategory.FREE_ELECTIVE + ) + .mapToDouble(DetailGraduationResult::getTakenCredit + ) + .sum(); + + double freeElectiveCredits = freeElectiveGraduationResult.getTakenCredit(); + double normalCultureCredits = normalCultureGraduationResult.getTakenCredit(); + + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + this.takenCredit += chapelResult.getTakenChapelCredit(); + } + this.takenCredit += freeElectiveCredits + normalCultureCredits; } - - private void handleLeftTakenNormaCulture(TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { + private void handleLeftTakenNormaCulture( + TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement, User user + ) { + int acknowledgedCredit = 0; + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + acknowledgedCredit = user.getTransferCredit().getNormalCulture(); + } this.normalCultureGraduationResult = NormalCultureGraduationResult.create( - graduationRequirement.getNormalCultureCredit(), takenLectureInventory, - detailGraduationResults); + graduationRequirement.getNormalCultureCredit(), + acknowledgedCredit, + takenLectureInventory, + detailGraduationResults + ); normalCultureGraduationResult.checkCompleted(); } - private void handleLeftTakenFreeElective(TakenLectureInventory takenLectureInventory, - GraduationRequirement graduationRequirement) { + private void handleLeftTakenFreeElective( + TakenLectureInventory takenLectureInventory, GraduationRequirement graduationRequirement, User user + ) { int leftNormalCultureCredit = normalCultureGraduationResult.getLeftCredit(); this.freeElectiveGraduationResult = FreeElectiveGraduationResult.create( - graduationRequirement.getFreeElectiveCredit(), takenLectureInventory, + graduationRequirement.getFreeElectiveCredit(), + takenLectureInventory, detailGraduationResults, - leftNormalCultureCredit); - + leftNormalCultureCredit, + user + ); freeElectiveGraduationResult.checkCompleted(); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResult.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResult.java index bd67965b..637152b5 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResult.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResult.java @@ -4,11 +4,9 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture; import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; - import java.util.List; import java.util.Set; import java.util.stream.Collectors; - import lombok.Builder; import lombok.Getter; @@ -17,57 +15,69 @@ public class NormalCultureGraduationResult { private static final String VOLUNTEER_CREDIT_CODE = "KMA02198"; - private final String categoryName; - private final int totalCredit; - private boolean isCompleted; - private int takenCredit; + private final String categoryName; + private final int totalCredit; + private boolean isCompleted; + private int takenCredit; - @Builder - private NormalCultureGraduationResult(String categoryName, boolean isCompleted, int totalCredit, - int takenCredit) { - this.categoryName = categoryName; - this.isCompleted = isCompleted; - this.totalCredit = totalCredit; - this.takenCredit = takenCredit; - } + @Builder + private NormalCultureGraduationResult( + String categoryName, + boolean isCompleted, + int totalCredit, + int takenCredit + ) { + this.categoryName = categoryName; + this.isCompleted = isCompleted; + this.totalCredit = totalCredit; + this.takenCredit = takenCredit; + } - public static NormalCultureGraduationResult create(int totalCredit, - TakenLectureInventory takenLectureInventory, - List detailGraduationResults) { - return NormalCultureGraduationResult.builder() - .categoryName(NORMAL_CULTURE.getName()) - .isCompleted(false) - .totalCredit(totalCredit) - .takenCredit(calculateTakenCredit(takenLectureInventory, detailGraduationResults)) - .build(); - } + public static NormalCultureGraduationResult create( + int totalCredit, + int acknowledgedCredit, + TakenLectureInventory takenLectureInventory, + List detailGraduationResults + ) { + return NormalCultureGraduationResult.builder() + .categoryName(NORMAL_CULTURE.getName()) + .isCompleted(false) + .totalCredit(totalCredit) + .takenCredit(calculateTakenCredit(acknowledgedCredit, takenLectureInventory, detailGraduationResults)) + .build(); + } - private static int calculateTakenCredit(TakenLectureInventory takenLectureInventory, - List detailGraduationResults) { - int remainCreditByDetailGraduationResult = detailGraduationResults.stream() - .mapToInt(DetailGraduationResult::getNormalLeftCredit) - .sum(); - Set remainTakenNormalCultures = takenLectureInventory.getCultureLectures().stream() - .filter(takenLecture -> !takenLecture.getLecture().getId().equals(VOLUNTEER_CREDIT_CODE)) - .collect(Collectors.toSet()); - int remainCreditByTakenLectures = remainTakenNormalCultures.stream() - .mapToInt(takenLecture -> takenLecture.getLecture().getCredit()) - .sum(); - takenLectureInventory.handleFinishedTakenLectures(remainTakenNormalCultures); - return remainCreditByDetailGraduationResult + remainCreditByTakenLectures; - } + private static int calculateTakenCredit( + int acknowledgedCredit, + TakenLectureInventory takenLectureInventory, + List detailGraduationResults + ) { + int remainCreditByDetailGraduationResult = acknowledgedCredit + detailGraduationResults.stream() + .mapToInt(DetailGraduationResult::getNormalLeftCredit) + .sum(); + Set remainTakenNormalCultures = takenLectureInventory.getCultureLectures() + .stream() + .filter(takenLecture -> !takenLecture.getLecture().getId() + .equals(VOLUNTEER_CREDIT_CODE)) + .collect(Collectors.toSet()); + int remainCreditByTakenLectures = remainTakenNormalCultures.stream() + .mapToInt(takenLecture -> takenLecture.getLecture().getCredit()) + .sum(); + takenLectureInventory.handleFinishedTakenLectures(remainTakenNormalCultures); + return remainCreditByDetailGraduationResult + remainCreditByTakenLectures; + } - public void checkCompleted() { - this.isCompleted = takenCredit >= totalCredit; - } + public void checkCompleted() { + this.isCompleted = takenCredit >= totalCredit; + } - public int getLeftCredit() { - if (totalCredit >= takenCredit) { - return 0; - } - int leftCredit = takenCredit - totalCredit; - this.takenCredit = totalCredit; - return leftCredit; - } + public int getLeftCredit() { + if (totalCredit >= takenCredit) { + return 0; + } + int leftCredit = takenCredit - totalCredit; + this.takenCredit = totalCredit; + return leftCredit; + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementType.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementType.java new file mode 100644 index 00000000..94b44a03 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementType.java @@ -0,0 +1,28 @@ +package com.plzgraduate.myongjigraduatebe.graduation.domain.model; + +import java.util.Arrays; +import java.util.NoSuchElementException; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum TransferGraduationRequirementType { + HUMANITIES("인문대", 51, 2), + SOCIAL_SCIENCE("사회과학대", 51, 2), + BUSINESS("경영대", 45, 2), + LAW("법과대", 48, 2), + ICT("ICT융합대", 57, 2); + + private final String collegeName; + private final int combinedCultureCredit; + private final int christianCredit; + + public static TransferGraduationRequirementType findByCollegeName(String collegeName) { + return Arrays.stream(TransferGraduationRequirementType.values()) + .filter(type -> type.getCollegeName().equals(collegeName)) + .findFirst() + .orElseThrow(() -> new NoSuchElementException("해당 단과대의 편입 졸업 요건이 존재하지 않습니다.")); + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/BusinessBasicAcademicalGraduationManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/BusinessBasicAcademicalGraduationManager.java index e052869f..2e9d02f4 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/BusinessBasicAcademicalGraduationManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/BusinessBasicAcademicalGraduationManager.java @@ -9,6 +9,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; 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.HashSet; import java.util.List; @@ -41,6 +42,13 @@ public DetailGraduationResult createDetailGraduationResult(User user, TakenLectureInventory takenLectureInventory, Set graduationLectures, int basicAcademicalCredit) { + + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + return DetailGraduationResult.createNonCategorizedGraduationResult( + basicAcademicalCredit, List.of() + ); + } + Set basicAcademicalLectures = convertToLectureSet(graduationLectures); Set finishedTakenLecture = new HashSet<>(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/DefaultBasicAcademicalGraduationManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/DefaultBasicAcademicalGraduationManager.java index 178430b0..84f387b8 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/DefaultBasicAcademicalGraduationManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/DefaultBasicAcademicalGraduationManager.java @@ -11,6 +11,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; 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.HashSet; import java.util.List; @@ -32,7 +33,13 @@ public boolean isSatisfied(String major) { public DetailGraduationResult createDetailGraduationResult(User user, TakenLectureInventory takenLectureInventory, Set graduationLectures, int basicAcademicalCredit) { - Set basicAcademicalLectures = convertToLectureSet(graduationLectures); + + if(user.getStudentCategory() == StudentCategory.TRANSFER) { + return DetailGraduationResult.createNonCategorizedGraduationResult( + basicAcademicalCredit, List.of() + ); + } + Set basicAcademicalLectures = convertToLectureSet(graduationLectures); Set finishedTakenLecture = new HashSet<>(); Set taken = new HashSet<>(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/SocialScienceBasicAcademicGraduationManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/SocialScienceBasicAcademicGraduationManager.java index d3c12380..3e356778 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/SocialScienceBasicAcademicGraduationManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/basicacademicalculture/SocialScienceBasicAcademicGraduationManager.java @@ -9,6 +9,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; 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.HashSet; import java.util.List; @@ -43,6 +44,12 @@ public DetailGraduationResult createDetailGraduationResult(User user, Set graduationLectures, int basicAcademicalCredit) { + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + return DetailGraduationResult.createNonCategorizedGraduationResult( + basicAcademicalCredit, List.of() + ); + } + Set basicAcademicalLectures = convertToLectureSet(graduationLectures); Set finishedTakenLecture = new HashSet<>(); Set taken = new HashSet<>(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonCultureDetailCategoryManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonCultureDetailCategoryManager.java index 3180aef2..3c76c60c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonCultureDetailCategoryManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonCultureDetailCategoryManager.java @@ -13,6 +13,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; 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.HashSet; import java.util.List; @@ -33,6 +34,12 @@ class CommonCultureDetailCategoryManager { public DetailCategoryResult generate(User user, TakenLectureInventory takenLectureInventory, Set graduationLectures, CommonCultureCategory category) { + + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + return DetailCategoryResult.create( + category.getName(), true, 0 + ); + } Set graduationCommonCultureLectures = categorizeCommonCultures(graduationLectures, category); Set finishedTakenLecture = new HashSet<>(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonGraduationManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonGraduationManager.java index e6844f65..090e2a6a 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonGraduationManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/commonculture/CommonGraduationManager.java @@ -21,23 +21,29 @@ public class CommonGraduationManager implements GraduationManager { @Override - public DetailGraduationResult createDetailGraduationResult(User user, - TakenLectureInventory takenLectureInventory, Set graduationLectures, - int commonCultureGraduationTotalCredit) { + public DetailGraduationResult createDetailGraduationResult( + User user, + TakenLectureInventory takenLectureInventory, + Set graduationLectures, + int commonCultureGraduationTotalCredit + ) { CommonCultureDetailCategoryManager commonCultureDetailCategoryManager = new CommonCultureDetailCategoryManager(); List commonCultureDetailCategoryResults = Arrays.stream( CommonCultureCategory.values()) - .filter( - commonCultureCategory -> commonCultureCategory.isContainsEntryYear( - user.getEntryYear())) - .map(commonCultureCategory -> commonCultureDetailCategoryManager.generate(user, + .filter(commonCultureCategory -> commonCultureCategory.isContainsEntryYear(user.getEntryYear())) + .map(commonCultureCategory -> commonCultureDetailCategoryManager.generate( + user, takenLectureInventory, - graduationLectures, commonCultureCategory)) + graduationLectures, + commonCultureCategory + )) .collect(Collectors.toList()); DetailGraduationResult detailGraduationResult = DetailGraduationResult.create( COMMON_CULTURE, - commonCultureGraduationTotalCredit, commonCultureDetailCategoryResults); + commonCultureGraduationTotalCredit, + commonCultureDetailCategoryResults + ); detailGraduationResult.addCredit(getTakenChapelCredits(takenLectureInventory)); return detailGraduationResult; } @@ -50,6 +56,5 @@ private double getTakenChapelCredits(TakenLectureInventory takenLectureInventory .equals(CHAPEL_LECTURE_CODE)) .count(); return chapelCount * CHAPEL_CREDIT; - } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java index 40abd7e4..3dd71582 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/coreculture/CoreCultureDetailCategoryManager.java @@ -8,6 +8,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; 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.HashSet; import java.util.List; @@ -29,6 +30,13 @@ public class CoreCultureDetailCategoryManager { public DetailCategoryResult generate(User user, TakenLectureInventory takenLectureInventory, Set graduationLectures, CoreCultureCategory category) { + + if (user.getStudentCategory() == StudentCategory.TRANSFER) { + return DetailCategoryResult.create( + category.getName(), true, 0 + ); + } + Set graduationCoreCultureLectures = categorizeCoreCultures(graduationLectures, category); Set finishedTakenLecture = new HashSet<>(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/ElectiveMajorManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/ElectiveMajorManager.java index 50744d1a..70087232 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/ElectiveMajorManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/ElectiveMajorManager.java @@ -5,17 +5,28 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture; import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; import java.util.HashSet; +import java.util.List; import java.util.Set; + import org.springframework.stereotype.Component; @Component public class ElectiveMajorManager { + // 현장실습과목(haveToLectrue 제외) + private static final List PRACTICE_LECTURE_CODES = List.of( + "KMR01801", "KMR01802", "KMR01804", "KMR01805", "KMR01851", "KMR01852", "HAH01371", "HFC01412", + "HFM01404", "JDC01361", "JEE01356", "JEE01357", "JEH01493", "JEH01494", "JEI01430", "JEI01467", "JEJ02549", + "JEJ02554", "JEJ02558", "JEJ02559", "JEJ02560", "JEJ02561", "KMD02902", "KMD02903", "KMR01551", "KMR01552", + "KMR01553", "KMR01554", "KMR01555", "KMR01560", "KMR01561", "KMR01562", "KMR01563", "KMR01564", "KMR01566", + "KMR01567", "KMR01703", "KMR01705", "KMR01710", "KMR01712", "KMR01803", "KMR01817" + ); private static final String ELECTIVE_MAJOR_NAME = "전공선택"; public DetailCategoryResult createDetailCategoryResult( TakenLectureInventory takenLectureInventory, - Set electiveLectures, int electiveMajorTotalCredit) { + Set electiveLectures, int electiveMajorTotalCredit + ) { Set takenElective = new HashSet<>(); Set finishedTakenLecture = new HashSet<>(); takenLectureInventory.getTakenLectures() @@ -26,10 +37,15 @@ public DetailCategoryResult createDetailCategoryResult( takenElective.add(takenLecture.getLecture()); }); DetailCategoryResult electiveMajorResult = DetailCategoryResult.create(ELECTIVE_MAJOR_NAME, - true, electiveMajorTotalCredit); + true, electiveMajorTotalCredit + ); + excludePracticeLectureForHaveToLecture(electiveLectures); electiveMajorResult.calculate(takenElective, electiveLectures); takenLectureInventory.handleFinishedTakenLectures(finishedTakenLecture); - return electiveMajorResult; } + + private void excludePracticeLectureForHaveToLecture(Set electiveLectures) { + electiveLectures.removeIf(lecture -> PRACTICE_LECTURE_CODES.contains(lecture.getId())); + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/MajorGraduationManager.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/MajorGraduationManager.java index f5320245..928e4a87 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/MajorGraduationManager.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/domain/service/major/MajorGraduationManager.java @@ -7,6 +7,7 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.MajorLecture; 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; @@ -44,6 +45,9 @@ public DetailGraduationResult createDetailGraduationResult(User user, MajorType int electiveMajorTotalCredit = graduationResultTotalCredit - mandantoryDetailCategoryResult.getTotalCredits(); + if(user.getStudentCategory() == StudentCategory.TRANSFER){ + electiveMajorTotalCredit+=user.getTransferCredit().getMajorLecture(); + } DetailCategoryResult electiveDetailCategoryResult = electiveMajorManager.createDetailCategoryResult( takenLectureInventory, electiveLectures, electiveMajorTotalCredit); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCulture.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCulture.java index 1d973426..5399fa73 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCulture.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCulture.java @@ -21,4 +21,12 @@ public static CommonCulture of(Lecture lecture, CommonCultureCategory category) .commonCultureCategory(category) .build(); } + + @Override + public String toString() { + return "CommonCulture{" + + "lecture=" + lecture + + ", commonCultureCategory=" + commonCultureCategory + + '}'; + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCultureCategory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCultureCategory.java index f15c5ed6..fffd407f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCultureCategory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/CommonCultureCategory.java @@ -21,5 +21,4 @@ public enum CommonCultureCategory { public boolean isContainsEntryYear(int entryYear) { return containsEntryYears.contains(entryYear); } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/Lecture.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/Lecture.java index 45127875..8d7fb03a 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/Lecture.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/domain/model/Lecture.java @@ -7,59 +7,85 @@ @Getter public class Lecture { - private static final String CULTURE_CODE_START_PREFIX = "KM"; + private static final String CULTURE_CODE_START_PREFIX = "KM"; - private final String id; - private final String name; - private final int credit; - private final String duplicateCode; - private final int isRevoked; + private final String id; + private final String name; + private final int credit; + private final String duplicateCode; + private final int isRevoked; - @Builder - private Lecture(String id, String name, int credit, int isRevoked, - String duplicateCode) { - this.id = id; - this.name = name; - this.credit = credit; - this.isRevoked = isRevoked; - this.duplicateCode = duplicateCode; - } + @Builder + private Lecture( + String id, + String name, + int credit, + int isRevoked, + String duplicateCode + ) { + this.id = id; + this.name = name; + this.credit = credit; + this.isRevoked = isRevoked; + this.duplicateCode = duplicateCode; + } - public static Lecture from(String lectureCode) { - return Lecture.builder() - .id(lectureCode) - .build(); - } + public static Lecture from(String lectureCode) { + return Lecture.builder() + .id(lectureCode) + .build(); + } - public static Lecture of(String lectureCode, String name, int credit, int isRevoked, - String duplicateCode) { - return Lecture.builder() - .id(lectureCode) - .name(name) - .credit(credit) - .isRevoked(isRevoked) - .duplicateCode(duplicateCode) - .build(); - } + public static Lecture from(String lectureCode, String name, int credit) { + return Lecture.builder() + .id(lectureCode) + .name(name) + .credit(credit) + .build(); + } - public boolean isCulture() { - return id.startsWith(CULTURE_CODE_START_PREFIX); - } + public static Lecture of( + String lectureCode, String name, int credit, int isRevoked, + String duplicateCode + ) { + return Lecture.builder() + .id(lectureCode) + .name(name) + .credit(credit) + .isRevoked(isRevoked) + .duplicateCode(duplicateCode) + .build(); + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Lecture lecture = (Lecture) o; - return Objects.equals(id, lecture.id); - } + @Override + public String toString() { + return "Lecture{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", credit=" + credit + + ", duplicateCode='" + duplicateCode + '\'' + + ", isRevoked=" + isRevoked + + '}'; + } - @Override - public int hashCode() { - return Objects.hash(id); - } + public boolean isCulture() { + return id.startsWith(CULTURE_CODE_START_PREFIX); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Lecture lecture = (Lecture) o; + return Objects.equals(id, lecture.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCommonCulturePersistenceAdapter.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCommonCulturePersistenceAdapter.java index 4945bc78..7710cf2b 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCommonCulturePersistenceAdapter.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCommonCulturePersistenceAdapter.java @@ -36,32 +36,28 @@ public Set findCommonCulture(User user) { } private Set findEngBasicCommonCultures(User user) { - return commonCultureRepository.findEngBasicGraduationCommonCulturesByEntryYear( - user.getEntryYear()) + return commonCultureRepository.findEngBasicGraduationCommonCulturesByEntryYear(user.getEntryYear()) .stream() .map(lectureMapper::mapToCommonCultureModel) .collect(Collectors.toSet()); } private Set findEng12CommonCultures(User user) { - return commonCultureRepository.findEng12GraduationCommonCulturesByEntryYear( - user.getEntryYear()) + return commonCultureRepository.findEng12GraduationCommonCulturesByEntryYear(user.getEntryYear()) .stream() .map(lectureMapper::mapToCommonCultureModel) .collect(Collectors.toSet()); } private Set findEng34CommonCultures(User user) { - return commonCultureRepository.findEng34GraduationCommonCulturesByEntryYear( - user.getEntryYear()) + return commonCultureRepository.findEng34GraduationCommonCulturesByEntryYear(user.getEntryYear()) .stream() .map(lectureMapper::mapToCommonCultureModel) .collect(Collectors.toSet()); } private Set findEngFreeCommonCultures(User user) { - return commonCultureRepository.findEngFreeGraduationCommonCulturesByEntryYear( - user.getEntryYear()) + return commonCultureRepository.findEngFreeGraduationCommonCulturesByEntryYear(user.getEntryYear()) .stream() .map(lectureMapper::mapToCommonCultureModel) .collect(Collectors.toSet()); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCoreCulturePersistenceAdapter.java b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCoreCulturePersistenceAdapter.java index 7c0e1dd6..68438749 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCoreCulturePersistenceAdapter.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/lecture/infrastructure/adapter/persistence/FindCoreCulturePersistenceAdapter.java @@ -24,5 +24,4 @@ public Set findCoreCulture(User user) { .map(lectureMapper::mapToCoreCultureModel) .collect(Collectors.toSet()); } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextController.java index 7ee9618d..f9166e16 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextController.java @@ -20,15 +20,21 @@ public class ParsingTextController implements ParsingTextApiPresentation { private final ParsingTextHistoryUseCase parsingTextHistoryUseCase; @PostMapping - public void enrollParsingText(@LoginUser Long userId, - @Valid @RequestBody ParsingTextRequest parsingTextRequest) { + public void enrollParsingText( + @LoginUser Long userId, + @Valid @RequestBody ParsingTextRequest parsingTextRequest + ) { try { parsingTextUseCase.enrollParsingText(userId, parsingTextRequest.getParsingText()); - parsingTextHistoryUseCase.generateSucceedParsingTextHistory(userId, - parsingTextRequest.getParsingText()); + parsingTextHistoryUseCase.generateSucceedParsingTextHistory( + userId, + parsingTextRequest.getParsingText() + ); } catch (Exception e) { - parsingTextHistoryUseCase.generateFailedParsingTextHistory(userId, - parsingTextRequest.getParsingText()); + parsingTextHistoryUseCase.generateFailedParsingTextHistory( + userId, + parsingTextRequest.getParsingText() + ); throw e; } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/dto/request/ParsingTextRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/dto/request/ParsingTextRequest.java index 7ab96250..2c884754 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/dto/request/ParsingTextRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/api/dto/request/ParsingTextRequest.java @@ -18,5 +18,4 @@ public class ParsingTextRequest { private ParsingTextRequest(String parsingText) { this.parsingText = parsingText; } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousService.java new file mode 100644 index 00000000..beabb690 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousService.java @@ -0,0 +1,81 @@ +package com.plzgraduate.myongjigraduatebe.parsing.application.service; + +import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.DOUBLE_SUB; + +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; +import com.plzgraduate.myongjigraduatebe.core.exception.InvalidPdfException; +import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; +import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.ParsingAnonymousUseCase; +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.dto.ParsingAnonymousDto; +import com.plzgraduate.myongjigraduatebe.parsing.domain.ParsingInformation; +import com.plzgraduate.myongjigraduatebe.parsing.domain.ParsingTakenLectureDto; +import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLecture; +import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class ParsingAnonymousService implements ParsingAnonymousUseCase { + + @Override + public ParsingAnonymousDto parseAnonymous(EnglishLevel englishLevel, String parsingText) { + validateParsingText(parsingText); + ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); + checkUnSupportedUser(parsingInformation); + + + User anonymous = User.createAnonymous( + englishLevel, + parsingInformation.getStudentName(), + parsingInformation.getStudentNumber(), + parsingInformation.getMajor(), + parsingInformation.getSubMajor(), + parsingInformation.getDualMajor(), + parsingInformation.getAssociatedMajor(), + parsingInformation.getStudentCategory(), + parsingInformation.getTransferCredit() + ); + + TakenLectureInventory takenLectureInventory = getTakenLectureInventory( + anonymous, + parsingInformation.getTakenLectureInformation() + ); + + return new ParsingAnonymousDto(anonymous, takenLectureInventory); + } + + private void validateParsingText(String parsingText) { + if (parsingText.trim().isEmpty()) { + throw new InvalidPdfException("PDF를 인식하지 못했습니다. 채널톡으로 문의 바랍니다."); + } + } + + private void checkUnSupportedUser(ParsingInformation parsingInformation) { + if (parsingInformation.getStudentCategory() == DOUBLE_SUB) { + throw new IllegalArgumentException(ErrorCode.UNSUPPORTED_STUDENT_CATEGORY.toString()); + } + } + + private TakenLectureInventory getTakenLectureInventory( + User anonymous, + List parsingTakenLectureDtoList + ) { + Set takenLectures = parsingTakenLectureDtoList.stream() + .map(parsingTakenLectureDto -> TakenLecture.of( + anonymous, + Lecture.from(parsingTakenLectureDto.getLectureCode()), + parsingTakenLectureDto.getYear(), + parsingTakenLectureDto.getSemester() + ) + ) + .collect(Collectors.toSet()); + + return TakenLectureInventory.from(takenLectures); + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java index 6e2388c0..c471768b 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java @@ -1,7 +1,6 @@ package com.plzgraduate.myongjigraduatebe.parsing.application.service; import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INCORRECT_STUDENT_NUMBER; -import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.ASSOCIATED_MAJOR; import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.DOUBLE_SUB; import com.plzgraduate.myongjigraduatebe.completedcredit.application.usecase.GenerateOrModifyCompletedCreditUseCase; @@ -35,7 +34,6 @@ class ParsingTextService implements ParsingTextUseCase { private final UpdateStudentInformationUseCase updateStudentInformationUseCase; private final SaveTakenLectureFromParsingTextUseCase saveTakenLectureFromParsingTextUseCase; private final DeleteTakenLectureUseCase deleteTakenLectureByUserUseCase; - private final GenerateOrModifyCompletedCreditUseCase generateOrModifyCompletedCreditUseCase; @Override @@ -75,8 +73,7 @@ private User updateUser(User user, ParsingInformation parsingInformation) { } private void validateParsingText(String parsingText) { - if (parsingText.trim() - .isEmpty()) { + if (parsingText.trim().isEmpty()) { throw new InvalidPdfException("PDF를 인식하지 못했습니다. 채널톡으로 문의 바랍니다."); } } @@ -88,13 +85,15 @@ private void validateStudentNumber(User user, ParsingInformation parsingInformat } private List getSaveTakenLectureCommand( - List parsingTakenLectureDtoList) { + List parsingTakenLectureDtoList + ) { return parsingTakenLectureDtoList.stream() .map(parsingTakenLectureDto -> TakenLectureInformation.createTakenLectureInformation( parsingTakenLectureDto.getLectureCode(), parsingTakenLectureDto.getYear(), - parsingTakenLectureDto.getSemester()) + parsingTakenLectureDto.getSemester() + ) ) .collect(Collectors.toList()); } @@ -104,5 +103,4 @@ private void checkUnSupportedUser(ParsingInformation parsingInformation) { throw new IllegalArgumentException(ErrorCode.UNSUPPORTED_STUDENT_CATEGORY.toString()); } } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/ParsingAnonymousUseCase.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/ParsingAnonymousUseCase.java new file mode 100644 index 00000000..0f74db16 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/ParsingAnonymousUseCase.java @@ -0,0 +1,9 @@ +package com.plzgraduate.myongjigraduatebe.parsing.application.usecase; + +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.dto.ParsingAnonymousDto; +import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; + +public interface ParsingAnonymousUseCase { + + ParsingAnonymousDto parseAnonymous(EnglishLevel englishLevel, String parsingText); +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/dto/ParsingAnonymousDto.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/dto/ParsingAnonymousDto.java new file mode 100644 index 00000000..9afb5d0a --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/usecase/dto/ParsingAnonymousDto.java @@ -0,0 +1,17 @@ +package com.plzgraduate.myongjigraduatebe.parsing.application.usecase.dto; + +import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import lombok.Getter; + +@Getter +public class ParsingAnonymousDto { + + private final User anonymous; + private final TakenLectureInventory takenLectureInventory; + + public ParsingAnonymousDto(User anonymous, TakenLectureInventory takenLectureInventory) { + this.anonymous = anonymous; + this.takenLectureInventory = takenLectureInventory; + } +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformation.java index a4768f67..509f6dba 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformation.java @@ -3,8 +3,12 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.Semester; import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import lombok.Builder; import lombok.Getter; @@ -18,14 +22,23 @@ public class ParsingInformation { private final String subMajor; private final String dualMajor; private final String associatedMajor; + private final TransferCredit transferCredit; private final StudentCategory studentCategory; private final List takenLectureInformation; @Builder - public ParsingInformation(String studentName, String studentNumber, String major, - String changeMajor, String subMajor, String dualMajor, - String associatedMajor, StudentCategory studentCategory, - List takenLectureInformation) { + public ParsingInformation( + String studentName, + String studentNumber, + String major, + String changeMajor, + String subMajor, + String dualMajor, + String associatedMajor, + StudentCategory studentCategory, + TransferCredit transferCredit, + List takenLectureInformation + ) { this.studentName = studentName; this.studentNumber = studentNumber; this.major = major; @@ -33,24 +46,24 @@ public ParsingInformation(String studentName, String studentNumber, String major this.dualMajor = dualMajor; this.subMajor = subMajor; this.associatedMajor = associatedMajor; - this.studentCategory = studentCategory; + this.studentCategory = studentCategory; + this.transferCredit = transferCredit; this.takenLectureInformation = takenLectureInformation; } public static ParsingInformation parsing(String parsingText) { String[] splitText = splitParsingText(parsingText); ParsingStudentCategoryDto parsingStudentCategoryDto = parseStudentCategory(splitText); - return ParsingInformation.builder() - .studentName(parseStudentName(splitText)) - .studentNumber(parseStudentNumber(splitText)) - .major(parseMajor(splitText)) + + return ParsingInformation.builder().studentName(parseStudentName(splitText)) + .studentNumber(parseStudentNumber(splitText)).major(parseMajor(splitText)) .dualMajor(parsingStudentCategoryDto.getDualMajor()) .changeMajor(parsingStudentCategoryDto.getChangeMajor()) .subMajor(parsingStudentCategoryDto.getSubMajor()) .associatedMajor(parsingStudentCategoryDto.getAssociatedMajor()) .studentCategory(parsingStudentCategoryDto.getStudentCategory()) - .takenLectureInformation(parseTakenLectureInformation(splitText)) - .build(); + .transferCredit(parsingStudentCategoryDto.getTransferCredit()) + .takenLectureInformation(parseTakenLectureInformation(splitText)).build(); } private static String[] splitParsingText(String parsingText) { @@ -80,8 +93,10 @@ private static ParsingStudentCategoryDto parseStudentCategory(String[] splitText String subMajor = null; String associatedMajor = null; StudentCategory studentCategory; + TransferCredit transferCredit; String secondLineText = splitText[2]; String thirdLineText = splitText[3]; + String fourthLineText = splitText[4]; List categories = new ArrayList<>(); String[] parts = secondLineText.split(", "); String[] thirdLineParts = thirdLineText.split(", "); @@ -103,18 +118,28 @@ private static ParsingStudentCategoryDto parseStudentCategory(String[] splitText } else if (part.startsWith("연계전공 - ")) { categories.add("연계전공"); associatedMajor = part.substring("연계전공 - ".length()); + } else if (part.contains("편입")) { + categories.add("편입"); } } studentCategory = StudentCategory.from(categories); - return ParsingStudentCategoryDto.of(changeMajor, subMajor, dualMajor, associatedMajor, - studentCategory); + String fourthLine = fourthLineText.substring("편입생 인정학점 - ".length()); + transferCredit = TransferCredit.from(Arrays.stream(fourthLine.split(",")) + .map(s -> s.replaceAll("\\D", "")) + .collect(Collectors.joining("/"))); + + return ParsingStudentCategoryDto.of( + changeMajor, subMajor, dualMajor, associatedMajor, studentCategory, transferCredit + ); } private static List parseTakenLectureInformation(String[] splitText) { List takenLectureInformation = new ArrayList<>(); for (int i = 16; i < splitText.length; i += 7) { - if (i + 3 < splitText.length && !Pattern.matches("^[A-Z]+$", - splitText[i + 3].substring(0, 1))) { + if (i + 3 < splitText.length && !Pattern.matches( + "^[A-Z]+$", + splitText[i + 3].substring(0, 1) + )) { return takenLectureInformation; } int year = Integer.parseInt(splitText[i + 1].split(" ")[0].substring(0, 4)); @@ -122,8 +147,11 @@ private static List parseTakenLectureInformation(String[ String code = splitText[i + 3]; char grade = splitText[i + 6].charAt(0); if (grade != 'F' && grade != 'N' && grade != 'R') { - takenLectureInformation.add( - ParsingTakenLectureDto.of(code, year, Semester.of(semester))); + takenLectureInformation.add(ParsingTakenLectureDto.of( + code, + year, + Semester.of(semester) + )); } if (i + 7 < splitText.length && Character.isDigit(splitText[i + 7].charAt(0))) { i++; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingStudentCategoryDto.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingStudentCategoryDto.java index 71f1d3db..c15db9f6 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingStudentCategoryDto.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingStudentCategoryDto.java @@ -1,6 +1,7 @@ package com.plzgraduate.myongjigraduatebe.parsing.domain; import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import lombok.Builder; import lombok.Getter; @@ -12,27 +13,41 @@ class ParsingStudentCategoryDto { private final String subMajor; private final String associatedMajor; private final StudentCategory studentCategory; + private final TransferCredit transferCredit; + @Builder - private ParsingStudentCategoryDto(String changeMajor, String dualMajor, String subMajor, - String associatedMajor, - StudentCategory studentCategory) { + private ParsingStudentCategoryDto( + String changeMajor, + String dualMajor, + String subMajor, + String associatedMajor, + StudentCategory studentCategory, + TransferCredit transferCredit + ) { this.changeMajor = changeMajor; this.dualMajor = dualMajor; this.subMajor = subMajor; this.associatedMajor = associatedMajor; - this.studentCategory = studentCategory; + this.studentCategory = studentCategory; + this.transferCredit = transferCredit; } - public static ParsingStudentCategoryDto of(String changeMajor, String subMajor, + public static ParsingStudentCategoryDto of( + String changeMajor, + String subMajor, String dualMajor, - String associatedMajor, StudentCategory studentCategory) { + String associatedMajor, + StudentCategory studentCategory, + TransferCredit transferCredit + ) { return ParsingStudentCategoryDto.builder() .changeMajor(changeMajor) .dualMajor(dualMajor) .subMajor(subMajor) .associatedMajor(associatedMajor) .studentCategory(studentCategory) + .transferCredit(transferCredit) .build(); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTakenLectureDto.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTakenLectureDto.java index 49a7243a..8ee53787 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTakenLectureDto.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTakenLectureDto.java @@ -12,7 +12,11 @@ public class ParsingTakenLectureDto { private final Semester semester; @Builder - private ParsingTakenLectureDto(String lectureCode, int year, Semester semester) { + private ParsingTakenLectureDto( + String lectureCode, + int year, + Semester semester + ) { this.lectureCode = lectureCode; this.year = year; this.semester = semester; @@ -25,5 +29,4 @@ public static ParsingTakenLectureDto of(String lectureCode, int year, Semester s .semester(semester) .build(); } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTextHistory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTextHistory.java index e2c9c74c..c969fdda 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTextHistory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingTextHistory.java @@ -13,8 +13,12 @@ public class ParsingTextHistory { private final ParsingResult parsingResult; @Builder - private ParsingTextHistory(Long id, User user, String parsingText, - ParsingResult parsingResult) { + private ParsingTextHistory( + Long id, + User user, + String parsingText, + ParsingResult parsingResult + ) { this.id = id; this.user = user; this.parsingText = parsingText; @@ -36,5 +40,4 @@ public static ParsingTextHistory fail(User user, String parsingText) { .parsingResult(ParsingResult.FAIL) .build(); } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/api/UpdateTakenLectureApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/api/UpdateTakenLectureApiPresentation.java index 7a993cb3..3531834d 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/api/UpdateTakenLectureApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/api/UpdateTakenLectureApiPresentation.java @@ -12,11 +12,15 @@ public interface UpdateTakenLectureApiPresentation { @Parameter(name = "userId", description = "로그인한 유저의 PK값") - void generateCustomizedTakenLecture(@LoginUser Long userId, - @Valid @RequestBody GenerateCustomizedTakenLectureRequest generateCustomizedTakenLectureRequest); + void generateCustomizedTakenLecture( + @LoginUser Long userId, + @Valid @RequestBody GenerateCustomizedTakenLectureRequest generateCustomizedTakenLectureRequest + ); @Parameter(name = "userId", description = "로그인한 유저의 PK값") @Parameter(name = "takenLectureId", description = "삭제할 수강 과목 ID") - void deleteCustomizedTakenLecture(@LoginUser Long userId, - @Valid @PathVariable Long takenLectureId); + void deleteCustomizedTakenLecture( + @LoginUser Long userId, + @Valid @PathVariable Long takenLectureId + ); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLecture.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLecture.java index 5a76aed5..160cb9d8 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLecture.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/domain/model/TakenLecture.java @@ -18,8 +18,14 @@ public class TakenLecture { private final Instant createdAt; @Builder - private TakenLecture(Long id, User user, Lecture lecture, Integer year, Semester semester, - Instant createdAt) { + private TakenLecture( + Long id, + User user, + Lecture lecture, + Integer year, + Semester semester, + Instant createdAt + ) { this.id = id; this.user = user; this.lecture = lecture; @@ -45,6 +51,18 @@ public static TakenLecture custom(User user, Lecture lecture) { .build(); } + @Override + public String toString() { + return "TakenLecture{" + + "id=" + id + + ", user=" + user + + ", lecture=" + lecture + + ", year=" + year + + ", semester=" + semester + + ", createdAt=" + createdAt + + '}'; + } + public boolean takenAfter(int year) { return this.year >= year; } 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 c28dc92c..f391c92b 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 @@ -13,7 +13,7 @@ public class TakenLectureInventory { @Builder private TakenLectureInventory(Set takenLecture) { - this.takenLecture = takenLecture; + this.takenLecture = new HashSet<>(takenLecture); } public static TakenLectureInventory from(Set takenLectures) { @@ -38,7 +38,7 @@ public Set getCultureLectures() { } public void handleFinishedTakenLectures(Set finishedTakenLecture) { - takenLecture.removeAll(finishedTakenLecture); + this.takenLecture.removeAll(finishedTakenLecture); } public void sync(Set finishedLectures) { @@ -70,4 +70,32 @@ private boolean checkChapelCountIsFour(Set takenLectures) { .count(); return chapelCount >= 4; } + + @Override + public String toString() { + return "TakenLectureInventory{" + + "takenLecture=" + takenLecture + + '}'; + } + + private static final Set CHRISTIAN_COURSE_CODES = Set.of( + "KMA00101", // 성서와인간이해 + "KMA02102", // 현대사회와기독교윤리 + "KMA02103", // 종교와과학 + "KMA02122" // 기독교와문화 + ); + + public Set getChristianLectures() { + return takenLecture.stream() + .map(TakenLecture::getLecture) + .filter(lecture -> CHRISTIAN_COURSE_CODES.contains(lecture.getId())) + .collect(Collectors.toSet()); + } + + public double calculateChristianCredits() { + return getChristianLectures().stream() + .mapToDouble(Lecture::getCredit) + .sum(); + } + } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/finduserinformation/FindUserInformationApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/finduserinformation/FindUserInformationApiPresentation.java index d3dad2ee..9ff83bac 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/finduserinformation/FindUserInformationApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/finduserinformation/FindUserInformationApiPresentation.java @@ -3,11 +3,12 @@ import com.plzgraduate.myongjigraduatebe.core.meta.LoginUser; import com.plzgraduate.myongjigraduatebe.user.api.finduserinformation.dto.response.UserInformationResponse; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; @Tag(name = "FindUserInformation", description = "로그인 한 회원 정보를 조회하는 API") public interface FindUserInformationApiPresentation { - @Parameter(name = "userId", description = "로그인한 유저의 PK값") - UserInformationResponse getUserInformation(@LoginUser Long userId); + @SecurityRequirement(name = "AccessToken") + UserInformationResponse getUserInformation(@Parameter(hidden = true) @LoginUser Long userId); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/update/UpdateStudentInformationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/update/UpdateStudentInformationService.java index 2b84c1e5..4a82fdd5 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/update/UpdateStudentInformationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/update/UpdateStudentInformationService.java @@ -28,6 +28,7 @@ public User updateUser(UpdateStudentInformationCommand updateStudentInformationC updateStudentInformationCommand.getTakenCredit(), updateStudentInformationCommand.isGraduate() ); + user.updateTransferCredit(updateStudentInformationCommand.getTransferCredit()); updateUserPort.updateUser(user); return user; } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/usecase/update/UpdateStudentInformationCommand.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/usecase/update/UpdateStudentInformationCommand.java index 81d2e8b7..a6ff714f 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/usecase/update/UpdateStudentInformationCommand.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/usecase/update/UpdateStudentInformationCommand.java @@ -3,6 +3,7 @@ import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationResult; import com.plzgraduate.myongjigraduatebe.parsing.domain.ParsingInformation; import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import lombok.Builder; import lombok.Getter; @@ -24,6 +25,8 @@ public class UpdateStudentInformationCommand { private String associatedMajor; + private TransferCredit transferCredit; + private StudentCategory studentCategory; private int totalCredit; @@ -34,7 +37,7 @@ public class UpdateStudentInformationCommand { @Builder private UpdateStudentInformationCommand(User user, String name, String major, String dualMajor, - String subMajor, String associatedMajor, StudentCategory studentCategory, int totalCredit, double takenCredit, + String subMajor, String associatedMajor, TransferCredit transferCredit, StudentCategory studentCategory, int totalCredit, double takenCredit, boolean graduate) { this.user = user; this.name = name; @@ -42,6 +45,7 @@ private UpdateStudentInformationCommand(User user, String name, String major, St this.dualMajor = dualMajor; this.subMajor = subMajor; this.associatedMajor = associatedMajor; + this.transferCredit = transferCredit; this.studentCategory = studentCategory; this.totalCredit = totalCredit; this.takenCredit = takenCredit; @@ -57,6 +61,7 @@ public static UpdateStudentInformationCommand of(User user, .dualMajor(parsingInformation.getDualMajor()) .subMajor(parsingInformation.getSubMajor()) .associatedMajor(parsingInformation.getAssociatedMajor()) + .transferCredit(parsingInformation.getTransferCredit()) .studentCategory(parsingInformation.getStudentCategory()) .build(); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java index 6ecf468c..dd17564e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java @@ -1,21 +1,5 @@ package com.plzgraduate.myongjigraduatebe.user.domain.model; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.CHAPEL; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.COMMON_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.CORE_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.DUAL_BASIC_ACADEMICAL_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.DUAL_ELECTIVE_MAJOR; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.DUAL_MANDATORY_MAJOR; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.FREE_ELECTIVE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.NORMAL_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_BASIC_ACADEMICAL_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_ELECTIVE_MAJOR; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_MANDATORY_MAJOR; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.ASSOCIATED_MANDATORY_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.ASSOCIATED_ELECTIVE_CULTURE; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.ASSOCIATED_MANDATORY_MAJOR; -import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.ASSOCIATED_ELECTIVE_MAJOR; - import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.PdfParsingException; import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory; @@ -25,40 +9,65 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.*; + @Getter @RequiredArgsConstructor public enum StudentCategory { - NORMAL(List.of(), + NORMAL( + List.of(), List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, - PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), - CHANGE_MAJOR(List.of("전과"), + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL + ) + ), + CHANGE_MAJOR( + List.of("전과"), List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, - PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), - SUB_MAJOR(List.of("부전공"), + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL + ) + ), + SUB_MAJOR( + List.of("부전공"), List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, PRIMARY_ELECTIVE_MAJOR, GraduationCategory.SUB_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, - CHAPEL)), - DUAL_MAJOR(List.of("복수전공"), + CHAPEL + ) + ), + DUAL_MAJOR( + List.of("복수전공"), List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, DUAL_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, PRIMARY_ELECTIVE_MAJOR, DUAL_MANDATORY_MAJOR, DUAL_ELECTIVE_MAJOR, NORMAL_CULTURE, - FREE_ELECTIVE, CHAPEL)), - ASSOCIATED_MAJOR(List.of("연계전공"), - // 현재 미지원 - List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, - ASSOCIATED_MANDATORY_CULTURE, ASSOCIATED_ELECTIVE_CULTURE, - PRIMARY_MANDATORY_MAJOR, PRIMARY_ELECTIVE_MAJOR, ASSOCIATED_MANDATORY_MAJOR, - ASSOCIATED_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL - )), - DOUBLE_SUB(List.of("복수전공", "부전공"), + FREE_ELECTIVE, CHAPEL + ) + ), + ASSOCIATED_MAJOR( + List.of("연계전공"), + List.of() + ), + DOUBLE_SUB( + List.of("복수전공", "부전공"), // 현재 미지원 List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, - PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)); + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL + ) + ), + TRANSFER( + List.of("편입"), + List.of( + PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, + TRANSFER_CHRISTIAN, + NORMAL_CULTURE, + FREE_ELECTIVE, + CHAPEL + ) + ); private final List categories; private final List includedGraduationCategories; @@ -75,5 +84,4 @@ public void validateGraduationCategoryInclusion(GraduationCategory graduationCat throw new IllegalArgumentException(ErrorCode.UNFITTED_GRADUATION_CATEGORY.toString()); } } - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/TransferCredit.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/TransferCredit.java new file mode 100644 index 00000000..ecbb882c --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/TransferCredit.java @@ -0,0 +1,65 @@ +package com.plzgraduate.myongjigraduatebe.user.domain.model; + +import java.util.Objects; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class TransferCredit { + + private int normalCulture; + private int majorLecture; + private int freeElective; + private int christianLecture; + + public static TransferCredit empty() { + return new TransferCredit(0, 0, 0, 0); + } + + public static TransferCredit from(String input) { + if (isValid(input)) { + String[] parts = input.split("/"); + int normalCulture = Integer.parseInt(parts[0]); + int majorLecture = Integer.parseInt(parts[1]); + int freeElective = Integer.parseInt(parts[2]); + int christianLecture = Integer.parseInt(parts[3]); + + return new TransferCredit(normalCulture, majorLecture, freeElective, christianLecture); + } else { + throw new IllegalArgumentException("잘못된 형식입니다."); + } + } + + private static boolean isValid(String input) { + return input.matches("^\\d+/\\d+/\\d+/\\d+$"); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TransferCredit that = (TransferCredit) o; + return normalCulture == that.normalCulture && majorLecture == that.majorLecture + && freeElective == that.freeElective && christianLecture == that.christianLecture; + } + + @Override + public int hashCode() { + return Objects.hash(normalCulture, majorLecture, freeElective, christianLecture); + } + + @Override + public String toString() { + return normalCulture + "/" + + majorLecture + "/" + + freeElective + "/" + + christianLecture; + } +} \ No newline at end of file diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java index 08668adb..4322b8fd 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java @@ -3,6 +3,7 @@ import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.MajorType.DUAL; import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.MajorType.PRIMARY; +import com.google.common.annotations.VisibleForTesting; import com.plzgraduate.myongjigraduatebe.graduation.domain.model.MajorType; import java.time.Instant; import java.util.Objects; @@ -20,6 +21,7 @@ public class User { private final int entryYear; private final Instant createdAt; private final Instant updatedAt; + private TransferCredit transferCredit; private String password; private String name; private String primaryMajor; @@ -32,12 +34,26 @@ public class User { private boolean graduated; @Builder - private User(Long id, String authId, String password, EnglishLevel englishLevel, String name, - String studentNumber, - int entryYear, String primaryMajor, String subMajor, String dualMajor, String associatedMajor, - StudentCategory studentCategory, - int totalCredit, double takenCredit, boolean graduated, Instant createdAt, - Instant updatedAt) { + private User( + Long id, + String authId, + String password, + EnglishLevel englishLevel, + String name, + String studentNumber, + int entryYear, + String primaryMajor, + String subMajor, + String dualMajor, + String associatedMajor, + TransferCredit transferCredit, + StudentCategory studentCategory, + int totalCredit, + double takenCredit, + boolean graduated, + Instant createdAt, + Instant updatedAt + ) { this.id = id; this.authId = authId; this.password = password; @@ -50,24 +66,51 @@ private User(Long id, String authId, String password, EnglishLevel englishLevel, this.dualMajor = dualMajor; this.associatedMajor = associatedMajor; this.studentCategory = studentCategory; + this.transferCredit = transferCredit != null ? transferCredit : TransferCredit.empty(); this.totalCredit = totalCredit; this.takenCredit = takenCredit; this.graduated = graduated; this.createdAt = createdAt; this.updatedAt = updatedAt; + } + + public static User create( + String authId, + String password, + EnglishLevel englishLevel, + String studentNumber + ) { + return User.builder() + .authId(authId).password(password).englishLevel(englishLevel) + .studentNumber(studentNumber).entryYear(parseEntryYearInStudentNumber(studentNumber)) + .totalCredit(0).takenCredit(0).graduated(false).build(); } - public static User create(String authId, String password, EnglishLevel englishLevel, - String studentNumber) { + public static User createAnonymous( + EnglishLevel englishLevel, + String name, + String studentNumber, + String primaryMajor, + String subMajor, + String dualMajor, + String associatedMajor, + StudentCategory studentCategory, + TransferCredit transferCredit) { return User.builder() - .authId(authId) - .password(password) + .authId("anonymous") + .name(name) .englishLevel(englishLevel) .studentNumber(studentNumber) .entryYear(parseEntryYearInStudentNumber(studentNumber)) + .primaryMajor(primaryMajor) + .subMajor(subMajor) + .dualMajor(dualMajor) + .associatedMajor(associatedMajor) + .studentCategory(studentCategory) .totalCredit(0) .takenCredit(0) .graduated(false) + .transferCredit(transferCredit) .build(); } @@ -75,9 +118,35 @@ private static int parseEntryYearInStudentNumber(String studentNumber) { return Integer.parseInt(studentNumber.substring(2, 4)); } - public void updateStudentInformation(String name, String major, String dualMajor, + @Override + public String toString() { + return "User{" + + "id=" + id + + ", authId='" + authId + '\'' + + ", englishLevel=" + englishLevel + + ", studentNumber='" + studentNumber + '\'' + + ", entryYear=" + entryYear + + ", createdAt=" + createdAt + + ", updatedAt=" + updatedAt + + ", password='" + password + '\'' + + ", name='" + name + '\'' + + ", primaryMajor='" + primaryMajor + '\'' + + ", subMajor='" + subMajor + '\'' + + ", dualMajor='" + dualMajor + '\'' + + ", associatedMajor='" + associatedMajor + '\'' + + ", transferCredit=" + transferCredit + + ", studentCategory=" + studentCategory + + ", totalCredit=" + totalCredit + + ", takenCredit=" + takenCredit + + ", graduated=" + graduated + + '}'; + } + + public void updateStudentInformation( + String name, String major, String dualMajor, String subMajor, String associatedMajor, - StudentCategory studentCategory, int totalCredit, double takenCredit, boolean graduate) { + StudentCategory studentCategory, int totalCredit, double takenCredit, boolean graduate + ) { this.name = name; this.primaryMajor = major; this.dualMajor = dualMajor; @@ -89,6 +158,11 @@ public void updateStudentInformation(String name, String major, String dualMajor this.graduated = graduate; } + public void updateTransferCredit(TransferCredit transferCredit) { + if (transferCredit != null) { + this.transferCredit = transferCredit; + } + } public boolean checkBeforeEntryYear(int entryYear) { return this.entryYear < entryYear; } @@ -135,12 +209,25 @@ public boolean equals(Object o) { return false; } User user = (User) o; - return Objects.equals(authId, user.authId) && Objects.equals(studentNumber, - user.studentNumber); + return Objects.equals(authId, user.authId) && Objects.equals( + studentNumber, + user.studentNumber + ); } @Override public int hashCode() { return Objects.hash(authId, studentNumber); } + + @VisibleForTesting + public void setStudentCategory(StudentCategory studentCategory) { + this.studentCategory = studentCategory; + } + + @VisibleForTesting + public void setTransferCredit(TransferCredit transferCredit) { + this.transferCredit = transferCredit; + } + } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/entity/UserJpaEntity.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/entity/UserJpaEntity.java index b986622c..9e6206ce 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/entity/UserJpaEntity.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/entity/UserJpaEntity.java @@ -51,6 +51,8 @@ public class UserJpaEntity extends TimeBaseEntity { private String associatedMajor; + private String transferCredit; + private int totalCredit; private double takenCredit; @@ -59,5 +61,4 @@ public class UserJpaEntity extends TimeBaseEntity { @Enumerated(value = EnumType.STRING) private StudentCategory studentCategory; - } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapper.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapper.java index 02affb27..8ab1c5fd 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapper.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapper.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.infrastructure.adapter.persistence.mapper; +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import com.plzgraduate.myongjigraduatebe.user.infrastructure.adapter.persistence.entity.UserJpaEntity; import org.springframework.stereotype.Component; @@ -20,6 +21,7 @@ public User mapToDomainEntity(UserJpaEntity user) { .dualMajor(user.getDualMajor()) .subMajor(user.getSubMajor()) .associatedMajor(user.getAssociatedMajor()) + .transferCredit(TransferCredit.from(user.getTransferCredit())) .studentCategory(user.getStudentCategory()) .totalCredit(user.getTotalCredit()) .takenCredit(user.getTakenCredit()) @@ -43,6 +45,7 @@ public UserJpaEntity mapToJpaEntity(User user) { .dualMajor(user.getDualMajor()) .subMajor(user.getSubMajor()) .associatedMajor(user.getAssociatedMajor()) + .transferCredit(user.getTransferCredit().toString()) .studentCategory(user.getStudentCategory()) .totalCredit(user.getTotalCredit()) .takenCredit(user.getTakenCredit()) diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditServiceTest.java index ab139cf8..4ea8f9f2 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/application/service/GenerateOrModifyCompletedCreditServiceTest.java @@ -40,72 +40,74 @@ class GenerateOrModifyCompletedCreditServiceTest { @DisplayName("새로운 기이수 학점을 저장한다.") @Test void generateOrModifyCompletedCreditPort() { - //given + // given User user = User.builder() - .id(1L) - .build(); + .id(1L) + .build(); given(findCompletedCreditPort.findCompletedCredit(user)).willReturn(List.of()); - int eachDetailGraduationResultTotalCredit = 10; - int eachDetailGraduationResultTakenCredit = 5; + double eachDetailGraduationResultTotalCredit = 10.0; + double eachDetailGraduationResultTakenCredit = 5.0; List detailGraduationResults = createDetailGraduationResults( - eachDetailGraduationResultTotalCredit, eachDetailGraduationResultTakenCredit); + (int) eachDetailGraduationResultTotalCredit, (int) eachDetailGraduationResultTakenCredit); GraduationResult graduationResult = GraduationResult.builder() - .detailGraduationResults(detailGraduationResults) - .chapelResult( - ChapelResult.builder() - .takenCount(3) - .build()) - .normalCultureGraduationResult( - NormalCultureGraduationResult.builder() - .totalCredit(eachDetailGraduationResultTotalCredit) - .takenCredit(eachDetailGraduationResultTakenCredit) - .build()) - .freeElectiveGraduationResult( - FreeElectiveGraduationResult.builder() - .totalCredit(eachDetailGraduationResultTotalCredit) - .takenCredit(eachDetailGraduationResultTakenCredit) - .build()) - .build(); + .detailGraduationResults(detailGraduationResults) + .chapelResult( + ChapelResult.builder() + .takenCount(3) + .build()) + .normalCultureGraduationResult( + NormalCultureGraduationResult.builder() + .totalCredit((int) eachDetailGraduationResultTotalCredit) + .takenCredit((int) eachDetailGraduationResultTakenCredit) + .build()) + .freeElectiveGraduationResult( + FreeElectiveGraduationResult.builder() + .totalCredit((int) eachDetailGraduationResultTotalCredit) + .takenCredit((int) eachDetailGraduationResultTakenCredit) + .build()) + .build(); given(calculateGraduationUseCase.calculateGraduation(user)).willReturn(graduationResult); + ArgumentCaptor> completedCreditArgumentCaptor = ArgumentCaptor.forClass( - List.class); + List.class); ArgumentCaptor userArgumentCaptor = ArgumentCaptor.forClass(User.class); - //when + // when generateOrModifyCompletedCreditService.generateOrModifyCompletedCredit(user); - //then + // then then(generateOrModifyCompletedCreditPort).should() - .generateOrModifyCompletedCredits(userArgumentCaptor.capture(), - completedCreditArgumentCaptor.capture()); + .generateOrModifyCompletedCredits(userArgumentCaptor.capture(), + completedCreditArgumentCaptor.capture()); List savedCompletedCredits = completedCreditArgumentCaptor.getValue(); Assertions.assertThat(savedCompletedCredits) - .hasSize(detailGraduationResults.size() + 3) - .extracting("graduationCategory", "totalCredit", "takenCredit") - .containsOnly( - tuple(GraduationCategory.COMMON_CULTURE, eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.CORE_CULTURE, eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.PRIMARY_MANDATORY_MAJOR, - eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.PRIMARY_ELECTIVE_MAJOR, - eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.PRIMARY_BASIC_ACADEMICAL_CULTURE, - eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.CHAPEL, 2, 1.5), - tuple(GraduationCategory.NORMAL_CULTURE, eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit), - tuple(GraduationCategory.FREE_ELECTIVE, eachDetailGraduationResultTotalCredit, - (double) eachDetailGraduationResultTakenCredit)); + .hasSize(detailGraduationResults.size() + 3) + .extracting("graduationCategory", "totalCredit", "takenCredit") + .containsOnly( + tuple(GraduationCategory.COMMON_CULTURE, eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.CORE_CULTURE, eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.PRIMARY_MANDATORY_MAJOR, + eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.PRIMARY_ELECTIVE_MAJOR, + eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.PRIMARY_BASIC_ACADEMICAL_CULTURE, + eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.CHAPEL, 2.0, 1.5), + tuple(GraduationCategory.NORMAL_CULTURE, eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit), + tuple(GraduationCategory.FREE_ELECTIVE, eachDetailGraduationResultTotalCredit, + eachDetailGraduationResultTakenCredit)); } + private List createDetailGraduationResults(int totalCredit, int takenCredit) { return List.of(DetailGraduationResult.builder() diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCreditTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCreditTest.java new file mode 100644 index 00000000..a3caafdd --- /dev/null +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/completedcredit/domain/model/CompletedCreditTest.java @@ -0,0 +1,57 @@ +package com.plzgraduate.myongjigraduatebe.completedcredit.domain.model; + +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.ChapelResult; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CompletedCreditTest { + + @Test + @DisplayName("편입생의 채플 요건은 0.5 학점이며, 이수 여부를 확인한다.") + void createChapelCompletedCreditModelForTransferStudent() { + // given + User transferStudent = User.builder() + .id(1L) + .studentCategory(StudentCategory.TRANSFER) // 편입생 + .build(); + + ChapelResult chapelResult = ChapelResult.builder() + .takenCount(1) // 채플 1회 이수 + .build(); + + // when + CompletedCredit completedCredit = CompletedCredit.createChapelCompletedCreditModel(chapelResult, transferStudent); + + // then + assertThat(completedCredit.getGraduationCategory()).isEqualTo(GraduationCategory.CHAPEL); + assertThat(completedCredit.getTotalCredit()).isEqualTo(0.5); // 편입생의 채플 요건 + assertThat(completedCredit.getTakenCredit()).isEqualTo(0.5); // 채플 1회 이수 + } + + @Test + @DisplayName("편입생이 채플을 이수하지 않았을 경우, 이수 여부를 확인한다.") + void createChapelCompletedCreditModelForUncompletedTransferStudent() { + // given + User transferStudent = User.builder() + .id(1L) + .studentCategory(StudentCategory.TRANSFER) // 편입생 + .build(); + + ChapelResult chapelResult = ChapelResult.builder() + .takenCount(0) // 채플 이수 없음 + .build(); + + // when + CompletedCredit completedCredit = CompletedCredit.createChapelCompletedCreditModel(chapelResult, transferStudent); + + // then + assertThat(completedCredit.getGraduationCategory()).isEqualTo(GraduationCategory.CHAPEL); + assertThat(completedCredit.getTotalCredit()).isEqualTo(0.5); // 편입생의 채플 요건 + assertThat(completedCredit.getTakenCredit()).isEqualTo(0.0); // 채플 미이수 + } +} diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/fixture/UserFixture.java b/src/test/java/com/plzgraduate/myongjigraduatebe/fixture/UserFixture.java index dbd22e9e..7f57b98a 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/fixture/UserFixture.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/fixture/UserFixture.java @@ -85,6 +85,11 @@ public class UserFixture { null, StudentCategory.NORMAL); } + public static User 경제학과_20학번_편입() { + return createUser("mj1003", "1234", EnglishLevel.FREE, "최편입", "60191666", 19, "경제학과", + null, + StudentCategory.NORMAL); + } public static User 응용소프트웨어학과_17학번() { return createUser("mj22", "1234", EnglishLevel.ENG34, "김응용", "60171022", 17, "응용소프트웨어전공", diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationServiceTest.java index 0a5c0350..de7aa4af 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateMajorGraduationServiceTest.java @@ -27,6 +27,8 @@ import com.plzgraduate.myongjigraduatebe.lecture.domain.model.MajorLecture; 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.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import java.util.HashSet; import java.util.List; @@ -50,13 +52,13 @@ class CalculateMajorGraduationServiceTest { @BeforeEach void setUp() { MandatoryMajorManager mandatoryMajorManager = new MandatoryMajorManager( - List.of(new OptionalMandatoryMajorHandler(), new ReplaceMandatoryMajorHandler())); + List.of(new OptionalMandatoryMajorHandler(), new ReplaceMandatoryMajorHandler())); ElectiveMajorManager electiveMajorManager = new ElectiveMajorManager(); SubMajorGraduationManager subMajorGraduationManager = new SubMajorGraduationManager(); MajorGraduationManager majorGraduationManager = new MajorGraduationManager( - mandatoryMajorManager, electiveMajorManager); + mandatoryMajorManager, electiveMajorManager); calculateMajorGraduationService = new CalculateMajorGraduationService(findMajorPort, - majorGraduationManager, subMajorGraduationManager); + majorGraduationManager, subMajorGraduationManager); } @DisplayName("MAJOR 관련 카테고리 일때만 MajorGraduationService를 호출한다.") @@ -78,50 +80,50 @@ void shouldSupportMajorCategory() { void shouldCalculateSingleDetailGraduationIfPrimaryMandatory() { //given User user = User.builder() - .id(1L) - .primaryMajor("응용소프트웨어전공") - .entryYear(19) - .build(); + .id(1L) + .primaryMajor("응용소프트웨어전공") + .entryYear(19) + .build(); HashSet graduationMajorLectures = new HashSet<>( - Set.of( - MajorLecture.of(Lecture.builder() - .id("HEC01211") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23), - MajorLecture.of(Lecture.builder() - .id("HEC01204") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23))); + Set.of( + MajorLecture.of(Lecture.builder() + .id("HEC01211") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23), + MajorLecture.of(Lecture.builder() + .id("HEC01204") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23))); given(findMajorPort.findMajor(user.getPrimaryMajor())).willReturn(graduationMajorLectures); HashSet takenLectures = new HashSet<>( - Set.of( - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01211") //전공 필수 - .credit(3) - .build()) - .build(), - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01305") //전공 선택 - .credit(3) - .build()) - .build())); + Set.of( + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01211") //전공 필수 + .credit(3) + .build()) + .build(), + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01305") //전공 선택 + .credit(3) + .build()) + .build())); TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); GraduationRequirement graduationRequirement = GraduationRequirement.builder() - .primaryMajorCredit(70) - .build(); + .primaryMajorCredit(70) + .build(); //when DetailGraduationResult detailPrimaryMandatoryMajorGraduationResult = calculateMajorGraduationService.calculateSingleDetailGraduation( - user, PRIMARY_MANDATORY_MAJOR, takenLectureInventory, graduationRequirement); + user, PRIMARY_MANDATORY_MAJOR, takenLectureInventory, graduationRequirement); //then assertThat(detailPrimaryMandatoryMajorGraduationResult) - .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") - .contains(PRIMARY_MANDATORY_MAJOR, false, 6, 3.0); + .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") + .contains(PRIMARY_MANDATORY_MAJOR, false, 6, 3.0); } @DisplayName("유저의 주전공선택 상세 졸업결과를 계산한다.") @@ -129,57 +131,57 @@ void shouldCalculateSingleDetailGraduationIfPrimaryMandatory() { void calculateSingleDetailGraduationIfPrimaryElective() { //given User user = User.builder() - .id(1L) - .primaryMajor("응용소프트웨어전공") - .entryYear(19) - .build(); + .id(1L) + .primaryMajor("응용소프트웨어전공") + .entryYear(19) + .build(); HashSet graduationMajorLectures = new HashSet<>( - Set.of( - // 전공 필수 - MajorLecture.of(Lecture.builder() - .id("HEC01211") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23), - // 전공 선택 - MajorLecture.of(Lecture.builder() - .id("HEC01305") - .credit(3) - .build(), "응용소프트웨어전공", 0, 16, 23), - // 전공 선택 - MajorLecture.of(Lecture.builder() - .id("HEC01318") - .credit(3) - .build(), "응용소프트웨어전공", 0, 16, 23))); + Set.of( + // 전공 필수 + MajorLecture.of(Lecture.builder() + .id("HEC01211") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23), + // 전공 선택 + MajorLecture.of(Lecture.builder() + .id("HEC01305") + .credit(3) + .build(), "응용소프트웨어전공", 0, 16, 23), + // 전공 선택 + MajorLecture.of(Lecture.builder() + .id("HEC01318") + .credit(3) + .build(), "응용소프트웨어전공", 0, 16, 23))); given(findMajorPort.findMajor(user.getPrimaryMajor())).willReturn(graduationMajorLectures); HashSet takenLectures = new HashSet<>( - Set.of( - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01211") //전공 필수 - .credit(3) - .build()) - .build(), - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01305") //전공 선택 - .credit(3) - .build()) - .build())); + Set.of( + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01211") //전공 필수 + .credit(3) + .build()) + .build(), + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01305") //전공 선택 + .credit(3) + .build()) + .build())); TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); GraduationRequirement graduationRequirement = GraduationRequirement.builder() - .primaryMajorCredit(70) - .build(); + .primaryMajorCredit(70) + .build(); //when DetailGraduationResult detailPrimaryElectiveMajorGraduationResult = calculateMajorGraduationService.calculateSingleDetailGraduation( - user, PRIMARY_ELECTIVE_MAJOR, takenLectureInventory, graduationRequirement); + user, PRIMARY_ELECTIVE_MAJOR, takenLectureInventory, graduationRequirement); //then assertThat(detailPrimaryElectiveMajorGraduationResult) - .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") - .contains(PRIMARY_ELECTIVE_MAJOR, false, 67, 3.0); + .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") + .contains(PRIMARY_ELECTIVE_MAJOR, false, 67, 3.0); } @DisplayName("유저의 복수전공필수 졸업결과를 계산한다.") @@ -187,50 +189,50 @@ void calculateSingleDetailGraduationIfPrimaryElective() { void calculateSingleDetailGraduationIfDualMandatory() { //given User user = User.builder() - .id(1L) - .dualMajor("응용소프트웨어전공") - .entryYear(19) - .build(); + .id(1L) + .dualMajor("응용소프트웨어전공") + .entryYear(19) + .build(); HashSet graduationMajorLectures = new HashSet<>( - Set.of( - MajorLecture.of(Lecture.builder() - .id("HEC01211") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23), - MajorLecture.of(Lecture.builder() - .id("HEC01204") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23))); + Set.of( + MajorLecture.of(Lecture.builder() + .id("HEC01211") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23), + MajorLecture.of(Lecture.builder() + .id("HEC01204") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23))); given(findMajorPort.findMajor(user.getDualMajor())).willReturn(graduationMajorLectures); HashSet takenLectures = new HashSet<>( - Set.of( - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01211") //전공 필수 - .credit(3) - .build()) - .build(), - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01305") //전공 선택 - .credit(3) - .build()) - .build())); + Set.of( + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01211") //전공 필수 + .credit(3) + .build()) + .build(), + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01305") //전공 선택 + .credit(3) + .build()) + .build())); TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); GraduationRequirement graduationRequirement = GraduationRequirement.builder() - .dualMajorCredit(70) - .build(); + .dualMajorCredit(70) + .build(); //when DetailGraduationResult detailDualMandatoryMajorGraduationResult = calculateMajorGraduationService.calculateSingleDetailGraduation( - user, DUAL_MANDATORY_MAJOR, takenLectureInventory, graduationRequirement); + user, DUAL_MANDATORY_MAJOR, takenLectureInventory, graduationRequirement); //then assertThat(detailDualMandatoryMajorGraduationResult) - .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") - .contains(DUAL_MANDATORY_MAJOR, false, 6, 3.0); + .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") + .contains(DUAL_MANDATORY_MAJOR, false, 6, 3.0); } @DisplayName("유저의 복수전공선택 졸업결과를 계산한다.") @@ -238,49 +240,102 @@ void calculateSingleDetailGraduationIfDualMandatory() { void calculateCoreCulture() { //given User user = User.builder() - .id(1L) - .dualMajor("응용소프트웨어전공") - .entryYear(19) - .build(); + .id(1L) + .dualMajor("응용소프트웨어전공") + .entryYear(19) + .build(); HashSet graduationMajorLectures = new HashSet<>( - Set.of( - MajorLecture.of(Lecture.builder() - .id("HEC01211") - .credit(3) - .build(), "응용소프트웨어전공", 1, 16, 23), - MajorLecture.of(Lecture.builder() - .id("HEC01304") - .credit(3) - .build(), "응용소프트웨어전공", 0, 16, 23))); + Set.of( + MajorLecture.of(Lecture.builder() + .id("HEC01211") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23), + MajorLecture.of(Lecture.builder() + .id("HEC01304") + .credit(3) + .build(), "응용소프트웨어전공", 0, 16, 23))); given(findMajorPort.findMajor(user.getDualMajor())).willReturn(graduationMajorLectures); HashSet takenLectures = new HashSet<>( - Set.of( - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01211") //전공 필수 - .credit(3) - .build()) - .build(), - TakenLecture.builder() - .lecture(Lecture.builder() - .id("HEC01304") //전공 선택 - .credit(3) - .build()) - .build())); + Set.of( + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01211") //전공 필수 + .credit(3) + .build()) + .build(), + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01304") //전공 선택 + .credit(3) + .build()) + .build())); TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); GraduationRequirement graduationRequirement = GraduationRequirement.builder() - .dualMajorCredit(70) - .build(); + .dualMajorCredit(70) + .build(); //when DetailGraduationResult detailDualMandatoryMajorGraduationResult = calculateMajorGraduationService.calculateSingleDetailGraduation( - user, DUAL_ELECTIVE_MAJOR, takenLectureInventory, graduationRequirement); + user, DUAL_ELECTIVE_MAJOR, takenLectureInventory, graduationRequirement); //then assertThat(detailDualMandatoryMajorGraduationResult) - .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") - .contains(DUAL_ELECTIVE_MAJOR, false, 67, 3.0); + .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") + .contains(DUAL_ELECTIVE_MAJOR, false, 67, 3.0); } -} + + @DisplayName("편입생 주전공필수 졸업결과를 계산한다.") + @Test + void calculateSingleDetailGraduationForTransferPrimaryMandatory() { + // given + User user = User.builder() + .id(1L) + .primaryMajor("응용소프트웨어전공") + .entryYear(19) + .studentCategory(StudentCategory.TRANSFER) + .transferCredit(TransferCredit.from("0/15/0/0")) + .build(); + + HashSet graduationMajorLectures = new HashSet<>( + Set.of( + MajorLecture.of(Lecture.builder() + .id("HEC01211") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23), + MajorLecture.of(Lecture.builder() + .id("HEC01204") + .credit(3) + .build(), "응용소프트웨어전공", 1, 16, 23) + ) + ); + given(findMajorPort.findMajor(user.getPrimaryMajor())).willReturn(graduationMajorLectures); + + HashSet takenLectures = new HashSet<>( + Set.of( + TakenLecture.builder() + .lecture(Lecture.builder() + .id("HEC01211") // 전공 필수 + .credit(3) + .build()) + .build() + ) + ); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); + + GraduationRequirement graduationRequirement = GraduationRequirement.builder() + .primaryMajorCredit(70) + .build(); + + // when + DetailGraduationResult detailPrimaryMandatoryMajorGraduationResult = calculateMajorGraduationService.calculateSingleDetailGraduation( + user, PRIMARY_MANDATORY_MAJOR, takenLectureInventory, graduationRequirement); + + // then + assertThat(detailPrimaryMandatoryMajorGraduationResult) + .extracting("graduationCategory", "isCompleted", "totalCredit", "takenCredit") + .contains(PRIMARY_MANDATORY_MAJOR, false, 6, 3.0); + } + +} \ No newline at end of file diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResultTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResultTest.java index b68c93b5..5ca6ddca 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResultTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/FreeElectiveGraduationResultTest.java @@ -11,6 +11,8 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.Semester; 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.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import java.util.HashSet; import java.util.List; @@ -63,7 +65,7 @@ void createFreeElectiveGraduationResult() { FreeElectiveGraduationResult freeElectiveGraduationResult = FreeElectiveGraduationResult.create( 7, takenLectureInventory, List.of(detailGraduationResult), - leftNormalCultureCredit); + leftNormalCultureCredit,user); //then assertThat(freeElectiveGraduationResult) @@ -90,7 +92,8 @@ void createFreeElectiveGraduationResult_withOneVolunteerCredit() { totalFreeElectiveCredit, takenLectureInventory, List.of(), - leftNormalCultureCredit); + leftNormalCultureCredit, + user); //then assertThat(freeElectiveGraduationResult) @@ -117,11 +120,90 @@ void createFreeElectiveGraduationResult_withTwoVolunteerCredits() { totalFreeElectiveCredit, takenLectureInventory, List.of(), - leftNormalCultureCredit); + leftNormalCultureCredit, + user); //then assertThat(freeElectiveGraduationResult) .extracting("categoryName", "takenCredit") .contains(FREE_ELECTIVE.getName(), 2); // 봉사학점 2학점 반영 } + @DisplayName("편입생의 자유선택 졸업 결과를 생성한다.") + @Test + void createFreeElectiveGraduationResult_forTransferStudent() { + // given + User user = UserFixture.경제학과_20학번_편입(); + user.setStudentCategory(StudentCategory.TRANSFER); + user.setTransferCredit(new TransferCredit(51, 0, 3,0)); // 편입 학점 설정 + + // Taken lectures (총 9학점) + Set takenLectures = new HashSet<>(Set.of( + TakenLecture.of(user, mockLectureMap.get("HBX01104"), 2019, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("HBX01113"), 2019, Semester.FIRST), + TakenLecture.of(user, mockLectureMap.get("HBX01106"), 2020, Semester.FIRST) + )); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); + + // 교양 초과분 (남은 4학점이 자유선택으로 넘어가야 함) + DetailGraduationResult combinedCultureGraduationResult = DetailGraduationResult.builder() + .graduationCategory(GraduationCategory.NORMAL_CULTURE) + .detailCategory(List.of( + DetailCategoryResult.builder() + .detailCategoryName("일반교양") + .freeElectiveLeftCredit(4) // 초과된 통합 교양 학점 + .build() + )) + .build(); + + int leftNormalCultureCredit = 1; + + // when + FreeElectiveGraduationResult freeElectiveGraduationResult = FreeElectiveGraduationResult.create( + 14, + takenLectureInventory, + List.of(combinedCultureGraduationResult), + leftNormalCultureCredit, + user + ); + + // then + assertThat(freeElectiveGraduationResult) + .extracting("categoryName", "takenCredit") + .contains(FREE_ELECTIVE.getName(), + 17); // 편입 학점 포함 계산 + } + + @DisplayName("편입생 봉사학점을 포함한 자유선택 졸업 결과를 생성한다.") + @Test + void createFreeElectiveGraduationResult_withVolunteerCredits_forTransferStudent() { + // given + User user = UserFixture.경제학과_20학번_편입(); + user.setStudentCategory(StudentCategory.TRANSFER); + user.setTransferCredit(new TransferCredit(0, 0, 3,0)); // 편입 학점 설정 + + Set takenLectures = new HashSet<>(Set.of( + TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2021, Semester.FIRST), // 봉사학점 1 + TakenLecture.of(user, mockLectureMap.get("KMA02198"), 2022, Semester.SECOND) // 봉사학점 2 + )); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(takenLectures); + + int totalFreeElectiveCredit = 14; + int leftNormalCultureCredit = 0; + + // when + FreeElectiveGraduationResult freeElectiveGraduationResult = FreeElectiveGraduationResult.create( + totalFreeElectiveCredit, + takenLectureInventory, + List.of(), + leftNormalCultureCredit, + user + ); + + // then + assertThat(freeElectiveGraduationResult) + .extracting("categoryName", "takenCredit") + .contains(FREE_ELECTIVE.getName(), 5); // 봉사학점 2 + 편입 학점 3 + 기타 계산 + } } + + diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResultTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResultTest.java index d0ef24d9..cb357f0f 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResultTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/GraduationResultTest.java @@ -124,7 +124,7 @@ void handleLeftTakenLectures() { .build(); //when - graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement); + graduationResult.handleLeftTakenLectures(takenLectureInventory, graduationRequirement, user); //then assertThat(graduationResult.getNormalCultureGraduationResult()) @@ -142,6 +142,7 @@ void handleLeftTakenLectures() { @DisplayName("채플 졸업 결과, 모든 세부 졸업 결과, 일반교양 졸업 결과, 자유선택 졸업 결과가 이수 완료일 시 전체 졸업 결과가 이수 완료이다.") @Test void checkCompletedGraduated() { + User user = UserFixture.데이터테크놀로지학과_19학번(); //given int detailCategoryTotalCredit = 10; int detailCategoryTakenCredit = 10; @@ -181,7 +182,7 @@ void checkCompletedGraduated() { //when graduationResult.checkGraduated(GraduationRequirement.builder() .totalCredit(134) - .build()); + .build(), user); //then assertThat(graduationResult.isGraduated()).isTrue(); @@ -199,6 +200,7 @@ void checkUnCompletedGraduated(ChapelResult chapelResult, NormalCultureGraduationResult normalCultureGraduationResult, FreeElectiveGraduationResult freeElectiveGraduationResult) { //given + User user = UserFixture.데이터테크놀로지학과_19학번(); GraduationResult graduationResult = GraduationResult.builder() .chapelResult(chapelResult) .detailGraduationResults(detailGraduationResults) @@ -209,10 +211,9 @@ void checkUnCompletedGraduated(ChapelResult chapelResult, //when graduationResult.checkGraduated(GraduationRequirement.builder() .totalCredit(134) - .build()); + .build(), user); //then assertThat(graduationResult.isGraduated()).isFalse(); } - } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResultTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResultTest.java index d59d9000..557fbe16 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResultTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/NormalCultureGraduationResultTest.java @@ -62,6 +62,7 @@ void createNormalCultureGraduationResult() { //when NormalCultureGraduationResult normalCultureGraduationResult = NormalCultureGraduationResult.create( 15, + 0, takenLectureInventory, List.of(detailGraduationResult)); @@ -86,6 +87,7 @@ void volunteerCreditIsNotIncludedInNormalCulture() { //when NormalCultureGraduationResult normalCultureGraduationResult = NormalCultureGraduationResult.create( 9, + 0, takenLectureInventory, List.of()); diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementTypeTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementTypeTest.java new file mode 100644 index 00000000..384b221e --- /dev/null +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/domain/model/TransferGraduationRequirementTypeTest.java @@ -0,0 +1,57 @@ +package com.plzgraduate.myongjigraduatebe.graduation.domain.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.NoSuchElementException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class TransferGraduationRequirementTypeTest { + + @Test + @DisplayName("단과대 이름으로 편입 졸업 요건을 찾는다.") + void findByCollegeNameSuccess() { + // given + String collegeName = "경영대"; + + // when + TransferGraduationRequirementType result = TransferGraduationRequirementType.findByCollegeName(collegeName); + + // then + assertThat(result).isNotNull(); + assertThat(result.getCollegeName()).isEqualTo(collegeName); + assertThat(result.getCombinedCultureCredit()).isEqualTo(45); + assertThat(result.getChristianCredit()).isEqualTo(2); + } + + @Test + @DisplayName("존재하지 않는 단과대 이름으로 편입 졸업 요건 조회 시 예외가 발생한다.") + void findByCollegeNameFailure() { + // given + String invalidCollegeName = "의과대"; + + // when & then + assertThatThrownBy(() -> TransferGraduationRequirementType.findByCollegeName(invalidCollegeName)) + .isInstanceOf(NoSuchElementException.class) + .hasMessage("해당 단과대의 편입 졸업 요건이 존재하지 않습니다."); + } + + @Test + @DisplayName("모든 단과대 편입 졸업 요건을 확인한다.") + void verifyAllRequirements() { + // when + TransferGraduationRequirementType humanities = TransferGraduationRequirementType.HUMANITIES; + TransferGraduationRequirementType ict = TransferGraduationRequirementType.ICT; + + // then + assertThat(humanities.getCollegeName()).isEqualTo("인문대"); + assertThat(humanities.getCombinedCultureCredit()).isEqualTo(51); + assertThat(humanities.getChristianCredit()).isEqualTo(2); + + assertThat(ict.getCollegeName()).isEqualTo("ICT융합대"); + assertThat(ict.getCombinedCultureCredit()).isEqualTo(57); + assertThat(ict.getChristianCredit()).isEqualTo(2); + } +} diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousServiceTest.java new file mode 100644 index 00000000..a51ee6a8 --- /dev/null +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingAnonymousServiceTest.java @@ -0,0 +1,44 @@ +package com.plzgraduate.myongjigraduatebe.parsing.application.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.plzgraduate.myongjigraduatebe.parsing.application.usecase.dto.ParsingAnonymousDto; +import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class ParsingAnonymousServiceTest { + + @InjectMocks + private ParsingAnonymousService parsingAnonymousService; + + @DisplayName("파싱 텍스트에서 정보를 추출해 anonymous user를 포함한 ParsingAnonymousDto를 반환한다.") + @Test + void parseAnonymous() { + // given + EnglishLevel englishLevel = EnglishLevel.ENG12; + String parsingText = "출력일자 : 2024/11/20|1/1|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 김보겸(60211648), 현학적 - 재학, 이수 - 6, 입학 - 신입학(2021/03/02)|토익 - 535, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2023/01/09)|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 융합전공 0, 부전공 0, 자유선택 0|공통교양 17, 핵심교양 12, 학문기초교양 15, 일반교양 14, 전공 50, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 0|총 취득학점 - 108, 총점 - 441.5, 평균평점 - 4.33|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2023년 2학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P|공통교양|2021년 2학기|교필105|KMA02105|발표와토의|3|A0|공통교양|2021년 2학기|교필127|KMA00101|성서와인간이해|2|A0|공통교양|2021년 1학기|교필106|KMA02106|영어1|2|A+|공통교양|2021년 2학기|교필107|KMA02107|영어2|2|A+|공통교양|2021년 1학기|교필108|KMA02108|영어회화1|1|A+|공통교양|2021년 2학기|교필109|KMA02109|영어회화2|1|A0|공통교양|2021년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2021년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2022년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2021년 2학기|교필102|KMA02102|현대사회와기독교윤리|2|A0|핵심교양|2022년 1학기|교선128|KMA02128|글로벌문화|3|A+|핵심교양|2021년 1학기|교선114|KMA02114|민주주의와현대사회|3|A+|핵심교양|2021년 2학기|교선112|KMA02112|역사와문명|3|A0|핵심교양|2021년 1학기|교선135|KMA02135|우주,생명,마음|3|B+|학문기초교양|2023년 1학기|기사133|KMD02133|ICT비즈니스와경영|3|A0|학문기초교양|2023년 1학기|기사134|KMD02134|마케팅과ICT융합기술|3|A0|학문기초교양|2021년 1학기|기인107|KMB02107|인간심리의이해|3|A+|학문기초교양|2021년 2학기|기사135|KMD02135|저작권과소프트웨어|3|A+|학문기초교양|2022년 1학기|기컴112|KMI02112|컴퓨터논리의이해|3|B+|일반교양|2022년 1학기|균인131|KMK02131|사랑의인문학(KCU)|3|A0|일반교양|2021년 1학기|기컴125|KMI02125|생활속의스마트IT(KCU)|3|A+|일반교양|2024년 1학기|기문227|KMC02227|인류문명과기록문화로의여행|3|A+|일반교양|2024년 1학기|균사181|KMM02181|자기경영과실전취업준비|2|A+|일반교양|2024년 1학기|기컴126|KMI02126|파이썬프로그래밍입문|3|A+|전공1단계|2022년 1학기|데테202|HED01202|R통계분석|3|A+|전공1단계|2022년 1학기|데테316|HED01316|고급웹프로그래밍|3|A+|전공1단계|2023년 2학기|데테206|HED01206|기초웹프로그래밍|3|A+|전공1단계|2021년 1학기|융소102|HEB01102|기초프로그래밍|3|A+|전공1단계|2021년 2학기|융소105|HEB01105|기초프로그래밍2|3|A+|전공1단계|2023년 1학기|데테318|HED01203|데이터베이스|3|A+|전공1단계|2024년 1학기|데테319|HED01318|모바일컴퓨팅|3|A+|전공1단계|2023년 2학기|데테403|HED01403|블록체인기초|3|A+|전공1단계|2024년 1학기|데테404|HED01404|빅데이터기술특론1|3|A+|전공1단계|2023년 1학기|데테301|HED01301|소프트웨어공학|3|A+|전공1단계|2023년 2학기|데테209|HED01307|알고리즘|3|A+|전공1단계|2023년 2학기|데테303|HED01303|운영체제|3|A+|전공1단계|2023년 2학기|데테311|HED01311|자기주도학습|2|P|전공1단계|2022년 1학기|데테201|HED01201|자료구조|3|A+|전공1단계|2024년 1학기|데테413|HED01413|캡스톤디자인|3|A+|전공1단계|2023년 1학기|데테309|HED01309|컴퓨터아키텍쳐|3|A0|전공1단계|2023년 2학기|데테313|HED01313|컴퓨터통신|3|A+|"; + + // when + ParsingAnonymousDto parsingAnonymousDto = parsingAnonymousService.parseAnonymous( + englishLevel, + parsingText + ); + + // then + assertThat(parsingAnonymousDto.getAnonymous()).extracting( + "authId", + "name", + "englishLevel", + "studentNumber", + "entryYear", + "totalCredit", + "takenCredit", + "graduated" + ).contains("anonymous", "김보겸", EnglishLevel.ENG12, "60211648", 21, 0, 0, false); + } +} diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformationTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformationTest.java index 94480849..2cb8193e 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformationTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/domain/ParsingInformationTest.java @@ -12,135 +12,116 @@ class ParsingInformationTest { @Test void createParsingInformation() { //given - String parsingText = "출력일자 : 2022/11/14|1/1" - + "|경영대학 경영학과, 이아현(60191000), 현학적 - 재학, 이수 - 6, 입학 - 신입학(2019/03/04)" - + "|토익 - 625, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2021/07/20)" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" - + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 15, 핵심교양 12, 학문기초교양 6, 일반교양 22, 전공 50, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 0" - + "|총 취득학점 - 105, 총점 - 368.5, 평균평점 - 4.14" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양 (구 필수교양)|2019년 1학기|교필104|KMA02104|글쓰기|3|A0|공통교양 (구 필수교양)|2019년 1학기|교필127|KMA00101|성서와인간이해|2|A0|공통교양 (구 필수교양)|2019년 2학기|교필106|KMA02106|영어1|2|A0|공통교양 (구 필수교양)|2021년 2학기|교필107|KMA02107|영어2|2|B0|공통교양 (구 필수교양)|2019년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2019년 2학기|교필102|KMA02102|현대사회와기독교윤리|2|A+|핵심교양 (구 선택교양)|2019년 2학기|교선136|KMA02136|SW프로그래밍입문|3|B+|핵심교양 (구 선택교양)|2019년 2학기|교선128|KMA02128|글로벌문화|3|A+|핵심교양 (구 선택교양)|2019년 1학기|교선114|KMA02114|민주주의와현대사회|3|A0|핵심교양 (구 선택교양)|2020년 1학기|교선112|KMA02112|역사와문명|3|A+|학문기초교양 (구 기초교양)|2020년 2학기|기사107|KMD02107|경상통계학|3|A0|학문기초교양 (구 기초교양)|2020년 1학기|기사114|KMD02114|미시경제학원론|3|A+|일반교양 (구 균형교양)|2020년 2학기|균명103|KMR02103|금융교육특강|2|P|일반교양 (구 균형교양)|2020년 2학기|균인104|KMK02104|데이팅과결혼|3|A+|일반교양 (구 균형교양)|2022년 1학기|기문104|KMC02104|문학과사회|3|A0|일반교양 (구 균형교양)|2019년 2학기|균명101|KMR02101|방목석좌교수특강|2|P|일반교양 (구 균형교양)|2020년 1학기|기컴125|KMI02125|생활속의스마트IT(KCU)|3|A+|일반교양 (구 균형교양)|2020년 2학기|균사148|KMM02148|자기분석과직무역량개발|2|P|일반교양 (구 균형교양)|2020년 2학기|균명901|KMR02901|전공과진로1|1|P|일반교양 (구 균형교양)|2019년 1학기|기공109|KMF02109|전공자유학부세미나|1|P|일반교양 (구 균형교양)|2019년 1학기|균사133|KMM02133|진로선택과대학생활|2|P|일반교양 (구 균형교양)|2019년 1학기|균과117|KMN02117|환경과웰빙(KCU)|3|A+|전공1단계|2021년 2학기|경영373|HCA02373|경영취업세미나|2|P|전공1단계|2021년 2학기|경영366|HCA02366|고급회계|3|A0|전공1단계|2021년 2학기|경영453|HCA02453|관리회계|3|B+|전공1단계|2022년 1학기|경영424|HCA02424|금융기관경영론|3|A+|전공1단계|2022년 1학기|경영348|HCA02348|기업법1|3|A0|전공1단계|2021년 2학기|경영349|HCA02349|기업법2|3|A0|전공1단계|2021년 2학기|경과138|HBX01138|기업재무론|3|A0|전공1단계|2020년 2학기|경과106|HBX01106|마케팅원론|3|A+|전공1단계|2020년 1학기|경과143|HBX01143|운영관리|3|A+|전공1단계|2022년 1학기|경영251|HCA02251|원가회계|3|A0|전공1단계|2020년 2학기|경과113|HBX01113|인적자원관리|3|B0|전공1단계|2020년 1학기|경과105|HBX01105|재무관리원론|3|A0|전공1단계|2020년 1학기|경과133|HBX01133|재무회계|3|A+|전공1단계|2020년 2학기|경영354|HCA02354|중급회계|3|A+|전공1단계|2022년 1학기|경영375|HCA02375|중급회계2|3|A0|전공1단계|2022년 1학기|경영451|HCA02451|회계감사|3|A+|전공1단계|2019년 2학기|경과104|HBX01104|회계원리|3|A+|2022년 2학기|기사167|KMD02167|MJ사회봉사|3|2022년 2학기|경과127|HBX01127|국제경영학|3|2022년 2학기|경상202|HBW01202|국제금융론|3|2022년 2학기|균사172|KMM02172|기업가정신과창업(KCU)|3|2022년 2학기|교필108|KMA02108|영어회화1|1|2022년 2학기|경영253|HCA02253|재무분석|3|"; + String parsingText = "출력일자 : 2022/11/14|1/1" + "|경영대학 경영학과, 이아현(60191000), 현학적 - 재학, 이수 - 6, 입학 - 신입학(2019/03/04)" + "|토익 - 625, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2021/07/20)" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 15, 핵심교양 12, 학문기초교양 6, 일반교양 22, 전공 50, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 0" + "|총 취득학점 - 105, 총점 - 368.5, 평균평점 - 4.14" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양 (구 필수교양)|2019년 1학기|교필104|KMA02104|글쓰기|3|A0|공통교양 (구 필수교양)|2019년 1학기|교필127|KMA00101|성서와인간이해|2|A0|공통교양 (구 필수교양)|2019년 2학기|교필106|KMA02106|영어1|2|A0|공통교양 (구 필수교양)|2021년 2학기|교필107|KMA02107|영어2|2|B0|공통교양 (구 필수교양)|2019년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2019년 2학기|교필102|KMA02102|현대사회와기독교윤리|2|A+|핵심교양 (구 선택교양)|2019년 2학기|교선136|KMA02136|SW프로그래밍입문|3|B+|핵심교양 (구 선택교양)|2019년 2학기|교선128|KMA02128|글로벌문화|3|A+|핵심교양 (구 선택교양)|2019년 1학기|교선114|KMA02114|민주주의와현대사회|3|A0|핵심교양 (구 선택교양)|2020년 1학기|교선112|KMA02112|역사와문명|3|A+|학문기초교양 (구 기초교양)|2020년 2학기|기사107|KMD02107|경상통계학|3|A0|학문기초교양 (구 기초교양)|2020년 1학기|기사114|KMD02114|미시경제학원론|3|A+|일반교양 (구 균형교양)|2020년 2학기|균명103|KMR02103|금융교육특강|2|P|일반교양 (구 균형교양)|2020년 2학기|균인104|KMK02104|데이팅과결혼|3|A+|일반교양 (구 균형교양)|2022년 1학기|기문104|KMC02104|문학과사회|3|A0|일반교양 (구 균형교양)|2019년 2학기|균명101|KMR02101|방목석좌교수특강|2|P|일반교양 (구 균형교양)|2020년 1학기|기컴125|KMI02125|생활속의스마트IT(KCU)|3|A+|일반교양 (구 균형교양)|2020년 2학기|균사148|KMM02148|자기분석과직무역량개발|2|P|일반교양 (구 균형교양)|2020년 2학기|균명901|KMR02901|전공과진로1|1|P|일반교양 (구 균형교양)|2019년 1학기|기공109|KMF02109|전공자유학부세미나|1|P|일반교양 (구 균형교양)|2019년 1학기|균사133|KMM02133|진로선택과대학생활|2|P|일반교양 (구 균형교양)|2019년 1학기|균과117|KMN02117|환경과웰빙(KCU)|3|A+|전공1단계|2021년 2학기|경영373|HCA02373|경영취업세미나|2|P|전공1단계|2021년 2학기|경영366|HCA02366|고급회계|3|A0|전공1단계|2021년 2학기|경영453|HCA02453|관리회계|3|B+|전공1단계|2022년 1학기|경영424|HCA02424|금융기관경영론|3|A+|전공1단계|2022년 1학기|경영348|HCA02348|기업법1|3|A0|전공1단계|2021년 2학기|경영349|HCA02349|기업법2|3|A0|전공1단계|2021년 2학기|경과138|HBX01138|기업재무론|3|A0|전공1단계|2020년 2학기|경과106|HBX01106|마케팅원론|3|A+|전공1단계|2020년 1학기|경과143|HBX01143|운영관리|3|A+|전공1단계|2022년 1학기|경영251|HCA02251|원가회계|3|A0|전공1단계|2020년 2학기|경과113|HBX01113|인적자원관리|3|B0|전공1단계|2020년 1학기|경과105|HBX01105|재무관리원론|3|A0|전공1단계|2020년 1학기|경과133|HBX01133|재무회계|3|A+|전공1단계|2020년 2학기|경영354|HCA02354|중급회계|3|A+|전공1단계|2022년 1학기|경영375|HCA02375|중급회계2|3|A0|전공1단계|2022년 1학기|경영451|HCA02451|회계감사|3|A+|전공1단계|2019년 2학기|경과104|HBX01104|회계원리|3|A+|2022년 2학기|기사167|KMD02167|MJ사회봉사|3|2022년 2학기|경과127|HBX01127|국제경영학|3|2022년 2학기|경상202|HBW01202|국제금융론|3|2022년 2학기|균사172|KMM02172|기업가정신과창업(KCU)|3|2022년 2학기|교필108|KMA02108|영어회화1|1|2022년 2학기|경영253|HCA02253|재무분석|3|"; //when ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "subMajor", "associatedMajor", - "studentCategory") - .contains("이아현", "60191000", "경영학과", null, null, StudentCategory.NORMAL); + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "subMajor", + "associatedMajor", + "studentCategory" + ).contains("이아현", "60191000", "경영학과", null, null, StudentCategory.NORMAL); } @DisplayName("복수전공을 할 경우 StudentCategory는 DUAL MAJOR이다.") @Test void 복수전공생_확인() { //given - String parsingText = "출력일자 : 2022/11/14|1/1" - + "|사회과학대학 정치외교학과, 복수전공 - 경제학과, 이인구(60161000), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2015/03/02)" - + "|토익 - 690, 영어교과목면제 - 면제없음, 최종학적변동 - 일반복학(2021/01/06)" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" - + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 15, 핵심교양 12, 학문기초교양 9, 일반교양 14, 전공 33, 복수전공 27, 연계전공 9, 부전공 0, 교직 0, 자유선택 3" - + "|총 취득학점 - 122, 총점 - 414, 평균평점 - 3.51" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2016년 2학기|교필105|KMA02105|발표와토의|3|A0|공통교양 (구 필수교양)|2015년 1학기|교필100|KMA02100|성경개론|2|A+|공통교양 (구 필수교양)|2015년 1학기|교필123|KMA02123|영어3|2|A0|공통교양 (구 필수교양)|2019년 1학기|교필124|KMA02124|영어4|2|A+|공통교양 (구 필수교양)|2015년 1학기|교필125|KMA02125|영어회화3|1|A+|공통교양 (구 필수교양)|2016년 2학기|교필126|KMA02126|영어회화4|1|B+|공통교양 (구 필수교양)|2019년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2019년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2016년 2학기|교필102|KMA02102|현대사회와기독교윤리|2|A0|핵심교양 (구 선택교양)|2016년 2학기|교선114|KMA02114|민주주의와현대사회|3|A+|핵심교양 (구 선택교양)|2021년 2학기|교선132|KMA02132|예술과창조성|3|D+|핵심교양 (구 선택교양)|2021년 1학기|교선127|KMA02127|창업입문|3|C+|핵심교양 (구 선택교양)|2019년 1학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양 (구 기초교양)|2016년 2학기|기사123|KMD02123|경제학원론|3|B+|학문기초교양 (구 기초교양)|2016년 2학기|기사111|KMD02111|동북아정세론|3|A+|학문기초교양 (구 기초교양)|2019년 2학기|기사116|KMD02116|청소년지도학|3|A0|일반교양 (구 균형교양)|2015년 1학기|균여219|KMO02119|교양바둑|2|A0|일반교양 (구 균형교양)|2022년 1학기|균여115|KMO02115|교양축구|2|B+|6|일반교양 (구 균형교양)|2016년 2학기|균기113|KMJ02113|기독교와상담|2|A+|일반교양 (구 균형교양)|2022년 1학기|기사114|KMD02114|미시경제학원론|3|A0|4|일반교양 (구 균형교양)|2015년 1학기|기사110|KMD02110|시민사회와행정|3|C+|일반교양 (구 균형교양)|2015년 1학기|균사133|KMM02133|진로선택과대학생활|2|P|전공1단계|2019년 2학기|정외212|HBB01212|국제정치론|3|A+|전공1단계|2022년 1학기|정외100|HBB01100|글로벌위기시대의한국과세계정치|3|B0|1|전공1단계|2021년 1학기|정외333|HBB01333|미국정치론|3|B+|전공1단계|2021년 2학기|정외242|HBB01242|비교정치론|3|B0|전공1단계|2019년 1학기|정외224|HBB01224|여론과정치참여|3|B+|전공1단계|2019년 1학기|정외257|HBB01257|여성정치론|3|B+|전공1단계|2019년 1학기|정외351|HBB01351|유럽연합정치학입문|3|B+|전공1단계|2015년 1학기|정외101|HBB01101|정치학개론|3|A0|전공1단계|2021년 2학기|정외256|HBB01256|정치학인턴쉽|3|A0|전공1단계|2019년 1학기|정외272|HBB01272|한반도와세계정치|3|A0|전공1단계|2019년 2학기|정외315|HBB01315|현대정치사상|3|B+|복수전공|2022년 1학기|경제104|HBE01493|Stata를이용한경제데이터분석론|3|B+|3|복수전공|2019년 2학기|경제204|HBE01204|경제수학|3|B+|복수전공|2019년 2학기|경제103|HBE01103|국민경제론|3|B+|복수전공|2021년 1학기|경제437|HBE01437|금융상품론|3|B+|복수전공|2021년 2학기|경제439|HBE01439|금융혁신과경제|3|B0|복수전공|2022년 1학기|경제413|HBE01413|기업금융론|3|B0|2|복수전공|2021년 1학기|경제327|HBE01327|벤처기업론|3|D+|복수전공|2021년 1학기|경제102|HBE01102|시장및기업이론|3|C+|복수전공|2021년 2학기|경제240|HBE01240|창업과혁신|3|C0|연계전공|2022년 1학기|혁신103|HGA01103|사회문제Prototype개발|3|A0|5|연계전공|2021년 1학기|혁신104|HGA01104|사회문제융합과제의실천|3|B+|연계전공|2021년 2학기|혁신102|HGA01102|사회문제의발견과융합|3|B+|자유선택|2018년 동계계절|균컴113|KMQ01113|SNS로톡하고빅데이터로놀아보자(KCU)|3|B+|2022년 1학기|경제104|HBE01493|Stata를이용한경제데이터분석론|3|3|2022년 1학기|균여115|KMO02115|교양축구|2|6|2022년 1학기|정외100|HBB01100|글로벌위기시대의한국과세계정치|3|1|2022년 1학기|경제413|HBE01413|기업금융론|3|2|2022년 1학기|기사114|KMD02114|미시경제학원론|3|4|2022년 1학기|혁신103|HGA01103|사회문제Prototype개발|3|5|일반교양 (구 균형교양)|2015년 1학기|균명102|KMR02102|성공학특강|2|N|"; + String parsingText = "출력일자 : 2022/11/14|1/1" + "|사회과학대학 정치외교학과, 복수전공 - 경제학과, 이인구(60161000), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2015/03/02)" + "|토익 - 690, 영어교과목면제 - 면제없음, 최종학적변동 - 일반복학(2021/01/06)" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 15, 핵심교양 12, 학문기초교양 9, 일반교양 14, 전공 33, 복수전공 27, 연계전공 9, 부전공 0, 교직 0, 자유선택 3" + "|총 취득학점 - 122, 총점 - 414, 평균평점 - 3.51" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2016년 2학기|교필105|KMA02105|발표와토의|3|A0|공통교양 (구 필수교양)|2015년 1학기|교필100|KMA02100|성경개론|2|A+|공통교양 (구 필수교양)|2015년 1학기|교필123|KMA02123|영어3|2|A0|공통교양 (구 필수교양)|2019년 1학기|교필124|KMA02124|영어4|2|A+|공통교양 (구 필수교양)|2015년 1학기|교필125|KMA02125|영어회화3|1|A+|공통교양 (구 필수교양)|2016년 2학기|교필126|KMA02126|영어회화4|1|B+|공통교양 (구 필수교양)|2019년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2019년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 1학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2021년 2학기|교필101|KMA02101|채플|0.5|P|공통교양 (구 필수교양)|2016년 2학기|교필102|KMA02102|현대사회와기독교윤리|2|A0|핵심교양 (구 선택교양)|2016년 2학기|교선114|KMA02114|민주주의와현대사회|3|A+|핵심교양 (구 선택교양)|2021년 2학기|교선132|KMA02132|예술과창조성|3|D+|핵심교양 (구 선택교양)|2021년 1학기|교선127|KMA02127|창업입문|3|C+|핵심교양 (구 선택교양)|2019년 1학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양 (구 기초교양)|2016년 2학기|기사123|KMD02123|경제학원론|3|B+|학문기초교양 (구 기초교양)|2016년 2학기|기사111|KMD02111|동북아정세론|3|A+|학문기초교양 (구 기초교양)|2019년 2학기|기사116|KMD02116|청소년지도학|3|A0|일반교양 (구 균형교양)|2015년 1학기|균여219|KMO02119|교양바둑|2|A0|일반교양 (구 균형교양)|2022년 1학기|균여115|KMO02115|교양축구|2|B+|6|일반교양 (구 균형교양)|2016년 2학기|균기113|KMJ02113|기독교와상담|2|A+|일반교양 (구 균형교양)|2022년 1학기|기사114|KMD02114|미시경제학원론|3|A0|4|일반교양 (구 균형교양)|2015년 1학기|기사110|KMD02110|시민사회와행정|3|C+|일반교양 (구 균형교양)|2015년 1학기|균사133|KMM02133|진로선택과대학생활|2|P|전공1단계|2019년 2학기|정외212|HBB01212|국제정치론|3|A+|전공1단계|2022년 1학기|정외100|HBB01100|글로벌위기시대의한국과세계정치|3|B0|1|전공1단계|2021년 1학기|정외333|HBB01333|미국정치론|3|B+|전공1단계|2021년 2학기|정외242|HBB01242|비교정치론|3|B0|전공1단계|2019년 1학기|정외224|HBB01224|여론과정치참여|3|B+|전공1단계|2019년 1학기|정외257|HBB01257|여성정치론|3|B+|전공1단계|2019년 1학기|정외351|HBB01351|유럽연합정치학입문|3|B+|전공1단계|2015년 1학기|정외101|HBB01101|정치학개론|3|A0|전공1단계|2021년 2학기|정외256|HBB01256|정치학인턴쉽|3|A0|전공1단계|2019년 1학기|정외272|HBB01272|한반도와세계정치|3|A0|전공1단계|2019년 2학기|정외315|HBB01315|현대정치사상|3|B+|복수전공|2022년 1학기|경제104|HBE01493|Stata를이용한경제데이터분석론|3|B+|3|복수전공|2019년 2학기|경제204|HBE01204|경제수학|3|B+|복수전공|2019년 2학기|경제103|HBE01103|국민경제론|3|B+|복수전공|2021년 1학기|경제437|HBE01437|금융상품론|3|B+|복수전공|2021년 2학기|경제439|HBE01439|금융혁신과경제|3|B0|복수전공|2022년 1학기|경제413|HBE01413|기업금융론|3|B0|2|복수전공|2021년 1학기|경제327|HBE01327|벤처기업론|3|D+|복수전공|2021년 1학기|경제102|HBE01102|시장및기업이론|3|C+|복수전공|2021년 2학기|경제240|HBE01240|창업과혁신|3|C0|연계전공|2022년 1학기|혁신103|HGA01103|사회문제Prototype개발|3|A0|5|연계전공|2021년 1학기|혁신104|HGA01104|사회문제융합과제의실천|3|B+|연계전공|2021년 2학기|혁신102|HGA01102|사회문제의발견과융합|3|B+|자유선택|2018년 동계계절|균컴113|KMQ01113|SNS로톡하고빅데이터로놀아보자(KCU)|3|B+|2022년 1학기|경제104|HBE01493|Stata를이용한경제데이터분석론|3|3|2022년 1학기|균여115|KMO02115|교양축구|2|6|2022년 1학기|정외100|HBB01100|글로벌위기시대의한국과세계정치|3|1|2022년 1학기|경제413|HBE01413|기업금융론|3|2|2022년 1학기|기사114|KMD02114|미시경제학원론|3|4|2022년 1학기|혁신103|HGA01103|사회문제Prototype개발|3|5|일반교양 (구 균형교양)|2015년 1학기|균명102|KMR02102|성공학특강|2|N|"; //when ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "dualMajor", "associatedMajor", - "studentCategory") - .contains("이인구", "60161000", "정치외교학과", "경제학과", null, StudentCategory.DUAL_MAJOR); + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "dualMajor", + "associatedMajor", + "studentCategory" + ).contains("이인구", "60161000", "정치외교학과", "경제학과", null, StudentCategory.DUAL_MAJOR); } @DisplayName("전과을 할 경우 StudentCategory는 CHANGE_MAJOR이다.") @Test void 전과생_확인() { //given - String parsingText = "출력일자 : 2023/12/08|1/1" - + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 나경호(60202455), 현학적 - 재학, 이수 - 3, 입학 - 신입학(2020/03/02)" - + "|토익 - 715, 영어교과목면제 - 면제없음, 최종학적변동 - 2/1전과(2023/01/27), 전과내역 - 기계공학과" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 16.5, 핵심교양 6, 학문기초교양 6, 일반교양 12, 전공 9, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 7" - + "|총 취득학점 - 56.5, 총점 - 230.5, 평균평점 - 4.43" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2020년 2학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P|공통교양|2020년 2학기|교필122|KMA02122|기독교와문화|2|A+|공통교양|2023년 1학기|교필105|KMA02105|발표와토의|3|A0|공통교양|2020년 1학기|교필127|KMA00101|성서와인간이해|2|A+|공통교양|2020년 1학기|교필123|KMA02123|영어3|2|A+|공통교양|2020년 2학기|교필124|KMA02124|영어4|2|A+|공통교양|2020년 1학기|교필125|KMA02125|영어회화3|1|A0|공통교양|2020년 2학기|교필126|KMA02126|영어회화4|1|A+|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2023년 1학기|교선128|KMA02128|글로벌문화|3|A0|핵심교양|2023년 1학기|교선114|KMA02114|민주주의와현대사회|3|A+|학문기초교양|2020년 1학기|기자111|KME02111|물리학1|3|A+|학문기초교양|2020년 1학기|기자101|KME02101|미적분학1|3|A+|일반교양|2020년 2학기|기자112|KME02112|물리학2|3|A+|일반교양|2020년 1학기|기자113|KME02113|물리학실험1|1|A+|일반교양|2020년 2학기|기자114|KME02114|물리학실험2|1|A+|일반교양|2020년 2학기|기자102|KME02102|미적분학2|3|A+|일반교양|2020년 1학기|기자121|KME02121|일반화학|3|A+|일반교양|2020년 1학기|기자122|KME02122|일반화학실험|1|A+|전공1단계|2023년 1학기|데테202|HED01202|R통계분석|3|A+|전공1단계|2023년 1학기|융소102|HEB01102|기초프로그래밍|3|A+|전공1단계|2023년 1학기|데테201|HED01201|자료구조|3|A+|자유선택|2020년 2학기|공과100|JEA00100|공학입문설계|3|A+|자유선택|2020년 1학기|기계207|JEP01207|기계신입생세미나|1|P|자유선택|2020년 2학기|기계209|JEP02209|정역학|3|A+|"; + String parsingText = "출력일자 : 2023/12/08|1/1" + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 나경호(60202455), 현학적 - 재학, 이수 - 3, 입학 - 신입학(2020/03/02)" + "|토익 - 715, 영어교과목면제 - 면제없음, 최종학적변동 - 2/1전과(2023/01/27), 전과내역 - 기계공학과" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 16.5, 핵심교양 6, 학문기초교양 6, 일반교양 12, 전공 9, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 7" + "|총 취득학점 - 56.5, 총점 - 230.5, 평균평점 - 4.43" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2020년 2학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P|공통교양|2020년 2학기|교필122|KMA02122|기독교와문화|2|A+|공통교양|2023년 1학기|교필105|KMA02105|발표와토의|3|A0|공통교양|2020년 1학기|교필127|KMA00101|성서와인간이해|2|A+|공통교양|2020년 1학기|교필123|KMA02123|영어3|2|A+|공통교양|2020년 2학기|교필124|KMA02124|영어4|2|A+|공통교양|2020년 1학기|교필125|KMA02125|영어회화3|1|A0|공통교양|2020년 2학기|교필126|KMA02126|영어회화4|1|A+|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2023년 1학기|교선128|KMA02128|글로벌문화|3|A0|핵심교양|2023년 1학기|교선114|KMA02114|민주주의와현대사회|3|A+|학문기초교양|2020년 1학기|기자111|KME02111|물리학1|3|A+|학문기초교양|2020년 1학기|기자101|KME02101|미적분학1|3|A+|일반교양|2020년 2학기|기자112|KME02112|물리학2|3|A+|일반교양|2020년 1학기|기자113|KME02113|물리학실험1|1|A+|일반교양|2020년 2학기|기자114|KME02114|물리학실험2|1|A+|일반교양|2020년 2학기|기자102|KME02102|미적분학2|3|A+|일반교양|2020년 1학기|기자121|KME02121|일반화학|3|A+|일반교양|2020년 1학기|기자122|KME02122|일반화학실험|1|A+|전공1단계|2023년 1학기|데테202|HED01202|R통계분석|3|A+|전공1단계|2023년 1학기|융소102|HEB01102|기초프로그래밍|3|A+|전공1단계|2023년 1학기|데테201|HED01201|자료구조|3|A+|자유선택|2020년 2학기|공과100|JEA00100|공학입문설계|3|A+|자유선택|2020년 1학기|기계207|JEP01207|기계신입생세미나|1|P|자유선택|2020년 2학기|기계209|JEP02209|정역학|3|A+|"; //when ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "subMajor", "associatedMajor", - "studentCategory") - .contains("나경호", "60202455", "데이터테크놀로지전공", null, null, StudentCategory.CHANGE_MAJOR); + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "subMajor", + "associatedMajor", + "studentCategory" + ).contains("나경호", "60202455", "데이터테크놀로지전공", null, null, StudentCategory.CHANGE_MAJOR); } @DisplayName("전과을 할 경우 StudentCategory는 CHANGE_MAJOR이다.") @Test void 부전공생_확인() { //given - String parsingText = "출력일자 : 2023/09/01|1/1" - + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 부전공 - 응용소프트웨어전공, 정지환(60181666), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2018/03/02)" - + "|토익 - 570, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2022/07/15)" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" - + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 17, 핵심교양 12, 학문기초교양 18, 일반교양 5, 전공 63, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 3" - + "|총 취득학점 - 118, 총점 - 436, 평균평점 - 3.82" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양|2022년 동계계절|교필104|KMA02104|글쓰기|3|C0|공통교양|2020년 1학기|교필122|KMA02122|기독교와문화|2|B0|공통교양|2019년 2학기|교필127|KMA00101|성서와인간이해|2|B+|공통교양|2019년 하계계절|교필106|KMA02106|영어1|2|B+|2|공통교양|2019년 2학기|교필107|KMA02107|영어2|2|B+|공통교양|2022년 동계계절|교필108|KMA02108|영어회화1|1|B+|3|공통교양|2023년 1학기|교필109|KMA02109|영어회화2|1|A0|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2022년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2022년 2학기|교선130|KMA02130|고전으로읽는인문학|3|A0|핵심교양|2019년 2학기|교선113|KMA02113|세계화와사회변화|3|B+|핵심교양|2018년 1학기|교선135|KMA02135|우주,생명,마음|3|C+|핵심교양|2020년 2학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양|2019년 1학기|기사133|KMD02133|ICT비즈니스와경영|3|B+|학문기초교양|2022년 2학기|기사123|KMD02123|경제학원론|3|A+|학문기초교양|2022년 2학기|기사103|KMD02103|대중문화와매스컴|3|A0|학문기초교양|2019년 1학기|기자107|KME02107|선형대수학개론|3|B0|6|학문기초교양|2019년 하계계절|기인107|KMB02107|인간심리의이해|3|B+|5|학문기초교양|2020년 2학기|기자106|KME02106|통계학개론|3|A+|일반교양|2022년 2학기|균여111|KMO02111|교양볼링|2|B+|일반교양|2020년 1학기|기컴118|KMI02118|엑셀기초및실무활용|3|B+|4|전공1단계|2019년 1학기|데테202|HED01202|R통계분석|3|A0|전공1단계|2022년 2학기|데테314|HED01314|게임프로그래밍|3|A+|전공1단계|2020년 1학기|데테316|HED01316|고급웹프로그래밍|3|A0|전공1단계|2019년 2학기|데테206|HED01206|기초웹프로그래밍|3|B+|전공1단계|2019년 1학기|융소102|HEB01102|기초프로그래밍|3|B+|1|전공1단계|2019년 2학기|융소105|HEB01105|기초프로그래밍2|3|C+|전공1단계|2019년 2학기|데테318|HED01203|데이터베이스|3|A0|전공1단계|2023년 1학기|데테317|HED01317|데이터베이스프로젝트|3|A+|전공1단계|2023년 1학기|데테407|HED01407|딥러닝|3|B+|전공1단계|2023년 1학기|데테319|HED01318|모바일컴퓨팅|3|A+|전공1단계|2020년 2학기|데테403|HED01403|블록체인기초|3|A+|전공1단계|2023년 1학기|데테404|HED01404|빅데이터기술특론1|3|B0|전공1단계|2022년 2학기|데테306|HED01306|빅데이터프로그래밍|3|A0|전공1단계|2020년 1학기|데테301|HED01301|소프트웨어공학|3|A+|전공1단계|2020년 2학기|데테209|HED01307|알고리즘|3|A+|전공1단계|2020년 2학기|데테303|HED01303|운영체제|3|A+|전공1단계|2020년 1학기|데테315|HED01315|인공지능|3|B+|전공1단계|2019년 1학기|데테201|HED01201|자료구조|3|A0|전공1단계|2023년 1학기|데테413|HED01413|캡스톤디자인|3|A+|전공1단계|2020년 1학기|데테309|HED01309|컴퓨터아키텍쳐|3|A0|전공1단계|2020년 2학기|데테313|HED01313|컴퓨터통신|3|A+|자유선택|2023년 1학기|교선136|KMA02136|SW프로그래밍입문|3|A+|공통교양|2019년 2학기|교필101|KMA02101|채플|0.5|N|공통교양|2018년 1학기|교필106|KMA02106|영어1|0|R|2|공통교양|2018년 1학기|교필108|KMA02108|영어회화1|0|R|3|공통교양|2020년 1학기|교필108|KMA02108|영어회화1|0|R|3|학문기초교양|2018년 1학기|기자107|KME02107|선형대수학개론|0|R|6|학문기초교양|2018년 1학기|기인107|KMB02107|인간심리의이해|0|R|5|일반교양|2018년 1학기|기컴118|KMI02118|엑셀기초및실무활용|0|R|4|전공1단계|2018년 1학기|융소102|HEB01102|기초프로그래밍|0|R|1|"; + String parsingText = "출력일자 : 2023/09/01|1/1" + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 부전공 - 응용소프트웨어전공, 정지환(60181666), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2018/03/02)" + "|토익 - 570, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2022/07/15)" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 17, 핵심교양 12, 학문기초교양 18, 일반교양 5, 전공 63, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 3" + "|총 취득학점 - 118, 총점 - 436, 평균평점 - 3.82" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양|2022년 동계계절|교필104|KMA02104|글쓰기|3|C0|공통교양|2020년 1학기|교필122|KMA02122|기독교와문화|2|B0|공통교양|2019년 2학기|교필127|KMA00101|성서와인간이해|2|B+|공통교양|2019년 하계계절|교필106|KMA02106|영어1|2|B+|2|공통교양|2019년 2학기|교필107|KMA02107|영어2|2|B+|공통교양|2022년 동계계절|교필108|KMA02108|영어회화1|1|B+|3|공통교양|2023년 1학기|교필109|KMA02109|영어회화2|1|A0|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2022년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2022년 2학기|교선130|KMA02130|고전으로읽는인문학|3|A0|핵심교양|2019년 2학기|교선113|KMA02113|세계화와사회변화|3|B+|핵심교양|2018년 1학기|교선135|KMA02135|우주,생명,마음|3|C+|핵심교양|2020년 2학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양|2019년 1학기|기사133|KMD02133|ICT비즈니스와경영|3|B+|학문기초교양|2022년 2학기|기사123|KMD02123|경제학원론|3|A+|학문기초교양|2022년 2학기|기사103|KMD02103|대중문화와매스컴|3|A0|학문기초교양|2019년 1학기|기자107|KME02107|선형대수학개론|3|B0|6|학문기초교양|2019년 하계계절|기인107|KMB02107|인간심리의이해|3|B+|5|학문기초교양|2020년 2학기|기자106|KME02106|통계학개론|3|A+|일반교양|2022년 2학기|균여111|KMO02111|교양볼링|2|B+|일반교양|2020년 1학기|기컴118|KMI02118|엑셀기초및실무활용|3|B+|4|전공1단계|2019년 1학기|데테202|HED01202|R통계분석|3|A0|전공1단계|2022년 2학기|데테314|HED01314|게임프로그래밍|3|A+|전공1단계|2020년 1학기|데테316|HED01316|고급웹프로그래밍|3|A0|전공1단계|2019년 2학기|데테206|HED01206|기초웹프로그래밍|3|B+|전공1단계|2019년 1학기|융소102|HEB01102|기초프로그래밍|3|B+|1|전공1단계|2019년 2학기|융소105|HEB01105|기초프로그래밍2|3|C+|전공1단계|2019년 2학기|데테318|HED01203|데이터베이스|3|A0|전공1단계|2023년 1학기|데테317|HED01317|데이터베이스프로젝트|3|A+|전공1단계|2023년 1학기|데테407|HED01407|딥러닝|3|B+|전공1단계|2023년 1학기|데테319|HED01318|모바일컴퓨팅|3|A+|전공1단계|2020년 2학기|데테403|HED01403|블록체인기초|3|A+|전공1단계|2023년 1학기|데테404|HED01404|빅데이터기술특론1|3|B0|전공1단계|2022년 2학기|데테306|HED01306|빅데이터프로그래밍|3|A0|전공1단계|2020년 1학기|데테301|HED01301|소프트웨어공학|3|A+|전공1단계|2020년 2학기|데테209|HED01307|알고리즘|3|A+|전공1단계|2020년 2학기|데테303|HED01303|운영체제|3|A+|전공1단계|2020년 1학기|데테315|HED01315|인공지능|3|B+|전공1단계|2019년 1학기|데테201|HED01201|자료구조|3|A0|전공1단계|2023년 1학기|데테413|HED01413|캡스톤디자인|3|A+|전공1단계|2020년 1학기|데테309|HED01309|컴퓨터아키텍쳐|3|A0|전공1단계|2020년 2학기|데테313|HED01313|컴퓨터통신|3|A+|자유선택|2023년 1학기|교선136|KMA02136|SW프로그래밍입문|3|A+|공통교양|2019년 2학기|교필101|KMA02101|채플|0.5|N|공통교양|2018년 1학기|교필106|KMA02106|영어1|0|R|2|공통교양|2018년 1학기|교필108|KMA02108|영어회화1|0|R|3|공통교양|2020년 1학기|교필108|KMA02108|영어회화1|0|R|3|학문기초교양|2018년 1학기|기자107|KME02107|선형대수학개론|0|R|6|학문기초교양|2018년 1학기|기인107|KMB02107|인간심리의이해|0|R|5|일반교양|2018년 1학기|기컴118|KMI02118|엑셀기초및실무활용|0|R|4|전공1단계|2018년 1학기|융소102|HEB01102|기초프로그래밍|0|R|1|"; //when ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "subMajor", "associatedMajor", - "studentCategory") - .contains("정지환", "60181666", "데이터테크놀로지전공", null, "응용소프트웨어전공", - StudentCategory.SUB_MAJOR); + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "subMajor", + "associatedMajor", + "studentCategory" + ).contains("정지환", "60181666", "데이터테크놀로지전공", null, "응용소프트웨어전공", StudentCategory.SUB_MAJOR); } @DisplayName("재수강, F학점, Non pass인 경우 수강 정보를 추출하지 않는다.") @Test void RFN인경우_수강정보제외() { //given - String parsingText = "출력일자 : 2023/09/01|1/1" - + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 정지환(60181666), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2018/03/02)" - + "|토익 - 570, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2022/07/15)" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" - + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 17, 핵심교양 12, 학문기초교양 18, 일반교양 5, 전공 63, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 3" - + "|총 취득학점 - 118, 총점 - 436, 평균평점 - 3.82" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양|2022년 동계계절|교필104|KMA02104|글쓰기|3|C0|공통교양|2020년 1학기|교필122|KMA02122|기독교와문화|2|B0|공통교양|2019년 2학기|교필127|KMA00101|성서와인간이해|2|B+|공통교양|2019년 하계계절|교필106|KMA02106|영어1|2|B+|2|공통교양|2019년 2학기|교필107|KMA02107|영어2|2|B+|공통교양|2022년 동계계절|교필108|KMA02108|영어회화1|1|B+|3|공통교양|2023년 1학기|교필109|KMA02109|영어회화2|1|A0|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2022년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2022년 2학기|교선130|KMA02130|고전으로읽는인문학|3|A0|핵심교양|2019년 2학기|교선113|KMA02113|세계화와사회변화|3|B+|핵심교양|2018년 1학기|교선135|KMA02135|우주,생명,마음|3|C+|핵심교양|2020년 2학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양|2019년 1학기|기사133|KMD02133|ICT비즈니스와경영|3|B+|학문기초교양|2022년 2학기|기사123|KMD02123|경제학원론|3|A+|학문기초교양|2022년 2학기|기사103|KMD02103|대중문화와매스컴|3|A0|학문기초교양|2019년 1학기|기자107|KME02107|선형대수학개론|3|B0|6|학문기초교양|2019년 하계계절|기인107|KMB02107|인간심리의이해|3|B+|5|학문기초교양|2020년 2학기|기자106|KME02106|통계학개론|3|A+|일반교양|2022년 2학기|균여111|KMO02111|교양볼링|2|B+|일반교양|2020년 1학기|기컴118|KMI02118|엑셀기초및실무활용|3|B+|4|전공1단계|2019년 1학기|데테202|HED01202|R통계분석|3|A0|전공1단계|2022년 2학기|데테314|HED01314|게임프로그래밍|3|A+|전공1단계|2020년 1학기|데테316|HED01316|고급웹프로그래밍|3|A0|전공1단계|2019년 2학기|데테206|HED01206|기초웹프로그래밍|3|B+|전공1단계|2019년 1학기|융소102|HEB01102|기초프로그래밍|3|B+|1|전공1단계|2019년 2학기|융소105|HEB01105|기초프로그래밍2|3|C+|전공1단계|2019년 2학기|데테318|HED01203|데이터베이스|3|A0|전공1단계|2023년 1학기|데테317|HED01317|데이터베이스프로젝트|3|A+|전공1단계|2023년 1학기|데테407|HED01407|딥러닝|3|B+|전공1단계|2023년 1학기|데테319|HED01318|모바일컴퓨팅|3|A+|전공1단계|2020년 2학기|데테403|HED01403|블록체인기초|3|A+|전공1단계|2023년 1학기|데테404|HED01404|빅데이터기술특론1|3|B0|전공1단계|2022년 2학기|데테306|HED01306|빅데이터프로그래밍|3|A0|전공1단계|2020년 1학기|데테301|HED01301|소프트웨어공학|3|A+|전공1단계|2020년 2학기|데테209|HED01307|알고리즘|3|A+|전공1단계|2020년 2학기|데테303|HED01303|운영체제|3|A+|전공1단계|2020년 1학기|데테315|HED01315|인공지능|3|B+|전공1단계|2019년 1학기|데테201|HED01201|자료구조|3|A0|전공1단계|2023년 1학기|데테413|HED01413|캡스톤디자인|3|A+|전공1단계|2020년 1학기|데테309|HED01309|컴퓨터아키텍쳐|3|A0|전공1단계|2020년 2학기|데테313|HED01313|컴퓨터통신|3|A+|자유선택|2023년 1학기|교선136|KMA02136|SW프로그래밍입문|3|A+|공통교양|2019년 2학기|교필101|KMA02101|채플|0.5|N|공통교양|2018년 1학기|교필106|KMA02106|영어1|0|R|2|공통교양|2018년 1학기|교필108|KMA02108|영어회화1|0|R|3|공통교양|2020년 1학기|교필108|KMA02108|영어회화1|0|R|3|학문기초교양|2018년 1학기|기자107|KME02107|선형대수학개론|0|R|6|학문기초교양|2018년 1학기|기인107|KMB02107|인간심리의이해|0|R|5|일반교양|2018년 1학기|기컴118|KMI02118|엑셀기초및실무활용|0|R|4|전공1단계|2018년 1학기|융소102|HEB01102|기초프로그래밍|0|R|1|"; + String parsingText = "출력일자 : 2023/09/01|1/1" + "|ICT융합대학 융합소프트웨어학부 데이터테크놀로지전공, 정지환(60181666), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2018/03/02)" + "|토익 - 570, 영어교과목면제 - 면제없음, 최종학적변동 - 불일치복학(2022/07/15)" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 17, 핵심교양 12, 학문기초교양 18, 일반교양 5, 전공 63, 복수전공 0, 연계전공 0, 부전공 0, 교직 0, 자유선택 3" + "|총 취득학점 - 118, 총점 - 436, 평균평점 - 3.82" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양|2019년 2학기|교필137|KMA02137|4차산업혁명시대의진로선택|2|P|공통교양|2022년 동계계절|교필104|KMA02104|글쓰기|3|C0|공통교양|2020년 1학기|교필122|KMA02122|기독교와문화|2|B0|공통교양|2019년 2학기|교필127|KMA00101|성서와인간이해|2|B+|공통교양|2019년 하계계절|교필106|KMA02106|영어1|2|B+|2|공통교양|2019년 2학기|교필107|KMA02107|영어2|2|B+|공통교양|2022년 동계계절|교필108|KMA02108|영어회화1|1|B+|3|공통교양|2023년 1학기|교필109|KMA02109|영어회화2|1|A0|공통교양|2020년 1학기|교필101|KMA02101|채플|0.5|P|공통교양|2020년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2022년 2학기|교필101|KMA02101|채플|0.5|P|공통교양|2023년 1학기|교필101|KMA02101|채플|0.5|P|핵심교양|2022년 2학기|교선130|KMA02130|고전으로읽는인문학|3|A0|핵심교양|2019년 2학기|교선113|KMA02113|세계화와사회변화|3|B+|핵심교양|2018년 1학기|교선135|KMA02135|우주,생명,마음|3|C+|핵심교양|2020년 2학기|교선111|KMA02111|한국근현대사의이해|3|A+|학문기초교양|2019년 1학기|기사133|KMD02133|ICT비즈니스와경영|3|B+|학문기초교양|2022년 2학기|기사123|KMD02123|경제학원론|3|A+|학문기초교양|2022년 2학기|기사103|KMD02103|대중문화와매스컴|3|A0|학문기초교양|2019년 1학기|기자107|KME02107|선형대수학개론|3|B0|6|학문기초교양|2019년 하계계절|기인107|KMB02107|인간심리의이해|3|B+|5|학문기초교양|2020년 2학기|기자106|KME02106|통계학개론|3|A+|일반교양|2022년 2학기|균여111|KMO02111|교양볼링|2|B+|일반교양|2020년 1학기|기컴118|KMI02118|엑셀기초및실무활용|3|B+|4|전공1단계|2019년 1학기|데테202|HED01202|R통계분석|3|A0|전공1단계|2022년 2학기|데테314|HED01314|게임프로그래밍|3|A+|전공1단계|2020년 1학기|데테316|HED01316|고급웹프로그래밍|3|A0|전공1단계|2019년 2학기|데테206|HED01206|기초웹프로그래밍|3|B+|전공1단계|2019년 1학기|융소102|HEB01102|기초프로그래밍|3|B+|1|전공1단계|2019년 2학기|융소105|HEB01105|기초프로그래밍2|3|C+|전공1단계|2019년 2학기|데테318|HED01203|데이터베이스|3|A0|전공1단계|2023년 1학기|데테317|HED01317|데이터베이스프로젝트|3|A+|전공1단계|2023년 1학기|데테407|HED01407|딥러닝|3|B+|전공1단계|2023년 1학기|데테319|HED01318|모바일컴퓨팅|3|A+|전공1단계|2020년 2학기|데테403|HED01403|블록체인기초|3|A+|전공1단계|2023년 1학기|데테404|HED01404|빅데이터기술특론1|3|B0|전공1단계|2022년 2학기|데테306|HED01306|빅데이터프로그래밍|3|A0|전공1단계|2020년 1학기|데테301|HED01301|소프트웨어공학|3|A+|전공1단계|2020년 2학기|데테209|HED01307|알고리즘|3|A+|전공1단계|2020년 2학기|데테303|HED01303|운영체제|3|A+|전공1단계|2020년 1학기|데테315|HED01315|인공지능|3|B+|전공1단계|2019년 1학기|데테201|HED01201|자료구조|3|A0|전공1단계|2023년 1학기|데테413|HED01413|캡스톤디자인|3|A+|전공1단계|2020년 1학기|데테309|HED01309|컴퓨터아키텍쳐|3|A0|전공1단계|2020년 2학기|데테313|HED01313|컴퓨터통신|3|A+|자유선택|2023년 1학기|교선136|KMA02136|SW프로그래밍입문|3|A+|공통교양|2019년 2학기|교필101|KMA02101|채플|0.5|N|공통교양|2018년 1학기|교필106|KMA02106|영어1|0|R|2|공통교양|2018년 1학기|교필108|KMA02108|영어회화1|0|R|3|공통교양|2020년 1학기|교필108|KMA02108|영어회화1|0|R|3|학문기초교양|2018년 1학기|기자107|KME02107|선형대수학개론|0|R|6|학문기초교양|2018년 1학기|기인107|KMB02107|인간심리의이해|0|R|5|일반교양|2018년 1학기|기컴118|KMI02118|엑셀기초및실무활용|0|R|4|전공1단계|2018년 1학기|융소102|HEB01102|기초프로그래밍|0|R|1|"; //when ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "subMajor", "associatedMajor", - "studentCategory") - .contains("정지환", "60181666", "데이터테크놀로지전공", null, null, StudentCategory.NORMAL); + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "subMajor", + "associatedMajor", + "studentCategory" + ).contains("정지환", "60181666", "데이터테크놀로지전공", null, null, StudentCategory.NORMAL); assertThat(parsingInformation.getTakenLectureInformation()).hasSize(46); } - @DisplayName("연계전공을 할 경우 StudentCategory는 ASSOCIATED_MAJOR이며, associated_major에 연계전공명이 입력된다.") - @Test - void 연계전공생_확인() { - //given - String parsingText = "출력일자 : 2022/11/14|1/1" - + "|경영대학 경영정보학과, 연계전공 - 프로세스 자동화 경영, 장예지(60191363), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2019/03/04)" - + "|토익 - 410, 영어교과목면제 - 면제없음, 최종학적변동 - 신입학(2019/03/04)" - + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" - + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" - + "|공통교양 17, 핵심교양 12, 학문기초교양 6, 일반교양 18, 전공 48, 복수전공 0, 연계전공 9, 부전공 0, 교직 0, 자유선택 9" - + "|총 취득학점 - 119, 총점 - 436.5, 평균평점 - 3.83" - + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2021년 1학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P" - + "|공통교양 (구 필수교양)|2019년 1학기|교필105|KMA02105|발표와토의|3|B0"; - - //when - ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); - - //then - assertThat(parsingInformation) - .extracting("studentName", "studentNumber", "major", "associatedMajor", - "studentCategory") - .contains("장예지", "60191363", "경영정보학과", "프로세스 자동화 경영", StudentCategory.ASSOCIATED_MAJOR); - } + @DisplayName("연계전공을 할 경우 StudentCategory는 ASSOCIATED_MAJOR이며, associated_major에 연계전공명이 입력된다.") + @Test + void 연계전공생_확인() { + //given + String parsingText = "출력일자 : 2022/11/14|1/1" + "|경영대학 경영정보학과, 연계전공 - 프로세스 자동화 경영, 장예지(60191363), 현학적 - 재학, 이수 - 7, 입학 - 신입학(2019/03/04)" + "|토익 - 410, 영어교과목면제 - 면제없음, 최종학적변동 - 신입학(2019/03/04)" + "|편입생 인정학점 - 교양 0, 전공 0, 자유선택 0, 성경과인간이해 0" + "|교환학생 인정학점 - 학문기초교양 0, 일반교양 0, 전공 0, 복수전공학문기초교양 0, 복수전공 0, 연계전공 0, 부전공 0, 자유선택 0" + "|공통교양 17, 핵심교양 12, 학문기초교양 6, 일반교양 18, 전공 48, 복수전공 0, 연계전공 9, 부전공 0, 교직 0, 자유선택 9" + "|총 취득학점 - 119, 총점 - 436.5, 평균평점 - 3.83" + "|이수구분|수강년도/학기|한글코드|과목코드|과목명|학점|등급|중복|공통교양 (구 필수교양)|2021년 1학기|교필141|KMA02141|4차산업혁명과미래사회진로선택|2|P" + "|공통교양 (구 필수교양)|2019년 1학기|교필105|KMA02105|발표와토의|3|B0"; + + //when + ParsingInformation parsingInformation = ParsingInformation.parsing(parsingText); + + //then + assertThat(parsingInformation).extracting( + "studentName", + "studentNumber", + "major", + "associatedMajor", + "studentCategory" + ) + .contains("장예지", "60191363", "경영정보학과", "프로세스 자동화 경영", StudentCategory.ASSOCIATED_MAJOR); + } } 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 4d78a421..9c2b0b95 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 @@ -109,4 +109,32 @@ private TakenLectureInventory getTakenLectureInventory() { TakenLecture.of(user, mockLectureMap.get("KMA02126"), 2023, Semester.FIRST) ))); } + @DisplayName("크리스천 과목 목록을 반환한다.") + @Test + void getChristianLectures() { + // given + TakenLectureInventory takenLectureInventory = getTakenLectureInventory(); + + // when + Set christianLectures = takenLectureInventory.getChristianLectures(); + + // then + assertThat(christianLectures) + .hasSize(3) // 크리스천 과목 3개 + .extracting("id") + .containsExactlyInAnyOrder("KMA00101", "KMA02102", "KMA02122"); // 예상 ID + } + + @DisplayName("크리스천 과목 학점 합계를 계산한다.") + @Test + void calculateChristianCredits() { + // given + TakenLectureInventory takenLectureInventory = getTakenLectureInventory(); + + // when + double christianCredits = takenLectureInventory.calculateChristianCredits(); + + // then + assertThat(christianCredits).isEqualTo(6.0); // 각 과목 2학점, 총 3개 과목 + } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/UserPersistenceAdapterTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/UserPersistenceAdapterTest.java index b135bc4e..32904579 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/UserPersistenceAdapterTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/UserPersistenceAdapterTest.java @@ -3,6 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import com.plzgraduate.myongjigraduatebe.support.PersistenceTestSupport; +import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import com.plzgraduate.myongjigraduatebe.user.infrastructure.adapter.persistence.entity.UserJpaEntity; import com.plzgraduate.myongjigraduatebe.user.infrastructure.adapter.persistence.repository.UserRepository; @@ -22,7 +24,7 @@ class UserPersistenceAdapterTest extends PersistenceTestSupport { @Test void 사용자_저장() { //given - User user = createUser("mju1001", "1q2w3e4r!", "60181666"); + User user = createUser(); //when userPersistenceAdapter.saveUser(user); //then @@ -34,7 +36,7 @@ class UserPersistenceAdapterTest extends PersistenceTestSupport { void 아아디_사용자_조회() { //given String authId = "mju1001"; - UserJpaEntity userEntity = createUserEntity(authId, "1q2w3e4r!", "60181666"); + UserJpaEntity userEntity = createUserEntity(authId, "60181666"); userRepository.save(userEntity); //when Optional user = userPersistenceAdapter.findUserByAuthId(authId); @@ -50,7 +52,7 @@ class UserPersistenceAdapterTest extends PersistenceTestSupport { void findUserByStudentNumber() { //given String studentNumber = "60181666"; - UserJpaEntity userJpaEntity = createUserEntity("mju1001", "1q2w3e4r!", studentNumber); + UserJpaEntity userJpaEntity = createUserEntity("mju1001", studentNumber); userRepository.save(userJpaEntity); //when @@ -67,7 +69,7 @@ void findUserByStudentNumber() { void 중복_아이디_확인() { //given String authId = "mju1001"; - UserJpaEntity user = createUserEntity(authId, "1q2w3e4r!", "60181666"); + UserJpaEntity user = createUserEntity(authId, "60181666"); userRepository.save(user); //when boolean check = userPersistenceAdapter.checkDuplicateAuthId(authId); @@ -81,7 +83,7 @@ void findUserByStudentNumber() { void 중복_학번_확인() { //given String studentNumber = "60181666"; - UserJpaEntity user = createUserEntity("mju1001", "1q2w3e4r!", studentNumber); + UserJpaEntity user = createUserEntity("mju1001", studentNumber); userRepository.save(user); //when boolean check = userPersistenceAdapter.checkDuplicateStudentNumber(studentNumber); @@ -95,7 +97,7 @@ void findUserByStudentNumber() { void deleteUser() { //given String authId = "mju1000"; - UserJpaEntity userJpaEntity = createUserEntity(authId, "1q2w3e4r!", "60181666"); + UserJpaEntity userJpaEntity = createUserEntity(authId, "60181666"); UserJpaEntity savedUserJpaEntity = userRepository.save(userJpaEntity); User user = User.builder() .id(savedUserJpaEntity.getId()) @@ -109,21 +111,27 @@ void deleteUser() { assertThat(foundUser.isPresent()).isFalse(); } - private User createUser(String authId, String password, String studentNumber) { + private User createUser() { return User - .builder() - .authId(authId) - .password(password) - .studentNumber(studentNumber) - .build(); + .builder() + .authId("mju1001") + .password("1q2w3e4r!") + .studentNumber("60181666") + .transferCredit(new TransferCredit(0, 0, 0, 0)) + .studentCategory(StudentCategory.NORMAL) + .build(); } - private UserJpaEntity createUserEntity(String authId, String password, String studentNumber) { + + private UserJpaEntity createUserEntity(String authId, String studentNumber) { return UserJpaEntity - .builder() - .authId(authId) - .password(password) - .studentNumber(studentNumber) - .build(); + .builder() + .authId(authId) + .password("1q2w3e4r!") + .studentNumber(studentNumber) + .transferCredit("0/0/0/0") + .studentCategory(StudentCategory.NORMAL) + .build(); } + } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapperTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapperTest.java index 5bede63c..102cfb99 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapperTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/infrastructure/adapter/persistence/mapper/UserMapperTest.java @@ -5,6 +5,7 @@ import com.plzgraduate.myongjigraduatebe.support.PersistenceTestSupport; import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; +import com.plzgraduate.myongjigraduatebe.user.domain.model.TransferCredit; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import com.plzgraduate.myongjigraduatebe.user.infrastructure.adapter.persistence.entity.UserJpaEntity; import org.junit.jupiter.api.DisplayName; @@ -33,6 +34,10 @@ void mapToDomainEntityTest() { "graduated") .contains(1L, "mju1000", "mju1000!", EnglishLevel.ENG12, "김명지", "60211111", 21, "경영", null, StudentCategory.NORMAL, 100, 40.0, false); + assertThat(user.getTransferCredit()) + .extracting("normalCulture", "majorLecture", "freeElective", "christianLecture") + .containsExactly(0, 0, 0, 0); + } @DisplayName("도메인 엔티티를 JPA 엔티티 변환한다.") @@ -51,6 +56,8 @@ void mapToJpaEntityTest() { "subMajor", "studentCategory", "totalCredit", "takenCredit", "graduated") .contains(1L, "mju1000", "mju1000!", EnglishLevel.ENG12, "김명지", "60211111", 21, "경영", null, StudentCategory.NORMAL, 100, 40.0, false); + assertThat(userJpaEntity.getTransferCredit()) + .isEqualTo("0/0/0/0"); } private User createUser() { @@ -65,6 +72,7 @@ private User createUser() { .primaryMajor("경영") .dualMajor(null) .subMajor(null) + .transferCredit(TransferCredit.from("0/0/0/0")) .totalCredit(100) .takenCredit(40) .graduated(false) @@ -74,20 +82,22 @@ private User createUser() { private UserJpaEntity createUserJpaEntity() { return UserJpaEntity.builder() - .id(1L) - .authId("mju1000") - .password("mju1000!") - .name("김명지") - .studentNumber("60211111") - .entryYear(21) - .englishLevel(EnglishLevel.ENG12) - .major("경영") - .dualMajor("복수전공") - .totalCredit(100) - .takenCredit(40) - .graduated(false) - .subMajor(null) - .studentCategory(StudentCategory.NORMAL) - .build(); + .id(1L) + .authId("mju1000") + .password("mju1000!") + .name("김명지") + .studentNumber("60211111") + .entryYear(21) + .englishLevel(EnglishLevel.ENG12) + .major("경영") + .dualMajor(null) // 복수전공을 null로 설정 + .subMajor(null) + .associatedMajor(null) + .transferCredit("0/0/0/0") // 기본값 설정 + .studentCategory(StudentCategory.NORMAL) + .totalCredit(100) + .takenCredit(40.0) + .graduated(false) + .build(); } }