diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderApplicationServiceImpl.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderApplicationServiceImpl.java new file mode 100644 index 0000000..9bb5b92 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderApplicationServiceImpl.java @@ -0,0 +1,31 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.create.CreateOrderCommand; +import com.food.order.domain.dto.create.CreateOrderResponse; +import com.food.order.domain.dto.track.TrackOrderQuery; +import com.food.order.domain.dto.track.TrackOrderResponse; +import com.food.order.domain.ports.input.service.OrderApplicationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +@Service +@Validated +@Slf4j +@RequiredArgsConstructor +class OrderApplicationServiceImpl implements OrderApplicationService { + + private final OrderCreateCommandHandler orderCreateCommandHandler; + private final OrderTrackCommandHandler orderTrackCommandHandler; + + @Override + public CreateOrderResponse createOrder(CreateOrderCommand createOrderCommand) { + return orderCreateCommandHandler.createOrder(createOrderCommand); + } + + @Override + public TrackOrderResponse trackOrder(TrackOrderQuery trackOrderQuery) { + return orderTrackCommandHandler.trackOrder(trackOrderQuery); + } +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateCommandHandler.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateCommandHandler.java new file mode 100644 index 0000000..571a1f4 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateCommandHandler.java @@ -0,0 +1,66 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.create.CreateOrderCommand; +import com.food.order.domain.dto.create.CreateOrderResponse; +import com.food.order.domain.mapper.OrderDataMapper; +import com.food.order.domain.ports.output.repository.CustomerRepository; +import com.food.order.domain.ports.output.repository.OrderRepository; +import com.food.order.domain.ports.output.repository.RestaurantRepository; +import com.food.order.system.domain.entity.Order; +import com.food.order.system.domain.entity.Restaurant; +import com.food.order.system.domain.exception.OrderDomainException; +import com.food.order.system.domain.service.OrderDomainService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Objects; +import java.util.UUID; + +@Component +@Slf4j +@RequiredArgsConstructor +public class OrderCreateCommandHandler { + + private final OrderDomainService orderDomainService; + private final OrderRepository orderRepository; + private final CustomerRepository customerRepository; + private final RestaurantRepository restaurantRepository; + private final OrderDataMapper orderDataMapper; + + @Transactional + public CreateOrderResponse createOrder(CreateOrderCommand createOrderCommand) { + log.info("createOrder: {}", createOrderCommand); + checkCustomer(createOrderCommand.getCustomerId()); + Restaurant restaurant = checkRestaurant(createOrderCommand); + var order = orderDataMapper.createOrderCommandToOrder(createOrderCommand); + var createdEventOrder = orderDomainService.validateAndInitiateOrder(order, restaurant); + var savedOrder = saveOrder(order); + log.info("createOrder with id: {}", savedOrder.getId().getValue()); + return orderDataMapper.orderToCreateOrderResponse(savedOrder,"Order created successfully"); + } + + private Restaurant checkRestaurant(CreateOrderCommand createOrderCommand) { + return restaurantRepository.findRestaurantInformation + (orderDataMapper.createOrderCommandToRestaurant(createOrderCommand)) + .orElseThrow(() -> new OrderDomainException("Restaurant not found. " + + "Please check restaurant id: " + createOrderCommand.getRestaurantId())); + } + + + private void checkCustomer(UUID customerId) { + customerRepository.findCustomer(customerId) + .orElseThrow(() -> new OrderDomainException("Customer not found. CustomerId: " + customerId)); + } + + private Order saveOrder(Order order){ + var savedOrder = orderRepository.save(order); + if (Objects.isNull(savedOrder)) { + throw new OrderDomainException("Order not saved"); + } + return savedOrder; + } + + +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java new file mode 100644 index 0000000..8cf4458 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java @@ -0,0 +1,16 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.track.TrackOrderQuery; +import com.food.order.domain.dto.track.TrackOrderResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class OrderTrackCommandHandler { + + public TrackOrderResponse trackOrder(TrackOrderQuery trackOrderQuery) { + log.info("trackOrder: {}", trackOrderQuery); + return null; + } +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java index 7cc0d71..c536e26 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java @@ -1,8 +1,74 @@ package com.food.order.domain.mapper; +import com.food.order.domain.dto.create.CreateOrderCommand; +import com.food.order.domain.dto.create.CreateOrderResponse; +import com.food.order.domain.dto.create.OrderAddress; +import com.food.order.domain.valueobject.CustomerId; +import com.food.order.domain.valueobject.Money; +import com.food.order.domain.valueobject.ProductId; +import com.food.order.domain.valueobject.RestaurantId; +import com.food.order.system.domain.entity.Order; +import com.food.order.system.domain.entity.OrderItem; +import com.food.order.system.domain.entity.Product; +import com.food.order.system.domain.entity.Restaurant; +import com.food.order.system.domain.valueobject.StreetAddress; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + @Component public class OrderDataMapper { + public Restaurant createOrderCommandToRestaurant(CreateOrderCommand createOrderCommand) { + return Restaurant.builder() + .id(new RestaurantId(createOrderCommand.getRestaurantId())) + .products(createOrderCommand.getOrderItems().stream() + .map(orderItem -> + new Product(new ProductId(orderItem.getProductId()))) + .collect(Collectors.toList()) + ) + .build(); + } + + public Order createOrderCommandToOrder(CreateOrderCommand createOrderCommand) { + return Order.builder() + .customerId(new CustomerId(createOrderCommand.getCustomerId())) + .restaurantId(new RestaurantId(createOrderCommand.getRestaurantId())) + .deliveryAddress(orderAddressToStreetAddress(createOrderCommand.getOrderAddress())) + .price(new Money(createOrderCommand.getPrice())) + .items(orderItemsToOrderItemEntities(createOrderCommand.getOrderItems())) + .build(); + } + + private List orderItemsToOrderItemEntities(List orderItems) { + return orderItems.stream() + .map(orderItem -> + OrderItem.builder() + .product(new Product(new ProductId(orderItem.getProductId()))) + .price(new Money(orderItem.getPrice())) + .quantity(orderItem.getQuantity()) + .subTotal(new Money(orderItem.getSubTotal())) + .build()) + .collect(Collectors.toList()); + } + + private StreetAddress orderAddressToStreetAddress(OrderAddress orderAddress) { + return new StreetAddress( + UUID.randomUUID(), + orderAddress.getStreet(), + orderAddress.getCity(), + orderAddress.getPostalCode() + ); + } + + + public CreateOrderResponse orderToCreateOrderResponse(Order order, String message) { + return CreateOrderResponse.builder() + .orderTrackingId(order.getTrackingId().getValue()) + .orderStatus(order.getStatus()) + .message(message) + .build(); + } } diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Product.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Product.java index 027513c..ae329f5 100644 --- a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Product.java +++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Product.java @@ -8,12 +8,17 @@ public class Product extends BaseEntity { private String name; private Money price; + public Product(ProductId id, String name, Money price) { super.setId(id); this.name = name; this.price = price; } + public Product(ProductId id) { + super.setId(id); + } + public String getName() { return name; }