Skip to content

Commit

Permalink
Merge pull request #64 from ClothingStoreService/refactor/#62-order
Browse files Browse the repository at this point in the history
Refactor/#62 order: 추가 리팩토링
  • Loading branch information
axhtl authored Jun 28, 2024
2 parents 4d45845 + 81b1aad commit 939374d
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -29,40 +28,26 @@ public class OrderController {

@Operation(summary = "단일 주문 조회", description = "단일 주문의 정보를 조회한다.")
@GetMapping("/{orderId}")
public ResponseEntity<OrderResponse> getOrder(@PathVariable("orderId") Long orderId) {

public ResponseEntity<OrderResponse> getOrder(@PathVariable Long orderId) {
OrderResponse orderResponse = orderService.getOrder(orderId);

return ResponseEntity.ok().body(orderResponse);
return ResponseEntity.ok(orderResponse);
}

@PermitAll
@Operation(summary = "주문 생성", description = "단일 주문을 생성한다.")
@PostMapping
public ResponseEntity<URI> saveOrder(
@RequestBody @Validated OrderRequestWrapper orderRequestWrapper) {

public ResponseEntity<URI> saveOrder(@RequestBody @Validated OrderRequestWrapper orderRequestWrapper) {
Long orderId = orderApplicationService.saveOrderWithTransaction(orderRequestWrapper);

URI location = URIBuilder.buildURI(orderId);

return ResponseEntity.created(location).build();
}

@Operation(summary = "구매 확정", description = "구매자가 구매 확정 시, 주문상태가 '구매확정'으로 변경된다.")
@PatchMapping("/{orderId}")
public ResponseEntity<MessageDTO> deliveredToConfirmOrder(@PathVariable("orderId") Long orderId) {

public ResponseEntity<MessageDTO> deliveredToConfirmOrder(@PathVariable Long orderId) {
orderService.deliveredToConfirmOrder(orderId);

return ResponseEntity.ok()
.body(new MessageDTO(
HttpStatus.OK.value(),
"주문이 정상적으로 구매 확정 되었습니다."));
return ResponseEntity.ok(new MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 구매 확정 되었습니다."));
}
}





Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,21 @@ public class OrderSellerController {
@Operation(summary = "(판매자) WAITING 주문 리스트 조회", description = "(판매자) 주문상태가 '승인대기'인 주문 리스트를 조회한다.")
@GetMapping
public ResponseEntity<List<OrderResponse>> getWaitingOrder() {

List<OrderResponse> orderResponseList = orderSellerService.getWaitingOrder();

return ResponseEntity.ok(orderResponseList);
}

@Operation(summary = "(판매자) 주문 승인 또는 취소", description = "(판매자) 주문을 승인 또는 취소한다.")
@PatchMapping("/{orderId}")
public ResponseEntity<MessageDTO> cancelOrApproveOrder(
@PathVariable("orderId") Long orderId,
@RequestBody @Validated OrderSellerRequest orderSellerRequest) {

MessageDTO messageDTO = orderSellerService.cancelOrApproveOrder(orderId, orderSellerRequest);
@Operation(summary = "(판매자) 주문 승인", description = "(판매자) 주문을 승인한다.")
@PatchMapping("/{orderId}/approve")
public ResponseEntity<MessageDTO> approveOrder(@PathVariable Long orderId) {
MessageDTO messageDTO = orderSellerService.approveOrder(orderId);
return ResponseEntity.ok(messageDTO);
}

return ResponseEntity.ok().body(messageDTO);
@Operation(summary = "(판매자) 주문 취소", description = "(판매자) 주문을 취소한다.")
@PatchMapping("/{orderId}/cancel")
public ResponseEntity<MessageDTO> cancelOrder(@PathVariable Long orderId) {
MessageDTO messageDTO = orderSellerService.cancelOrder(orderId);
return ResponseEntity.ok(messageDTO);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
import org.springframework.transaction.annotation.Transactional;
import org.store.clothstar.order.entity.OrderEntity;

import java.util.List;

public interface JpaOrderSellerRepository extends JpaRepository<OrderEntity, Long> {
@Query("SELECT o FROM orders o WHERE o.status = 'WAITING'")
List<OrderEntity> findWaitingOrders();

@Transactional
@Modifying
@Query("UPDATE orders o SET o.status = 'APPROVE' WHERE o.orderId = :orderId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.springframework.stereotype.Repository;
import org.store.clothstar.order.domain.Order;
import org.store.clothstar.order.domain.type.Status;
import org.store.clothstar.order.entity.OrderEntity;

import java.util.List;
Expand All @@ -18,10 +17,8 @@ public class JpaOrderSellerRepositoryAdapter implements UpperOrderSellerReposito

@Override
public List<Order> SelectWaitingOrders() {
List<OrderEntity> orderEntityList = jpaOrderSellerRepository.findAll();

List<OrderEntity> orderEntityList = jpaOrderSellerRepository.findWaitingOrders();
return orderEntityList.stream()
.filter(orderEntity -> orderEntity.getStatus() == Status.WAITING)
.map(Order::new)
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import org.store.clothstar.order.domain.type.Status;
import org.store.clothstar.order.dto.reponse.OrderResponse;
import org.store.clothstar.order.dto.request.OrderSellerRequest;
import org.store.clothstar.order.repository.order.MybatisOrderRepository;
import org.store.clothstar.order.repository.order.UpperOrderRepository;
import org.store.clothstar.order.repository.orderSeller.UpperOrderSellerRepository;
import org.store.clothstar.orderDetail.service.OrderDetailService;

import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -20,15 +21,19 @@
public class OrderSellerService {

private final UpperOrderSellerRepository upperOrderSellerRepository;
private final MybatisOrderRepository orderRepository;
private final UpperOrderRepository upperOrderRepository;
private final OrderDetailService orderDetailService;

public OrderSellerService(
@Qualifier("jpaOrderSellerRepositoryAdapter") UpperOrderSellerRepository upperOrderSellerRepository
@Qualifier("jpaOrderSellerRepositoryAdapter") UpperOrderSellerRepository upperOrderSellerRepository,
@Qualifier("jpaOrderRepositoryAdapter") UpperOrderRepository upperOrderRepository
// @Qualifier("mybatisOrderSellerRepository") UpperOrderSellerRepository upperOrderSellerRepository
, MybatisOrderRepository orderRepository
// @Qualifier("mybatisOrderRepository") UpperOrderRepository upperOrderRepository
,OrderDetailService orderDetailService
) {
this.upperOrderSellerRepository = upperOrderSellerRepository;
this.orderRepository = orderRepository;
this.upperOrderRepository = upperOrderRepository;
this.orderDetailService=orderDetailService;
}

@Transactional(readOnly = true)
Expand All @@ -40,31 +45,38 @@ public List<OrderResponse> getWaitingOrder() {
}

@Transactional
public MessageDTO cancelOrApproveOrder(Long orderId, OrderSellerRequest orderSellerRequest) {
public MessageDTO approveOrder(Long orderId) {
MessageDTO messageDTO;

// 주문 유효성 검사
orderRepository.getOrder(orderId)
upperOrderRepository.getOrder(orderId)
.filter(Order -> Order.getStatus() == Status.WAITING)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "주문이 존재하지 않거나 상태가 'WAITING'이 아니어서 처리할 수 없습니다."));

return processOrder(orderId, orderSellerRequest);
upperOrderSellerRepository.approveOrder(orderId);
messageDTO = new MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 승인 되었습니다.");

upperOrderRepository.getOrder(orderId)
.map(OrderResponse::fromOrder)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "처리 후 주문 정보를 찾을 수 없습니다."));

return messageDTO;
}

// 주문 처리
@Transactional
public MessageDTO processOrder(Long orderId, OrderSellerRequest orderSellerRequest) {
public MessageDTO cancelOrder(Long orderId) {
MessageDTO messageDTO;

MessageDTO messageDTO = null;
// 주문 유효성 검사
upperOrderRepository.getOrder(orderId)
.filter(Order -> Order.getStatus() == Status.WAITING)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "주문이 존재하지 않거나 상태가 'WAITING'이 아니어서 처리할 수 없습니다."));

if (orderSellerRequest.getApprovalStatus() == ApprovalStatus.APPROVE) {
upperOrderSellerRepository.approveOrder(orderId);
messageDTO = new MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 승인 되었습니다.");
} else if (orderSellerRequest.getApprovalStatus() == ApprovalStatus.CANCEL) {
upperOrderSellerRepository.cancelOrder(orderId);
messageDTO = new MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 취소 되었습니다.");
}
upperOrderSellerRepository.cancelOrder(orderId);
orderDetailService.restoreStockByOrder(orderId);
messageDTO = new MessageDTO(HttpStatus.OK.value(), "주문이 정상적으로 취소 되었습니다.");

orderRepository.getOrder(orderId)
upperOrderRepository.getOrder(orderId)
.map(OrderResponse::fromOrder)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "처리 후 주문 정보를 찾을 수 없습니다."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ public class OrderService {
private final UpperOrderRepository upperOrderRepository;
private final MemberRepository memberRepository;
private final AddressRepository addressRepository;
private final OrderDetailService orderDetailService;

public OrderService(
@Qualifier("jpaOrderRepositoryAdapter") UpperOrderRepository upperOrderRepository
,@Qualifier("memberJpaRepository") MemberRepository memberRepository
,@Qualifier("addressJpaRepository") AddressRepository addressRepository
// @Qualifier("mybatisOrderRepository") UpperOrderRepository upperOrderRepository
, MemberRepository memberRepository
, AddressRepository addressRepository
, OrderDetailService orderDetailService
) {
this.upperOrderRepository = upperOrderRepository;
this.memberRepository = memberRepository;
this.addressRepository = addressRepository;
this.orderDetailService = orderDetailService;
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,9 @@ public class OrderDetailController {

@Operation(summary = "주문상세 추가 저장", description = "개별 상품에 대한 주문상세(상품명, 가격, 개수...)를 특정 주문에 추가 저장한다.")
@PostMapping
public ResponseEntity<URI> addOrderDetail(
@RequestBody @Validated AddOrderDetailRequest addOrderDetailRequest) {

public ResponseEntity<URI> addOrderDetail(@RequestBody @Validated AddOrderDetailRequest addOrderDetailRequest) {
Long orderDetailId = orderdetailService.addOrderDetail(addOrderDetailRequest);

URI location = URIBuilder.buildURI(orderDetailId);

return ResponseEntity.created(location).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.store.clothstar.orderDetail.service;

import jakarta.annotation.security.PermitAll;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -70,14 +69,12 @@ public void saveOrderDetailWithOrder(CreateOrderDetailRequest createOrderDetailR
order.getTotalProductsPrice() + order.getTotalShippingPrice() + orderDetail.getOneKindTotalPrice();

order.updatePrices(newTotalProductsPrice, newTotalPaymentPrice);
log.info("총 주문 가격 =" + order.getTotalPaymentPrice());
upperOrderRepository.updateOrderPrices(order);

// 주문 수량만큼 상품 재고 차감
updateProductStock(product, orderDetail.getQuantity());
}

@PermitAll
// 주문 상세 추가 생성
@Transactional
public Long addOrderDetail(AddOrderDetailRequest addOrderDetailRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@
import org.springframework.web.server.ResponseStatusException;
import org.store.clothstar.common.dto.MessageDTO;
import org.store.clothstar.order.domain.Order;
import org.store.clothstar.order.domain.type.ApprovalStatus;
import org.store.clothstar.order.domain.type.Status;
import org.store.clothstar.order.dto.reponse.OrderResponse;
import org.store.clothstar.order.dto.request.OrderSellerRequest;
import org.store.clothstar.order.repository.order.MybatisOrderRepository;
import org.store.clothstar.order.repository.order.UpperOrderRepository;
import org.store.clothstar.order.repository.orderSeller.UpperOrderSellerRepository;
import org.store.clothstar.orderDetail.service.OrderDetailService;

import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -38,13 +37,13 @@ class OrderSellerServiceApplicationTest {
private Order mockOrder;

@Mock
private OrderSellerRequest mockOrderSellerRequest;
private UpperOrderSellerRepository upperOrderSellerRepository;

@Mock
private UpperOrderSellerRepository upperOrderSellerRepository;
private UpperOrderRepository upperOrderRepository;

@Mock
private MybatisOrderRepository orderRepository;
private OrderDetailService orderDetailService;

@Test
@DisplayName("getWaitingOrders: '승인대기' 주문 조회 - 메서드 호출 & 반환값 테스트")
Expand Down Expand Up @@ -73,78 +72,59 @@ void getWaitingOrder_test() {
}

@Test
@DisplayName("cancelOrApproveOrder: 판매자 주문 승인 - 메서드 호출 & 반환값 테스트")
@DisplayName("approveOrder: 판매자 주문 승인 - 메서드 호출 & 반환값 테스트")
void approveOrder_verify_test() {
//given
Long orderId = 1L;
given(mockOrder.getStatus()).willReturn(Status.WAITING);
given(mockOrder.getCreatedAt()).willReturn(LocalDateTime.now());
given(mockOrderSellerRequest.getApprovalStatus()).willReturn(ApprovalStatus.APPROVE);
given(orderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));
given(upperOrderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));

//when
MessageDTO messageDTO = orderSellerService.cancelOrApproveOrder(orderId, mockOrderSellerRequest);
MessageDTO messageDTO = orderSellerService.approveOrder(orderId);

//then
then(upperOrderSellerRepository).should(times(1)).approveOrder(orderId);
then(orderRepository).should(times(2)).getOrder(orderId);
then(upperOrderRepository).should(times(2)).getOrder(orderId);
assertThat(messageDTO.getStatusCode()).isEqualTo(HttpStatus.OK.value());
assertThat(messageDTO.getMessage()).isEqualTo("주문이 정상적으로 승인 되었습니다.");
}

@Test
@DisplayName("cancelOrApproveOrder: 판매자 주문 취소 - 메서드 호출 & 반환값 테스트")
void cancelOrApproveOrder_verify_test() {
@DisplayName("cancelOrder: 판매자 주문 취소 - 메서드 호출 & 반환값 테스트")
void cancelOrder_verify_test() {
// given
Long orderId = mockOrder.getOrderId();
given(mockOrder.getOrderId()).willReturn(1L);
given(mockOrder.getStatus()).willReturn(Status.WAITING);
given(mockOrder.getCreatedAt()).willReturn(LocalDateTime.now());
given(mockOrderSellerRequest.getApprovalStatus()).willReturn(ApprovalStatus.CANCEL);
given(orderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));
given(upperOrderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));

//when
MessageDTO messageDTO = orderSellerService.cancelOrApproveOrder(orderId, mockOrderSellerRequest);
MessageDTO messageDTO = orderSellerService.cancelOrder(orderId);

//then
then(upperOrderSellerRepository).should(times(1)).cancelOrder(orderId);
then(orderRepository).should(times(2)).getOrder(orderId);
then(upperOrderRepository).should(times(2)).getOrder(orderId);
assertThat(messageDTO.getStatusCode()).isEqualTo(HttpStatus.OK.value());
assertThat(messageDTO.getMessage()).isEqualTo("주문이 정상적으로 취소 되었습니다.");
}

@Test
@DisplayName("cancelOrApproveOrder: 주문상태가 '승인대기'가 아닐 때 예외처리 테스트")
@DisplayName("approveOrder: 주문상태가 '승인대기'가 아닐 때 예외처리 테스트")
void cancelOrApproveOrder_NotWAITING_exception_test() {

//given
Long orderId = 1L;
given(orderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));
given(upperOrderRepository.getOrder(orderId)).willReturn(Optional.of(mockOrder));
given(mockOrder.getStatus()).willReturn(Status.DELIVERED);

//when
ResponseStatusException thrown = assertThrows(ResponseStatusException.class, () -> {
orderSellerService.cancelOrApproveOrder(orderId, mockOrderSellerRequest);
orderSellerService.approveOrder(orderId);
});

//then
assertEquals("400 BAD_REQUEST \"주문이 존재하지 않거나 상태가 'WAITING'이 아니어서 처리할 수 없습니다.\"", thrown.getMessage());
}

@Test
@DisplayName("cancelOrApproveOrder: 판매자 주문 관리 처리 후, 주문 정보를 찾을 수 없을 때 예외처리 테스트")
void cancelOrApproveOrder_after_cannotFindOrder_exception_test() {
//given
Long orderId = 1L;
given(mockOrderSellerRequest.getApprovalStatus()).willReturn(ApprovalStatus.APPROVE);
given(orderRepository.getOrder(orderId)).willReturn(Optional.empty());

//when
ResponseStatusException thrown = assertThrows(ResponseStatusException.class, () -> {
orderSellerService.processOrder(orderId, mockOrderSellerRequest);
});

//then
assertEquals("500 INTERNAL_SERVER_ERROR \"처리 후 주문 정보를 찾을 수 없습니다.\"", thrown.getMessage());
}
}
Loading

0 comments on commit 939374d

Please sign in to comment.