From 2282519f6906ba2d59cf6feed10f70e8b1004514 Mon Sep 17 00:00:00 2001 From: Ali CANLI Date: Wed, 13 Jul 2022 21:16:20 +0300 Subject: [PATCH] Add Restaurant-Service domain layer. --- .../valueobject/RestaurantOrderStatus.java | 5 + ...PaidRestaurantRequestMessagePublisher.java | 8 ++ pom.xml | 7 ++ restaurant-service/pom.xml | 24 ++++ .../restaurant-container/pom.xml | 16 +++ .../restaurant-dataaccess/pom.xml | 15 +++ restaurant-service/restaurant-domain/pom.xml | 22 ++++ .../restaurant-application-service/pom.xml | 39 +++++++ .../RestaurantApprovalRequestHelper.java | 63 ++++++++++ ...antApprovalRequestMessageListenerImpl.java | 21 ++++ .../config/RestaurantServiceConfig.java | 15 +++ .../dto/RestaurantApprovalRequest.java | 25 ++++ ...RestaurantApplicationServiceException.java | 14 +++ .../service/mapper/RestaurantDataMapper.java | 35 ++++++ ...taurantApprovalRequestMessageListener.java | 7 ++ .../OrderApprovedMessagePublisher.java | 8 ++ .../OrderRejectedMessagePublisher.java | 8 ++ .../repository/OrderApprovalRepository.java | 7 ++ .../repository/RestaurantRepository.java | 10 ++ .../restaurant-domain-core/pom.xml | 23 ++++ .../domain/core/RestaurantDomainService.java | 17 +++ .../core/RestaurantDomainServiceImpl.java | 40 +++++++ .../domain/core/entity/OrderApproval.java | 72 ++++++++++++ .../domain/core/entity/OrderDetail.java | 72 ++++++++++++ .../domain/core/entity/Product.java | 88 ++++++++++++++ .../domain/core/entity/Restaurant.java | 110 ++++++++++++++++++ .../domain/core/event/OrderApprovalEvent.java | 42 +++++++ .../domain/core/event/OrderApprovedEvent.java | 28 +++++ .../domain/core/event/OrderRejectedEvent.java | 27 +++++ .../exception/RestaurantDomainException.java | 13 +++ .../RestaurantNotFoundException.java | 13 +++ .../core/valueobject/OrderApprovalId.java | 11 ++ .../restaurant-messaging/pom.xml | 15 +++ 33 files changed, 920 insertions(+) create mode 100644 common/common-domain/src/main/java/com/food/order/sysyem/valueobject/RestaurantOrderStatus.java create mode 100644 order-service/order-domain/order-application-service/src/main/java/com/food/order/sysyem/ports/output/message/publisher/restaurantapproval/OrderPaidRestaurantRequestMessagePublisher.java create mode 100644 restaurant-service/pom.xml create mode 100644 restaurant-service/restaurant-container/pom.xml create mode 100644 restaurant-service/restaurant-dataaccess/pom.xml create mode 100644 restaurant-service/restaurant-domain/pom.xml create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/pom.xml create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestHelper.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestMessageListenerImpl.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/config/RestaurantServiceConfig.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/dto/RestaurantApprovalRequest.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/exception/RestaurantApplicationServiceException.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/mapper/RestaurantDataMapper.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/input/message/listener/RestaurantApprovalRequestMessageListener.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderApprovedMessagePublisher.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderRejectedMessagePublisher.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/OrderApprovalRepository.java create mode 100644 restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/RestaurantRepository.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/pom.xml create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainService.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainServiceImpl.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderApproval.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderDetail.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Product.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Restaurant.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovalEvent.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovedEvent.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderRejectedEvent.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantDomainException.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantNotFoundException.java create mode 100644 restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/valueobject/OrderApprovalId.java create mode 100644 restaurant-service/restaurant-messaging/pom.xml diff --git a/common/common-domain/src/main/java/com/food/order/sysyem/valueobject/RestaurantOrderStatus.java b/common/common-domain/src/main/java/com/food/order/sysyem/valueobject/RestaurantOrderStatus.java new file mode 100644 index 0000000..d485e55 --- /dev/null +++ b/common/common-domain/src/main/java/com/food/order/sysyem/valueobject/RestaurantOrderStatus.java @@ -0,0 +1,5 @@ +package com.food.order.sysyem.valueobject; + +public enum RestaurantOrderStatus { + PAID +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/sysyem/ports/output/message/publisher/restaurantapproval/OrderPaidRestaurantRequestMessagePublisher.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/sysyem/ports/output/message/publisher/restaurantapproval/OrderPaidRestaurantRequestMessagePublisher.java new file mode 100644 index 0000000..1d03f3f --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/sysyem/ports/output/message/publisher/restaurantapproval/OrderPaidRestaurantRequestMessagePublisher.java @@ -0,0 +1,8 @@ +package com.food.order.sysyem.ports.output.message.publisher.restaurantapproval; + +import com.food.order.sysyem.event.publisher.DomainEventPublisher; +import com.food.order.system.domain.event.OrderPaidEvent; + +public interface OrderPaidRestaurantRequestMessagePublisher extends DomainEventPublisher { + +} diff --git a/pom.xml b/pom.xml index bf3e86b..b2ddad0 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ infrastructure/kafka customer-service payment-service + restaurant-service @@ -97,6 +98,12 @@ ${project.version} + + com.food.order + restaurant-domain-core + ${project.version} + + com.food.order kafka-producer diff --git a/restaurant-service/pom.xml b/restaurant-service/pom.xml new file mode 100644 index 0000000..c83f998 --- /dev/null +++ b/restaurant-service/pom.xml @@ -0,0 +1,24 @@ + + + + food-ordering-system + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + restaurant-service + pom + + restaurant-domain + restaurant-messaging + restaurant-container + restaurant-dataaccess + restaurant-domain/restaurant-domain-core + restaurant-domain/restaurant-application-service + + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-container/pom.xml b/restaurant-service/restaurant-container/pom.xml new file mode 100644 index 0000000..ed41982 --- /dev/null +++ b/restaurant-service/restaurant-container/pom.xml @@ -0,0 +1,16 @@ + + + + restaurant-service + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + restaurant-container + + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-dataaccess/pom.xml b/restaurant-service/restaurant-dataaccess/pom.xml new file mode 100644 index 0000000..ab2c9c2 --- /dev/null +++ b/restaurant-service/restaurant-dataaccess/pom.xml @@ -0,0 +1,15 @@ + + + + restaurant-service + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + restaurant-dataaccess + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-domain/pom.xml b/restaurant-service/restaurant-domain/pom.xml new file mode 100644 index 0000000..9150a31 --- /dev/null +++ b/restaurant-service/restaurant-domain/pom.xml @@ -0,0 +1,22 @@ + + + + restaurant-service + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + + restaurant-domain-core + restaurant-application-service + + pom + + restaurant-domain + + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/pom.xml b/restaurant-service/restaurant-domain/restaurant-application-service/pom.xml new file mode 100644 index 0000000..690422b --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/pom.xml @@ -0,0 +1,39 @@ + + + + restaurant-domain + com.food.order + 1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + restaurant-application-service + + + + + com.food.order + restaurant-domain-core + + + + org.springframework.boot + spring-boot-starter-validation + + + + com.food.order + common-domain + + + + org.springframework + spring-tx + + + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestHelper.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestHelper.java new file mode 100644 index 0000000..11f8786 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestHelper.java @@ -0,0 +1,63 @@ +package com.food.ordery.system.restaurant.domain.service; + +import com.food.order.system.restaurant.domain.core.RestaurantDomainService; +import com.food.order.system.restaurant.domain.core.entity.Restaurant; +import com.food.order.system.restaurant.domain.core.event.OrderApprovalEvent; +import com.food.order.system.restaurant.domain.core.exception.RestaurantNotFoundException; +import com.food.order.sysyem.valueobject.OrderId; +import com.food.ordery.system.restaurant.domain.service.dto.RestaurantApprovalRequest; +import com.food.ordery.system.restaurant.domain.service.mapper.RestaurantDataMapper; +import com.food.ordery.system.restaurant.domain.service.ports.output.message.publisher.OrderApprovedMessagePublisher; +import com.food.ordery.system.restaurant.domain.service.ports.output.message.publisher.OrderRejectedMessagePublisher; +import com.food.ordery.system.restaurant.domain.service.ports.output.repository.OrderApprovalRepository; +import com.food.ordery.system.restaurant.domain.service.ports.output.repository.RestaurantRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Slf4j +@Component +@RequiredArgsConstructor +public class RestaurantApprovalRequestHelper { + + private final RestaurantDomainService restaurantDomainService; + private final RestaurantDataMapper restaurantDataMapper; + private final RestaurantRepository restaurantRepository; + private final OrderApprovalRepository orderApprovalRepository; + private final OrderApprovedMessagePublisher orderApprovedMessagePublisher; + private final OrderRejectedMessagePublisher orderRejectedMessagePublisher; + + @Transactional + public OrderApprovalEvent persistOrderApproval(RestaurantApprovalRequest request) { + log.info("Persisting order approval request: {}", request); + List failureMessages = new ArrayList<>(); + var restaurant = findRestaurant(request); + var event = restaurantDomainService.validateOrder + (restaurant, failureMessages, orderApprovedMessagePublisher, orderRejectedMessagePublisher); + + orderApprovalRepository.save(restaurant.getOrderApproval()); + return event; + + } + + private Restaurant findRestaurant(RestaurantApprovalRequest request) { + var restaurant = restaurantDataMapper.restaurantApprovalRequestToRestaurant(request); + var resultRestaurant = restaurantRepository.findRestaurantInformation(restaurant).orElseThrow( + () -> new RestaurantNotFoundException("Restaurant not found") + ); + restaurant.setActive(resultRestaurant.isActive()); + restaurant.getOrderDetail().getProducts().forEach(product -> { + resultRestaurant.getOrderDetail().getProducts().forEach(p -> { + if (p.getId().equals(product.getId())) { + p.updateWithConfirmedNamePriceAndAvailablity(p.getName(),p.getPrice(), p.isAvailable()); + }}); + }); + restaurant.getOrderDetail().setId(new OrderId(UUID.fromString(request.getOrderId()))); + return restaurant; + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestMessageListenerImpl.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestMessageListenerImpl.java new file mode 100644 index 0000000..4b58fa5 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/RestaurantApprovalRequestMessageListenerImpl.java @@ -0,0 +1,21 @@ +package com.food.ordery.system.restaurant.domain.service; + +import com.food.ordery.system.restaurant.domain.service.dto.RestaurantApprovalRequest; +import com.food.ordery.system.restaurant.domain.service.ports.input.message.listener.RestaurantApprovalRequestMessageListener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class RestaurantApprovalRequestMessageListenerImpl implements RestaurantApprovalRequestMessageListener { + + private final RestaurantApprovalRequestHelper restaurantApprovalRequestHelper; + + @Override + public void approveOrder(RestaurantApprovalRequest request) { + var event = restaurantApprovalRequestHelper.persistOrderApproval(request); + event.fire(); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/config/RestaurantServiceConfig.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/config/RestaurantServiceConfig.java new file mode 100644 index 0000000..320fff1 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/config/RestaurantServiceConfig.java @@ -0,0 +1,15 @@ +package com.food.ordery.system.restaurant.domain.service.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "restaurant-service") +public class RestaurantServiceConfig { + + private String restaurantApprovalRequestTopicName; + private String restaurantApprovalResponseTopicName; + +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/dto/RestaurantApprovalRequest.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/dto/RestaurantApprovalRequest.java new file mode 100644 index 0000000..b0afe0e --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/dto/RestaurantApprovalRequest.java @@ -0,0 +1,25 @@ +package com.food.ordery.system.restaurant.domain.service.dto; + +import com.food.order.system.restaurant.domain.core.entity.Product; +import com.food.order.sysyem.valueobject.RestaurantOrderStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.math.BigDecimal; +import java.time.Instant; +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +public class RestaurantApprovalRequest { + private String id; + private String sagaId; + private String restaurantId; + private String orderId; + private RestaurantOrderStatus status; + private List products; + private BigDecimal price; + private Instant createdAt; +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/exception/RestaurantApplicationServiceException.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/exception/RestaurantApplicationServiceException.java new file mode 100644 index 0000000..6816abc --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/exception/RestaurantApplicationServiceException.java @@ -0,0 +1,14 @@ +package com.food.ordery.system.restaurant.domain.service.exception; + +import com.food.order.sysyem.exception.DomainException; + +public class RestaurantApplicationServiceException extends DomainException { + + public RestaurantApplicationServiceException(String message) { + super(message); + } + + public RestaurantApplicationServiceException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/mapper/RestaurantDataMapper.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/mapper/RestaurantDataMapper.java new file mode 100644 index 0000000..727e0de --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/mapper/RestaurantDataMapper.java @@ -0,0 +1,35 @@ +package com.food.ordery.system.restaurant.domain.service.mapper; + +import com.food.order.system.restaurant.domain.core.entity.OrderDetail; +import com.food.order.system.restaurant.domain.core.entity.Product; +import com.food.order.system.restaurant.domain.core.entity.Restaurant; +import com.food.order.sysyem.valueobject.Money; +import com.food.order.sysyem.valueobject.OrderId; +import com.food.order.sysyem.valueobject.OrderStatus; +import com.food.order.sysyem.valueobject.RestaurantId; +import com.food.ordery.system.restaurant.domain.service.dto.RestaurantApprovalRequest; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +public class RestaurantDataMapper { + + public Restaurant restaurantApprovalRequestToRestaurant(RestaurantApprovalRequest request) { + return Restaurant.builder() + .restaurantId(new RestaurantId(UUID.fromString(request.getRestaurantId()))) + .orderDetail(OrderDetail.builder() + .orderId(new OrderId(UUID.fromString(request.getOrderId()))) + .products(request.getProducts().stream().map( + product -> Product.builder() + .productId(product.getId()) + .quantity(product.getQuantity()) + + .build() + ).toList()) + .totalAmount(new Money(request.getPrice())) + .status(OrderStatus.valueOf(request.getStatus().name())) + .build()) + .build(); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/input/message/listener/RestaurantApprovalRequestMessageListener.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/input/message/listener/RestaurantApprovalRequestMessageListener.java new file mode 100644 index 0000000..4b72ecd --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/input/message/listener/RestaurantApprovalRequestMessageListener.java @@ -0,0 +1,7 @@ +package com.food.ordery.system.restaurant.domain.service.ports.input.message.listener; + +import com.food.ordery.system.restaurant.domain.service.dto.RestaurantApprovalRequest; + +public interface RestaurantApprovalRequestMessageListener { + void approveOrder(RestaurantApprovalRequest request); +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderApprovedMessagePublisher.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderApprovedMessagePublisher.java new file mode 100644 index 0000000..80c5962 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderApprovedMessagePublisher.java @@ -0,0 +1,8 @@ +package com.food.ordery.system.restaurant.domain.service.ports.output.message.publisher; + +import com.food.order.system.restaurant.domain.core.event.OrderApprovedEvent; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; + +public interface OrderApprovedMessagePublisher extends DomainEventPublisher { + +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderRejectedMessagePublisher.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderRejectedMessagePublisher.java new file mode 100644 index 0000000..2878ce6 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/message/publisher/OrderRejectedMessagePublisher.java @@ -0,0 +1,8 @@ +package com.food.ordery.system.restaurant.domain.service.ports.output.message.publisher; + +import com.food.order.system.restaurant.domain.core.event.OrderRejectedEvent; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; + +public interface OrderRejectedMessagePublisher extends DomainEventPublisher { + +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/OrderApprovalRepository.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/OrderApprovalRepository.java new file mode 100644 index 0000000..e897f1d --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/OrderApprovalRepository.java @@ -0,0 +1,7 @@ +package com.food.ordery.system.restaurant.domain.service.ports.output.repository; + +import com.food.order.system.restaurant.domain.core.entity.OrderApproval; + +public interface OrderApprovalRepository { + OrderApproval save(OrderApproval orderApproval); +} diff --git a/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/RestaurantRepository.java b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/RestaurantRepository.java new file mode 100644 index 0000000..8ca9da5 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-application-service/src/main/java/com/food/ordery/system/restaurant/domain/service/ports/output/repository/RestaurantRepository.java @@ -0,0 +1,10 @@ +package com.food.ordery.system.restaurant.domain.service.ports.output.repository; + +import com.food.order.system.restaurant.domain.core.entity.Restaurant; + +import java.util.Optional; + +public interface RestaurantRepository { + Optional findRestaurantInformation(Restaurant restaurant); + +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/pom.xml b/restaurant-service/restaurant-domain/restaurant-domain-core/pom.xml new file mode 100644 index 0000000..cbe2990 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/pom.xml @@ -0,0 +1,23 @@ + + + + restaurant-domain + com.food.order + 1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + restaurant-domain-core + + + + com.food.order + common-domain + + + + + \ No newline at end of file diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainService.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainService.java new file mode 100644 index 0000000..7ec250f --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainService.java @@ -0,0 +1,17 @@ +package com.food.order.system.restaurant.domain.core; + +import com.food.order.system.restaurant.domain.core.entity.Restaurant; +import com.food.order.system.restaurant.domain.core.event.OrderApprovalEvent; +import com.food.order.system.restaurant.domain.core.event.OrderApprovedEvent; +import com.food.order.system.restaurant.domain.core.event.OrderRejectedEvent; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; + +import java.util.List; + +public interface RestaurantDomainService { + OrderApprovalEvent validateOrder(Restaurant restaurant, + List failureMessages, + DomainEventPublisher publisher, + DomainEventPublisher rejectedPublisher); + +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainServiceImpl.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainServiceImpl.java new file mode 100644 index 0000000..8559162 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/RestaurantDomainServiceImpl.java @@ -0,0 +1,40 @@ +package com.food.order.system.restaurant.domain.core; + +import com.food.order.system.restaurant.domain.core.entity.Restaurant; +import com.food.order.system.restaurant.domain.core.event.OrderApprovalEvent; +import com.food.order.system.restaurant.domain.core.event.OrderApprovedEvent; +import com.food.order.system.restaurant.domain.core.event.OrderRejectedEvent; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; +import com.food.order.sysyem.valueobject.OrderApprovalStatus; +import lombok.extern.slf4j.Slf4j; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; + +import static com.food.order.sysyem.DomainConstants.UTC; + +@Slf4j +public class RestaurantDomainServiceImpl implements RestaurantDomainService { + + @Override + public OrderApprovalEvent validateOrder(Restaurant restaurant, + List failureMessages, + DomainEventPublisher publisher, + DomainEventPublisher rejectedPublisher) { + restaurant.validateOrder(failureMessages); + log.info("Order validation with id {}", restaurant.getOrderDetail().getId()); + if (failureMessages.isEmpty()) { + log.info("Order validation with id {} is successful", restaurant.getOrderDetail().getId()); + restaurant.constructOrderApproval(OrderApprovalStatus.APPROVED); + return new OrderApprovedEvent(restaurant.getOrderApproval(), restaurant.getId(), + failureMessages, ZonedDateTime.now(ZoneId.of(UTC)), publisher); + } else { + log.info("Order validation with id {} is failed", restaurant.getOrderDetail().getId()); + restaurant.constructOrderApproval(OrderApprovalStatus.REJECTED); + return new OrderRejectedEvent(restaurant.getOrderApproval(), restaurant.getId(), + failureMessages, ZonedDateTime.now(), rejectedPublisher); + } + + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderApproval.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderApproval.java new file mode 100644 index 0000000..79416d9 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderApproval.java @@ -0,0 +1,72 @@ +package com.food.order.system.restaurant.domain.core.entity; + +import com.food.order.system.restaurant.domain.core.valueobject.OrderApprovalId; +import com.food.order.sysyem.entity.BaseEntity; +import com.food.order.sysyem.valueobject.OrderApprovalStatus; +import com.food.order.sysyem.valueobject.OrderId; +import com.food.order.sysyem.valueobject.RestaurantId; + +public class OrderApproval extends BaseEntity { + + private final RestaurantId restaurantId; + private final OrderId orderId; + private final OrderApprovalStatus status; + + private OrderApproval(Builder builder) { + setId(builder.orderApprovalId); + restaurantId = builder.restaurantId; + orderId = builder.orderId; + status = builder.status; + } + + public static Builder builder() { + return new Builder(); + } + + public RestaurantId getRestaurantId() { + return restaurantId; + } + + public OrderId getOrderId() { + return orderId; + } + + public OrderApprovalStatus getStatus() { + return status; + } + + + public static final class Builder { + private OrderApprovalId orderApprovalId; + private RestaurantId restaurantId; + private OrderId orderId; + private OrderApprovalStatus status; + + private Builder() { + } + + public Builder orderApprovalId(OrderApprovalId val) { + orderApprovalId = val; + return this; + } + + public Builder restaurantId(RestaurantId val) { + restaurantId = val; + return this; + } + + public Builder orderId(OrderId val) { + orderId = val; + return this; + } + + public Builder status(OrderApprovalStatus val) { + status = val; + return this; + } + + public OrderApproval build() { + return new OrderApproval(this); + } + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderDetail.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderDetail.java new file mode 100644 index 0000000..a8831e4 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/OrderDetail.java @@ -0,0 +1,72 @@ +package com.food.order.system.restaurant.domain.core.entity; + +import com.food.order.sysyem.entity.BaseEntity; +import com.food.order.sysyem.valueobject.Money; +import com.food.order.sysyem.valueobject.OrderId; +import com.food.order.sysyem.valueobject.OrderStatus; + +import java.util.List; + +public class OrderDetail extends BaseEntity { + private OrderStatus status; + private Money totalAmount; + private final List products; + + private OrderDetail(Builder builder) { + setId(builder.orderId); + status = builder.status; + totalAmount = builder.totalAmount; + products = builder.products; + } + + public static Builder builder() { + return new Builder(); + } + + public OrderStatus getStatus() { + return status; + } + + public Money getTotalAmount() { + return totalAmount; + } + + public List getProducts() { + return products; + } + + + public static final class Builder { + private OrderId orderId; + private OrderStatus status; + private Money totalAmount; + private List products; + + private Builder() { + } + + public Builder orderId(OrderId val) { + orderId = val; + return this; + } + + public Builder status(OrderStatus val) { + status = val; + return this; + } + + public Builder totalAmount(Money val) { + totalAmount = val; + return this; + } + + public Builder products(List val) { + products = val; + return this; + } + + public OrderDetail build() { + return new OrderDetail(this); + } + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Product.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Product.java new file mode 100644 index 0000000..c997d06 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Product.java @@ -0,0 +1,88 @@ +package com.food.order.system.restaurant.domain.core.entity; + +import com.food.order.sysyem.entity.BaseEntity; +import com.food.order.sysyem.valueobject.Money; +import com.food.order.sysyem.valueobject.ProductId; + +public class Product extends BaseEntity { + + private String name; + private Money price; + private final int quantity; + private boolean available; + + public void updateWithConfirmedNamePriceAndAvailablity(String name, Money price, boolean available) { + this.name = name; + this.price = price; + this.available = available; + } + + private Product(Builder builder) { + setId(builder.productId); + name = builder.name; + price = builder.price; + quantity = builder.quantity; + available = builder.available; + } + + public static Builder builder() { + return new Builder(); + } + + public String getName() { + return name; + } + + public Money getPrice() { + return price; + } + + public int getQuantity() { + return quantity; + } + + public boolean isAvailable() { + return available; + } + + + public static final class Builder { + private ProductId productId; + private String name; + private Money price; + private int quantity; + private boolean available; + + private Builder() { + } + + public Builder productId(ProductId val) { + productId = val; + return this; + } + + public Builder name(String val) { + name = val; + return this; + } + + public Builder price(Money val) { + price = val; + return this; + } + + public Builder quantity(int val) { + quantity = val; + return this; + } + + public Builder available(boolean val) { + available = val; + return this; + } + + public Product build() { + return new Product(this); + } + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Restaurant.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Restaurant.java new file mode 100644 index 0000000..050bf9d --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/entity/Restaurant.java @@ -0,0 +1,110 @@ +package com.food.order.system.restaurant.domain.core.entity; + +import com.food.order.system.restaurant.domain.core.valueobject.OrderApprovalId; +import com.food.order.sysyem.entity.AggregateRoot; +import com.food.order.sysyem.valueobject.Money; +import com.food.order.sysyem.valueobject.OrderApprovalStatus; +import com.food.order.sysyem.valueobject.OrderStatus; +import com.food.order.sysyem.valueobject.RestaurantId; + +import java.util.List; +import java.util.UUID; + +public class Restaurant extends AggregateRoot { + private OrderApproval orderApproval; + private boolean active; + private final OrderDetail orderDetail; + + public void validateOrder(List failureMessages){ + if (!orderDetail.getStatus().equals(OrderStatus.PAID)){ + failureMessages.add("Order is not paid"); + } + var totalAmount = orderDetail.getProducts() + .stream() + .map(product -> { + if (Boolean.FALSE.equals(product.isAvailable())) + { + failureMessages.add("Product is not available"); + } + return product.getPrice().multiply(product.getQuantity()); + }) + .reduce(Money.ZERO, Money::add); + + if(!totalAmount.equals(orderDetail.getTotalAmount())) + { + failureMessages.add("Total amount is not correct"); + } + + } + + public void constructOrderApproval(OrderApprovalStatus status){ + this.orderApproval = OrderApproval.builder() + .orderApprovalId(new OrderApprovalId(UUID.randomUUID())) + .restaurantId(this.getId()) + .orderId(this.getOrderDetail().getId()) + .status(status) + .build(); + } + + public void setActive(boolean active) { + this.active = active; + } + + private Restaurant(Builder builder) { + setId(builder.restaurantId); + orderApproval = builder.orderApproval; + active = builder.active; + orderDetail = builder.orderDetail; + } + + public static Builder builder() { + return new Builder(); + } + + public OrderApproval getOrderApproval() { + return orderApproval; + } + + public boolean isActive() { + return active; + } + + public OrderDetail getOrderDetail() { + return orderDetail; + } + + + public static final class Builder { + private RestaurantId restaurantId; + private OrderApproval orderApproval; + private boolean active; + private OrderDetail orderDetail; + + private Builder() { + } + + public Builder restaurantId(RestaurantId val) { + restaurantId = val; + return this; + } + + public Builder orderApproval(OrderApproval val) { + orderApproval = val; + return this; + } + + public Builder active(boolean val) { + active = val; + return this; + } + + public Builder orderDetail(OrderDetail val) { + orderDetail = val; + return this; + } + + public Restaurant build() { + return new Restaurant(this); + } + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovalEvent.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovalEvent.java new file mode 100644 index 0000000..064e683 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovalEvent.java @@ -0,0 +1,42 @@ +package com.food.order.system.restaurant.domain.core.event; + +import com.food.order.system.restaurant.domain.core.entity.OrderApproval; +import com.food.order.sysyem.event.DomainEvent; +import com.food.order.sysyem.valueobject.RestaurantId; + +import java.time.ZonedDateTime; +import java.util.List; + +public abstract class OrderApprovalEvent implements DomainEvent { + + private final OrderApproval orderApproval; + private final RestaurantId restaurantId; + private final List failureMessages; + private final ZonedDateTime createdAt; + + public OrderApprovalEvent(OrderApproval orderApproval, + RestaurantId restaurantId, + List failureMessages, + ZonedDateTime createdAt) { + this.orderApproval = orderApproval; + this.restaurantId = restaurantId; + this.failureMessages = failureMessages; + this.createdAt = createdAt; + } + + public OrderApproval getOrderApproval() { + return orderApproval; + } + + public RestaurantId getRestaurantId() { + return restaurantId; + } + + public List getFailureMessages() { + return failureMessages; + } + + public ZonedDateTime getCreatedAt() { + return createdAt; + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovedEvent.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovedEvent.java new file mode 100644 index 0000000..02baddc --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderApprovedEvent.java @@ -0,0 +1,28 @@ +package com.food.order.system.restaurant.domain.core.event; + +import com.food.order.system.restaurant.domain.core.entity.OrderApproval; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; +import com.food.order.sysyem.valueobject.RestaurantId; + +import java.time.ZonedDateTime; +import java.util.List; + +public class OrderApprovedEvent extends OrderApprovalEvent { + + + private final DomainEventPublisher publisher; + + public OrderApprovedEvent(OrderApproval orderApproval, + RestaurantId restaurantId, + List failureMessages, + ZonedDateTime createdAt, + DomainEventPublisher publisher) { + super(orderApproval, restaurantId, failureMessages, createdAt); + this.publisher = publisher; + } + + @Override + public void fire() { + publisher.publish(this); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderRejectedEvent.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderRejectedEvent.java new file mode 100644 index 0000000..db850e5 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/event/OrderRejectedEvent.java @@ -0,0 +1,27 @@ +package com.food.order.system.restaurant.domain.core.event; + +import com.food.order.system.restaurant.domain.core.entity.OrderApproval; +import com.food.order.sysyem.event.publisher.DomainEventPublisher; +import com.food.order.sysyem.valueobject.RestaurantId; + +import java.time.ZonedDateTime; +import java.util.List; + +public class OrderRejectedEvent extends OrderApprovalEvent { + + private final DomainEventPublisher publisher; + + public OrderRejectedEvent(OrderApproval orderApproval, + RestaurantId restaurantId, + List failureMessages, + ZonedDateTime createdAt, + DomainEventPublisher publisher) { + super(orderApproval, restaurantId, failureMessages, createdAt); + this.publisher = publisher; + } + + @Override + public void fire() { + publisher.publish(this); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantDomainException.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantDomainException.java new file mode 100644 index 0000000..c4d8ea3 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantDomainException.java @@ -0,0 +1,13 @@ +package com.food.order.system.restaurant.domain.core.exception; + +import com.food.order.sysyem.exception.DomainException; + +public class RestaurantDomainException extends DomainException { + public RestaurantDomainException(String message) { + super(message); + } + + public RestaurantDomainException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantNotFoundException.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantNotFoundException.java new file mode 100644 index 0000000..39edb1e --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/exception/RestaurantNotFoundException.java @@ -0,0 +1,13 @@ +package com.food.order.system.restaurant.domain.core.exception; + +import com.food.order.sysyem.exception.DomainException; + +public class RestaurantNotFoundException extends DomainException { + public RestaurantNotFoundException(String message) { + super(message); + } + + public RestaurantNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/valueobject/OrderApprovalId.java b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/valueobject/OrderApprovalId.java new file mode 100644 index 0000000..08a77d1 --- /dev/null +++ b/restaurant-service/restaurant-domain/restaurant-domain-core/src/main/java/com/food/order/system/restaurant/domain/core/valueobject/OrderApprovalId.java @@ -0,0 +1,11 @@ +package com.food.order.system.restaurant.domain.core.valueobject; + +import com.food.order.sysyem.valueobject.BaseId; + +import java.util.UUID; + +public class OrderApprovalId extends BaseId { + public OrderApprovalId(UUID value) { + super(value); + } +} diff --git a/restaurant-service/restaurant-messaging/pom.xml b/restaurant-service/restaurant-messaging/pom.xml new file mode 100644 index 0000000..e4ad75c --- /dev/null +++ b/restaurant-service/restaurant-messaging/pom.xml @@ -0,0 +1,15 @@ + + + + restaurant-service + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + restaurant-messaging + + + \ No newline at end of file