-
Notifications
You must be signed in to change notification settings - Fork 1
[Feature] 일반 회원(Customer) Refund 생성/조회 구현 #179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b5c40c5
feature #164: refund 생성 구현
willjsw 4341f46
feature #164: refund 상세 조회 구현
willjsw fd702df
refactor #164: refundId -> response 필드 추가
willjsw fa6ebd2
refactor #164: CustomerRefundDetailResponse 파라미터 구조 수정
willjsw 82ad0a7
refactor #164: 코드 병합
willjsw c28d2ab
refactor #164: CustomerRefund & StoreRefund 통합
willjsw ed4d3b1
refactor #164: PR 리뷰 수정사항 반영
willjsw 8310cc9
refactor #164: Order/Refund Repository 충돌 해결
willjsw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/main/java/com/irum/come2us/domain/order/domain/repository/OrderDetailRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.irum.come2us.domain.order.domain.repository; | ||
|
|
||
| import com.irum.come2us.domain.order.domain.entity.Order; | ||
| import com.irum.come2us.domain.order.domain.entity.OrderDetail; | ||
| import java.util.List; | ||
| import java.util.UUID; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface OrderDetailRepository extends JpaRepository<OrderDetail, UUID> { | ||
|
|
||
| List<OrderDetail> findAllByOrder(Order order); | ||
| } |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/irum/come2us/domain/order/domain/repository/OrderRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.irum.come2us.domain.order.domain.repository; | ||
|
|
||
| import com.irum.come2us.domain.order.domain.entity.Order; | ||
| import java.util.Optional; | ||
| import java.util.UUID; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Query; | ||
| import org.springframework.data.repository.query.Param; | ||
|
|
||
| public interface OrderRepository extends JpaRepository<Order, UUID> { | ||
| @Query("SELECT o FROM Order o JOIN FETCH o.deliveryAddress da WHERE o.orderId =: orderId") | ||
| Optional<Order> findOrderWithAddress(@Param("orderId") UUID orderId); | ||
| } | ||
75 changes: 75 additions & 0 deletions
75
src/main/java/com/irum/come2us/domain/refund/application/service/CustomerRefundService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package com.irum.come2us.domain.refund.application.service; | ||
|
|
||
| import com.irum.come2us.domain.order.domain.entity.Order; | ||
| import com.irum.come2us.domain.order.domain.entity.OrderDetail; | ||
| import com.irum.come2us.domain.order.domain.repository.OrderDetailRepository; | ||
| import com.irum.come2us.domain.order.domain.repository.OrderRepository; | ||
| import com.irum.come2us.domain.refund.domain.entity.Refund; | ||
| import com.irum.come2us.domain.refund.domain.repository.RefundRepository; | ||
| import com.irum.come2us.domain.refund.presentation.dto.request.CustomerRefundCreateRequest; | ||
| import com.irum.come2us.domain.refund.presentation.dto.response.CustomerRefundDetailResponse; | ||
| import com.irum.come2us.global.presentation.advice.exception.CommonException; | ||
| import com.irum.come2us.global.presentation.advice.exception.errorcode.RefundErrorCode; | ||
| import com.irum.come2us.global.util.MemberUtil; | ||
| import java.util.List; | ||
| import java.util.UUID; | ||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Transactional | ||
| @Slf4j | ||
| public class CustomerRefundService { | ||
| private final MemberUtil memberUtil; | ||
| private final RefundRepository refundRepository; | ||
| private final OrderRepository orderRepository; | ||
| private final OrderDetailRepository orderDetailRepository; | ||
|
|
||
| public void createRefund(UUID orderId, CustomerRefundCreateRequest request) { | ||
| assertNoRefundExistsByOrder(orderId); | ||
| Order order = getValidOrder(orderId); | ||
| refundRepository.save( | ||
| Refund.create( | ||
| request.reason(), request.description(), order.getPayment().getAmount())); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public CustomerRefundDetailResponse findRefundDetail(UUID orderId) { | ||
| Order order = getValidOrderWithAddress(orderId); | ||
| Refund refund = getValidRefund(orderId); | ||
| List<OrderDetail> orderDetails = orderDetailRepository.findAllByOrder(order); | ||
| return CustomerRefundDetailResponse.of(order, orderDetails, refund); | ||
| } | ||
|
|
||
| private void assertNoRefundExistsByOrder(UUID orderId) { | ||
| if (refundRepository.existsByOrderId(orderId)) | ||
| throw new CommonException(RefundErrorCode.REFUND_ALREADY_EXISTS); | ||
| } | ||
|
|
||
| private Order getValidOrder(UUID orderId) { | ||
| Order order = | ||
| orderRepository | ||
| .findById(orderId) | ||
| .orElseThrow(() -> new CommonException(OrderErrorCode.ORDER_NOT_FOUND)); | ||
| memberUtil.assertMemberResourceAccess(order.getMember()); | ||
| return order; | ||
| } | ||
|
|
||
| private Order getValidOrderWithAddress(UUID orderId) { | ||
| Order order = | ||
| orderRepository | ||
| .findOrderWithAddress(orderId) | ||
| .orElseThrow(() -> new CommonException(OrderErrorCode.ORDER_NOT_FOUND)); | ||
| memberUtil.assertMemberResourceAccess(order.getMember()); | ||
| return order; | ||
| } | ||
|
|
||
| private Refund getValidRefund(UUID orderId) { | ||
| return refundRepository | ||
| .findByOrderId(orderId) | ||
| .orElseThrow(() -> new CommonException(RefundErrorCode.REFUND_NOT_FOUND)); | ||
| } | ||
| } |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/irum/come2us/domain/refund/domain/repository/RefundRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.irum.come2us.domain.refund.domain.repository; | ||
|
|
||
| import com.irum.come2us.domain.refund.domain.entity.Refund; | ||
| import java.util.Optional; | ||
| import java.util.UUID; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Query; | ||
| import org.springframework.data.repository.query.Param; | ||
|
|
||
| public interface RefundRepository extends JpaRepository<Refund, UUID> { | ||
| @Query("SELECT COUNT(r)>0 FROM Refund r WHERE r.order.orderId =: orderId") | ||
| boolean existsByOrderId(@Param("orderId") UUID orderId); | ||
|
|
||
| @Query("SELECT r FROM Refund r WHERE r.order.orderId =: orderId") | ||
| Optional<Refund> findByOrderId(@Param("orderId") UUID orderId); | ||
| } |
30 changes: 30 additions & 0 deletions
30
...java/com/irum/come2us/domain/refund/presentation/controller/CustomerRefundController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package com.irum.come2us.domain.refund.presentation.controller; | ||
|
|
||
| import com.irum.come2us.domain.refund.application.service.CustomerRefundService; | ||
| import com.irum.come2us.domain.refund.presentation.dto.request.CustomerRefundCreateRequest; | ||
| import com.irum.come2us.domain.refund.presentation.dto.response.CustomerRefundDetailResponse; | ||
| import jakarta.validation.Valid; | ||
| import java.util.UUID; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/refund/customer") | ||
| @RequiredArgsConstructor | ||
| public class CustomerRefundController { | ||
| private final CustomerRefundService customerRefundService; | ||
|
|
||
| @PostMapping("/{orderId}") | ||
| public ResponseEntity<Void> registerRefund( | ||
| @PathVariable UUID orderId, @Valid @RequestBody CustomerRefundCreateRequest request) { | ||
| customerRefundService.createRefund(orderId, request); | ||
| return ResponseEntity.status(HttpStatus.CREATED).build(); | ||
| } | ||
|
|
||
| @GetMapping("/{orderId}/detail") | ||
| public CustomerRefundDetailResponse getRefundDetail(@PathVariable UUID orderId) { | ||
| return customerRefundService.findRefundDetail(orderId); | ||
| } | ||
| } |
9 changes: 9 additions & 0 deletions
9
.../com/irum/come2us/domain/refund/presentation/dto/request/CustomerRefundCreateRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.irum.come2us.domain.refund.presentation.dto.request; | ||
|
|
||
| import com.irum.come2us.domain.refund.domain.entity.enums.RefundReason; | ||
| import jakarta.annotation.Nullable; | ||
| import jakarta.validation.constraints.NotNull; | ||
|
|
||
| public record CustomerRefundCreateRequest( | ||
| @NotNull(message = "환불 사유는 필수 입력값입니다.") RefundReason reason, | ||
| @Nullable String description) {} |
79 changes: 79 additions & 0 deletions
79
...om/irum/come2us/domain/refund/presentation/dto/response/CustomerRefundDetailResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| package com.irum.come2us.domain.refund.presentation.dto.response; | ||
|
|
||
| import com.irum.come2us.domain.deliveryaddress.domain.entity.DeliveryAddress; | ||
| import com.irum.come2us.domain.order.domain.entity.Order; | ||
| import com.irum.come2us.domain.order.domain.entity.OrderDetail; | ||
| import com.irum.come2us.domain.refund.domain.entity.Refund; | ||
| import com.irum.come2us.domain.refund.domain.entity.enums.RefundReason; | ||
| import com.irum.come2us.domain.refund.domain.entity.enums.RefundStatus; | ||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
| import java.util.UUID; | ||
|
|
||
| public record CustomerRefundDetailResponse( | ||
| UUID orderId, | ||
| String orderNum, | ||
| List<ProductInfoDto> productList, | ||
| RecipientAddressDto recipientAddress, | ||
| LocalDateTime cancelDate, | ||
| UUID refundId, | ||
| RefundStatus refundStatus, | ||
| int refundPrice, | ||
| RefundReason refundReason) { | ||
| public record ProductInfoDto( | ||
| UUID orderDetailId, | ||
| int productPrice, | ||
| String productName, | ||
| String optionTitle, | ||
| int quantity) { | ||
| public static ProductInfoDto fromEntity(OrderDetail orderDetail) { | ||
| return new ProductInfoDto( | ||
| orderDetail.getOrderDetailId(), | ||
| orderDetail.getPrice(), | ||
| orderDetail.getProductName(), | ||
| orderDetail.getOptionName(), | ||
| orderDetail.getQuantity()); | ||
| } | ||
| } | ||
|
|
||
| public record RecipientAddressDto( | ||
| String postalCode, | ||
| String city, | ||
| String sigungu, | ||
| String RoadName, | ||
| String AddressDetail, | ||
| String recipientName, | ||
| String recipientContact) { | ||
| public static RecipientAddressDto fromEntity(DeliveryAddress deliveryAddress) { | ||
| return new RecipientAddressDto( | ||
| deliveryAddress.getAddress().getPostalCode(), | ||
| deliveryAddress.getAddress().getCity(), | ||
| deliveryAddress.getAddress().getSigungu(), | ||
| deliveryAddress.getAddress().getRoadName(), | ||
| deliveryAddress.getAddress().getAddressDetail(), | ||
| deliveryAddress.getRecipientName(), | ||
| deliveryAddress.getRecipientContact()); | ||
| } | ||
| } | ||
|
|
||
| public static CustomerRefundDetailResponse of( | ||
| Order order, List<OrderDetail> orderDetails, Refund refund) { | ||
|
|
||
| List<ProductInfoDto> productList = | ||
| orderDetails.stream().map(ProductInfoDto::fromEntity).toList(); | ||
|
|
||
| RecipientAddressDto recipientAddress = | ||
| RecipientAddressDto.fromEntity(order.getDeliveryAddress()); | ||
|
|
||
| return new CustomerRefundDetailResponse( | ||
| order.getOrderId(), | ||
| order.getOrderNum(), | ||
| productList, | ||
| recipientAddress, | ||
| refund.getRefundId(), | ||
| refund.getCreatedAt(), | ||
| refund.getRefundStatus(), | ||
| refund.getPrice(), | ||
| refund.getReason()); | ||
| } | ||
| } |
20 changes: 20 additions & 0 deletions
20
...java/com/irum/come2us/global/presentation/advice/exception/errorcode/RefundErrorCode.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.irum.come2us.global.presentation.advice.exception.errorcode; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public enum RefundErrorCode implements BaseErrorCode { | ||
| REFUND_NOT_FOUND(HttpStatus.NOT_FOUND, "환불 정보를 찾을 수 없습니다."), | ||
| REFUND_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "이미 해당 주문에 대한 환불이 존재합니다."); | ||
|
|
||
| private final HttpStatus httpStatus; | ||
| private final String message; | ||
|
|
||
| @Override | ||
| public String errorClassName() { | ||
| return this.name(); | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.