Skip to content
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.unionmate.backend.domain.applicant.application.dto.response;

import java.util.Map;

import com.unionmate.backend.domain.recruitment.application.exception.ItemTypeNotExistException;
import com.unionmate.backend.domain.recruitment.domain.entity.enums.ItemType;
import com.unionmate.backend.domain.recruitment.domain.entity.item.CalendarItem;
Expand All @@ -17,10 +19,10 @@ public sealed interface ApplicationAnswerResponse

String description();

static ApplicationAnswerResponse from(Item item) {
static ApplicationAnswerResponse from(Item item, Map<Long, String> selectOptionTitleById) {
return switch (item) {
case TextItem textItem -> TextAnswerResponse.from(textItem);
case SelectItem selectItem -> SelectAnswerResponse.from(selectItem);
case SelectItem selectItem -> SelectAnswerResponse.from(selectItem, selectOptionTitleById);
case CalendarItem calendarItem -> CalendarAnswerResponse.from(calendarItem);
default -> throw new ItemTypeNotExistException();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.unionmate.backend.domain.applicant.domain.entity.Application;
import com.unionmate.backend.domain.applicant.domain.entity.embed.Interview;
import com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus;
import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment;
import com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus;
import com.unionmate.backend.domain.recruitment.domain.entity.item.Item;
import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem;
import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItemOption;

import io.swagger.v3.oas.annotations.media.Schema;

Expand Down Expand Up @@ -37,9 +42,11 @@ public record GetApplicationAdminResponse(
LocalDateTime submittedAt
) {
public static GetApplicationAdminResponse from(Application application) {
Map<Long, String> selectOptionTitleById = buildSelectOptionTitleMap(application.getRecruitment());

List<ApplicationAnswerResponse> sortedAnswers = application.getAnswers().stream()
.sorted(Comparator.comparing(Item::getOrder))
.map(ApplicationAnswerResponse::from)
.map(item -> ApplicationAnswerResponse.from(item, selectOptionTitleById))
.toList();

InterviewResponse interviewResponse = from(application.getInterview());
Expand Down Expand Up @@ -118,4 +125,15 @@ public record InterviewResponse(
String place
) {
}

private static Map<Long, String> buildSelectOptionTitleMap(Recruitment recruitment) {
return recruitment.getItems().stream()
.filter(item -> item instanceof SelectItem)
.map(item -> (SelectItem)item)
.flatMap(selectItem -> selectItem.getSelectItemOptions().stream())
.collect(Collectors.toMap(
SelectItemOption::getId,
SelectItemOption::getTitle
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.unionmate.backend.domain.applicant.domain.entity.Application;
import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment;
import com.unionmate.backend.domain.recruitment.domain.entity.item.Item;
import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem;
import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItemOption;

import io.swagger.v3.oas.annotations.media.Schema;

Expand All @@ -29,9 +34,11 @@ public record GetApplicationResponse(
List<ApplicationAnswerResponse> answers
) {
public static GetApplicationResponse from(Application application) {
Map<Long, String> selectOptionTitleById = buildSelectOptionTitleMap(application.getRecruitment());

List<ApplicationAnswerResponse> answer = application.getAnswers().stream()
.sorted(Comparator.comparing(Item::getOrder))
.map(ApplicationAnswerResponse::from)
.map(item -> ApplicationAnswerResponse.from(item, selectOptionTitleById))
.toList();

return new GetApplicationResponse(
Expand All @@ -44,4 +51,15 @@ public static GetApplicationResponse from(Application application) {
answer
);
}

private static Map<Long, String> buildSelectOptionTitleMap(Recruitment recruitment) {
return recruitment.getItems().stream()
.filter(item -> item instanceof SelectItem)
.map(item -> (SelectItem)item)
.flatMap(selectItem -> selectItem.getSelectItemOptions().stream())
.collect(Collectors.toMap(
SelectItemOption::getId,
SelectItemOption::getTitle
));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.unionmate.backend.domain.applicant.application.dto.response;

import java.util.List;
import java.util.Map;

import com.unionmate.backend.domain.recruitment.domain.entity.enums.ItemType;
import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem;
Expand All @@ -23,18 +24,24 @@ public record SelectAnswerResponse(
@Schema(description = "중복 선택 가능 여부 ", example = "false")
boolean multiple,

@Schema(description = "답변한 선택지")
List<Long> selectedOptionIds
@Schema(description = "답변한 선택지 항목")
List<SelectOptionAnswerResponse> selectOptions
) implements ApplicationAnswerResponse {

public static SelectAnswerResponse from(SelectItem selectItem) {
public static SelectAnswerResponse from(SelectItem selectItem, Map<Long, String> selectOptionTitleById) {
List<Long> selectOptionIds = selectItem.getAnswer() == null ? List.of() : selectItem.getAnswer().answer();

List<SelectOptionAnswerResponse> selectOptionTitles = selectOptionIds.stream()
.map(optionId -> new SelectOptionAnswerResponse(optionId, selectOptionTitleById.get(optionId)))
.toList();

return new SelectAnswerResponse(
ItemType.SELECT,
selectItem.getTitle(),
selectItem.getOrder(),
selectItem.getDescription(),
selectItem.isMultiple(),
selectItem.getAnswer() == null ? List.of() : selectItem.getAnswer().answer()
selectOptionTitles
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.unionmate.backend.domain.applicant.application.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;

public record SelectOptionAnswerResponse(
@Schema(description = "선택지 id", example = "1")
Long optionId,

@Schema(description = "선택지 title", example = "월요일")
String title
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface ApplicationRepository extends JpaRepository<Application, Long>
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and (
a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING
or (
Expand All @@ -39,100 +39,100 @@ public interface ApplicationRepository extends JpaRepository<Application, Long>
)
order by a.id desc
""")
List<CouncilApplicantQueryRow> findDocumentListNoFilter(@Param("council") Council council);
List<CouncilApplicantQueryRow> findDocumentListNoFilter(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findDocumentListSubmitted(@Param("council") Council council);
List<CouncilApplicantQueryRow> findDocumentListSubmitted(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findDocumentListPassed(@Param("council") Council council);
List<CouncilApplicantQueryRow> findDocumentListPassed(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.FAILED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findDocumentListFailed(@Param("council") Council council);
List<CouncilApplicantQueryRow> findDocumentListFailed(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus in (
com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW,
com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL
)
order by a.id desc
""")
List<CouncilApplicantQueryRow> findInterviewListNoFilter(@Param("council") Council council);
List<CouncilApplicantQueryRow> findInterviewListNoFilter(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findInterviewListSubmitted(@Param("council") Council council);
List<CouncilApplicantQueryRow> findInterviewListSubmitted(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.PASSED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findInterviewListPassed(@Param("council") Council council);
List<CouncilApplicantQueryRow> findInterviewListPassed(@Param("recruitment") Recruitment recruitment);

@Query("""
select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow(
a.name, a.email, a.tel, a.createdAt, a.stage.evaluationStatus, a.stage.recruitmentStatus
)
from Application a
join a.recruitment r
where r.council = :council
where r = :recruitment
and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL
and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.FAILED
order by a.id desc
""")
List<CouncilApplicantQueryRow> findInterviewListFailed(@Param("council") Council council);
List<CouncilApplicantQueryRow> findInterviewListFailed(@Param("recruitment") Recruitment recruitment);

@EntityGraph(attributePaths = {"recruitment", "recruitment.council", "answers"})
@Query("select a from Application a where a.id = :id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,33 @@ public Application getByRecruitmentIdAndNameAndEmailWithRecruitmentAndCouncil(
.orElseThrow(ApplicationNotFoundException::new);
}

public List<CouncilApplicantQueryRow> getDocumentScreeningApplicantsForCouncil(
Council council, EvaluationStatus evaluationFilterOrNull
public List<CouncilApplicantQueryRow> getDocumentScreeningApplicantsForRecruitment(
Recruitment recruitment, EvaluationStatus evaluationFilterOrNull
) {
if (evaluationFilterOrNull == null) {

return applicationRepository.findDocumentListNoFilter(council);
return applicationRepository.findDocumentListNoFilter(recruitment);
}
return switch (evaluationFilterOrNull) {
case SUBMITTED -> applicationRepository.findDocumentListSubmitted(council);
case PASSED -> applicationRepository.findDocumentListPassed(council);
case FAILED -> applicationRepository.findDocumentListFailed(council);
default -> applicationRepository.findDocumentListNoFilter(council);
case SUBMITTED -> applicationRepository.findDocumentListSubmitted(recruitment);
case PASSED -> applicationRepository.findDocumentListPassed(recruitment);
case FAILED -> applicationRepository.findDocumentListFailed(recruitment);
default -> applicationRepository.findDocumentListNoFilter(recruitment);
};
}

public List<CouncilApplicantQueryRow> getInterviewApplicantsForCouncil(
Council council, EvaluationStatus evaluationFilterOrNull
public List<CouncilApplicantQueryRow> getInterviewApplicantsForRecruitment(
Recruitment recruitment, EvaluationStatus evaluationFilterOrNull
) {
if (evaluationFilterOrNull == null) {

return applicationRepository.findInterviewListNoFilter(council);
return applicationRepository.findInterviewListNoFilter(recruitment);
}
return switch (evaluationFilterOrNull) {
case SUBMITTED -> applicationRepository.findInterviewListSubmitted(council);
case PASSED -> applicationRepository.findInterviewListPassed(council);
case FAILED -> applicationRepository.findInterviewListFailed(council);
default -> applicationRepository.findInterviewListNoFilter(council);
case SUBMITTED -> applicationRepository.findInterviewListSubmitted(recruitment);
case PASSED -> applicationRepository.findInterviewListPassed(recruitment);
case FAILED -> applicationRepository.findInterviewListFailed(recruitment);
default -> applicationRepository.findInterviewListNoFilter(recruitment);
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import com.unionmate.backend.domain.member.domain.entity.School;
import com.unionmate.backend.domain.member.domain.service.MemberGetService;
import com.unionmate.backend.domain.member.domain.service.SchoolGetService;
import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment;
import com.unionmate.backend.domain.recruitment.domain.service.RecruitmentGetService;

import lombok.RequiredArgsConstructor;

Expand All @@ -39,6 +41,7 @@ public class CouncilManageUsecase {
private final ApplicationGetService applicationGetService;
private final CouncilManagerGetService councilManagerGetService;
private final CouncilGetService councilGetService;
private final RecruitmentGetService recruitmentGetService;

private final CouncilSaveService councilSaveService;
private final CouncilManagerSaveService councilManagerSaveService;
Expand Down Expand Up @@ -113,14 +116,16 @@ private void validateCouncilManagerExists(Member member) {
}

public List<CouncilApplicantResponse> getDocumentScreeningApplicants(
long memberId, long councilId, EvaluationStatus evaluationFilterOrNull
long memberId, long recruitmentId, EvaluationStatus evaluationFilterOrNull
) {
Recruitment recruitment = recruitmentGetService.getRecruitmentById(recruitmentId);

CouncilManager councilManager = councilManagerGetService.getCouncilManagerByMemberId(memberId);
Council council = councilGetService.getCouncilById(councilId);
Council council = recruitment.getCouncil();
councilManager.validateBelongsToCouncil(councilManager, council);

List<CouncilApplicantQueryRow> rows =
applicationGetService.getDocumentScreeningApplicantsForCouncil(council, evaluationFilterOrNull);
applicationGetService.getDocumentScreeningApplicantsForRecruitment(recruitment, evaluationFilterOrNull);

return rows.stream()
.map(row -> CouncilApplicantResponse.of(
Expand All @@ -130,14 +135,16 @@ public List<CouncilApplicantResponse> getDocumentScreeningApplicants(
}

public List<CouncilApplicantResponse> getInterviewApplicants(
long memberId, long councilId, EvaluationStatus evaluationFilterOrNull
long memberId, long recruitmentId, EvaluationStatus evaluationFilterOrNull
) {
Recruitment recruitment = recruitmentGetService.getRecruitmentById(recruitmentId);

CouncilManager councilManager = councilManagerGetService.getCouncilManagerByMemberId(memberId);
Council council = councilGetService.getCouncilById(councilId);
Council council = recruitment.getCouncil();
councilManager.validateBelongsToCouncil(councilManager, council);

List<CouncilApplicantQueryRow> rows =
applicationGetService.getInterviewApplicantsForCouncil(council, evaluationFilterOrNull);
applicationGetService.getInterviewApplicantsForRecruitment(recruitment, evaluationFilterOrNull);

return rows.stream()
.map(row -> CouncilApplicantResponse.of(
Expand Down
Loading