11package com .loopers .application .order ;
22
33import com .loopers .application .orderitem .OrderItemInfo ;
4- import com .loopers .application .product .UserActionEvent ;
54import com .loopers .domain .coupon .Coupon ;
65import com .loopers .domain .coupon .CouponRepository ;
76import com .loopers .domain .order .Order ;
87import com .loopers .domain .order .OrderRepository ;
98import com .loopers .domain .orderitem .OrderItem ;
109import com .loopers .domain .orderitem .OrderItemRepository ;
10+ import com .loopers .domain .outbox .AggregateType ;
11+ import com .loopers .domain .outbox .OutboxEvent ;
12+ import com .loopers .domain .outbox .OutboxRepository ;
13+ import com .loopers .domain .outbox .OutboxType ;
1114import com .loopers .domain .product .Product ;
1215import com .loopers .domain .product .ProductRepository ;
1316import com .loopers .domain .user .UserRepository ;
1417import com .loopers .interfaces .api .order .OrderV1Dto ;
1518import com .loopers .support .error .CoreException ;
1619import com .loopers .support .error .ErrorType ;
1720import lombok .RequiredArgsConstructor ;
18- import org .springframework .context .ApplicationEventPublisher ;
1921import org .springframework .stereotype .Component ;
2022import org .springframework .transaction .annotation .Transactional ;
2123
@@ -30,7 +32,7 @@ public class OrderFacade {
3032 private final UserRepository userRepository ;
3133 private final ProductRepository productRepository ;
3234 private final CouponRepository couponRepository ;
33- private final ApplicationEventPublisher publisher ;
35+ private final OutboxRepository outBoxRepository ;
3436
3537 @ Transactional
3638 public OrderResultInfo createOrder (OrderV1Dto .OrderRequest request ) {
@@ -49,31 +51,31 @@ public OrderResultInfo createOrder(OrderV1Dto.OrderRequest request) {
4951 List <OrderV1Dto .OrderItemRequest > orderItemRequests = request .orderItems ();
5052
5153 List <OrderItem > orderItems = orderItemRequests .stream ()
52- .map (item -> {
53- // 상품 검증
54- Long productId = item .productId ();
55- Product product = productRepository .findById (productId ).orElseThrow (
56- () -> new CoreException (ErrorType .NOT_FOUND , "존재하는 상품이 아닙니다." )
57- );
58-
59- if (product .getStock () < item .quantity ()) {
60- throw new CoreException (ErrorType .BAD_REQUEST , product .getName () + " 상품의 재고가 부족합니다." );
61- }
62-
63- product .decreaseStock (item .quantity ());
64-
65- OrderItem orderItem = item .toEntity (
66- null ,
67- product .getPrice ().multiply (BigDecimal .valueOf (item .quantity ()))
68- );
69- return orderItem ;
70-
71- })
72- .toList ();
54+ .map (item -> {
55+ // 상품 검증
56+ Long productId = item .productId ();
57+ Product product = productRepository .findById (productId ).orElseThrow (
58+ () -> new CoreException (ErrorType .NOT_FOUND , "존재하는 상품이 아닙니다." )
59+ );
60+
61+ if (product .getStock () < item .quantity ()) {
62+ throw new CoreException (ErrorType .BAD_REQUEST , product .getName () + " 상품의 재고가 부족합니다." );
63+ }
64+
65+ product .decreaseStock (item .quantity ());
66+
67+ OrderItem orderItem = item .toEntity (
68+ null ,
69+ product .getPrice ().multiply (BigDecimal .valueOf (item .quantity ()))
70+ );
71+ return orderItem ;
72+
73+ })
74+ .toList ();
7375
7476 BigDecimal totalPrice = orderItems .stream ()
75- .map (OrderItem ::getOrderPrice )
76- .reduce (BigDecimal .ZERO , BigDecimal ::add );
77+ .map (OrderItem ::getOrderPrice )
78+ .reduce (BigDecimal .ZERO , BigDecimal ::add );
7779
7880 Long couponId = request .couponId ();
7981
@@ -91,15 +93,25 @@ public OrderResultInfo createOrder(OrderV1Dto.OrderRequest request) {
9193 .multiply (BigDecimal .valueOf (100 - rate ))
9294 .divide (BigDecimal .valueOf (100 ));
9395
94- publisher . publishEvent ( new OrderCreatedEvent ( couponId ) );
96+ coupon . useCoupon ( );
9597
9698 Order order = request .toEntity (totalPrice );
9799 Order saved = orderRepository .save (order );
98100
99101 orderItems .forEach (item -> item .assignOrderId (saved .getId ()));
100- orderItemRepository .saveAll (orderItems );
102+ List <OrderItem > savedOrderItems = orderItemRepository .saveAll (orderItems );
103+
104+ savedOrderItems .forEach (orderItem -> {
105+ OutboxEvent outboxEvent = OutboxEvent .of (
106+ AggregateType .PRODUCT ,
107+ orderItem .getProductId (),
108+ OutboxType .PRODUCT_SALES
109+ );
110+
111+ outBoxRepository .save (outboxEvent );
112+ });
101113
102- List <OrderItemInfo > orderItemInfos = orderItems .stream ()
114+ List <OrderItemInfo > orderItemInfos = savedOrderItems .stream ()
103115 .map (orderItem -> OrderItemInfo .from (orderItem , orderItem .getOrderPrice ()))
104116 .toList ();
105117
0 commit comments