[ SourceCode 참고]
https://github.com/jjangsky/Testing-study
병 음료
, 베이커리
이다.@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Stock extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String productNumber;
private int quantity;
}
주문 생성 시, 재고를 관리하는 기능이므로 이전에 생성한 주문 Service 로직을 수정한다.
[ 전체 코드 ]
public OrderResponse createOrder(OrderCreateRequest request,
LocalDateTime registeredDateTime) {
List<String> productNumbers = request.getProductNumbers();
// Prodcut
List<Product> products = findProductsBy(productNumbers);
// 1. 재고 차감 체크가 필요한 상품들 Filter
List<String> stockProductNumbers = products.stream()
.filter(product -> ProductType.containsStockType(product.getType()))
.map(Product::getProductNumber)
.collect(Collectors.toList());
// 2. 재고 엔티티 조회
List<Stock> stocks = stockRepository
.findAllByProductNumberIn(stockProductNumbers);
Map<String, Stock> stockMap = stocks.stream()
.collect(Collectors.toMap(Stock::getProductNumber, s -> s));
// 3. 상품별 Counting
Map<String, Long> producCountingMap = stockProductNumbers.stream()
.collect(Collectors.groupingBy(p -> p, Collectors.counting()));
// 4. 재고 차감 시도(중복 제거 필요함)
for(String stockProductNumber : new HashSet<>(stockProductNumbers)){
Stock stock = stockMap.get(stockProductNumber);
int quantity = producCountingMap.get(stockProductNumber).intValue();
if(stock.isQuantityLessThan(quantity)){
// 재고가 부족한 경우 예외 처리
throw new IllegalArgumentException("재고가 부족한 상품이 있습니다.");
}
stock.deductQuantity(quantity);
}
Order order = Order.create(products, registeredDateTime);
Order savedOrder = orderRepository.save(order);
return OrderResponse.of(savedOrder);
}
요구 사항에서는 병 음료와 베이커리만 재고를 차감해야 하기 때문에 이전에 조회한 상품 목록에서 해당 목록만 따로 추출 해야한다.
// 상품 정보
List<Product> products = findProductsBy(productNumbers);
List<String> stockProductNumbers = products.stream()
.filter(product -> ProductType.containsStockType(product.getType()))
.map(Product::getProductNumber)
.collect(Collectors.toList());