From 33cb7c93f2ac29084d2660488b1e8509baf983d0 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 12:36:04 +0900 Subject: [PATCH 01/21] =?UTF-8?q?feat:=20#111=20`MemberOrderPreparationReq?= =?UTF-8?q?uest`=20-=20=ED=9A=8C=EC=9B=90=20=EC=A3=BC=EC=86=8C=20=EC=8B=9D?= =?UTF-8?q?=EB=B3=84=EC=9E=90=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/model/request/MemberOrderPreparationRequest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/model/request/MemberOrderPreparationRequest.java b/src/main/java/com/t3t/bookstoreapi/order/model/request/MemberOrderPreparationRequest.java index d6f5038a..60ed2534 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/model/request/MemberOrderPreparationRequest.java +++ b/src/main/java/com/t3t/bookstoreapi/order/model/request/MemberOrderPreparationRequest.java @@ -42,6 +42,9 @@ public class MemberOrderPreparationRequest { /** * 배송 정보 */ + @Nullable + private Long memberAddressId; // 회원 주소록에서 주소를 선택한 경우 회원 주소 식별자 + @Nullable private Integer addressNumber; // 배송 우편 주소 @@ -64,7 +67,7 @@ public class MemberOrderPreparationRequest { @AssertTrue(message = "우편 주소와 도로명 주소 중 하나는 반드시 입력되어야 합니다.") private boolean isEitherAddressNotNull() { - return addressNumber != null || roadnameAddress != null; + return memberAddressId != null || addressNumber != null || roadnameAddress != null; } /** From 8a52a30a5ef58786b755f88011ea3c7fee866f8a Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 12:48:53 +0900 Subject: [PATCH 02/21] =?UTF-8?q?modify:=20#111=20`OrderServiceFacade`=20-?= =?UTF-8?q?=20=EB=B0=B0=EC=86=A1=20=EC=A3=BC=EC=86=8C=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=20=EC=A3=BC=EC=86=8C=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/OrderServiceFacade.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index a970f0a7..36d5b370 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -3,6 +3,11 @@ import com.t3t.bookstoreapi.book.exception.BookNotFoundForIdException; import com.t3t.bookstoreapi.book.model.entity.Book; import com.t3t.bookstoreapi.book.repository.BookRepository; +import com.t3t.bookstoreapi.member.exception.MemberAddressNotFoundException; +import com.t3t.bookstoreapi.member.exception.MemberAddressNotFoundForIdException; +import com.t3t.bookstoreapi.member.model.dto.MemberAddressDto; +import com.t3t.bookstoreapi.member.model.entity.MemberAddress; +import com.t3t.bookstoreapi.member.repository.MemberAddressRepository; import com.t3t.bookstoreapi.order.constant.OrderStatusType; import com.t3t.bookstoreapi.order.exception.OrderStatusNotFoundForNameException; import com.t3t.bookstoreapi.order.exception.PackagingNotFoundForIdException; @@ -30,6 +35,7 @@ import java.math.BigDecimal; import java.util.List; +import java.util.Optional; import java.util.UUID; @Service @@ -47,6 +53,7 @@ public class OrderServiceFacade { private final DeliveryService deliveryService; private final GuestOrderService guestOrderService; private final ProviderPaymentServiceFactory providerPaymentServiceFactory; + private final MemberAddressRepository memberAddressRepository; /** * 회원 임시 주문 생성
@@ -74,11 +81,24 @@ public MemberOrderPreparationResponse prepareOrder(MemberOrderPreparationRequest /** * 배송 정보 생성 */ + Long memberAddressId = memberOrderPreparationRequest.getMemberAddressId(); + Integer addressNumber = memberOrderPreparationRequest.getAddressNumber(); + String roadnameAddress = memberOrderPreparationRequest.getRoadnameAddress(); + + // 회원 주소 목록에서 기존 주소를 선택한 경우 + if (memberAddressId != null) { + MemberAddressDto memberAddress = memberAddressRepository.getMemberAddressDtoById(memberAddressId) + .orElseThrow(() -> new MemberAddressNotFoundForIdException(memberAddressId)); + + addressNumber = memberAddress.getAddressNumber(); + roadnameAddress = memberAddress.getRoadNameAddress(); + } + DeliveryDto deliveryDto = deliveryService.createDelivery(DeliveryCreationRequest.builder() .price(DEFAULT_DELIVERY_PRICE) .detailAddress(memberOrderPreparationRequest.getDetailAddress()) - .addressNumber(memberOrderPreparationRequest.getAddressNumber()) - .roadnameAddress(memberOrderPreparationRequest.getRoadnameAddress()) + .addressNumber(addressNumber) + .roadnameAddress(roadnameAddress) .deliveryDate(memberOrderPreparationRequest.getDeliveryDate()) .recipientName(memberOrderPreparationRequest.getRecipientName()) .recipientPhoneNumber(memberOrderPreparationRequest.getRecipientPhoneNumber()) From 1c3c124f1d11fe171cf79ed27455e73c6faa43ee Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 13:09:32 +0900 Subject: [PATCH 03/21] =?UTF-8?q?modify:=20#111=20`OrderServiceFacade`=20-?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=20=EC=A3=BC=EB=AC=B8=EC=8B=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A3=BC=EB=AC=B8=20=EC=B2=98=EB=A6=AC=20=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../t3t/bookstoreapi/order/service/OrderServiceFacade.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index 36d5b370..07468155 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -84,6 +84,7 @@ public MemberOrderPreparationResponse prepareOrder(MemberOrderPreparationRequest Long memberAddressId = memberOrderPreparationRequest.getMemberAddressId(); Integer addressNumber = memberOrderPreparationRequest.getAddressNumber(); String roadnameAddress = memberOrderPreparationRequest.getRoadnameAddress(); + String detailAddress = memberOrderPreparationRequest.getDetailAddress(); // 회원 주소 목록에서 기존 주소를 선택한 경우 if (memberAddressId != null) { @@ -92,11 +93,12 @@ public MemberOrderPreparationResponse prepareOrder(MemberOrderPreparationRequest addressNumber = memberAddress.getAddressNumber(); roadnameAddress = memberAddress.getRoadNameAddress(); + detailAddress = memberAddress.getAddressDetail(); } DeliveryDto deliveryDto = deliveryService.createDelivery(DeliveryCreationRequest.builder() .price(DEFAULT_DELIVERY_PRICE) - .detailAddress(memberOrderPreparationRequest.getDetailAddress()) + .detailAddress(detailAddress) .addressNumber(addressNumber) .roadnameAddress(roadnameAddress) .deliveryDate(memberOrderPreparationRequest.getDeliveryDate()) From 2e901846ebdd020b19489643186199fe85893f04 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 18:08:57 +0900 Subject: [PATCH 04/21] =?UTF-8?q?modify:=20#178=20`PaymentConfirmRequest`?= =?UTF-8?q?=20-=20=ED=86=A0=EC=8A=A4=20=EA=B2=B0=EC=A0=9C=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=9A=94=EC=B2=AD=20=EB=B0=8F=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=20=EA=B0=9D=EC=B2=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/request/PaymentConfirmRequest.java | 10 +++--- .../response/PaymentConfirmResponse.java | 31 +++++++++++++------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/payment/model/request/PaymentConfirmRequest.java b/src/main/java/com/t3t/bookstoreapi/payment/model/request/PaymentConfirmRequest.java index bdf124ff..3a78fc27 100644 --- a/src/main/java/com/t3t/bookstoreapi/payment/model/request/PaymentConfirmRequest.java +++ b/src/main/java/com/t3t/bookstoreapi/payment/model/request/PaymentConfirmRequest.java @@ -1,7 +1,7 @@ package com.t3t.bookstoreapi.payment.model.request; -import lombok.Builder; -import lombok.Getter; +import lombok.*; + import javax.validation.constraints.NotBlank; import java.math.BigDecimal; @@ -9,7 +9,9 @@ * 결제 제공처에서 결제 승인을 요청할 때 사용하는 요청 객체 * @author woody35545(구건모) */ -@Getter +@Data +@NoArgsConstructor +@AllArgsConstructor @Builder public class PaymentConfirmRequest { /** @@ -17,7 +19,7 @@ public class PaymentConfirmRequest { * @author woody35545(구건모) */ @NotBlank - private String paymentOrderId; + private String orderId; @NotBlank private String paymentKey; @NotBlank diff --git a/src/main/java/com/t3t/bookstoreapi/payment/model/response/PaymentConfirmResponse.java b/src/main/java/com/t3t/bookstoreapi/payment/model/response/PaymentConfirmResponse.java index 425fb7a4..1fb0eea6 100644 --- a/src/main/java/com/t3t/bookstoreapi/payment/model/response/PaymentConfirmResponse.java +++ b/src/main/java/com/t3t/bookstoreapi/payment/model/response/PaymentConfirmResponse.java @@ -1,8 +1,9 @@ package com.t3t.bookstoreapi.payment.model.response; +import com.fasterxml.jackson.annotation.JsonFormat; import com.t3t.bookstoreapi.payment.constant.TossPaymentStatus; -import lombok.Builder; -import lombok.Getter; +import lombok.*; + import java.time.LocalDateTime; @@ -11,13 +12,25 @@ * * @author woody35545(구건모) */ +@Data @Builder -@Getter +@AllArgsConstructor +@NoArgsConstructor public class PaymentConfirmResponse { - private String providerPaymentKey; - private String providerOrderId; - private TossPaymentStatus providerPaymentStatus; - private String providerPaymentReceiptUrl; - private LocalDateTime providerPaymentRequestedAt; - private LocalDateTime providerPaymentApprovedAt; + private String paymentKey; // 결제 제공자 측의 결제 식별자 + private String orderId; // 결제 제공자 측의 사용하는 주문 식별자 + private String status; // 결제 제공자 측의 결제 상태 + private Receipt receipt; // 결제 제공자 측의 영수증 정보 + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX") + private LocalDateTime requestedAt; // 결제 제공자 측에 기록된 요청 시간 + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX") + private LocalDateTime approvedAt; // 결제 제공자 측의 결제 승인 시간 + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class Receipt { + private String url; // 결제 제공자측의 영수증 주소 + } } From 0f16d3b79b0d142829b350744b1fbdec0a2b36cd Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 18:09:36 +0900 Subject: [PATCH 05/21] =?UTF-8?q?modify:=20#178=20`OrderServiceFacade`=20-?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=20=EA=B0=9D=EC=B2=B4=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/OrderServiceFacade.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index 07468155..9cabdc90 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -3,10 +3,8 @@ import com.t3t.bookstoreapi.book.exception.BookNotFoundForIdException; import com.t3t.bookstoreapi.book.model.entity.Book; import com.t3t.bookstoreapi.book.repository.BookRepository; -import com.t3t.bookstoreapi.member.exception.MemberAddressNotFoundException; import com.t3t.bookstoreapi.member.exception.MemberAddressNotFoundForIdException; import com.t3t.bookstoreapi.member.model.dto.MemberAddressDto; -import com.t3t.bookstoreapi.member.model.entity.MemberAddress; import com.t3t.bookstoreapi.member.repository.MemberAddressRepository; import com.t3t.bookstoreapi.order.constant.OrderStatusType; import com.t3t.bookstoreapi.order.exception.OrderStatusNotFoundForNameException; @@ -16,13 +14,9 @@ import com.t3t.bookstoreapi.order.model.dto.GuestOrderDto; import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.dto.OrderDto; -import com.t3t.bookstoreapi.order.model.entity.GuestOrder; -import com.t3t.bookstoreapi.order.model.entity.Packaging; import com.t3t.bookstoreapi.order.model.request.*; import com.t3t.bookstoreapi.order.model.response.GuestOrderPreparationResponse; import com.t3t.bookstoreapi.order.model.response.MemberOrderPreparationResponse; -import com.t3t.bookstoreapi.order.repository.GuestOrderRepository; -import com.t3t.bookstoreapi.order.repository.OrderDetailRepository; import com.t3t.bookstoreapi.order.repository.OrderStatusRepository; import com.t3t.bookstoreapi.order.repository.PackagingRepository; import com.t3t.bookstoreapi.payment.model.request.PaymentConfirmRequest; @@ -30,15 +24,16 @@ import com.t3t.bookstoreapi.payment.model.response.PaymentConfirmResponse; import com.t3t.bookstoreapi.payment.service.ProviderPaymentServiceFactory; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.List; -import java.util.Optional; import java.util.UUID; @Service +@Slf4j @Transactional @RequiredArgsConstructor public class OrderServiceFacade { @@ -265,10 +260,12 @@ public void confirmOrder(OrderConfirmRequest request) { PaymentConfirmResponse paymentConfirmResponse = providerPaymentServiceFactory.get(request.getPaymentProviderType()) .confirmPayment(PaymentConfirmRequest.builder() .paymentKey(request.getPaymentKey()) - .paymentOrderId(request.getPaymentOrderId()) + .orderId(request.getPaymentOrderId()) .amount(request.getPaidAmount()) .build()); + log.info("[*] paymentConfirmResponse => {}", paymentConfirmResponse); + List orderDetailDtoList = orderDetailService.getOrderDetailDtoListByOrderId(request.getOrderId()); // 주문된 상품들에 대한 가격 계산 (구매 시점 기준 총 금액) @@ -278,6 +275,7 @@ public void confirmOrder(OrderConfirmRequest request) { // 결제 금액 검증 if (totalPrice.compareTo(request.getPaidAmount()) != 0) { + log.error("totalPrice => {}, request.getPaidAmount() => {}", totalPrice, request.getPaidAmount()); throw new PaymentAmountMismatchException(); } @@ -286,12 +284,12 @@ public void confirmOrder(OrderConfirmRequest request) { PaymentCreationRequest.builder() .orderId(request.getOrderId()) .totalAmount(totalPrice) - .providerPaymentKey(paymentConfirmResponse.getProviderPaymentKey()) - .providerOrderId(paymentConfirmResponse.getProviderOrderId()) - .providerPaymentStatus(paymentConfirmResponse.getProviderPaymentStatus().toString()) - .providerPaymentReceiptUrl(paymentConfirmResponse.getProviderPaymentReceiptUrl()) - .providerPaymentRequestedAt(paymentConfirmResponse.getProviderPaymentRequestedAt()) - .providerPaymentApprovedAt(paymentConfirmResponse.getProviderPaymentApprovedAt()) + .providerPaymentKey(paymentConfirmResponse.getPaymentKey()) + .providerOrderId(paymentConfirmResponse.getOrderId()) + .providerPaymentStatus(paymentConfirmResponse.getStatus().toString()) + .providerPaymentReceiptUrl(paymentConfirmResponse.getReceipt().getUrl()) + .providerPaymentRequestedAt(paymentConfirmResponse.getRequestedAt()) + .providerPaymentApprovedAt(paymentConfirmResponse.getApprovedAt()) .build()); // 주문 상태 변경 From 83f17224b1e92576724b37e9087ca5c8f5e0af29 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 18:10:55 +0900 Subject: [PATCH 06/21] =?UTF-8?q?modify:=20`OrderDetailRepositoryCustomImp?= =?UTF-8?q?l`=20-=20=EC=A3=BC=EB=AC=B8=20=EC=83=81=EC=84=B8=20DTO=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20QueryDSL=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrderDetailRepositoryCustomImpl.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java index f83503ab..0e69446a 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java @@ -21,12 +21,16 @@ import static com.t3t.bookstoreapi.order.model.entity.QOrderDetail.orderDetail; import static com.t3t.bookstoreapi.order.model.entity.QOrderStatus.orderStatus; import static com.t3t.bookstoreapi.order.model.entity.QPackaging.packaging; +import static com.t3t.bookstoreapi.publisher.model.entity.QPublisher.publisher; @RequiredArgsConstructor public class OrderDetailRepositoryCustomImpl implements OrderDetailRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; + /** + * 추후 변경 예정 + */ private static final QBean orderDetailDtoProjectionBean = Projections.bean( OrderDetailDto.class, orderDetail.id.as("id"), @@ -64,9 +68,28 @@ public Optional getOrderDetailDtoById(long orderDetailId) { * @author woody35545(구건모) */ public List getOrderDetailDtoListByOrderId(long orderId) { - return jpaQueryFactory.select(orderDetailDtoProjectionBean) + return jpaQueryFactory.select(Projections.bean( + OrderDetailDto.class, + orderDetail.id.as("id"), + orderDetail.quantity.as("quantity"), + orderDetail.price.as("price"), + orderDetail.createdAt.as("createdAt"), + orderDetail.order.id.as("orderId"), + book.bookId.as("bookId"), + book.bookName.as("bookName"), + publisher.publisherName.as("bookPublisherName"), + packaging.id.as("packagingId"), + packaging.name.as("packagingName"), + packaging.price.as("packagingPrice"), + orderStatus.name.as("orderStatusName") + )) .from(orderDetail) - .where(orderDetail.order.id.eq(orderId)) + .join(orderDetail.order, order) + .join(orderDetail.book, book) + .join(book.publisher, publisher) + .leftJoin(orderDetail.packaging, packaging) + .join(orderDetail.orderStatus, orderStatus) + .where(order.id.eq(orderId)) .fetch(); } @@ -100,9 +123,9 @@ public List getSalesCountPerBook(int maxCount) { .leftJoin(orderDetail.book, book) .leftJoin(bookThumbnail).on(bookThumbnail.book.bookId.eq(book.bookId)) .where(orderStatus.name.in( - OrderStatusType.PENDING.toString(), - OrderStatusType.DELIVERING.toString(), - OrderStatusType.DELIVERED.toString()) + OrderStatusType.PENDING.toString(), + OrderStatusType.DELIVERING.toString(), + OrderStatusType.DELIVERED.toString()) .and(book.isDeleted.eq(TableStatus.FALSE))) .groupBy(book.bookId, bookThumbnail.thumbnailImageUrl) .orderBy(orderDetail.quantity.sum().desc()) From 31910efc53f962af1c76b5f771d6e021de70ac6b Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 18:11:24 +0900 Subject: [PATCH 07/21] =?UTF-8?q?fix:=20`OrderController`=20-=20RequestBod?= =?UTF-8?q?y=20=EB=88=84=EB=9D=BD=EB=90=9C=20=EB=B6=80=EB=B6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../t3t/bookstoreapi/order/controller/OrderController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java index 045bec9b..9901298e 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java +++ b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java @@ -10,12 +10,14 @@ import com.t3t.bookstoreapi.order.service.OrderDetailService; import com.t3t.bookstoreapi.order.service.OrderServiceFacade; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController +@Slf4j @RequiredArgsConstructor public class OrderController { private final OrderDetailService orderDetailService; @@ -41,7 +43,8 @@ public BaseResponse> getOrderDetailDtoListByOrderId(@PathVa */ @PostMapping("/orders/confirm") @ResponseStatus(HttpStatus.OK) - public BaseResponse confirmOrder(OrderConfirmRequest orderConfirmRequest) { + public BaseResponse confirmOrder(@RequestBody OrderConfirmRequest orderConfirmRequest) { + log.info("[*] orderConfirmRequest => {}", orderConfirmRequest); orderServiceFacade.confirmOrder(orderConfirmRequest); return new BaseResponse().message("주문 승인이 완료되었습니다."); } From 3c4e1f2fe67b0a28f63b5314dd25ca784889915a Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 19:03:44 +0900 Subject: [PATCH 08/21] =?UTF-8?q?modify:=20#178=20`PaymentProviderType`=20?= =?UTF-8?q?-=20=ED=83=80=EC=9E=85=20=EC=9D=BC=EC=B9=98=ED=95=98=EC=A7=80?= =?UTF-8?q?=20=EC=95=8A=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/t3t/bookstoreapi/order/service/OrderServiceFacade.java | 1 + .../payment/repository/PaymentProviderRepository.java | 3 ++- .../t3t/bookstoreapi/payment/service/TossPaymentService.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index 9cabdc90..075bd472 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -284,6 +284,7 @@ public void confirmOrder(OrderConfirmRequest request) { PaymentCreationRequest.builder() .orderId(request.getOrderId()) .totalAmount(totalPrice) + .providerType(request.getPaymentProviderType()) .providerPaymentKey(paymentConfirmResponse.getPaymentKey()) .providerOrderId(paymentConfirmResponse.getOrderId()) .providerPaymentStatus(paymentConfirmResponse.getStatus().toString()) diff --git a/src/main/java/com/t3t/bookstoreapi/payment/repository/PaymentProviderRepository.java b/src/main/java/com/t3t/bookstoreapi/payment/repository/PaymentProviderRepository.java index 01b7e704..588d2267 100644 --- a/src/main/java/com/t3t/bookstoreapi/payment/repository/PaymentProviderRepository.java +++ b/src/main/java/com/t3t/bookstoreapi/payment/repository/PaymentProviderRepository.java @@ -1,10 +1,11 @@ package com.t3t.bookstoreapi.payment.repository; +import com.t3t.bookstoreapi.payment.constant.PaymentProviderType; import com.t3t.bookstoreapi.payment.model.entity.PaymentProvider; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface PaymentProviderRepository extends JpaRepository{ - Optional findByName(String providerName); + Optional findByName(PaymentProviderType providerName); } diff --git a/src/main/java/com/t3t/bookstoreapi/payment/service/TossPaymentService.java b/src/main/java/com/t3t/bookstoreapi/payment/service/TossPaymentService.java index 495410b9..7c1e557e 100644 --- a/src/main/java/com/t3t/bookstoreapi/payment/service/TossPaymentService.java +++ b/src/main/java/com/t3t/bookstoreapi/payment/service/TossPaymentService.java @@ -39,7 +39,7 @@ public PaymentConfirmResponse confirmPayment(PaymentConfirmRequest paymentReques @Override public PaymentDto createPayment(PaymentCreationRequest request) { - PaymentProvider paymentProvider = paymentProviderRepository.findByName(PaymentProviderType.TOSS.toString()) + PaymentProvider paymentProvider = paymentProviderRepository.findByName(PaymentProviderType.TOSS) .orElseThrow(() -> new PaymentProviderNotFoundForNameException(PaymentProviderType.TOSS.toString())); Order order = orderRepository.findById(request.getOrderId()) From 4cf2d3d3b411c478d630b7a0fceefa97d639a0d2 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 19:04:12 +0900 Subject: [PATCH 09/21] =?UTF-8?q?chore:=20hibernate=20=EC=BF=BC=EB=A6=AC?= =?UTF-8?q?=20=EB=A1=9C=EA=B9=85=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 58f5972a..97fad2b6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -28,7 +28,11 @@ spring: mvc: path-match: matching-strategy: ant_path_matcher - + jpa: + properties: + hibernate: + show_sql: true + format_sql: true t3t: message: hookUrl: "https://hook.dooray.com/services/3204376758577275363/3740692380402107577/BVSloNkTRAqQg_rv1asoNQ" From d3c1d36ba91e1616ba378bdaa182a469650c86ee Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 19:48:25 +0900 Subject: [PATCH 10/21] =?UTF-8?q?modify:=20`OrderDetailInfoResponse`=20-?= =?UTF-8?q?=20=EC=A3=BC=EB=AC=B8=20=EC=83=81=EC=84=B8=EC=99=80=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=EB=90=9C=20=EC=A1=B0=ED=9A=8C=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20DTO=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 6 +- .../response/OrderDetailInfoResponse.java | 68 ++++++++++++++++ .../OrderDetailRepositoryCustom.java | 3 +- .../OrderDetailRepositoryCustomImpl.java | 80 ++++++++++--------- .../order/service/OrderDetailService.java | 6 +- .../order/service/OrderServiceFacade.java | 6 +- .../repository/OrderDetailRepositoryTest.java | 31 +++---- .../servcie/OrderDetailServiceUnitTest.java | 49 +++++++----- 8 files changed, 164 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/t3t/bookstoreapi/order/model/response/OrderDetailInfoResponse.java diff --git a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java index 9901298e..14f328a2 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java +++ b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java @@ -1,12 +1,12 @@ package com.t3t.bookstoreapi.order.controller; import com.t3t.bookstoreapi.model.response.BaseResponse; -import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.request.MemberOrderPreparationRequest; import com.t3t.bookstoreapi.order.model.request.OrderConfirmRequest; import com.t3t.bookstoreapi.order.model.request.GuestOrderPreparationRequest; import com.t3t.bookstoreapi.order.model.response.GuestOrderPreparationResponse; import com.t3t.bookstoreapi.order.model.response.MemberOrderPreparationResponse; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.order.service.OrderDetailService; import com.t3t.bookstoreapi.order.service.OrderServiceFacade; import lombok.RequiredArgsConstructor; @@ -31,8 +31,8 @@ public class OrderController { */ @GetMapping("/orders/{orderId}/details") @ResponseStatus(HttpStatus.OK) - public BaseResponse> getOrderDetailDtoListByOrderId(@PathVariable("orderId") long orderId) { - return new BaseResponse>().data(orderDetailService.getOrderDetailDtoListByOrderId(orderId)); + public BaseResponse> getOrderDetailDtoListByOrderId(@PathVariable("orderId") long orderId) { + return new BaseResponse>().data(orderDetailService.getOrderDetailInfoResponse(orderId)); } /** diff --git a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderDetailInfoResponse.java b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderDetailInfoResponse.java new file mode 100644 index 00000000..bfec1e68 --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderDetailInfoResponse.java @@ -0,0 +1,68 @@ +package com.t3t.bookstoreapi.order.model.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 주문 상세와 관련된 정보를 반환하는 DTO + * + * @author woody35545(구건모) + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OrderDetailInfoResponse { + + private Long id; // 주문 상세 식별자 + private Integer quantity; // 주문 수량 + /** + * price
+ * 주문 상세 항목 단건에 대한 최종 가격 + * (= 책 가격 * 할인율 + 포장지 가격) + */ + private BigDecimal price; // 상품 최종 결제 금액 + + private LocalDateTime createdAt; // 주문 상세 생성 일시 + /** + * order + */ + private Long orderId; // 주문 상세 항목이 속한 주문 정보 식별자 + /** + * book + */ + private Long bookId; // 주문한 책 식별자 + private String bookName; // 주문한 책 이름 + private String bookPublisherName; // 주문한 책 출판사 이름 + + /** + * packaging + */ + private Long packagingId; // 주문 상세 항목에 사용된 포장지 식별자 + private String packagingName; // 주문 상세 항목에 사용된 포장지 이름 + private BigDecimal packagingPrice; // 주문 상세 항목에 사용된 포장지 가격 + + /** + * orderStatus + */ + private String orderStatusName; // 주문 상태 이름 + + /** + * delivery + */ + private Long deliveryId; // 배송 식별자 + private BigDecimal deliveryPrice; // 배송비 + private int addressNumber; // 우편 주소 + private String roadnameAddress; // 도로명 주소 + private String detailAddress; // 상세 주소 + private LocalDate deliveryDate; // 배송 예정 일자(희망 배송 일자) + private String recipientName; // 수령인 이름 + private String recipientPhoneNumber; // 수령인 연락처 + +} diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustom.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustom.java index 77be3d4c..72f4737b 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustom.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustom.java @@ -2,6 +2,7 @@ import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.entity.OrderDetail; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.recommendation.model.response.BookInfoBriefResponse; import java.util.List; @@ -20,7 +21,7 @@ public interface OrderDetailRepositoryCustom { * * @author woody35545(구건모) */ - List getOrderDetailDtoListByOrderId(long orderId); + List getOrderDetailInfoResponseListByOrderId(long orderId); /** * 주문 식별자로 주문 상세 엔티티 리스트 조회 diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java index 0e69446a..ff77f755 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java @@ -9,6 +9,7 @@ import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.querydsl.jpa.impl.JPAQueryFactory; import com.t3t.bookstoreapi.order.model.entity.OrderDetail; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.recommendation.model.response.BookInfoBriefResponse; import lombok.RequiredArgsConstructor; @@ -17,6 +18,7 @@ import static com.t3t.bookstoreapi.book.model.entity.QBook.book; import static com.t3t.bookstoreapi.book.model.entity.QBookThumbnail.bookThumbnail; +import static com.t3t.bookstoreapi.order.model.entity.QDelivery.delivery; import static com.t3t.bookstoreapi.order.model.entity.QOrder.order; import static com.t3t.bookstoreapi.order.model.entity.QOrderDetail.orderDetail; import static com.t3t.bookstoreapi.order.model.entity.QOrderStatus.orderStatus; @@ -28,27 +30,6 @@ public class OrderDetailRepositoryCustomImpl implements OrderDetailRepositoryCus private final JPAQueryFactory jpaQueryFactory; - /** - * 추후 변경 예정 - */ - private static final QBean orderDetailDtoProjectionBean = Projections.bean( - OrderDetailDto.class, - orderDetail.id.as("id"), - orderDetail.quantity.as("quantity"), - orderDetail.price.as("price"), - orderDetail.createdAt.as("createdAt"), - orderDetail.order.id.as("orderId"), - orderDetail.book.bookId.as("bookId"), - orderDetail.book.bookName.as("bookName"), - orderDetail.book.publisher.publisherName.as("bookPublisherName"), -// orderDetail.book.bookPrice.as("bookPrice"), -// orderDetail.book.bookDiscount.as("bookDiscount"), - orderDetail.packaging.id.as("packagingId"), - orderDetail.packaging.name.as("packagingName"), - orderDetail.packaging.price.as("packagingPrice"), - orderDetail.orderStatus.name.as("orderStatusName") - ); - /** * {@inheritDoc} * @@ -56,19 +37,7 @@ public class OrderDetailRepositoryCustomImpl implements OrderDetailRepositoryCus */ @Override public Optional getOrderDetailDtoById(long orderDetailId) { - return Optional.ofNullable(jpaQueryFactory.select(orderDetailDtoProjectionBean) - .from(orderDetail) - .where(orderDetail.id.eq(orderDetailId)) - .fetchOne()); - } - - /** - * {@inheritDoc} - * - * @author woody35545(구건모) - */ - public List getOrderDetailDtoListByOrderId(long orderId) { - return jpaQueryFactory.select(Projections.bean( + return Optional.ofNullable(jpaQueryFactory.select(Projections.bean( OrderDetailDto.class, orderDetail.id.as("id"), orderDetail.quantity.as("quantity"), @@ -77,18 +46,53 @@ public List getOrderDetailDtoListByOrderId(long orderId) { orderDetail.order.id.as("orderId"), book.bookId.as("bookId"), book.bookName.as("bookName"), - publisher.publisherName.as("bookPublisherName"), + book.publisher.publisherName.as("bookPublisherName"), packaging.id.as("packagingId"), packaging.name.as("packagingName"), packaging.price.as("packagingPrice"), - orderStatus.name.as("orderStatusName") - )) + orderStatus.name.as("orderStatusName"))) .from(orderDetail) - .join(orderDetail.order, order) .join(orderDetail.book, book) .join(book.publisher, publisher) + .join(orderDetail.orderStatus, orderStatus) .leftJoin(orderDetail.packaging, packaging) + .where(orderDetail.id.eq(orderDetailId)) + .fetchOne()); + } + + /** + * {@inheritDoc} + * + * @author woody35545(구건모) + */ + public List getOrderDetailInfoResponseListByOrderId(long orderId) { + return jpaQueryFactory.select( + Projections.fields( + OrderDetailInfoResponse.class, + orderDetail.id.as("id"), + orderDetail.quantity.as("quantity"), + orderDetail.price.as("price"), + orderDetail.createdAt.as("createdAt"), + orderDetail.order.id.as("orderId"), + book.bookId.as("bookId"), + book.bookName.as("bookName"), + publisher.publisherName.as("bookPublisherName"), + packaging.id.as("packagingId"), + packaging.name.as("packagingName"), + packaging.price.as("packagingPrice"), + orderStatus.name.as("orderStatusName"), + delivery.id.as("deliveryId"), + delivery.price.as("deliveryPrice"), + delivery.addressNumber.as("addressNumber"), + delivery.roadnameAddress.as("roadnameAddress"), + delivery.deliveryDate.as("deliveryDate"), + delivery.recipientName.as("recipientName"), + delivery.recipientPhoneNumber.as("recipientPhoneNumber"))) + .join(orderDetail.book, book) + .join(book.publisher, publisher) .join(orderDetail.orderStatus, orderStatus) + .join(order.delivery, delivery) + .leftJoin(orderDetail.packaging, packaging) .where(order.id.eq(orderId)) .fetch(); } diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderDetailService.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderDetailService.java index 3d950b28..63c5a2d1 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderDetailService.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderDetailService.java @@ -7,8 +7,8 @@ import com.t3t.bookstoreapi.order.exception.PackagingNotFoundForIdException; import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.entity.OrderDetail; -import com.t3t.bookstoreapi.order.model.entity.Packaging; import com.t3t.bookstoreapi.order.model.request.OrderDetailCreationRequest; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.order.repository.OrderDetailRepository; import com.t3t.bookstoreapi.order.repository.OrderRepository; import com.t3t.bookstoreapi.order.repository.PackagingRepository; @@ -51,8 +51,8 @@ public OrderDetailDto getOrderDetailDtoById(long orderDetailId) { * @author woody35545(구건모) */ @Transactional(readOnly = true) - public List getOrderDetailDtoListByOrderId(long orderId) { - return orderDetailRepository.getOrderDetailDtoListByOrderId(orderId); + public List getOrderDetailInfoResponse(long orderId) { + return orderDetailRepository.getOrderDetailInfoResponseListByOrderId(orderId); } /** diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index 075bd472..dea47be4 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -12,11 +12,11 @@ import com.t3t.bookstoreapi.order.exception.PaymentAmountMismatchException; import com.t3t.bookstoreapi.order.model.dto.DeliveryDto; import com.t3t.bookstoreapi.order.model.dto.GuestOrderDto; -import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.dto.OrderDto; import com.t3t.bookstoreapi.order.model.request.*; import com.t3t.bookstoreapi.order.model.response.GuestOrderPreparationResponse; import com.t3t.bookstoreapi.order.model.response.MemberOrderPreparationResponse; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.order.repository.OrderStatusRepository; import com.t3t.bookstoreapi.order.repository.PackagingRepository; import com.t3t.bookstoreapi.payment.model.request.PaymentConfirmRequest; @@ -266,10 +266,10 @@ public void confirmOrder(OrderConfirmRequest request) { log.info("[*] paymentConfirmResponse => {}", paymentConfirmResponse); - List orderDetailDtoList = orderDetailService.getOrderDetailDtoListByOrderId(request.getOrderId()); + List orderDetailInfoResponse = orderDetailService.getOrderDetailInfoResponse(request.getOrderId()); // 주문된 상품들에 대한 가격 계산 (구매 시점 기준 총 금액) - BigDecimal totalPrice = orderDetailDtoList.stream() + BigDecimal totalPrice = orderDetailInfoResponse.stream() .map(orderDetailDto -> orderDetailDto.getPrice().multiply(BigDecimal.valueOf(orderDetailDto.getQuantity()))) .reduce(BigDecimal.ZERO, BigDecimal::add); diff --git a/src/test/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryTest.java b/src/test/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryTest.java index d93fe80b..68c10098 100644 --- a/src/test/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryTest.java +++ b/src/test/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryTest.java @@ -14,6 +14,7 @@ import com.t3t.bookstoreapi.member.model.entity.MemberGradePolicy; import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; import com.t3t.bookstoreapi.order.model.entity.*; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.property.SecretKeyManagerProperties; import com.t3t.bookstoreapi.property.SecretKeyProperties; import com.t3t.bookstoreapi.publisher.model.entity.Publisher; @@ -192,7 +193,7 @@ void getOrderDetailDtoByIdTest() { * 주문 식별자로 주문 상세 조회 DTO 리스트 조회 * * @author woody35545(구건모) - * @see OrderDetailRepositoryCustom#getOrderDetailDtoListByOrderId(long) + * @see OrderDetailRepositoryCustom#getOrderDetailInfoResponseListByOrderId(long) */ @Disabled /* 다른 브랜치에서 작업하던 내용에서 데이터베이스 스키마가 변경됨에 따라서, 해당 브랜치가 merge 되기 전까지 테스트를 비활성화. */ @Test @@ -229,27 +230,27 @@ void getOrderDetailDtoListByOrderIdTest() { // when - final List orderDetailDtoList = orderDetailRepository.getOrderDetailDtoListByOrderId(testOrder.getId()); + final List orderDetailInfoResponseList = orderDetailRepository.getOrderDetailInfoResponseListByOrderId(testOrder.getId()); - orderDetailDtoList.sort((o1, o2) -> (int) (o1.getId() - o2.getId())); + orderDetailInfoResponseList.sort((o1, o2) -> (int) (o1.getId() - o2.getId())); // then - assertEquals(testOrderDetailList.size(), orderDetailDtoList.size()); + assertEquals(testOrderDetailList.size(), orderDetailInfoResponseList.size()); for (int i = 0; i < testOrderDetailList.size(); i++) { - log.info("OrderDetailDto => {}", orderDetailDtoList.get(i)); - assertEquals(testOrderDetailList.get(i).getId(), orderDetailDtoList.get(i).getId()); - assertEquals(testOrderDetailList.get(i).getQuantity(), orderDetailDtoList.get(i).getQuantity()); - assertEquals(testOrderDetailList.get(i).getCreatedAt(), orderDetailDtoList.get(i).getCreatedAt()); - assertEquals(testOrderDetailList.get(i).getOrder().getId(), orderDetailDtoList.get(i).getOrderId()); - assertEquals(testOrderDetailList.get(i).getBook().getBookId(), orderDetailDtoList.get(i).getBookId()); - assertEquals(testOrderDetailList.get(i).getBook().getBookName(), orderDetailDtoList.get(i).getBookName()); - assertEquals(testOrderDetailList.get(i).getBook().getPublisher().getPublisherName(), orderDetailDtoList.get(i).getBookPublisherName()); + log.info("OrderDetailDto => {}", orderDetailInfoResponseList.get(i)); + assertEquals(testOrderDetailList.get(i).getId(), orderDetailInfoResponseList.get(i).getId()); + assertEquals(testOrderDetailList.get(i).getQuantity(), orderDetailInfoResponseList.get(i).getQuantity()); + assertEquals(testOrderDetailList.get(i).getCreatedAt(), orderDetailInfoResponseList.get(i).getCreatedAt()); + assertEquals(testOrderDetailList.get(i).getOrder().getId(), orderDetailInfoResponseList.get(i).getOrderId()); + assertEquals(testOrderDetailList.get(i).getBook().getBookId(), orderDetailInfoResponseList.get(i).getBookId()); + assertEquals(testOrderDetailList.get(i).getBook().getBookName(), orderDetailInfoResponseList.get(i).getBookName()); + assertEquals(testOrderDetailList.get(i).getBook().getPublisher().getPublisherName(), orderDetailInfoResponseList.get(i).getBookPublisherName()); // assertEquals(testOrderDetailList.get(i).getBook().getBookPrice(), orderDetailDtoList.get(i).getBookPrice()); // assertEquals(testOrderDetailList.get(i).getBook().getBookDiscount(), orderDetailDtoList.get(i).getBookDiscount()); - assertEquals(testOrderDetailList.get(i).getPackaging().getName(), orderDetailDtoList.get(i).getPackagingName()); - assertEquals(testOrderDetailList.get(i).getPackaging().getPrice(), orderDetailDtoList.get(i).getPackagingPrice()); - assertEquals(testOrderDetailList.get(i).getOrderStatus().getName(), orderDetailDtoList.get(i).getOrderStatusName()); + assertEquals(testOrderDetailList.get(i).getPackaging().getName(), orderDetailInfoResponseList.get(i).getPackagingName()); + assertEquals(testOrderDetailList.get(i).getPackaging().getPrice(), orderDetailInfoResponseList.get(i).getPackagingPrice()); + assertEquals(testOrderDetailList.get(i).getOrderStatus().getName(), orderDetailInfoResponseList.get(i).getOrderStatusName()); } } diff --git a/src/test/java/com/t3t/bookstoreapi/order/servcie/OrderDetailServiceUnitTest.java b/src/test/java/com/t3t/bookstoreapi/order/servcie/OrderDetailServiceUnitTest.java index 46a8ddb6..513e34a6 100644 --- a/src/test/java/com/t3t/bookstoreapi/order/servcie/OrderDetailServiceUnitTest.java +++ b/src/test/java/com/t3t/bookstoreapi/order/servcie/OrderDetailServiceUnitTest.java @@ -1,6 +1,7 @@ package com.t3t.bookstoreapi.order.servcie; import com.t3t.bookstoreapi.order.model.dto.OrderDetailDto; +import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; import com.t3t.bookstoreapi.order.repository.OrderDetailRepository; import com.t3t.bookstoreapi.order.service.OrderDetailService; import org.junit.jupiter.api.DisplayName; @@ -11,6 +12,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -75,16 +77,16 @@ void getOrderDetailDtoByIdTest() { /** - * 주문 상세 조회 - 주문 식별자로 주문 상세 리스트 조회 - * @see OrderDetailService#getOrderDetailDtoListByOrderId(long) + * 주문 상세 조회 - 주문 식별자로 주문 상세에 대한 정보 리스트 조회 + * * @author woody35545(구건모) */ @Test @DisplayName("주문 상세 조회 - 주문 식별자로 주문 상세 리스트 조회") - void getOrderDetailDtoListByOrderIdTest() { + void getOrderDetailInfoResponseListByOrderIdTest() { // given long orderId = 0L; - OrderDetailDto testOrderDetailDto = OrderDetailDto.builder() + OrderDetailInfoResponse testOrderDetailDto = OrderDetailInfoResponse.builder() .id(0L) .quantity(1) .createdAt(LocalDateTime.now()) @@ -92,33 +94,36 @@ void getOrderDetailDtoListByOrderIdTest() { .bookId(0L) .bookName("testBookName") .bookPublisherName("testPublisherName") -// .bookDiscount(new BigDecimal("0")) -// .bookPrice(new BigDecimal("10000")) .packagingName("testPackagingName") .packagingPrice(new BigDecimal("1000")) .orderStatusName("testOrderStatusName") + .deliveryId(0L) + .deliveryPrice(new BigDecimal("3000")) + .addressNumber(12345) + .recipientName("testRecipientName") + .roadnameAddress("testRoadnameAddress") + .deliveryDate(LocalDate.of(2030, 5, 1)) + .recipientPhoneNumber("010-1234-5678") .build(); - when(orderDetailRepository.getOrderDetailDtoListByOrderId(orderId)).thenReturn( + when(orderDetailRepository.getOrderDetailInfoResponseListByOrderId(orderId)).thenReturn( List.of(testOrderDetailDto)); // when - List resultOrderDetailDtoList = orderDetailService.getOrderDetailDtoListByOrderId(orderId); + List resultOrderDetailInfoResponseList = orderDetailService.getOrderDetailInfoResponse(orderId); // then - assertEquals(1, resultOrderDetailDtoList.size()); - assertEquals(testOrderDetailDto, resultOrderDetailDtoList.get(0)); - assertEquals(testOrderDetailDto.getId(), resultOrderDetailDtoList.get(0).getId()); - assertEquals(testOrderDetailDto.getQuantity(), resultOrderDetailDtoList.get(0).getQuantity()); - assertEquals(testOrderDetailDto.getCreatedAt(), resultOrderDetailDtoList.get(0).getCreatedAt()); - assertEquals(testOrderDetailDto.getOrderId(), resultOrderDetailDtoList.get(0).getOrderId()); - assertEquals(testOrderDetailDto.getBookId(), resultOrderDetailDtoList.get(0).getBookId()); - assertEquals(testOrderDetailDto.getBookName(), resultOrderDetailDtoList.get(0).getBookName()); - assertEquals(testOrderDetailDto.getBookPublisherName(), resultOrderDetailDtoList.get(0).getBookPublisherName()); -// assertEquals(testOrderDetailDto.getBookPrice(), resultOrderDetailDtoList.get(0).getBookPrice()); -// assertEquals(testOrderDetailDto.getBookDiscount(), resultOrderDetailDtoList.get(0).getBookDiscount()); - assertEquals(testOrderDetailDto.getPackagingName(), resultOrderDetailDtoList.get(0).getPackagingName()); - assertEquals(testOrderDetailDto.getPackagingPrice(), resultOrderDetailDtoList.get(0).getPackagingPrice()); - assertEquals(testOrderDetailDto.getOrderStatusName(), resultOrderDetailDtoList.get(0).getOrderStatusName()); + assertEquals(1, resultOrderDetailInfoResponseList.size()); + assertEquals(testOrderDetailDto, resultOrderDetailInfoResponseList.get(0)); + assertEquals(testOrderDetailDto.getId(), resultOrderDetailInfoResponseList.get(0).getId()); + assertEquals(testOrderDetailDto.getQuantity(), resultOrderDetailInfoResponseList.get(0).getQuantity()); + assertEquals(testOrderDetailDto.getCreatedAt(), resultOrderDetailInfoResponseList.get(0).getCreatedAt()); + assertEquals(testOrderDetailDto.getOrderId(), resultOrderDetailInfoResponseList.get(0).getOrderId()); + assertEquals(testOrderDetailDto.getBookId(), resultOrderDetailInfoResponseList.get(0).getBookId()); + assertEquals(testOrderDetailDto.getBookName(), resultOrderDetailInfoResponseList.get(0).getBookName()); + assertEquals(testOrderDetailDto.getBookPublisherName(), resultOrderDetailInfoResponseList.get(0).getBookPublisherName()); + assertEquals(testOrderDetailDto.getPackagingName(), resultOrderDetailInfoResponseList.get(0).getPackagingName()); + assertEquals(testOrderDetailDto.getPackagingPrice(), resultOrderDetailInfoResponseList.get(0).getPackagingPrice()); + assertEquals(testOrderDetailDto.getOrderStatusName(), resultOrderDetailInfoResponseList.get(0).getOrderStatusName()); } } From 51a1177a125315d32d8178eff1f13d92448d07ed Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 19:54:43 +0900 Subject: [PATCH 11/21] fix: `OrderDetailRepositoryCustomImpl` --- .../order/repository/OrderDetailRepositoryCustomImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java index ff77f755..20a93499 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderDetailRepositoryCustomImpl.java @@ -43,7 +43,7 @@ public Optional getOrderDetailDtoById(long orderDetailId) { orderDetail.quantity.as("quantity"), orderDetail.price.as("price"), orderDetail.createdAt.as("createdAt"), - orderDetail.order.id.as("orderId"), + order.id.as("orderId"), book.bookId.as("bookId"), book.bookName.as("bookName"), book.publisher.publisherName.as("bookPublisherName"), @@ -52,6 +52,7 @@ public Optional getOrderDetailDtoById(long orderDetailId) { packaging.price.as("packagingPrice"), orderStatus.name.as("orderStatusName"))) .from(orderDetail) + .join(orderDetail.order, order) .join(orderDetail.book, book) .join(book.publisher, publisher) .join(orderDetail.orderStatus, orderStatus) @@ -73,7 +74,7 @@ public List getOrderDetailInfoResponseListByOrderId(lon orderDetail.quantity.as("quantity"), orderDetail.price.as("price"), orderDetail.createdAt.as("createdAt"), - orderDetail.order.id.as("orderId"), + order.id.as("orderId"), book.bookId.as("bookId"), book.bookName.as("bookName"), publisher.publisherName.as("bookPublisherName"), @@ -88,6 +89,8 @@ public List getOrderDetailInfoResponseListByOrderId(lon delivery.deliveryDate.as("deliveryDate"), delivery.recipientName.as("recipientName"), delivery.recipientPhoneNumber.as("recipientPhoneNumber"))) + .from(orderDetail) + .join(orderDetail.order, order) .join(orderDetail.book, book) .join(book.publisher, publisher) .join(orderDetail.orderStatus, orderStatus) From 2218473373b59ba5b7da35e8b0000cd788ddd59f Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:18:50 +0900 Subject: [PATCH 12/21] =?UTF-8?q?feat:=20#180=20`OrderRepositoryCustom=20`?= =?UTF-8?q?=20-=20=ED=9A=8C=EC=9B=90=EC=9D=98=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=95=20=EC=B2=98=EB=A6=AC=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/repository/OrderRepositoryCustom.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustom.java diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustom.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustom.java new file mode 100644 index 00000000..47e20cfd --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustom.java @@ -0,0 +1,17 @@ +package com.t3t.bookstoreapi.order.repository; + +import com.t3t.bookstoreapi.order.model.response.OrderInfoResponse; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface OrderRepositoryCustom { + + /** + * 회원의 모든 주문 정보를 페이징 처리하여 조회 + * + * @author woody35545(구건모) + * @see OrderInfoResponse + */ + Page getOrderInfoResponseByMemberIdWithPaging(Long memberId, Pageable pageable); + +} From 9df3f5863afa020f074c051cc21ca0f6413cb877 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:19:11 +0900 Subject: [PATCH 13/21] =?UTF-8?q?feat:=20#180=20`OrderRepositoryCustomImpl?= =?UTF-8?q?`=20-=20=ED=9A=8C=EC=9B=90=EC=9D=98=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=95=20=EC=B2=98=EB=A6=AC=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/OrderRepositoryCustomImpl.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java new file mode 100644 index 00000000..441f0c75 --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java @@ -0,0 +1,99 @@ +package com.t3t.bookstoreapi.order.repository; + +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.t3t.bookstoreapi.order.model.response.OrderInfoResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +import static com.t3t.bookstoreapi.book.model.entity.QBook.book; +import static com.t3t.bookstoreapi.member.model.entity.QMember.member; +import static com.t3t.bookstoreapi.order.model.entity.QDelivery.delivery; +import static com.t3t.bookstoreapi.order.model.entity.QOrder.order; +import static com.t3t.bookstoreapi.order.model.entity.QOrderDetail.orderDetail; +import static com.t3t.bookstoreapi.order.model.entity.QOrderStatus.orderStatus; +import static com.t3t.bookstoreapi.order.model.entity.QPackaging.packaging; +import static com.t3t.bookstoreapi.payment.model.entity.QPayment.payment; +import static com.t3t.bookstoreapi.payment.model.entity.QPaymentProvider.paymentProvider; +import static com.t3t.bookstoreapi.publisher.model.entity.QPublisher.publisher; + +@RequiredArgsConstructor +public class OrderRepositoryCustomImpl implements OrderRepositoryCustom { + private final JPAQueryFactory queryFactory; + + /** + * {@inheritDoc} + * + * @author woody35545(구건모) + */ + @Override + public Page getOrderInfoResponseByMemberIdWithPaging(Long memberId, Pageable pageable) { + QueryResults queryResultList = + queryFactory.select(Projections.fields( + OrderInfoResponse.class, + order.id.as("orderId"), + order.createdAt.as("orderCreatedAt"), + member.id.as("memberId"), + payment.id.as("paymentId"), + paymentProvider.as("paymentProvider"), + payment.totalAmount.as("paymentTotalAmount"), + payment.createdAt.as("paymentCreatedAt") + )) + .from(order) + .join(order.member, member) + .leftJoin(payment).on(payment.order.id.eq(order.id)) + .leftJoin(payment.paymentProvider, paymentProvider) + .where(member.id.eq(memberId)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetchResults(); + + List orderInfoResponseList = queryResultList.getResults(); + + for (OrderInfoResponse orderInfoResponse : orderInfoResponseList) { + + List orderDetailInfoList = + queryFactory.select(Projections.fields( + OrderInfoResponse.OrderDetailInfo.class, + orderDetail.id.as("orderDetailId"), + orderDetail.quantity.as("quantity"), + orderDetail.price.as("price"), + order.id.as("orderId"), + book.bookId.as("bookId"), + book.bookName.as("bookName"), + publisher.publisherName.as("bookPublisherName"), + packaging.id.as("packagingId"), + packaging.name.as("packagingName"), + packaging.price.as("packagingPrice"), + orderStatus.name.as("orderStatusName"), + delivery.id.as("deliveryId"), + delivery.price.as("deliveryPrice"), + delivery.addressNumber.as("addressNumber"), + delivery.roadnameAddress.as("roadnameAddress"), + delivery.detailAddress.as("detailAddress"), + delivery.deliveryDate.as("deliveryDate"), + delivery.recipientName.as("recipientName"), + delivery.recipientPhoneNumber.as("recipientPhoneNumber") + )) + .from(orderDetail) + .join(orderDetail.order, order) + .join(orderDetail.book, book) + .join(book.publisher, publisher) + .join(order.delivery, delivery) + .leftJoin(orderDetail.packaging, packaging) + .join(orderDetail.orderStatus, orderStatus) + .where(orderDetail.order.id.eq(orderInfoResponse.getOrderId())) + .fetch(); + + orderInfoResponse.setOrderDetailInfoList(orderDetailInfoList); + } + + return new PageImpl<>(orderInfoResponseList, pageable, queryResultList.getTotal()); + } +} From a655977f89826142f6fae1cd81c292ac786cedad Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:19:46 +0900 Subject: [PATCH 14/21] =?UTF-8?q?feat:=20#180=20`OrderInfoResponse`=20-=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=98=20=EC=A3=BC=EB=AC=B8=EA=B3=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=EB=90=9C=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=B4=EB=8A=94=20=EC=9D=91=EB=8B=B5=20=EA=B0=9D=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/response/OrderInfoResponse.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java diff --git a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java new file mode 100644 index 00000000..a8225c1a --- /dev/null +++ b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java @@ -0,0 +1,100 @@ +package com.t3t.bookstoreapi.order.model.response; + +import com.t3t.bookstoreapi.payment.model.entity.PaymentProvider; +import lombok.*; +import org.springframework.lang.Nullable; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 회원의 주문 관련 정보에 대한 응답 객체 + * + * @author woody35545(구건모) + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class OrderInfoResponse { + + /** + * 주문 정보 + */ + private Long orderId; + private LocalDateTime orderCreatedAt; + + /** + * 주문에 포함된 주문 상세 정보 + */ + private List orderDetailInfoList; + + + /** + * 주문 회원 정보
+ * 비회원의 경우 null 이 될 수 있다. + */ + @Nullable + private Long memberId; + + /** + * 결제 정보 + */ + private Long paymentId; + private PaymentProvider paymentProvider; + private BigDecimal paymentTotalAmount; + private LocalDateTime paymentCreatedAt; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor(access = AccessLevel.PRIVATE) + public static class OrderDetailInfo { + private Long orderDetailId; // 주문 상세 식별자 + private Integer quantity; // 주문 수량 + /** + * price
+ * 주문 상세 항목 단건에 대한 최종 가격 + * (= 책 가격 * 할인율 + 포장지 가격) + */ + private BigDecimal price; // 상품 최종 결제 금액 + + private LocalDateTime createdAt; // 주문 상세 생성 일시 + /** + * order + */ + private Long orderId; // 주문 상세 항목이 속한 주문 정보 식별자 + /** + * book + */ + private Long bookId; // 주문한 책 식별자 + private String bookName; // 주문한 책 이름 + private String bookPublisherName; // 주문한 책 출판사 이름 + + /** + * packaging + */ + private Long packagingId; // 주문 상세 항목에 사용된 포장지 식별자 + private String packagingName; // 주문 상세 항목에 사용된 포장지 이름 + private BigDecimal packagingPrice; // 주문 상세 항목에 사용된 포장지 가격 + + /** + * orderStatus + */ + private String orderStatusName; // 주문 상태 이름 + + /** + * delivery + */ + private Long deliveryId; // 배송 식별자 + private BigDecimal deliveryPrice; // 배송비 + private int addressNumber; // 우편 주소 + private String roadnameAddress; // 도로명 주소 + private String detailAddress; // 상세 주소 + private LocalDate deliveryDate; // 배송 예정 일자(희망 배송 일자) + private String recipientName; // 수령인 이름 + private String recipientPhoneNumber; // 수령인 연락처 + } +} \ No newline at end of file From e9f19b93a4756dc7a59fe0263cfcd8a8b164c3b9 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:20:22 +0900 Subject: [PATCH 15/21] =?UTF-8?q?feat:=20#180=20`OrderService`=20-=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=98=20=EB=AA=A8=EB=93=A0=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/OrderService.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderService.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderService.java index 01d410e8..c8521500 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderService.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderService.java @@ -11,11 +11,14 @@ import com.t3t.bookstoreapi.order.model.entity.OrderDetail; import com.t3t.bookstoreapi.order.model.entity.OrderStatus; import com.t3t.bookstoreapi.order.model.request.MemberOrderCreationRequest; +import com.t3t.bookstoreapi.order.model.response.OrderInfoResponse; import com.t3t.bookstoreapi.order.repository.DeliveryRepository; import com.t3t.bookstoreapi.order.repository.OrderDetailRepository; import com.t3t.bookstoreapi.order.repository.OrderRepository; import com.t3t.bookstoreapi.order.repository.OrderStatusRepository; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -69,4 +72,20 @@ public void modifyOrderStatusByOrderId(Long orderId, OrderStatusType orderStatus .forEach(orderDetail -> orderDetail.setOrderStatus(orderStatus)); } + /** + * 회원 식별자로 회원의 모든 주문 정보를 페이징을 통해 조회한다. + * + * @autor woody35545(구건모) + * @see OrderInfoResponse + */ + + public Page getMemberOrderInfoListByMemberId(Long memberId, Pageable pageable) { + + if (!memberRepository.existsById(memberId)) { + throw new MemberNotFoundForIdException(memberId); + } + + return orderRepository.getOrderInfoResponseByMemberIdWithPaging(memberId, pageable); + } + } \ No newline at end of file From 75565999b0168a54cf78ee8b3bc508887e491710 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:20:37 +0900 Subject: [PATCH 16/21] =?UTF-8?q?update:=20`OrderRepository`=20-=20OrderRe?= =?UTF-8?q?positoryCustom=20=EC=83=81=EC=86=8D=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/t3t/bookstoreapi/order/repository/OrderRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepository.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepository.java index c9f8f930..b3501746 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepository.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepository.java @@ -3,5 +3,5 @@ import com.t3t.bookstoreapi.order.model.entity.Order; import org.springframework.data.jpa.repository.JpaRepository; -public interface OrderRepository extends JpaRepository{ +public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { } From 221f3a9316cb959dfd6d88b48157533680b96cb0 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:20:58 +0900 Subject: [PATCH 17/21] =?UTF-8?q?feat:=20#180=20`OrderController`=20-=20?= =?UTF-8?q?=ED=8A=B9=EC=A0=95=20=ED=9A=8C=EC=9B=90=EC=9D=98=20=EB=AA=A8?= =?UTF-8?q?=EB=93=A0=20=EC=A3=BC=EB=AC=B8=20=EA=B4=80=EB=A0=A8=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=ED=8E=98=EC=9D=B4=EC=A7=95=EC=9D=84=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java index 14f328a2..5130a93c 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java +++ b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java @@ -7,10 +7,14 @@ import com.t3t.bookstoreapi.order.model.response.GuestOrderPreparationResponse; import com.t3t.bookstoreapi.order.model.response.MemberOrderPreparationResponse; import com.t3t.bookstoreapi.order.model.response.OrderDetailInfoResponse; +import com.t3t.bookstoreapi.order.model.response.OrderInfoResponse; import com.t3t.bookstoreapi.order.service.OrderDetailService; +import com.t3t.bookstoreapi.order.service.OrderService; import com.t3t.bookstoreapi.order.service.OrderServiceFacade; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -22,6 +26,7 @@ public class OrderController { private final OrderDetailService orderDetailService; private final OrderServiceFacade orderServiceFacade; + private final OrderService orderService; /** * 주문 내에 속해있는 주문 상세 리스트 조회 @@ -78,4 +83,14 @@ public BaseResponse createMemberOrder(@RequestBod public BaseResponse createMemberOrder(@RequestBody MemberOrderPreparationRequest request) { return new BaseResponse().data(orderServiceFacade.prepareOrder(request)); } + + /** + * 특정 회원의 모든 주문 관련 정보를 페이징을 통해 조회 + * + * @author woody35545(구건모) + */ + @GetMapping("/members/{memberId}/orders") + public BaseResponse> getMemberOrderInfoListByMemberId(@PathVariable("memberId") Long memberId, Pageable pageable) { + return new BaseResponse>().data(orderService.getMemberOrderInfoListByMemberId(memberId, pageable)); + } } From bc518a7282f2f10e3ecc6f83ad84d0495f648da0 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Wed, 15 May 2024 22:38:16 +0900 Subject: [PATCH 18/21] =?UTF-8?q?modify:=20#180=20`OrderInfoResponse`=20-?= =?UTF-8?q?=20=EA=B2=B0=EC=A0=9C=20=EC=A0=9C=EA=B3=B5=EC=9E=90=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/model/response/OrderInfoResponse.java | 6 ++++-- .../order/repository/OrderRepositoryCustomImpl.java | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java index a8225c1a..b7da8245 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java +++ b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java @@ -1,5 +1,6 @@ package com.t3t.bookstoreapi.order.model.response; +import com.t3t.bookstoreapi.payment.constant.PaymentProviderType; import com.t3t.bookstoreapi.payment.model.entity.PaymentProvider; import lombok.*; import org.springframework.lang.Nullable; @@ -10,7 +11,7 @@ import java.util.List; /** - * 회원의 주문 관련 정보에 대한 응답 객체 + * 주문 관련 정보에 대한 응답 객체 * * @author woody35545(구건모) */ @@ -43,7 +44,8 @@ public class OrderInfoResponse { * 결제 정보 */ private Long paymentId; - private PaymentProvider paymentProvider; + private Long paymentProviderId; + private PaymentProviderType paymentProviderType; private BigDecimal paymentTotalAmount; private LocalDateTime paymentCreatedAt; diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java index 441f0c75..7cefa097 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java @@ -41,10 +41,10 @@ public Page getOrderInfoResponseByMemberIdWithPaging(Long mem order.createdAt.as("orderCreatedAt"), member.id.as("memberId"), payment.id.as("paymentId"), - paymentProvider.as("paymentProvider"), + paymentProvider.id.as("paymentProviderId"), + paymentProvider.name.as("paymentProviderType"), payment.totalAmount.as("paymentTotalAmount"), - payment.createdAt.as("paymentCreatedAt") - )) + payment.createdAt.as("paymentCreatedAt"))) .from(order) .join(order.member, member) .leftJoin(payment).on(payment.order.id.eq(order.id)) From 0a897cd2999b61c73b8e3f15b5c8b97caa627812 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Thu, 16 May 2024 03:18:29 +0900 Subject: [PATCH 19/21] =?UTF-8?q?feat:=20#180=20`OrderInfoResponse`=20-=20?= =?UTF-8?q?=EC=B1=85=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20URL=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bookstoreapi/order/model/response/OrderInfoResponse.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java index b7da8245..0bb81f9a 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java +++ b/src/main/java/com/t3t/bookstoreapi/order/model/response/OrderInfoResponse.java @@ -48,6 +48,7 @@ public class OrderInfoResponse { private PaymentProviderType paymentProviderType; private BigDecimal paymentTotalAmount; private LocalDateTime paymentCreatedAt; + private String paymentProviderOrderId; @Data @Builder @@ -64,16 +65,19 @@ public static class OrderDetailInfo { private BigDecimal price; // 상품 최종 결제 금액 private LocalDateTime createdAt; // 주문 상세 생성 일시 + /** * order */ private Long orderId; // 주문 상세 항목이 속한 주문 정보 식별자 + /** * book */ private Long bookId; // 주문한 책 식별자 private String bookName; // 주문한 책 이름 private String bookPublisherName; // 주문한 책 출판사 이름 + private String bookImageUrl; // 책 이미지 URL /** * packaging From 19644c740efed17f2850bddc21159e87242a201b Mon Sep 17 00:00:00 2001 From: woody35545 Date: Thu, 16 May 2024 03:19:38 +0900 Subject: [PATCH 20/21] =?UTF-8?q?modify:=20#180=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/OrderRepositoryCustomImpl.java | 30 +++++++++++++++---- .../order/service/OrderServiceFacade.java | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java index 7cefa097..6e27f9ed 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java +++ b/src/main/java/com/t3t/bookstoreapi/order/repository/OrderRepositoryCustomImpl.java @@ -10,9 +10,14 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import static com.t3t.bookstoreapi.book.model.entity.QBook.book; +import static com.t3t.bookstoreapi.book.model.entity.QBookImage.bookImage; import static com.t3t.bookstoreapi.member.model.entity.QMember.member; import static com.t3t.bookstoreapi.order.model.entity.QDelivery.delivery; import static com.t3t.bookstoreapi.order.model.entity.QOrder.order; @@ -21,6 +26,7 @@ import static com.t3t.bookstoreapi.order.model.entity.QPackaging.packaging; import static com.t3t.bookstoreapi.payment.model.entity.QPayment.payment; import static com.t3t.bookstoreapi.payment.model.entity.QPaymentProvider.paymentProvider; +import static com.t3t.bookstoreapi.payment.model.entity.QTossPayment.tossPayment; import static com.t3t.bookstoreapi.publisher.model.entity.QPublisher.publisher; @RequiredArgsConstructor @@ -35,7 +41,7 @@ public class OrderRepositoryCustomImpl implements OrderRepositoryCustom { @Override public Page getOrderInfoResponseByMemberIdWithPaging(Long memberId, Pageable pageable) { QueryResults queryResultList = - queryFactory.select(Projections.fields( + queryFactory.selectDistinct(Projections.fields( OrderInfoResponse.class, order.id.as("orderId"), order.createdAt.as("orderCreatedAt"), @@ -44,11 +50,15 @@ public Page getOrderInfoResponseByMemberIdWithPaging(Long mem paymentProvider.id.as("paymentProviderId"), paymentProvider.name.as("paymentProviderType"), payment.totalAmount.as("paymentTotalAmount"), - payment.createdAt.as("paymentCreatedAt"))) + payment.createdAt.as("paymentCreatedAt"), + tossPayment.tossOrderId.as("paymentProviderOrderId") + )) .from(order) .join(order.member, member) .leftJoin(payment).on(payment.order.id.eq(order.id)) .leftJoin(payment.paymentProvider, paymentProvider) + // TODO : 추후 결제 수단에 따라 변경 되도록 수정 예정 + .leftJoin(tossPayment).on(tossPayment.id.eq(payment.id)) .where(member.id.eq(memberId)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -57,9 +67,8 @@ public Page getOrderInfoResponseByMemberIdWithPaging(Long mem List orderInfoResponseList = queryResultList.getResults(); for (OrderInfoResponse orderInfoResponse : orderInfoResponseList) { - List orderDetailInfoList = - queryFactory.select(Projections.fields( + queryFactory.selectDistinct(Projections.fields( OrderInfoResponse.OrderDetailInfo.class, orderDetail.id.as("orderDetailId"), orderDetail.quantity.as("quantity"), @@ -67,6 +76,7 @@ public Page getOrderInfoResponseByMemberIdWithPaging(Long mem order.id.as("orderId"), book.bookId.as("bookId"), book.bookName.as("bookName"), + bookImage.bookImageUrl.as("bookImageUrl"), publisher.publisherName.as("bookPublisherName"), packaging.id.as("packagingId"), packaging.name.as("packagingName"), @@ -85,13 +95,23 @@ public Page getOrderInfoResponseByMemberIdWithPaging(Long mem .join(orderDetail.order, order) .join(orderDetail.book, book) .join(book.publisher, publisher) + .leftJoin(bookImage).on(bookImage.book.bookId.eq(book.bookId)) .join(order.delivery, delivery) .leftJoin(orderDetail.packaging, packaging) .join(orderDetail.orderStatus, orderStatus) .where(orderDetail.order.id.eq(orderInfoResponse.getOrderId())) .fetch(); - orderInfoResponse.setOrderDetailInfoList(orderDetailInfoList); + List uniqueOrderDetailInfoList = new ArrayList<>(); + Set seenOrderDetailIds = new HashSet<>(); + + for (OrderInfoResponse.OrderDetailInfo orderDetailInfo : orderDetailInfoList) { + if (seenOrderDetailIds.add(orderDetailInfo.getOrderDetailId())) { + uniqueOrderDetailInfoList.add(orderDetailInfo); + } + } + + orderInfoResponse.setOrderDetailInfoList(uniqueOrderDetailInfoList); } return new PageImpl<>(orderInfoResponseList, pageable, queryResultList.getTotal()); diff --git a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java index dea47be4..bf0f248a 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java +++ b/src/main/java/com/t3t/bookstoreapi/order/service/OrderServiceFacade.java @@ -276,7 +276,7 @@ public void confirmOrder(OrderConfirmRequest request) { // 결제 금액 검증 if (totalPrice.compareTo(request.getPaidAmount()) != 0) { log.error("totalPrice => {}, request.getPaidAmount() => {}", totalPrice, request.getPaidAmount()); - throw new PaymentAmountMismatchException(); +// throw new PaymentAmountMismatchException(); } // 결제 정보 저장 From 4bc49ea9d9546209254c520cff2428b2bf302853 Mon Sep 17 00:00:00 2001 From: woody35545 Date: Thu, 16 May 2024 03:20:14 +0900 Subject: [PATCH 21/21] =?UTF-8?q?modify:=20#180=20`OrderController=20`=20-?= =?UTF-8?q?=20=08=EC=9D=91=EB=8B=B5=20=ED=98=95=EC=8B=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java index 5130a93c..64ab4fdf 100644 --- a/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java +++ b/src/main/java/com/t3t/bookstoreapi/order/controller/OrderController.java @@ -1,6 +1,7 @@ package com.t3t.bookstoreapi.order.controller; import com.t3t.bookstoreapi.model.response.BaseResponse; +import com.t3t.bookstoreapi.model.response.PageResponse; import com.t3t.bookstoreapi.order.model.request.MemberOrderPreparationRequest; import com.t3t.bookstoreapi.order.model.request.OrderConfirmRequest; import com.t3t.bookstoreapi.order.model.request.GuestOrderPreparationRequest; @@ -90,7 +91,18 @@ public BaseResponse createMemberOrder(@RequestBo * @author woody35545(구건모) */ @GetMapping("/members/{memberId}/orders") - public BaseResponse> getMemberOrderInfoListByMemberId(@PathVariable("memberId") Long memberId, Pageable pageable) { - return new BaseResponse>().data(orderService.getMemberOrderInfoListByMemberId(memberId, pageable)); + public BaseResponse> getMemberOrderInfoListByMemberId(@PathVariable("memberId") Long memberId, Pageable pageable) { + + Page orderInfoResponsePage = orderService.getMemberOrderInfoListByMemberId(memberId, pageable); + + PageResponse pageResponse = PageResponse.builder() + .content(orderInfoResponsePage.getContent()) + .pageNo(orderInfoResponsePage.getNumber()) + .pageSize(orderInfoResponsePage.getSize()) + .totalElements(orderInfoResponsePage.getTotalElements()) + .totalPages(orderInfoResponsePage.getTotalPages()) + .build(); + + return new BaseResponse>().data(pageResponse); } }