1package com.acme.order; 2 3import com.acme.payment.PaymentClient; 4import org.springframework.stereotype.Service; 5import org.springframework.transaction.annotation.Transactional; 6import java.math.BigDecimal; 7import java.util.List; 8 9@Service 10public class OrderService { 11 12 private final OrderRepository orderRepository; 13 private final PaymentClient paymentClient; 14 15 public OrderService(OrderRepository orderRepository, PaymentClient paymentClient) { 16 this.orderRepository = orderRepository; 17 this.paymentClient = paymentClient; 18 } 19 20 @Transactional 21 public Order placeOrder(CreateOrderRequest request) { 22 BigDecimal total = request.items().stream() 23 .map(item -> item.price().multiply(BigDecimal.valueOf(item.quantity()))) 24 .reduce(BigDecimal.ZERO, BigDecimal::add); 25 26 if (total.compareTo(BigDecimal.ZERO) <= 0) { 27 throw new IllegalArgumentException("Order total must be positive"); 28 } 29 30 Order order = Order.create(request.customerId(), request.items(), total); 31 orderRepository.save(order); 32 33 PaymentResult result = paymentClient.charge(order.id(), total); 34 if (!result.success()) { 35 order.markFailed(result.reason()); 36 return order; 37 } 38 39 order.markPaid(result.transactionId()); 40 return order; 41 } 42 43 public List<Order> findRecent(String customerId, int limit) { 44 // TODO: move paging to repository layer 45 return orderRepository.findByCustomerIdOrderByCreatedAtDesc(customerId) 46 .stream() 47 .limit(limit) 48 .toList(); 49 } 50}