diff --git a/build.gradle b/build.gradle index 09787886..37afe9e4 100644 --- a/build.gradle +++ b/build.gradle @@ -87,6 +87,7 @@ dependencies { annotationProcessor "com.querydsl:querydsl-apt::jakarta" annotationProcessor "jakarta.persistence:jakarta.persistence-api" + //feign client implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' implementation group: 'io.github.openfeign', name: 'feign-gson', version: '11.0' diff --git a/src/main/java/com/irum/come2us/domain/order/application/mapper/CustomerOrderMapper.java b/src/main/java/com/irum/come2us/domain/order/application/mapper/CustomerOrderMapper.java index 71ddff92..f5d07114 100644 --- a/src/main/java/com/irum/come2us/domain/order/application/mapper/CustomerOrderMapper.java +++ b/src/main/java/com/irum/come2us/domain/order/application/mapper/CustomerOrderMapper.java @@ -2,14 +2,61 @@ import com.irum.come2us.domain.order.domain.entity.Order; import com.irum.come2us.domain.order.domain.entity.OrderDetail; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderDetailRow; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderSummaryRow; import com.irum.come2us.domain.order.presentation.dto.response.AddressResponse; +import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderListResponse; import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderResponse; +import com.irum.come2us.domain.order.presentation.dto.response.OrderDetailResponse; +import com.irum.come2us.domain.refund.domain.entity.Refund; +import com.irum.come2us.domain.refund.domain.entity.enums.RefundStatus; import java.util.List; import org.springframework.stereotype.Component; @Component public class CustomerOrderMapper { + public static OrderDetailResponse toOrderDetailResponse( + Order order, List orderDetailList, Refund refund) { + List pList = + orderDetailList.stream().map(CustomerOrderMapper::toProductResponse).toList(); + + RefundStatus refundStatus; + if (refund == null) { + refundStatus = null; + } else { + refundStatus = refund.getRefundStatus(); + } + + return OrderDetailResponse.builder() + .orderAt(order.getCreatedAt()) + .paymentStatus(order.getPayment().getPaymentStatus()) + .paymentMethod(order.getPayment().getPaymentMethod()) + .deliveryFee(order.getDeliveryFee()) + .discountAmount(order.getPayment().getTotalDiscountAmount()) + .totalProductPrice(order.getTotalPrice()) + .totalPaymentPrice(order.getPayment().getAmount()) + .orderStatusAll(order.getOrderStatusAll()) + .refundStatus(refundStatus) + .deliveryRequest(order.getDeliveryRequest()) + .address(AddressResponse.from(order.getDeliveryAddress().getAddress())) + .recipientContact(order.getDeliveryAddress().getRecipientContact()) + .recipientName(order.getDeliveryAddress().getRecipientName()) + .productResponseList(pList) + .build(); + } + + private static OrderDetailResponse.ProductResponse toProductResponse(OrderDetail orderDetail) { + + return OrderDetailResponse.ProductResponse.builder() + .receivedDate(orderDetail.getArrivedDate().toLocalDate()) + .productName(orderDetail.getProductName()) + .optionTitle(orderDetail.getOptionName()) + .price(orderDetail.getPrice()) + .quantity(orderDetail.getQuantity()) + .build(); + } + public static CustomerOrderResponse toCustomerOrderResponse( Order order, List orderDetailList) { List productSummaryList = @@ -29,8 +76,32 @@ private static CustomerOrderResponse.ProductSummary toProductSummary(OrderDetail return CustomerOrderResponse.ProductSummary.builder() .orderDetailId(orderDetail.getOrderDetailId()) .productName(orderDetail.getProductName()) + .optionName(orderDetail.getOptionName()) .price(orderDetail.getPrice()) .quantity(orderDetail.getQuantity()) .build(); } + + public static CustomerOrderListResponse.OrderResponse toOrderResponse( + CustomerOrderSummaryRow or, List pList) { + + return CustomerOrderListResponse.OrderResponse.builder() + .orderId(or.orderId()) + .orderAt(or.orderAt()) + .refundStatus(or.refundStatus()) + .productResponseList(pList) + .build(); + } + + public static CustomerOrderListResponse.ProductResponse toProductResponse( + CustomerOrderDetailRow c) { + return CustomerOrderListResponse.ProductResponse.builder() + .orderStatus(c.orderStatusIndi()) + .orderDetailId(c.orderDetailId()) + .optionName(c.optionName()) + .price(c.price()) + .productName(c.productName()) + .quantity(c.quantity()) + .build(); + } } diff --git a/src/main/java/com/irum/come2us/domain/order/application/mapper/OrderMapper.java b/src/main/java/com/irum/come2us/domain/order/application/mapper/OrderMapper.java index 7576ba7a..29a9efe4 100644 --- a/src/main/java/com/irum/come2us/domain/order/application/mapper/OrderMapper.java +++ b/src/main/java/com/irum/come2us/domain/order/application/mapper/OrderMapper.java @@ -8,7 +8,8 @@ @Component public class OrderMapper { - /** Repository DTO -> Response DTO로 변환 */ + + // TODO: builder로 리팩터링 public OwnerOrderListResponse.ProductSummary toProductSummary(OrderDetailRow detail) { return new OwnerOrderListResponse.ProductSummary( detail.orderDetailId(), @@ -18,7 +19,6 @@ public OwnerOrderListResponse.ProductSummary toProductSummary(OrderDetailRow det detail.optionTitle()); } - /** Repository DTO -> Response DTO로 변환 */ public OwnerOrderListResponse.OrderSummary toOrderSummary( OrderSummaryRow header, List products) { return new OwnerOrderListResponse.OrderSummary( diff --git a/src/main/java/com/irum/come2us/domain/order/application/service/CustomerOrderService.java b/src/main/java/com/irum/come2us/domain/order/application/service/CustomerOrderService.java index 6d3b2f1a..3ed39772 100644 --- a/src/main/java/com/irum/come2us/domain/order/application/service/CustomerOrderService.java +++ b/src/main/java/com/irum/come2us/domain/order/application/service/CustomerOrderService.java @@ -11,8 +11,13 @@ import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; import com.irum.come2us.domain.order.domain.repository.OrderDetailRepository; import com.irum.come2us.domain.order.domain.repository.OrderRepository; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderDetailRow; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderSummaryRow; import com.irum.come2us.domain.order.presentation.dto.request.CustomerOrderRequest; +import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderListResponse; import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderResponse; +import com.irum.come2us.domain.order.presentation.dto.response.OrderDetailResponse; +import com.irum.come2us.domain.order.presentation.dto.response.OrderDetailStatusResponse; import com.irum.come2us.domain.payment.application.service.PaymentService; import com.irum.come2us.domain.payment.domain.entity.Payment; import com.irum.come2us.domain.payment.domain.entity.enums.PaymentCorp; @@ -20,6 +25,8 @@ import com.irum.come2us.domain.product.domain.entity.ProductOptionValue; import com.irum.come2us.domain.product.domain.repository.ProductOptionValueRepository; import com.irum.come2us.domain.product.domain.repository.ProductRepository; +import com.irum.come2us.domain.refund.domain.entity.Refund; +import com.irum.come2us.domain.refund.domain.repository.RefundRepository; import com.irum.come2us.domain.store.domain.entity.Store; import com.irum.come2us.domain.store.domain.repository.StoreRepository; import com.irum.come2us.global.presentation.advice.exception.CommonException; @@ -28,6 +35,7 @@ import com.irum.come2us.global.presentation.advice.exception.errorcode.ProductErrorCode; import com.irum.come2us.global.presentation.advice.exception.errorcode.StoreErrorCode; import com.irum.come2us.global.util.MemberUtil; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -39,20 +47,112 @@ import org.springframework.transaction.annotation.Transactional; @Service -@Transactional @Slf4j @RequiredArgsConstructor +@Transactional public class CustomerOrderService { + private final OrderDetailRepository orderDetailRepository; + private final OrderRepository orderRepository; + private final RefundRepository refundRepository; private final MemberUtil memberUtil; private final ProductOptionValueRepository productOptionValueRepository; private final ProductRepository productRepository; private final StoreRepository storeRepository; private final DeliveryAddressRepository deliveryAddressRepository; - private final OrderDetailRepository orderDetailRepository; private final CouponService couponService; private final AppliedCouponService appliedCouponService; private final PaymentService paymentService; - private final OrderRepository orderRepository; + + @Transactional(readOnly = true) + public OrderDetailStatusResponse getOrderDetailStatus(UUID orderDetailId) { + Member member = memberUtil.getCurrentMember(); + + OrderDetail orderDetail = + orderDetailRepository + .findByOrderDetailIdWithOrderAndMember(orderDetailId) + .orElseThrow( + () -> new CommonException(OrderErrorCode.ORDER_DETAIL_NOT_FOUND)); + + if (member.equals(orderDetail.getOrder().getMember())) + throw new CommonException(OrderErrorCode.ORDER_FORBIDDEN); + + return OrderDetailStatusResponse.from(orderDetail); + } + + @Transactional(readOnly = true) + public OrderDetailResponse getOrderDetail(UUID orderId) { + Member member = memberUtil.getCurrentMember(); + + // order 조회 및 member 검증 + Order order = + orderRepository + .findByOrderIdAndMember(orderId, member) + .orElseThrow(() -> new CommonException(OrderErrorCode.ORDER_NOT_FOUND)); + + List orderDetailList = orderDetailRepository.findAllByOrder(order); + + Refund refund = refundRepository.findByOrder(order).orElse(null); + + return CustomerOrderMapper.toOrderDetailResponse(order, orderDetailList, refund); + } + + @Transactional + public CustomerOrderListResponse getOrderList( + UUID cursor, int size, LocalDate startDate, LocalDate endDate) { + + Member member = memberUtil.getCurrentMember(); + log.info("member {}", member.getMemberId()); + + // 2. order list 검색 + List headerList = + orderRepository.fetchOrderListByMember(member, startDate, endDate, cursor, size); + log.info("order list {}", headerList); + + boolean hasNext = headerList.size() > size; + if (hasNext) { + headerList = headerList.subList(0, size); + } + log.info("hasNext {}", hasNext); + + // 3. order id list + List orderIdList = headerList.stream().map(CustomerOrderSummaryRow::orderId).toList(); + List orderDetailList = + orderRepository.fetchOrderDetailListByMember(orderIdList); + log.info("orderDetailList {}", orderDetailList); + + // 4. orderId로 그룹핑 : productSummary 제작 + Map> detailMap = + orderDetailList.stream() + .collect( + Collectors.groupingBy( + CustomerOrderDetailRow::orderId, + Collectors.mapping( + CustomerOrderMapper::toProductResponse, + Collectors.toList()))); + + // 5. orderResponse 제작 + List orderResponseList = + headerList.stream() + .filter(order -> detailMap.containsKey(order.orderId())) + .map( + order -> + CustomerOrderMapper.toOrderResponse( + order, + detailMap.getOrDefault( + order.orderId(), + List.of()) // order detail 없다면 빈 리스트 + )) + .toList(); + + // 6. next cursor계산 + UUID nextCursor = orderResponseList.isEmpty() ? null : headerList.getLast().orderId(); + + return CustomerOrderListResponse.builder() + .orderList(orderResponseList) + .hasNext(hasNext) + .nextCursor(nextCursor) + .build(); + } public CustomerOrderResponse prepareOrder(CustomerOrderRequest request) { Member member = memberUtil.getCurrentMember(); diff --git a/src/main/java/com/irum/come2us/domain/order/application/service/OwnerOrderService.java b/src/main/java/com/irum/come2us/domain/order/application/service/OwnerOrderService.java index d53ff07b..17cc585a 100644 --- a/src/main/java/com/irum/come2us/domain/order/application/service/OwnerOrderService.java +++ b/src/main/java/com/irum/come2us/domain/order/application/service/OwnerOrderService.java @@ -6,7 +6,6 @@ import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; import com.irum.come2us.domain.order.domain.repository.OrderDetailRepository; import com.irum.come2us.domain.order.domain.repository.OrderRepository; -import com.irum.come2us.domain.order.domain.repository.OrderRepositoryCustom; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderDetailRow; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderSummaryRow; import com.irum.come2us.domain.order.presentation.dto.request.OwnerOrderShippedRequest; @@ -29,7 +28,6 @@ public class OwnerOrderService { private final OrderDetailRepository orderDetailRepository; private final OrderRepository orderRepository; - private final OrderRepositoryCustom orderRepositoryCustom; private final OrderMapper orderMapper; @Transactional(readOnly = true) @@ -79,8 +77,7 @@ private OwnerOrderListResponse getOwnerOrderList( UUID storeId, OrderStatus orderStatus, UUID cursor, Integer size) { // 2. order list 검색 - var headerList = - orderRepositoryCustom.fetchOrderHeaderList(storeId, orderStatus, cursor, size); + var headerList = orderRepository.fetchOrderHeaderList(storeId, orderStatus, cursor, size); boolean hasNext = headerList.size() > size; if (hasNext) { @@ -89,7 +86,7 @@ private OwnerOrderListResponse getOwnerOrderList( // 3. order detail 검색 var orderIdList = headerList.stream().map(OrderSummaryRow::orderId).toList(); - var orderDetailList = orderRepositoryCustom.fetchOrderDetailList(orderIdList); + List orderDetailList = orderRepository.fetchOrderDetailList(orderIdList); // 4. orderId로 그룹핑 : productSummary 제작 Map> detailMap = diff --git a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderDetailRepository.java b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderDetailRepository.java index 5e2cb454..4dbf2987 100644 --- a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderDetailRepository.java +++ b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderDetailRepository.java @@ -2,13 +2,13 @@ import com.irum.come2us.domain.order.domain.entity.Order; import com.irum.come2us.domain.order.domain.entity.OrderDetail; +import io.lettuce.core.dynamic.annotation.Param; import java.util.List; import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository @@ -16,6 +16,16 @@ public interface OrderDetailRepository extends JpaRepository Optional findByOrderDetailId(UUID orderDetailId); + @Query( + """ + select od from OrderDetail od + join fetch od.order o + join fetch o.member m + where od.orderDetailId = :orderDetailId +""") + Optional findByOrderDetailIdWithOrderAndMember( + @Param("orderDetailId") UUID orderDetailId); + List findAllByOrder(Order order); @Modifying(clearAutomatically = true) diff --git a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepository.java b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepository.java index b850148f..af367714 100644 --- a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepository.java +++ b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepository.java @@ -1,5 +1,6 @@ package com.irum.come2us.domain.order.domain.repository; +import com.irum.come2us.domain.member.domain.entity.Member; import com.irum.come2us.domain.order.domain.entity.Order; import java.time.LocalDateTime; import java.util.List; @@ -12,7 +13,11 @@ import org.springframework.stereotype.Repository; @Repository -public interface OrderRepository extends JpaRepository { +public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { + Optional findByOrderIdAndMember(UUID orderId, Member member); + + List findAllByMember(Member member); + Optional findByOrderId(UUID orderId); @Query( diff --git a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepositoryCustom.java b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepositoryCustom.java index 8d254220..22a43842 100644 --- a/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepositoryCustom.java +++ b/src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepositoryCustom.java @@ -1,8 +1,12 @@ package com.irum.come2us.domain.order.domain.repository; +import com.irum.come2us.domain.member.domain.entity.Member; import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderDetailRow; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderSummaryRow; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderDetailRow; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderSummaryRow; +import java.time.LocalDate; import java.util.List; import java.util.UUID; @@ -11,4 +15,9 @@ List fetchOrderHeaderList( UUID storeId, OrderStatus orderStatus, UUID cursor, int size); List fetchOrderDetailList(List orderIdList); + + List fetchOrderListByMember( + Member member, LocalDate startDate, LocalDate endDate, UUID cursor, int size); + + List fetchOrderDetailListByMember(List orderIdList); } diff --git a/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/OrderRepositoryImpl.java b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/OrderRepositoryImpl.java index e61df15b..6a0f225c 100644 --- a/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/OrderRepositoryImpl.java +++ b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/OrderRepositoryImpl.java @@ -1,14 +1,23 @@ package com.irum.come2us.domain.order.infrastructure.repository; +import static com.querydsl.core.group.GroupBy.*; +import static java.util.Collections.*; + +import com.irum.come2us.domain.member.domain.entity.Member; +import com.irum.come2us.domain.member.domain.entity.QMember; import com.irum.come2us.domain.order.domain.entity.QOrder; import com.irum.come2us.domain.order.domain.entity.QOrderDetail; import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; import com.irum.come2us.domain.order.domain.repository.OrderRepositoryCustom; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderDetailRow; +import com.irum.come2us.domain.order.infrastructure.repository.dto.CustomerOrderSummaryRow; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderDetailRow; import com.irum.come2us.domain.order.infrastructure.repository.dto.OrderSummaryRow; +import com.irum.come2us.domain.refund.domain.entity.QRefund; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import java.time.LocalDate; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -24,6 +33,16 @@ private BooleanExpression ltCursor(UUID cursor, QOrder qOrder) { return cursor != null ? qOrder.orderId.lt(cursor) : null; } + /** createdAt >= startDate(00:00:00). null이면 필터 없음 */ + private BooleanExpression geStartDate(LocalDate startDate, QOrder o) { + return (startDate == null) ? null : o.createdAt.goe(startDate.atStartOfDay()); + } + + /** createdAt < (endDate + 1일 00:00:00). null이면 필터 없음 */ + private BooleanExpression ltEndDateExclusive(LocalDate endDate, QOrder o) { + return (endDate == null) ? null : o.createdAt.lt(endDate.plusDays(1).atStartOfDay()); + } + /** [상점] 주문 목록 조회 */ @Override public List fetchOrderHeaderList( @@ -65,6 +84,7 @@ public List fetchOrderDetailList(List orderIdList) { .select( Projections.constructor( OrderDetailRow.class, + od.order.orderId, od.orderDetailId, od.productName, od.quantity, @@ -74,4 +94,57 @@ public List fetchOrderDetailList(List orderIdList) { .where(od.order.orderId.in(orderIdList)) .fetch(); } + + /** 주목 목록 및 refundstatus 조회, pageing적용 */ + @Override + public List fetchOrderListByMember( + Member member, LocalDate startDate, LocalDate endDate, UUID cursor, int size) { + + QOrder o = QOrder.order; + QRefund r = QRefund.refund; + QMember m = QMember.member; + + return queryFactory + .select( + Projections.constructor( + CustomerOrderSummaryRow.class, + o.orderId, + o.createdAt, + r.refundStatus)) + .from(o) + .leftJoin(r) + .on(r.order.eq(o)) + .leftJoin(o.member, m) + .where( + ltCursor(cursor, o), + m.memberId.eq(member.getMemberId()), + geStartDate(startDate, o), + ltEndDateExclusive(endDate, o)) + .orderBy(o.orderId.desc()) + .limit(size + 1) + .fetch(); + } + + @Override + public List fetchOrderDetailListByMember(List orderIdList) { + if (orderIdList.isEmpty()) { + return List.of(); + } + QOrderDetail od = QOrderDetail.orderDetail; + + return queryFactory + .select( + Projections.constructor( + CustomerOrderDetailRow.class, + od.order.orderId, + od.orderDetailId, + od.productName, + od.optionName, + od.quantity, + od.price, + od.orderStatusIndi)) + .from(od) + .where(od.order.orderId.in(orderIdList)) + .fetch(); + } } diff --git a/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderDetailRow.java b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderDetailRow.java new file mode 100644 index 00000000..57e634c9 --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderDetailRow.java @@ -0,0 +1,14 @@ +package com.irum.come2us.domain.order.infrastructure.repository.dto; + +import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; +import java.util.UUID; + +/** 내부용 주문 상세 DTO */ +public record CustomerOrderDetailRow( + UUID orderId, + UUID orderDetailId, + String productName, + String optionName, + int quantity, + int price, + OrderStatus orderStatusIndi) {} diff --git a/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderSummaryRow.java b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderSummaryRow.java new file mode 100644 index 00000000..9676355b --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/order/infrastructure/repository/dto/CustomerOrderSummaryRow.java @@ -0,0 +1,9 @@ +package com.irum.come2us.domain.order.infrastructure.repository.dto; + +import com.irum.come2us.domain.refund.domain.entity.enums.RefundStatus; +import java.time.LocalDateTime; +import java.util.UUID; + +/** 내부용 주문 헤더 DTO (productList 없는 버전) */ +public record CustomerOrderSummaryRow( + UUID orderId, LocalDateTime orderAt, RefundStatus refundStatus) {} diff --git a/src/main/java/com/irum/come2us/domain/order/presentation/controller/CustomerOrderController.java b/src/main/java/com/irum/come2us/domain/order/presentation/controller/CustomerOrderController.java index 1bf56e56..980fdb3b 100644 --- a/src/main/java/com/irum/come2us/domain/order/presentation/controller/CustomerOrderController.java +++ b/src/main/java/com/irum/come2us/domain/order/presentation/controller/CustomerOrderController.java @@ -2,22 +2,45 @@ import com.irum.come2us.domain.order.application.service.CustomerOrderService; import com.irum.come2us.domain.order.presentation.dto.request.CustomerOrderRequest; +import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderListResponse; import com.irum.come2us.domain.order.presentation.dto.response.CustomerOrderResponse; +import com.irum.come2us.domain.order.presentation.dto.response.OrderDetailResponse; +import com.irum.come2us.domain.order.presentation.dto.response.OrderDetailStatusResponse; import jakarta.validation.Valid; +import java.time.LocalDate; +import java.util.UUID; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +@RequiredArgsConstructor @RestController @RequestMapping("orders/customer") -@RequiredArgsConstructor -@Slf4j public class CustomerOrderController { private final CustomerOrderService customerOrderService; + /** 주문 상태 조회 */ + @GetMapping("/order-detail/{orderDetailId}/delivery-status") + public OrderDetailStatusResponse orderDetailStatusGet( + @PathVariable(name = "orderDetailId") UUID orderDetailId) { + return customerOrderService.getOrderDetailStatus(orderDetailId); + } + + /** 주문 상세 조회 */ + @GetMapping("/{orderId}") + public OrderDetailResponse orderDetailGet(@PathVariable(name = "orderId") UUID orderId) { + return customerOrderService.getOrderDetail(orderId); + } + + /** 주문 목록 조회 */ + @GetMapping + public CustomerOrderListResponse orderListGet( + @RequestParam(required = false) UUID cursor, + @RequestParam int size, + @RequestParam(required = false) LocalDate startDate, + @RequestParam(required = false) LocalDate endDate) { + return customerOrderService.getOrderList(cursor, size, startDate, endDate); + } + @PostMapping public CustomerOrderResponse orderCreate(@Valid @RequestBody CustomerOrderRequest request) { return customerOrderService.prepareOrder(request); diff --git a/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/CustomerOrderListResponse.java b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/CustomerOrderListResponse.java new file mode 100644 index 00000000..5a487f6b --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/CustomerOrderListResponse.java @@ -0,0 +1,28 @@ +package com.irum.come2us.domain.order.presentation.dto.response; + +import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; +import com.irum.come2us.domain.refund.domain.entity.enums.RefundStatus; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import lombok.Builder; + +@Builder +public record CustomerOrderListResponse( + UUID nextCursor, Boolean hasNext, List orderList) { + @Builder + public record OrderResponse( + UUID orderId, + LocalDateTime orderAt, + RefundStatus refundStatus, + List productResponseList) {} + + @Builder + public record ProductResponse( + UUID orderDetailId, + String productName, + String optionName, + int quantity, + int price, + OrderStatus orderStatus) {} +} diff --git a/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailResponse.java b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailResponse.java new file mode 100644 index 00000000..b232132a --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailResponse.java @@ -0,0 +1,36 @@ +package com.irum.come2us.domain.order.presentation.dto.response; + +import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; +import com.irum.come2us.domain.payment.domain.entity.enums.PaymentMethod; +import com.irum.come2us.domain.payment.domain.entity.enums.PaymentStatus; +import com.irum.come2us.domain.refund.domain.entity.enums.RefundStatus; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Builder; + +@Builder +public record OrderDetailResponse( + LocalDateTime orderAt, + PaymentStatus paymentStatus, + PaymentMethod paymentMethod, + int deliveryFee, + int discountAmount, + int totalProductPrice, + int totalPaymentPrice, + OrderStatus orderStatusAll, + RefundStatus refundStatus, + String deliveryRequest, + AddressResponse address, + String recipientContact, + String recipientName, + List productResponseList) { + + @Builder + public record ProductResponse( + String productName, + String optionTitle, + int quantity, + int price, + LocalDate receivedDate) {} +} diff --git a/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailStatusResponse.java b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailStatusResponse.java new file mode 100644 index 00000000..e0e42071 --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/order/presentation/dto/response/OrderDetailStatusResponse.java @@ -0,0 +1,26 @@ +package com.irum.come2us.domain.order.presentation.dto.response; + +import com.irum.come2us.domain.order.domain.entity.OrderDetail; +import com.irum.come2us.domain.order.domain.entity.enums.OrderStatus; + +public record OrderDetailStatusResponse( + String productName, + int quantity, + String optionName, + AddressResponse address, + String recipientName, + OrderStatus orderStatus, + String trackingNumber, + String deliveryRequest) { + public static OrderDetailStatusResponse from(OrderDetail orderDetail) { + return new OrderDetailStatusResponse( + orderDetail.getProductName(), + orderDetail.getQuantity(), + orderDetail.getOptionName(), + AddressResponse.from(orderDetail.getOrder().getDeliveryAddress().getAddress()), + orderDetail.getOrder().getDeliveryAddress().getRecipientName(), + orderDetail.getOrderStatusIndi(), + orderDetail.getTrackingNumber(), + orderDetail.getOrder().getDeliveryRequest()); + } +} diff --git a/src/main/java/com/irum/come2us/domain/refund/domain/entity/Refund.java b/src/main/java/com/irum/come2us/domain/refund/domain/entity/Refund.java index 9638e6c4..79ae9381 100644 --- a/src/main/java/com/irum/come2us/domain/refund/domain/entity/Refund.java +++ b/src/main/java/com/irum/come2us/domain/refund/domain/entity/Refund.java @@ -6,7 +6,11 @@ import com.irum.come2us.global.domain.BaseEntity; import jakarta.persistence.*; import java.util.UUID; -import lombok.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; diff --git a/src/main/java/com/irum/come2us/domain/refund/domain/repository/RefundRepository.java b/src/main/java/com/irum/come2us/domain/refund/domain/repository/RefundRepository.java index afa14510..b8721a3c 100644 --- a/src/main/java/com/irum/come2us/domain/refund/domain/repository/RefundRepository.java +++ b/src/main/java/com/irum/come2us/domain/refund/domain/repository/RefundRepository.java @@ -12,6 +12,8 @@ @Repository public interface RefundRepository extends JpaRepository { + Optional findByOrder(Order order); + List findByRefundStatus(RefundStatus status); // RefundRepository 추후 orderRepository에서 가져오는 것으로 변경 예정 diff --git a/src/main/java/com/irum/come2us/global/presentation/advice/exception/errorcode/OrderErrorCode.java b/src/main/java/com/irum/come2us/global/presentation/advice/exception/errorcode/OrderErrorCode.java index 9dfef719..e6d88885 100644 --- a/src/main/java/com/irum/come2us/global/presentation/advice/exception/errorcode/OrderErrorCode.java +++ b/src/main/java/com/irum/come2us/global/presentation/advice/exception/errorcode/OrderErrorCode.java @@ -8,8 +8,8 @@ @AllArgsConstructor public enum OrderErrorCode implements BaseErrorCode { ORDER_NOT_FOUND(HttpStatus.NOT_FOUND, "주문을 찾을 수 없습니다."), + ORDER_FORBIDDEN(HttpStatus.FORBIDDEN, "해당 주문에 대해 권한이 없습니다"), INVALID_ORDER(HttpStatus.BAD_REQUEST, "유효하지 않은 주문입니다."), - ORDER_DETAIL_NOT_FOUND(HttpStatus.NOT_FOUND, "주문 상세를 찾을 수 없습니다."), ;