-
Notifications
You must be signed in to change notification settings - Fork 1
π Fix: 3μ°¨ μ€νλ¦°νΈ κ°μ μ μ μμ νλ€ #162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f968e47
b308ae4
744a7e8
dc8bdfd
3157af1
39ebf1d
3f7dda6
8ac22dd
dfe294c
cfaf223
eb009a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,7 @@ | |
| import KUSITMS.WITHUS.global.infra.upload.dto.FileResponseDTO; | ||
| import KUSITMS.WITHUS.global.infra.upload.service.FileUploadService; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.jetbrains.annotations.NotNull; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
π€ Prompt for AI Agents |
||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.PageImpl; | ||
| import org.springframework.data.domain.Pageable; | ||
|
|
@@ -254,11 +255,75 @@ public ApplicationResponseDTO.AdminPageWithStageCounts getByRecruitmentIdForAdmi | |
| AdminStageFilter stage, | ||
| Pageable pageable, | ||
| AdminApplicationSortField sortBy, | ||
| Sort.Direction direction | ||
| Sort.Direction direction, | ||
| List<Long> organizationRoleIds, | ||
| List<ApplicationStatus> statuses, | ||
| String keyword | ||
| ) { | ||
| List<Application> allApps = applicationRepository | ||
| .findByRecruitmentIdAndStatusIn(recruitmentId, stage.toStatusList()); | ||
|
|
||
| // POSITION_NAME νν° | ||
| if (organizationRoleIds != null && !organizationRoleIds.isEmpty()) { | ||
| allApps = allApps.stream() | ||
| .filter(app -> | ||
| app.getOrganizationRole() != null && | ||
| organizationRoleIds.contains(app.getOrganizationRole().getId()) | ||
| ) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| // STATUS νν° | ||
| if (statuses != null && !statuses.isEmpty()) { | ||
| allApps = allApps.stream() | ||
| .filter(app -> statuses.contains(app.getStatus())) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| // NAME KEYWORD νν° | ||
| if (keyword != null && !keyword.trim().isEmpty()) { | ||
| String lower = keyword.trim().toLowerCase(Locale.ROOT); | ||
| allApps = allApps.stream() | ||
| .filter(app -> | ||
| app.getName() != null && | ||
| app.getName().toLowerCase().contains(lower) | ||
| ) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| List<Application> sortedApps = getSortedApps(sortBy, direction, allApps); | ||
|
|
||
| List<ApplicationResponseDTO.SummaryForAdmin> allDtos = IntStream.range(0, sortedApps.size()) | ||
| .mapToObj(i -> ApplicationResponseDTO.SummaryForAdmin.from(sortedApps.get(i), i + 1L)) | ||
| .toList(); | ||
|
|
||
| int start = (int) pageable.getOffset(); | ||
| int end = Math.min(start + pageable.getPageSize(), allDtos.size()); | ||
| List<ApplicationResponseDTO.SummaryForAdmin> content = start > end | ||
| ? List.of() | ||
| : allDtos.subList(start, end); | ||
|
|
||
| Page<ApplicationResponseDTO.SummaryForAdmin> page = new PageImpl<>(content, pageable, allDtos.size()); | ||
|
|
||
| long documentCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.DOCUMENT.toStatusList()); | ||
| long interviewCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.INTERVIEW.toStatusList()); | ||
| long finalPassCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.FINAL_PASS.toStatusList()); | ||
| long failCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.FAIL.toStatusList()); | ||
|
|
||
| ApplicationResponseDTO.StageCount counts = ApplicationResponseDTO.StageCount.from( | ||
| documentCnt, interviewCnt, finalPassCnt, failCnt | ||
| ); | ||
|
|
||
| return ApplicationResponseDTO.AdminPageWithStageCounts.from(page, counts); | ||
| } | ||
|
|
||
| @NotNull | ||
| private static List<Application> getSortedApps(AdminApplicationSortField sortBy, Sort.Direction direction, List<Application> allApps) { | ||
|
|
||
| allApps.sort((a, b) -> { | ||
| var sa = ApplicationResponseDTO.SummaryForAdmin.from(a, 0L); | ||
| var sb = ApplicationResponseDTO.SummaryForAdmin.from(b, 0L); | ||
|
|
@@ -300,41 +365,17 @@ public ApplicationResponseDTO.AdminPageWithStageCounts getByRecruitmentIdForAdmi | |
| boolean smsB = Boolean.TRUE.equals(sb.isSmsSent()); | ||
| cmp = Boolean.compare(smsA, smsB); | ||
| break; | ||
| case LATEST: | ||
| cmp = a.getCreatedAt().compareTo(b.getCreatedAt()); | ||
| break; | ||
| case NAME: | ||
| default: | ||
| cmp = sa.name().compareToIgnoreCase(sb.name()); | ||
| break; | ||
| } | ||
| return direction.isDescending() ? -cmp : cmp; | ||
| }); | ||
|
|
||
|
|
||
| List<ApplicationResponseDTO.SummaryForAdmin> allDtos = IntStream.range(0, allApps.size()) | ||
| .mapToObj(i -> ApplicationResponseDTO.SummaryForAdmin.from(allApps.get(i), i + 1L)) | ||
| .toList(); | ||
|
|
||
| int start = (int) pageable.getOffset(); | ||
| int end = Math.min(start + pageable.getPageSize(), allDtos.size()); | ||
| List<ApplicationResponseDTO.SummaryForAdmin> content = start > end | ||
| ? List.of() | ||
| : allDtos.subList(start, end); | ||
|
|
||
| Page<ApplicationResponseDTO.SummaryForAdmin> page = new PageImpl<>(content, pageable, allDtos.size()); | ||
|
|
||
| long documentCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.DOCUMENT.toStatusList()); | ||
| long interviewCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.INTERVIEW.toStatusList()); | ||
| long finalPassCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.FINAL_PASS.toStatusList()); | ||
| long failCnt = applicationRepository.countByRecruitmentIdAndStatusIn( | ||
| recruitmentId, AdminStageFilter.FAIL.toStatusList()); | ||
|
|
||
| ApplicationResponseDTO.StageCount counts = ApplicationResponseDTO.StageCount.from( | ||
| documentCnt, interviewCnt, finalPassCnt, failCnt | ||
| ); | ||
|
|
||
| return ApplicationResponseDTO.AdminPageWithStageCounts.from(page, counts); | ||
| return allApps; | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -425,6 +466,99 @@ public List<ApplicationResponseDTO.CandidateDTO> findTimeslotCandidates( | |
| return applicationRepository.findEligibleCandidates(recruitmentId, timeslotId, q, excludeCurrent); | ||
| } | ||
|
|
||
| @Override | ||
| public List<ApplicationResponseDTO.Detail> getAllDetailForExcel( | ||
| Long recruitmentId, | ||
| AdminStageFilter stage, | ||
| AdminApplicationSortField sortBy, | ||
| Sort.Direction direction, | ||
| List<Long> organizationRoleIds, | ||
| List<ApplicationStatus> statuses, | ||
| String keyword, | ||
| Long currentUserId | ||
| ) { | ||
|
|
||
| List<Application> apps = applicationRepository.findByRecruitmentIdAndStatusIn( | ||
| recruitmentId, stage.toStatusList() | ||
| ); | ||
|
|
||
| // POSITION(OrganizationRole) νν° | ||
| if (organizationRoleIds != null && !organizationRoleIds.isEmpty()) { | ||
| apps = apps.stream() | ||
| .filter(a -> a.getOrganizationRole() != null && | ||
| organizationRoleIds.contains(a.getOrganizationRole().getId())) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| // STATUS νν° | ||
| if (statuses != null && !statuses.isEmpty()) { | ||
| apps = apps.stream() | ||
| .filter(a -> statuses.contains(a.getStatus())) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| // KEYWORD (name κ²μ) | ||
| if (keyword != null && !keyword.isBlank()) { | ||
| String kw = keyword.trim().toLowerCase(Locale.ROOT); | ||
| apps = apps.stream() | ||
| .filter(a -> a.getName() != null && a.getName().toLowerCase().contains(kw)) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| // SORT | ||
| apps = getSortedApps(sortBy, direction, apps); | ||
|
EunjinWoo marked this conversation as resolved.
|
||
|
|
||
| if (apps.isEmpty()) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| // μ±λ₯ μ΅μ ν - bulk μ‘°ν | ||
| List<Long> appIds = apps.stream() | ||
| .map(Application::getId) | ||
| .toList(); | ||
|
|
||
| // λ©΄μ κ°λ₯ μκ° μ 체 μ‘°ν | ||
| List<ApplicantAvailability> allAvail = | ||
| applicantAvailabilityRepository.findAllByApplicationIdIn(appIds); | ||
|
|
||
| // νκ° μ 체 μ‘°ν | ||
| List<Evaluation> allEvaluations = | ||
| evaluationRepository.findAllByApplicationIdIn(appIds); | ||
|
|
||
| // νκ° κΈ°μ€ (κΈ°μ‘΄ λ¨κ±΄ μμΈ λ°©μκ³Ό λμΌ) | ||
| // λ¨κ±΄μμλ DOCUMENT κΈ°μ€λ§ κ°μ Έμ€μ§λ§, Detail.from() λ΄λΆμμ μΈν°λ·°/μλ₯ λͺ¨λ μ¬μ©νλ―λ‘ recruitment.getEvaluationCriteriaList() κ·Έλλ‘ μ¨λ λ¨. | ||
| Recruitment recruitment = apps.isEmpty() ? null : apps.get(0).getRecruitment(); | ||
| List<EvaluationCriteria> criteriaList = | ||
| recruitment != null ? recruitment.getEvaluationCriteriaList() : List.of(); | ||
|
|
||
|
|
||
| // previous, next β μμ μμλ λΆνμνλ―λ‘ null | ||
| Long previous = null; | ||
| Long next = null; | ||
|
|
||
|
|
||
| // Detail DTO λ³ν | ||
| Map<Long, List<ApplicantAvailability>> availMap = | ||
| allAvail.stream().collect(Collectors.groupingBy(a -> a.getApplication().getId())); | ||
|
|
||
| Map<Long, List<Evaluation>> evalMap = | ||
| allEvaluations.stream().collect(Collectors.groupingBy(e -> e.getApplication().getId())); | ||
|
|
||
|
|
||
| return apps.stream() | ||
| .map(app -> assembler.toDetail( | ||
| app, | ||
| availMap.getOrDefault(app.getId(), List.of()), | ||
| evalMap.getOrDefault(app.getId(), List.of()), | ||
| criteriaList, | ||
| currentUserId, | ||
| previous, | ||
| next | ||
| )) | ||
| .toList(); | ||
| } | ||
|
EunjinWoo marked this conversation as resolved.
|
||
|
|
||
|
|
||
| /** | ||
| * PASS/FAIL/HOLDμ κ°λ¨ μνλ₯Ό λ¨κ³μ νμ¬ μνμ λ§μΆ° ApplicationStatusμΌλ‘ λ§€ν | ||
| * @param stage λ³κ²½ν λ¨κ³ (DOCUMENT, INTERVIEW, FINAL_PASS, FAIL) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.