@Test
public void 상품주문(){
Member member = new Member();
member.setUsername("회원1");
member.setAddress(new Address("서울", "강가", "123-123"));
em.persist(member);
Item book = new Book();
book.setName("시골 JPA");
book.setPrice(10000);
book.setStockQuantity(10);
em.persist(book);
int orderCount = 2;
Long orderId = orderSerivce.order(member.getId(), book.getId(), orderCount);
Item findBook = itemService.findOne(book.getId());
Order findOrder = orderRepository.findOne(orderId);
assertThat(findOrder.getStatus()).isEqualTo(OrderStatus.ORDER);
assertThat(findOrder.getTotalPrice()).isEqualTo(10000 * orderCount);
assertThat(book.getStockQuantity()).isEqualTo(8);
}
먼저 멤버 만들고,
등록 후,
item 만들고 가격, 제고 등록 후,
주문을 해봄.
그 후 다시 조회해서 찾아온 다음, (주문도)
주문 상태가 바뀌었는지,
총 가격이 주문수량 * 상품주문가격과 맞는지,
또 다시 조회해서 찾아온 아이템의 재고가 남아있어야 할 수량과 맞는지.
order()를 하게 되면
public Long order(Long memberId, Long itemId, int count){
Member member = memberRepository.findOne(memberId);
Item item = itemRepository.findOne(itemId);
Delivery delivery = new Delivery();
delivery.setAddress(member.getAddress());
OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);
Order order = Order.createOrder(member, delivery, orderItem);
orderRepository.save(order);
return order.getId();
}
member 찾아오고, item 찾아온 다음,
배송정보 등록하고,
createOrderItem을 하는데
public static OrderItem createOrderItem(Item item, int orderPrice, int count){
OrderItem orderItem = new OrderItem();
orderItem.setItem(item);
orderItem.setOrderPrice(orderPrice);
orderItem.setCount(count);
item.removeStock(count);
return orderItem;
}
새 아이템 생성하고,
원본 아이템을 넣고,
주문가격,
주문 수량 하고
원본 아이템에서 재고를 주문수만큼 줄임.
public void removeStock(int quantity){
int restStock = this.stockQuantity - quantity;
if(restStock <0){
throw new NotEnoughStockException("need more stock");
}
this.setStockQuantity(restStock);
}
재고 - 주문수량이 0이하면 오류를 내뱉음.
아니면 재고에서 줄여버림.
public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems){
Order order = new Order();
order.changeMember(member);
order.changeDelivery(delivery);
for (OrderItem orderItem : orderItems) {
order.addOrderItem(orderItem);
}
order.setStatus(OrderStatus.ORDER);
order.setOrderDate(LocalDateTime.now());
return order;
}
createOrder는 주문에 대한 set을 다 한 다음,
order()에서 받아서 영속성 컨텍스트에 등록시켜줌. 그럼 나중에 트랜잭션 끝날 때 쿼리 나감.
그렇게 끝이고, 나머진 그냥 찾아서 비교.
다음 재고수량 초과
@Test
public void 상품주문_재고수량초과(){
Member member = createMember();
em.persist(member);
Item book = createBook("시골 JPA", 10000, 10);
em.persist(book);
int orderCount = 11;
assertThatThrownBy(()->orderSerivce.order(member.getId(), book.getId(), orderCount))
.isInstanceOf(NotEnoughStockException.class);
}
저거 위에 member 만드는 과정이랑 Item 만드는 과정 메소드로 만듦.
저렇게 수량 10개로 두고,
order 하는데, 그 수량이 재고 추가 시,
public void removeStock(int quantity){
int restStock = this.stockQuantity - quantity;
if(restStock <0){
throw new NotEnoughStockException("need more stock");
}
this.setStockQuantity(restStock);
}
이 메소드에 의해 오류를 뱉음.(Item)
order를 콜백함수로 주고, 에러가 나와야 하며, 그 에러의 instance는 NotEnoughStockException 이어야 함.
@Test
public void 주문취소(){
Member member = createMember();
em.persist(member);
Item book = createBook("name", 10000, 10);
em.persist(book);
int orderCount = 2;
Long orderId = orderSerivce.order(member.getId(), book.getId(), orderCount);
Item findBook = itemService.findOne(book.getId());
assertThat(findBook.getStockQuantity()).isEqualTo(8);
orderSerivce.cancelOrder(orderId);
Order findOrder = orderRepository.findOne(orderId);
assertThat(findOrder.getStatus()).isEqualTo(OrderStatus.CANCEL);
assertThat(findBook.getStockQuantity()).isEqualTo(10);
}
멤버 등록,
아이템 등록
주문한다.
주문 후 아이템을 찾아와서
재고 보면 8이어야 한다.
그 다음 주문 취소 시,
public void cancelOrder(Long orderId){
Order order = orderRepository.findOne(orderId);
order.cancel();
}
이게 호출 되어
public void cancel(){
if(delivery.getStatus() == DeliveryStatus.COMP){
throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
}
this.setStatus(OrderStatus.CANCEL);
for (OrderItem orderItem : orderItems) {
orderItem.cancel();
}
}
orderState를 CANCEL로 바꾸고,
public void cancel(){
this.getItem().addStock(count);
}
이렇게 OrderItem에서 기존 재고를 주문했던수량만큼 더한다.
public void addStock(int quantity){
this.stockQuantity += quantity;
}
Item의 addStock
'스프링데이터 + JPA > 웹 애플리케이션 개발' 카테고리의 다른 글
20. 웹 계층 개발 (0) | 2023.11.09 |
---|---|
19. 주문 검색 기능 개발 (0) | 2023.11.09 |
17. 주문 리포지토리, 서비스 (0) | 2023.11.07 |
16. 주문 도메인 개발 (0) | 2023.11.07 |
15. 상품 개발 (0) | 2023.11.07 |