Skip to content
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

[FEATURE] 마감임박순 정렬 구현 #214

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gohigher.application.port.out.persistence;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

Expand All @@ -12,7 +13,7 @@
public interface ApplicationPersistenceQueryPort {

PagingContainer<Application> findAllByUserId(Long userId, int page, int size, ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName);
List<ProcessType> process, List<Boolean> completed, String companyName, LocalDateTime today);

boolean existsByIdAndUserId(Long id, Long userId);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gohigher.application.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
Expand All @@ -21,10 +22,10 @@
import gohigher.application.port.in.KanbanByProcessApplicationResponse;
import gohigher.application.port.in.MyApplicationRequest;
import gohigher.application.port.in.MyApplicationResponse;
import gohigher.application.port.in.UnscheduledApplicationResponse;
import gohigher.application.port.in.PagingRequest;
import gohigher.application.port.in.PagingResponse;
import gohigher.application.port.in.ProcessResponse;
import gohigher.application.port.in.UnscheduledApplicationResponse;
import gohigher.application.port.out.persistence.ApplicationPersistenceQueryPort;
import gohigher.application.search.ApplicationSortingType;
import gohigher.common.Process;
Expand All @@ -41,12 +42,15 @@ public class ApplicationQueryService implements ApplicationQueryPort {
private final ApplicationPersistenceQueryPort applicationPersistenceQueryPort;

@Override
public PagingResponse<MyApplicationResponse> findAllByUserId(Long userId, PagingRequest pagingRequest, MyApplicationRequest request) {
public PagingResponse<MyApplicationResponse> findAllByUserId(Long userId, PagingRequest pagingRequest,
MyApplicationRequest request) {
PagingContainer<Application> pagingContainer = applicationPersistenceQueryPort.findAllByUserId(
userId, pagingRequest.getPage(), pagingRequest.getSize(),
ApplicationSortingType.from(request.getSort()),
ProcessType.from(request.getProcess()), request.getCompleted(), request.getCompanyName());
List<MyApplicationResponse> responses = findApplicationsByUserId(pagingContainer.getContent(), MyApplicationResponse::of);
ProcessType.from(request.getProcess()), request.getCompleted(), request.getCompanyName(),
LocalDateTime.now());
List<MyApplicationResponse> responses = findApplicationsByUserId(pagingContainer.getContent(),
MyApplicationResponse::of);
return new PagingResponse<>(pagingContainer.hasNext(), responses);
}

Expand Down Expand Up @@ -81,7 +85,8 @@ public List<DateApplicationResponse> findByDate(DateApplicationRequest request)
public PagingResponse<UnscheduledApplicationResponse> findUnscheduled(Long userId, PagingRequest request) {
PagingContainer<Application> pagingContainer = applicationPersistenceQueryPort.findUnscheduledByUserId(
userId, request.getPage(), request.getSize());
List<UnscheduledApplicationResponse> responses = findApplicationsByUserId(pagingContainer.getContent(), UnscheduledApplicationResponse::of);
List<UnscheduledApplicationResponse> responses = findApplicationsByUserId(pagingContainer.getContent(),
UnscheduledApplicationResponse::of);
return new PagingResponse<>(pagingContainer.hasNext(), responses);
}

Expand All @@ -99,13 +104,15 @@ public List<KanbanByProcessApplicationResponse> findForKanbanByProcess(Long user
.toList();
}

private <T> List<T> findApplicationsByUserId(List<Application> applications, BiFunction<Application, Process, T> responseMapper) {
private <T> List<T> findApplicationsByUserId(List<Application> applications,
BiFunction<Application, Process, T> responseMapper) {
return applications.stream()
.flatMap(application -> extractApplicationResponse(application, responseMapper))
.toList();
}

private <T> Stream<T> extractApplicationResponse(Application application, BiFunction<Application, Process, T> responseMapper) {
private <T> Stream<T> extractApplicationResponse(Application application,
BiFunction<Application, Process, T> responseMapper) {
return application.getProcesses()
.stream()
.map(process -> responseMapper.apply(application, process));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ public class ApplicationPersistenceQueryAdapter implements ApplicationPersistenc
private final ApplicationRepository applicationRepository;

@Override
public PagingContainer<Application> findAllByUserId(Long userId, int page, int size, ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName) {
public PagingContainer<Application> findAllByUserId(Long userId, int page, int size,
ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName, LocalDateTime today) {
Slice<ApplicationJpaEntity> applicationJpaEntities = applicationRepository.findAllByUserId(userId,
PageRequest.of(page - DIFFERENCES_PAGES_AND_DB_INDEX, size),
sortingType, process, completed, companyName);
sortingType, process, completed, companyName, today);

return convertToPagingContainer(applicationJpaEntities);
}
Expand Down Expand Up @@ -78,7 +79,8 @@ public List<Application> findOnlyWithCurrentProcessByUserId(Long userId) {

@Override
public List<Application> findOnlyCurrentProcessByUserIdAndProcessType(Long userId, ProcessType processType) {
List<ApplicationJpaEntity> applications = applicationRepository.findOnlyCurrentProcessByUserIdAndProcessType(userId, processType);
List<ApplicationJpaEntity> applications = applicationRepository.findOnlyCurrentProcessByUserIdAndProcessType(
userId, processType);
return convertToKanbanApplication(applications);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gohigher.application.entity;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.data.domain.Pageable;
Expand All @@ -10,6 +11,6 @@

public interface ApplicationRepositoryCustom {

Slice<ApplicationJpaEntity> findAllByUserId(Long userId, Pageable pageable, ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName);
Slice<ApplicationJpaEntity> findAllByUserId(Long userId, Pageable pageable, ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName, LocalDateTime today);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package gohigher.application.entity;

import static gohigher.application.entity.QApplicationJpaEntity.applicationJpaEntity;
import static gohigher.application.entity.QApplicationProcessJpaEntity.applicationProcessJpaEntity;
import static gohigher.application.entity.QApplicationJpaEntity.*;
import static gohigher.application.entity.QApplicationProcessJpaEntity.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -31,7 +32,7 @@ public class ApplicationRepositoryCustomImpl implements ApplicationRepositoryCus
@Override
public Slice<ApplicationJpaEntity> findAllByUserId(Long userId, Pageable pageable,
ApplicationSortingType sortingType,
List<ProcessType> process, List<Boolean> completed, String companyName) {
List<ProcessType> process, List<Boolean> completed, String companyName, LocalDateTime today) {

JPAQuery<ProcessWithApplicationResponse> query = jpaQueryFactory
.select(Projections.bean(
Expand All @@ -58,7 +59,7 @@ public Slice<ApplicationJpaEntity> findAllByUserId(Long userId, Pageable pageabl
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize() + 1)
.orderBy(selectOrderSpecifierAboutFindAll(sortingType));
.orderBy(selectOrderSpecifierAboutFindAll(sortingType, today));

List<ApplicationJpaEntity> applications = convertToApplicationJpaEntity(query);

Expand Down Expand Up @@ -98,25 +99,41 @@ private BooleanExpression inProcessType(List<ProcessType> process) {
return applicationProcessJpaEntity.type.in(process);
}

private OrderSpecifier<?> selectOrderSpecifierAboutFindAll(ApplicationSortingType sortingType) {
private OrderSpecifier<?>[] selectOrderSpecifierAboutFindAll(ApplicationSortingType sortingType,
LocalDateTime today) {
return switch (sortingType) {
case CREATED -> applicationProcessJpaEntity.id.desc();
case PROCESS_TYPE -> sortByProcessType().asc();
case REVERSE_PROCESS_TYPE -> sortByProcessType().desc();
case CLOSING -> applicationProcessJpaEntity.id.asc();
case CREATED -> new OrderSpecifier<?>[] {applicationProcessJpaEntity.id.desc()};
case PROCESS_TYPE -> new OrderSpecifier<?>[] {sortByProcessType().asc()};
case REVERSE_PROCESS_TYPE -> new OrderSpecifier<?>[] {sortByProcessType().desc()};
case CLOSING -> sortByEndDate(today);
};
}

private NumberExpression<Integer> sortByProcessType() {
int order = 0;
return new CaseBuilder()
.when(applicationProcessJpaEntity.type.eq(ProcessType.TO_APPLY)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.DOCUMENT)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.TEST)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.INTERVIEW)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.COMPLETE)).then(order++)
.otherwise(order);
}
private NumberExpression<Integer> sortByProcessType() {
int order = 0;
return new CaseBuilder()
.when(applicationProcessJpaEntity.type.eq(ProcessType.TO_APPLY)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.DOCUMENT)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.TEST)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.INTERVIEW)).then(order++)
.when(applicationProcessJpaEntity.type.eq(ProcessType.COMPLETE)).then(order++)
.otherwise(order);
}

private OrderSpecifier<?>[] sortByEndDate(LocalDateTime today) {
// 마감이 지나지 않은 경우 (schedule이 today 이후)
NumberExpression<Long> notExpiredCase = new CaseBuilder()
.when(applicationProcessJpaEntity.schedule.after(today)).then(0L)
.otherwise(1L);

// 마감이 임박한 순서로 정렬 (notExpiredCase 오름차순, schedule 오름차순)
OrderSpecifier<Long> notExpiredOrder = notExpiredCase.asc();
OrderSpecifier<LocalDateTime> scheduleOrder = applicationProcessJpaEntity.schedule.asc();

// 이미 지나간 schedule은 id 내림차순으로
OrderSpecifier<Long> expiredOrder = applicationProcessJpaEntity.id.desc();
return new OrderSpecifier<?>[] {notExpiredOrder, scheduleOrder, expiredOrder};
}

private List<ApplicationJpaEntity> convertToApplicationJpaEntity(JPAQuery<ProcessWithApplicationResponse> query) {
return query.fetch().stream()
Expand Down
Loading