@Entity@Getter@SetterpublicclassOrderItem {...// 생성 메서드publicstaticOrderItemcreateOrderItem(Item item,int orderPrice,int count) {// 쿠폰 등의 가격 변경 가능성 때문에 객체를 따로 만든다.OrderItem orderItem =newOrderItem();orderItem.setItem(item);orderItem.setOrderPrice(orderPrice);orderItem.setCount(count);// 넘어온 것만큼 재고를 뺀다.item.removeStock(count);return orderItem; }}
@Entity@Getter@Setter@Table(name ="orders")publicclassOrder {...// 생성 메서드publicstaticOrdercreateOrder(Member member,Delivery delivery,OrderItem... orderItems) {Order order =newOrder();// 연관 관계를 한 곳에서 관리할 수 있다.order.setMember(member);order.setDelivery(delivery);for (OrderItem orderItem : orderItems) {order.addOrderItem(orderItem); }order.setStatus(OrderStatus.ORDER);order.setOrderDate(LocalDateTime.now());return order; }}
createOrderItem에서 이미 removeStock()으로 재고를 깐 상태로 orderItem이 넘어오게 된다.
주문 취소
@Entity@Getter@Setter@Table(name ="orders")publicclassOrder {...// 비즈니스 로직 /** * 주문 취소 */publicvoidcancel() {if (delivery.getStatus() ==DeliveryStatus.COMP) {thrownewIllegalStateException("이미 배송 완료된 상품은 취소가 불가능합니다."); }this.setStatus(OrderStatus.CANCEL);// IDE 에디터 색 때문에 정말 this를 꼭 명시적으로 보여줘야할 때가 아니면// this.orderItems보다 orderItems를 선호한다.for (OrderItem orderItem : orderItems) {// 주문한 아이템들도 다 취소를 해줘야 한다.orderItem.cancel(); } }}
@Entity@Getter@SetterpublicclassOrderItem {...// 비즈니스 로직publicvoidcancel() {// 해당 아이템에 대한 주문 수량을 취소한 만큼 원복시켜야 한다.getItem().addStock(count); }}
마찬가지로 담당 도메인에서 로직을 처리하도록 한다.
전체 주문 가격 조회
@Entity@Getter@Setter@Table(name ="orders")publicclassOrder {...// 조회 로직 /** * 전체 주문 가격 조회 */publicintgetTotalPrice() {returnorderItems.stream().mapToInt(OrderItem::getTotalPrice).sum(); }}
@Entity@Getter@SetterpublicclassOrderItem {...// 주문 가격과 수량이 orderItem에 있으므로 여기서 가격을 계산한다.publicintgetTotalPrice() {returngetOrderPrice()*getCount(); }}