From db9d6f7ea743b301bf30e1fb3befb7c3e787f640 Mon Sep 17 00:00:00 2001 From: GiHwan2 Date: Mon, 18 Aug 2025 00:03:22 +0900 Subject: [PATCH] =?UTF-8?q?Fix/784:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=83=81=ED=83=9C=EB=B3=84=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadAdminOrderOverviewsService.java | 12 +- .../ReadAdminOrderOverviewsResponseDto.java | 123 +++++++++++++++++- .../ReadUserOrderDetailResponseDto.java | 2 +- .../order/repository/OrderRepository.java | 2 + .../repository/impl/OrderRepositoryImpl.java | 35 +++++ 5 files changed, 168 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/tookscan/tookscan/order/application/service/ReadAdminOrderOverviewsService.java b/src/main/java/com/tookscan/tookscan/order/application/service/ReadAdminOrderOverviewsService.java index 4284dbca..f6473bc7 100644 --- a/src/main/java/com/tookscan/tookscan/order/application/service/ReadAdminOrderOverviewsService.java +++ b/src/main/java/com/tookscan/tookscan/order/application/service/ReadAdminOrderOverviewsService.java @@ -6,6 +6,7 @@ import com.tookscan.tookscan.order.presentation.dto.response.ReadAdminOrderOverviewsResponseDto; import com.tookscan.tookscan.order.repository.OrderRepository; import java.util.List; +import java.util.Map; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -31,12 +32,19 @@ public ReadAdminOrderOverviewsResponseDto execute(int page, int size, String sta Boolean isAsInProgress, Boolean isInProgress, UUID customerKey) { Pageable pageable = PageRequest.of(page - 1, size); + // 필터링된 주문 조회 (페이지네이션) Page orderIdPages = orderRepository.findOrderOverviews(startDate, endDate, search, searchType, sort, direction, pageable, orderStatus, isOneDayScan, hasRecoveryOption, isAsInProgress, isInProgress, customerKey); - List orders = orderRepository.findAllWithDocumentsByIdIn(orderIdPages.getContent()); + List filteredOrders = orderRepository.findAllWithDocumentsByIdIn(orderIdPages.getContent()); - return ReadAdminOrderOverviewsResponseDto.of(orders, orderIdPages); + // 상태별 개수 조회 (isInProgress 필터만 적용) + Map statusCounts = orderRepository.findOrderStatusCountsByIsInProgress(isInProgress); + + // 전체 통계 조회 (모든 필터 제외) + Map overallStatusCounts = orderRepository.findOrderStatusCountsByIsInProgress(null); + + return ReadAdminOrderOverviewsResponseDto.of(filteredOrders, statusCounts, overallStatusCounts, orderIdPages); } } diff --git a/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadAdminOrderOverviewsResponseDto.java b/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadAdminOrderOverviewsResponseDto.java index 63fe4259..2762ca44 100644 --- a/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadAdminOrderOverviewsResponseDto.java +++ b/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadAdminOrderOverviewsResponseDto.java @@ -19,6 +19,9 @@ @Getter public class ReadAdminOrderOverviewsResponseDto extends SelfValidating { + @JsonProperty("orders_info") + private final OrderOverviewsInfoDto ordersInfo; + @JsonProperty("orders") private final List orders; @@ -26,29 +29,143 @@ public class ReadAdminOrderOverviewsResponseDto extends SelfValidating orders, PageInfoDto pageInfo) { + public ReadAdminOrderOverviewsResponseDto(List orders, PageInfoDto pageInfo, + OrderOverviewsInfoDto ordersInfo) { + this.ordersInfo = ordersInfo; this.orders = orders; this.pageInfo = pageInfo; this.validateSelf(); } - public static ReadAdminOrderOverviewsResponseDto of(List orders, Page pageInfo) { + public static ReadAdminOrderOverviewsResponseDto of(List filteredOrders, Map statusCounts, Map overallStatusCounts, Page pageInfo) { List orderIds = pageInfo.getContent(); - Map orderMap = orders.stream() + Map orderMap = filteredOrders.stream() .collect(Collectors.toMap(Order::getId, Function.identity())); List sortedOrders = orderIds.stream() .map(orderMap::get) .toList(); + OrderOverviewsInfoDto ordersInfo = OrderOverviewsInfoDto.fromStatusCounts(sortedOrders, statusCounts, overallStatusCounts); return ReadAdminOrderOverviewsResponseDto.builder() .orders(sortedOrders.stream().map(OrderOverviewsDto::fromEntity).toList()) .pageInfo(PageInfoDto.fromEntity(pageInfo)) + .ordersInfo(ordersInfo) .build(); } + public static class OrderOverviewsInfoDto extends SelfValidating { + @JsonProperty("total_count") + private final Integer totalCount; + + @JsonProperty("apply_completed_count") + private final Integer applyCompletedCount; + + @JsonProperty("company_arrived_count") + private final Integer companyArrivedCount; + + @JsonProperty("payment_waiting_count") + private final Integer paymentWaitingCount; + + @JsonProperty("payment_completed_count") + private final Integer paymentCompletedCount; + + @JsonProperty("scan_in_progress_count") + private final Integer scanInProgressCount; + + @JsonProperty("scan_completed_count") + private final Integer scanCompletedCount; + + @JsonProperty("recovery_in_progress_count") + private final Integer recoveryInProgressCount; + + @JsonProperty("post_waiting_count") + private final Integer postWaitingCount; + + @JsonProperty("all_completed_count") + private final Integer allCompletedCount; + + @JsonProperty("cancel_count") + private final Integer cancelCount; + + @JsonProperty("overall_total_count") + private final Integer overallTotalCount; + + @JsonProperty("overall_in_progress_count") + private final Integer overallInProgressCount; + + @JsonProperty("overall_completed_count") + private final Integer overallCompletedCount; + + @Builder + public OrderOverviewsInfoDto(Integer applyCompletedCount, Integer companyArrivedCount, + Integer paymentWaitingCount, + Integer paymentCompletedCount, Integer scanInProgressCount, + Integer scanCompletedCount, Integer recoveryInProgressCount, + Integer postWaitingCount, Integer allCompletedCount, Integer cancelCount, + Integer totalCount, Integer overallTotalCount, Integer overallInProgressCount, + Integer overallCompletedCount) { + this.totalCount = totalCount; + this.applyCompletedCount = applyCompletedCount; + this.companyArrivedCount = companyArrivedCount; + this.paymentWaitingCount = paymentWaitingCount; + this.paymentCompletedCount = paymentCompletedCount; + this.scanInProgressCount = scanInProgressCount; + this.scanCompletedCount = scanCompletedCount; + this.recoveryInProgressCount = recoveryInProgressCount; + this.postWaitingCount = postWaitingCount; + this.allCompletedCount = allCompletedCount; + this.cancelCount = cancelCount; + this.overallTotalCount = overallTotalCount; + this.overallInProgressCount = overallInProgressCount; + this.overallCompletedCount = overallCompletedCount; + this.validateSelf(); + } + + public static OrderOverviewsInfoDto fromStatusCounts(List currentPageOrders, Map statusCounts, Map overallStatusCounts) { + return OrderOverviewsInfoDto.builder() + .totalCount(currentPageOrders.size()) + .applyCompletedCount(getStatusCount(statusCounts, EOrderStatus.APPLY_COMPLETED)) + .companyArrivedCount(getStatusCount(statusCounts, EOrderStatus.COMPANY_ARRIVED)) + .paymentWaitingCount(getStatusCount(statusCounts, EOrderStatus.PAYMENT_WAITING)) + .paymentCompletedCount(getStatusCount(statusCounts, EOrderStatus.PAYMENT_COMPLETED)) + .scanInProgressCount(getStatusCount(statusCounts, EOrderStatus.SCAN_IN_PROGRESS)) + .scanCompletedCount(getStatusCount(statusCounts, EOrderStatus.SCAN_COMPLETED)) + .recoveryInProgressCount(getStatusCount(statusCounts, EOrderStatus.RECOVERY_IN_PROGRESS)) + .postWaitingCount(getStatusCount(statusCounts, EOrderStatus.POST_WAITING)) + .allCompletedCount(getStatusCount(statusCounts, EOrderStatus.ALL_COMPLETED)) + .cancelCount(getStatusCount(statusCounts, EOrderStatus.CANCEL)) + .overallTotalCount(calculateTotalCount(overallStatusCounts)) + .overallInProgressCount(calculateInProgressCount(overallStatusCounts)) + .overallCompletedCount(calculateCompletedCount(overallStatusCounts)) + .build(); + } + + private static Integer calculateTotalCount(Map statusCounts) { + return Math.toIntExact(statusCounts.values().stream().mapToLong(Long::longValue).sum()); + } + + private static Integer calculateInProgressCount(Map statusCounts) { + long cancelCount = statusCounts.getOrDefault(EOrderStatus.CANCEL, 0L); + long allCompletedCount = statusCounts.getOrDefault(EOrderStatus.ALL_COMPLETED, 0L); + long totalCount = statusCounts.values().stream().mapToLong(Long::longValue).sum(); + return Math.toIntExact(totalCount - cancelCount - allCompletedCount); + } + + private static Integer calculateCompletedCount(Map statusCounts) { + long cancelCount = statusCounts.getOrDefault(EOrderStatus.CANCEL, 0L); + long allCompletedCount = statusCounts.getOrDefault(EOrderStatus.ALL_COMPLETED, 0L); + return Math.toIntExact(cancelCount + allCompletedCount); + } + + private static Integer getStatusCount(Map statusCounts, EOrderStatus status) { + return Math.toIntExact(statusCounts.getOrDefault(status, 0L)); + } + } + + public static class OrderOverviewsDto extends SelfValidating { @JsonProperty("order_id") private final String orderId; diff --git a/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadUserOrderDetailResponseDto.java b/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadUserOrderDetailResponseDto.java index 0be72639..80d810a5 100644 --- a/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadUserOrderDetailResponseDto.java +++ b/src/main/java/com/tookscan/tookscan/order/presentation/dto/response/ReadUserOrderDetailResponseDto.java @@ -199,7 +199,7 @@ public static DocumentInfoDto fromEntity(Document document) { return DocumentInfoDto.builder() .name(document.getName()) .pageCount(document.getPageCount()) - .pagePrice(document.getDefaultPricePerPage()) + .pagePrice(document.getPagePrice()) .documentPrice(document.getDocumentPrice()) .recoveryOption(document.getRecoveryOption()) .isOcrEnabled(document.getIsOcrEnabled()) diff --git a/src/main/java/com/tookscan/tookscan/order/repository/OrderRepository.java b/src/main/java/com/tookscan/tookscan/order/repository/OrderRepository.java index e1e354de..84b3bb45 100644 --- a/src/main/java/com/tookscan/tookscan/order/repository/OrderRepository.java +++ b/src/main/java/com/tookscan/tookscan/order/repository/OrderRepository.java @@ -94,4 +94,6 @@ Page findAllByUserAndSearchAndOrderStatusInOrElseNull(User user, String s Integer countByIsAsInProgressTrue(); + Map findOrderStatusCountsByIsInProgress(Boolean isInProgress); + } diff --git a/src/main/java/com/tookscan/tookscan/order/repository/impl/OrderRepositoryImpl.java b/src/main/java/com/tookscan/tookscan/order/repository/impl/OrderRepositoryImpl.java index 1a6c3f1a..5d8bbfb5 100644 --- a/src/main/java/com/tookscan/tookscan/order/repository/impl/OrderRepositoryImpl.java +++ b/src/main/java/com/tookscan/tookscan/order/repository/impl/OrderRepositoryImpl.java @@ -1,5 +1,6 @@ package com.tookscan.tookscan.order.repository.impl; +import com.querydsl.core.Tuple; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.Expressions; @@ -725,4 +726,38 @@ private BooleanExpression buildFilterPredicate(QOrder order, Boolean isApplied, return predicate; } + + @Override + public Map findOrderStatusCountsByIsInProgress(Boolean isInProgress) { + QOrder order = QOrder.order; + + BooleanExpression predicate = Expressions.TRUE; + + if (isInProgress != null) { + if (isInProgress) { + // 진행 중인 상태(취소·완료 제외) + predicate = predicate.and( + order.orderStatus.notIn(EOrderStatus.CANCEL, EOrderStatus.ALL_COMPLETED) + ); + } else { + // 진행 중이 아닌 상태(취소 혹은 전부 완료) + predicate = predicate.and( + order.orderStatus.in(EOrderStatus.CANCEL, EOrderStatus.ALL_COMPLETED) + ); + } + } + + List results = jpaQueryFactory + .select(order.orderStatus, order.count()) + .from(order) + .where(predicate) + .groupBy(order.orderStatus) + .fetch(); + + return results.stream() + .collect(Collectors.toMap( + tuple -> tuple.get(order.orderStatus), + tuple -> tuple.get(order.count()) + )); + } }