diff --git a/common/common-application/pom.xml b/common/common-application/pom.xml
new file mode 100644
index 0000000..ef98914
--- /dev/null
+++ b/common/common-application/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ common
+ com.food.order
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ common-application
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+
\ No newline at end of file
diff --git a/common/common-application/src/main/java/com/food/order/system/application/handler/ErrorDTO.java b/common/common-application/src/main/java/com/food/order/system/application/handler/ErrorDTO.java
new file mode 100644
index 0000000..701dfd4
--- /dev/null
+++ b/common/common-application/src/main/java/com/food/order/system/application/handler/ErrorDTO.java
@@ -0,0 +1,7 @@
+package com.food.order.system.application.handler;
+
+import lombok.Builder;
+
+@Builder
+public record ErrorDTO(String code, String message) {
+}
diff --git a/common/common-application/src/main/java/com/food/order/system/application/handler/GlobalExceptionHandler.java b/common/common-application/src/main/java/com/food/order/system/application/handler/GlobalExceptionHandler.java
new file mode 100644
index 0000000..a8ace14
--- /dev/null
+++ b/common/common-application/src/main/java/com/food/order/system/application/handler/GlobalExceptionHandler.java
@@ -0,0 +1,59 @@
+package com.food.order.system.application.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
+import java.util.stream.Collectors;
+
+@Slf4j
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+ @ExceptionHandler(value = {Exception.class})
+ @ResponseBody
+ public ErrorDTO handleOrderDomainException(Exception e) {
+ log.error("Error occurred: {}", e.getMessage());
+ return ErrorDTO.builder()
+ .code(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
+ .message("Unknown error occurred")
+ .build();
+ }
+
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ExceptionHandler(value = {ValidationException.class})
+ @ResponseBody
+ public ErrorDTO handleOrderDomainException(ValidationException e) {
+ ErrorDTO errorDTO;
+ if (e instanceof ConstraintViolationException) {
+ String violations = extractViolationsFromException((ConstraintViolationException) e);
+ log.error("Error occurred: {}", violations);
+ errorDTO = ErrorDTO.builder()
+ .code(HttpStatus.BAD_REQUEST.getReasonPhrase())
+ .message(violations)
+ .build();
+ }
+ else {
+ log.error("Error occurred: {}", e.getMessage());
+ errorDTO = ErrorDTO.builder()
+ .code(HttpStatus.BAD_REQUEST.getReasonPhrase())
+ .message(e.getMessage())
+ .build();
+ }
+ return errorDTO;
+ }
+
+ private String extractViolationsFromException(ConstraintViolationException e) {
+ return e.getConstraintViolations()
+ .stream()
+ .map(ConstraintViolation::getMessage)
+ .collect(Collectors.joining("->"));
+ }
+}
diff --git a/common/pom.xml b/common/pom.xml
index 3aaef7e..54296de 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -13,6 +13,7 @@
pom
common-domain
+ common-application
diff --git a/order-service/order-app/pom.xml b/order-service/order-app/pom.xml
index 06d5b62..5290602 100644
--- a/order-service/order-app/pom.xml
+++ b/order-service/order-app/pom.xml
@@ -19,6 +19,21 @@
com.food.order
order-application-service
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ com.food.order
+ common-application
+
\ No newline at end of file
diff --git a/order-service/order-app/src/main/java/com/food/order/system/service/app/api/OrderController.java b/order-service/order-app/src/main/java/com/food/order/system/service/app/api/OrderController.java
new file mode 100644
index 0000000..5429e96
--- /dev/null
+++ b/order-service/order-app/src/main/java/com/food/order/system/service/app/api/OrderController.java
@@ -0,0 +1,43 @@
+package com.food.order.system.service.app.api;
+
+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.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.annotation.RequestScope;
+
+import java.util.UUID;
+
+@RestController
+@CrossOrigin
+@RequestScope
+@RequiredArgsConstructor
+@Slf4j
+@Validated
+@RequestMapping(value = "/api/orders", produces = "application/vnd.api.v1+json")
+public class OrderController {
+
+ private final OrderApplicationService orderApplicationService;
+
+ @PostMapping
+ public ResponseEntity createOrder(@RequestBody CreateOrderCommand createOrderCommand) {
+ log.info("Creating order with command: {}", createOrderCommand);
+ CreateOrderResponse createOrderResponse = orderApplicationService.createOrder(createOrderCommand);
+ log.info("Created order with tracking id: {}", createOrderResponse.orderTrackingId());
+ return ResponseEntity.ok(createOrderResponse);
+ }
+
+ @GetMapping("/{orderTrackingId}")
+ public ResponseEntity trackOrder(@PathVariable("orderTrackingId") UUID orderTrackingId) {
+ TrackOrderResponse trackOrderResponse = orderApplicationService.trackOrder
+ (new TrackOrderQuery(orderTrackingId));
+ log.info("Tracked order with tracking id: {}", orderTrackingId);
+ return ResponseEntity.ok(trackOrderResponse);
+ }
+}
diff --git a/order-service/order-app/src/main/java/com/food/order/system/service/app/exception/OrderGlobalException.java b/order-service/order-app/src/main/java/com/food/order/system/service/app/exception/OrderGlobalException.java
new file mode 100644
index 0000000..113e6ca
--- /dev/null
+++ b/order-service/order-app/src/main/java/com/food/order/system/service/app/exception/OrderGlobalException.java
@@ -0,0 +1,42 @@
+package com.food.order.system.service.app.exception;
+
+import com.food.order.system.application.handler.ErrorDTO;
+import com.food.order.system.application.handler.GlobalExceptionHandler;
+import com.food.order.system.domain.exception.OrderDomainException;
+import com.food.order.system.domain.exception.OrderNotFoundException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ControllerAdvice
+@Slf4j
+public class OrderGlobalException extends GlobalExceptionHandler {
+
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ExceptionHandler(value = {OrderDomainException.class})
+ @ResponseBody
+ public ErrorDTO handleOrderDomainException(OrderDomainException e) {
+ log.error("Error occurred: {}", e.getMessage());
+ return ErrorDTO.builder()
+ .code(HttpStatus.BAD_REQUEST.getReasonPhrase())
+ .message(e.getMessage())
+ .build();
+ }
+
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ @ExceptionHandler(value = {OrderNotFoundException.class})
+ @ResponseBody
+ public ErrorDTO handleOrderDomainException(OrderNotFoundException e) {
+ log.error("Error occurred: {}", e.getMessage());
+ return ErrorDTO.builder()
+ .code(HttpStatus.NOT_FOUND.getReasonPhrase())
+ .message(e.getMessage())
+ .build();
+ }
+
+
+
+}
diff --git a/order-service/order-data-access/pom.xml b/order-service/order-data-access/pom.xml
index eb0839a..f85e3e8 100644
--- a/order-service/order-data-access/pom.xml
+++ b/order-service/order-data-access/pom.xml
@@ -19,6 +19,16 @@
com.food.order
order-application-service
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.postgresql
+ postgresql
+
\ No newline at end of file
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/adapter/CustomerRepositoryImpl.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/adapter/CustomerRepositoryImpl.java
new file mode 100644
index 0000000..783b089
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/adapter/CustomerRepositoryImpl.java
@@ -0,0 +1,27 @@
+package com.food.order.system.data.access.customer.adapter;
+
+import com.food.order.domain.ports.output.repository.CustomerRepository;
+import com.food.order.system.data.access.customer.mapper.CustomerDataAccessMapper;
+import com.food.order.system.data.access.customer.repository.CustomerJPARepository;
+import com.food.order.system.domain.entity.Customer;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+public class CustomerRepositoryImpl implements CustomerRepository {
+
+
+ private final CustomerJPARepository customerJpaRepository;
+ private final CustomerDataAccessMapper customerDataAccessMapper;
+
+
+ @Override
+ public Optional findCustomer(UUID customerId) {
+ return customerJpaRepository.findById(customerId)
+ .map(customerDataAccessMapper::customerEntityToCustomer);
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/entity/CustomerEntity.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/entity/CustomerEntity.java
new file mode 100644
index 0000000..ceb1d15
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/entity/CustomerEntity.java
@@ -0,0 +1,23 @@
+package com.food.order.system.data.access.customer.entity;
+
+import lombok.*;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.UUID;
+
+@Entity
+@DynamicUpdate
+@Table(name = "order_customer_m_view",schema = "customer")
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CustomerEntity {
+
+ @Id
+ private UUID id;
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/mapper/CustomerDataAccessMapper.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/mapper/CustomerDataAccessMapper.java
new file mode 100644
index 0000000..24db9f2
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/mapper/CustomerDataAccessMapper.java
@@ -0,0 +1,14 @@
+package com.food.order.system.data.access.customer.mapper;
+
+import com.food.order.domain.valueobject.CustomerId;
+import com.food.order.system.data.access.customer.entity.CustomerEntity;
+import com.food.order.system.domain.entity.Customer;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CustomerDataAccessMapper {
+
+ public Customer customerEntityToCustomer(CustomerEntity customerEntity) {
+ return new Customer(new CustomerId(customerEntity.getId()));
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/repository/CustomerJPARepository.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/repository/CustomerJPARepository.java
new file mode 100644
index 0000000..e550d0a
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/customer/repository/CustomerJPARepository.java
@@ -0,0 +1,11 @@
+package com.food.order.system.data.access.customer.repository;
+
+import com.food.order.system.data.access.customer.entity.CustomerEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.UUID;
+
+@Repository
+public interface CustomerJPARepository extends JpaRepository {
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/adapter/OrderRepositoryImpl.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/adapter/OrderRepositoryImpl.java
new file mode 100644
index 0000000..335ca93
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/adapter/OrderRepositoryImpl.java
@@ -0,0 +1,34 @@
+package com.food.order.system.data.access.order.adapter;
+
+import com.food.order.domain.ports.output.repository.OrderRepository;
+import com.food.order.system.data.access.order.mapper.OrderDataAccessMapper;
+import com.food.order.system.data.access.order.repository.OrderJpaRepository;
+import com.food.order.system.domain.entity.Order;
+import com.food.order.system.domain.valueobject.TrackingId;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class OrderRepositoryImpl implements OrderRepository {
+
+ private final OrderJpaRepository orderJpaRepository;
+ private final OrderDataAccessMapper orderDataAccessMapper;
+
+
+ @Override
+ public Order save(Order order) {
+ return orderDataAccessMapper.orderEntityToOrder(orderJpaRepository
+ .save(orderDataAccessMapper.orderToOrderEntity(order)));
+ }
+
+ @Override
+ public Optional findByTrackingId(TrackingId trackingId) {
+ return orderJpaRepository.findByTrackingId(trackingId.getValue())
+ .map(orderDataAccessMapper::orderEntityToOrder);
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderAddressEntity.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderAddressEntity.java
new file mode 100644
index 0000000..e591b33
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderAddressEntity.java
@@ -0,0 +1,41 @@
+package com.food.order.system.data.access.order.entity;
+
+import lombok.*;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@DynamicUpdate
+@Table(name = "order_address")
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderAddressEntity {
+
+ @Id
+ private UUID id;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumn(name = "ORDER_ID")
+ private OrderEntity order;
+
+ private String street;
+ private String city;
+ private String postalCode;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof OrderAddressEntity that)) return false;
+ return id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+}
\ No newline at end of file
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderEntity.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderEntity.java
new file mode 100644
index 0000000..a5fc66d
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderEntity.java
@@ -0,0 +1,55 @@
+package com.food.order.system.data.access.order.entity;
+
+import com.food.order.domain.valueobject.OrderStatus;
+import lombok.*;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+@Entity
+@DynamicUpdate
+@Table(name = "orders")
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderEntity {
+
+ @Id
+ private UUID id;
+
+ private UUID customerId;
+
+ private UUID restaurantId;
+
+ private UUID trackingId;
+
+ @Enumerated(EnumType.STRING)
+ private OrderStatus orderStatus;
+
+ private BigDecimal price;
+
+ private String failureMessages;
+
+ @OneToOne(mappedBy = "order", cascade = CascadeType.ALL)
+ private OrderAddressEntity address;
+
+ @OneToMany(mappedBy = "orderEntity", cascade = CascadeType.ALL)
+ private List items;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof OrderEntity that)) return false;
+ return id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntity.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntity.java
new file mode 100644
index 0000000..750649a
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntity.java
@@ -0,0 +1,50 @@
+package com.food.order.system.data.access.order.entity;
+
+import lombok.*;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+import java.util.UUID;
+
+@Entity
+@DynamicUpdate
+@Table(name = "order_items")
+@IdClass(OrderItemEntityId.class)
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderItemEntity {
+
+ @Id
+ private Long id;
+ @Id
+ @ManyToOne(cascade = CascadeType.ALL)
+ @JoinColumn(name = "ORDER_ID")
+ private OrderEntity orderEntity;
+
+ private UUID productId;
+
+ private Integer quantity;
+
+ private BigDecimal price;
+
+ private BigDecimal subTotal;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof OrderItemEntity that)) return false;
+ if (!id.equals(that.id)) return false;
+ return orderEntity.equals(that.orderEntity);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id.hashCode();
+ result = 31 * result + orderEntity.hashCode();
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntityId.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntityId.java
new file mode 100644
index 0000000..1521f1d
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/entity/OrderItemEntityId.java
@@ -0,0 +1,29 @@
+package com.food.order.system.data.access.order.entity;
+
+import lombok.*;
+
+import java.io.Serializable;
+
+
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderItemEntityId implements Serializable {
+
+ private Long id;
+ private OrderEntity order;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof OrderItemEntityId that)) return false;
+ return id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/mapper/OrderDataAccessMapper.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/mapper/OrderDataAccessMapper.java
new file mode 100644
index 0000000..d7c82b5
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/mapper/OrderDataAccessMapper.java
@@ -0,0 +1,92 @@
+package com.food.order.system.data.access.order.mapper;
+
+import com.food.order.domain.valueobject.*;
+import com.food.order.system.data.access.order.entity.OrderAddressEntity;
+import com.food.order.system.data.access.order.entity.OrderEntity;
+import com.food.order.system.data.access.order.entity.OrderItemEntity;
+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.valueobject.OrderItemId;
+import com.food.order.system.domain.valueobject.StreetAddress;
+import com.food.order.system.domain.valueobject.TrackingId;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.food.order.system.domain.entity.Order.FAILURE_MESSAGE_DELIMITER;
+
+@Component
+public class OrderDataAccessMapper {
+
+ public OrderEntity orderToOrderEntity(Order order){
+ OrderEntity orderEntity = new OrderEntity();
+ orderEntity.setId(order.getId().getValue());
+ orderEntity.setOrderStatus(order.getStatus());
+ orderEntity.setCustomerId(order.getCustomerId().getValue());
+ orderEntity.setRestaurantId(order.getRestaurantId().getValue());
+ orderEntity.setTrackingId(order.getTrackingId().getValue());
+ orderEntity.setAddress(deliveryAddressToAddressEntity(order.getDeliveryAddress()));
+ orderEntity.setPrice(order.getPrice().getAmount());
+ orderEntity.setItems(orderItemsToOrderItemsEntity(order.getItems()));
+ orderEntity.setFailureMessages(order.getFailureMessages() != null ?
+ String.join(FAILURE_MESSAGE_DELIMITER, order.getFailureMessages()) : "");
+ orderEntity.getAddress().setOrder(orderEntity);
+ orderEntity.getItems().forEach(item -> item.setOrderEntity(orderEntity));
+ return orderEntity;
+ }
+
+ public Order orderEntityToOrder(OrderEntity orderEntity){
+ return Order.builder()
+ .orderId(new OrderId(orderEntity.getId()))
+ .customerId(new CustomerId(orderEntity.getCustomerId()))
+ .restaurantId(new RestaurantId(orderEntity.getRestaurantId()))
+ .deliveryAddress(addressEntityToDeliveryAddress(orderEntity.getAddress()))
+ .price(new Money(orderEntity.getPrice()))
+ .items(orderItemsEntityToOrderItems(orderEntity.getItems()))
+ .trackingId(new TrackingId(orderEntity.getTrackingId()))
+ .status(orderEntity.getOrderStatus())
+ .failureMessages(orderEntity.getFailureMessages() != null ?
+ List.of(orderEntity.getFailureMessages().split(FAILURE_MESSAGE_DELIMITER)) :
+ new ArrayList<>())
+ .build();
+ }
+
+ private List orderItemsEntityToOrderItems(List items) {
+ return items.stream()
+ .map(item -> OrderItem.builder()
+ .orderItemId(new OrderItemId(item.getId()))
+ .product(new Product(new ProductId(item.getProductId())))
+ .quantity(item.getQuantity())
+ .price(new Money(item.getPrice()))
+ .subTotal(new Money(item.getSubTotal()))
+ .build())
+ .toList();
+ }
+
+ private StreetAddress addressEntityToDeliveryAddress(OrderAddressEntity address) {
+ return new StreetAddress(address.getId(),address.getStreet(), address.getCity() , address.getPostalCode());
+ }
+
+ private List orderItemsToOrderItemsEntity(List items) {
+ return items.stream()
+ .map(item -> OrderItemEntity.builder()
+ .id(item.getId().getValue())
+ .productId(item.getProduct().getId().getValue())
+ .price(item.getPrice().getAmount())
+ .quantity(item.getQuantity())
+ .subTotal(item.getSubTotal().getAmount())
+ .build())
+ .toList();
+ }
+
+ private OrderAddressEntity deliveryAddressToAddressEntity(StreetAddress deliveryAddress) {
+ OrderAddressEntity orderAddressEntity = new OrderAddressEntity();
+ orderAddressEntity.setId(deliveryAddress.getId());
+ orderAddressEntity.setStreet(deliveryAddress.getStreet());
+ orderAddressEntity.setCity(deliveryAddress.getCity());
+ orderAddressEntity.setPostalCode(deliveryAddress.getPostalCode());
+ return orderAddressEntity;
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/repository/OrderJpaRepository.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/repository/OrderJpaRepository.java
new file mode 100644
index 0000000..cc40b86
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/order/repository/OrderJpaRepository.java
@@ -0,0 +1,16 @@
+package com.food.order.system.data.access.order.repository;
+
+import com.food.order.system.data.access.order.entity.OrderEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+import java.util.UUID;
+
+@Repository
+public interface OrderJpaRepository extends JpaRepository {
+
+ Optional findByTrackingId(UUID trackingId);
+
+
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/adapter/RestaurantRepositoryImpl.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/adapter/RestaurantRepositoryImpl.java
new file mode 100644
index 0000000..8f5d5ff
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/adapter/RestaurantRepositoryImpl.java
@@ -0,0 +1,26 @@
+package com.food.order.system.data.access.restaurant.adapter;
+
+import com.food.order.domain.ports.output.repository.RestaurantRepository;
+import com.food.order.system.data.access.restaurant.mapper.RestaurantDataAccessMapper;
+import com.food.order.system.data.access.restaurant.repository.RestaurantJpaRepository;
+import com.food.order.system.domain.entity.Restaurant;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class RestaurantRepositoryImpl implements RestaurantRepository {
+
+ private final RestaurantJpaRepository restaurantJpaRepository;
+ private final RestaurantDataAccessMapper restaurantDataAccessMapper;
+
+ @Override
+ public Optional findRestaurantInformation(Restaurant restaurant) {
+ return restaurantJpaRepository.findByRestaurantIdAndProductIdIn
+ (restaurant.getId().getValue(),
+ restaurantDataAccessMapper.restaurantToRestaurantProducts(restaurant))
+ .map(restaurantDataAccessMapper::restaurantEntityToRestaurant);
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntity.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntity.java
new file mode 100644
index 0000000..b3d73d8
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntity.java
@@ -0,0 +1,51 @@
+package com.food.order.system.data.access.restaurant.entity;
+
+
+import lombok.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+import java.math.BigDecimal;
+import java.util.UUID;
+
+@Entity
+@Table(name = "order_restaurant_m_view",schema = "restaurant")
+@Getter
+@Setter
+@Builder
+@IdClass(RestaurantEntityId.class)
+@NoArgsConstructor
+@AllArgsConstructor
+public class RestaurantEntity {
+
+ @Id
+ private UUID restaurantId;
+
+ @Id
+ private UUID productId;
+
+ private String restaurantName;
+
+ private Boolean restaurantActive;
+
+ private String productName;
+
+ private BigDecimal productPrice;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof RestaurantEntity that)) return false;
+ if (!restaurantId.equals(that.restaurantId)) return false;
+ return productId.equals(that.productId);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = restaurantId.hashCode();
+ result = 31 * result + productId.hashCode();
+ return result;
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntityId.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntityId.java
new file mode 100644
index 0000000..46cbac3
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/entity/RestaurantEntityId.java
@@ -0,0 +1,32 @@
+package com.food.order.system.data.access.restaurant.entity;
+
+import lombok.*;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class RestaurantEntityId implements Serializable {
+
+ private UUID restaurantId;
+ private UUID productId;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof RestaurantEntityId that)) return false;
+ if (!restaurantId.equals(that.restaurantId)) return false;
+ return productId.equals(that.productId);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = restaurantId.hashCode();
+ result = 31 * result + productId.hashCode();
+ return result;
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/exception/RestaurantDataAccessException.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/exception/RestaurantDataAccessException.java
new file mode 100644
index 0000000..6220767
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/exception/RestaurantDataAccessException.java
@@ -0,0 +1,7 @@
+package com.food.order.system.data.access.restaurant.exception;
+
+public class RestaurantDataAccessException extends RuntimeException{
+ public RestaurantDataAccessException(String s) {
+ super(s);
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/mapper/RestaurantDataAccessMapper.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/mapper/RestaurantDataAccessMapper.java
new file mode 100644
index 0000000..690c4b9
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/mapper/RestaurantDataAccessMapper.java
@@ -0,0 +1,40 @@
+package com.food.order.system.data.access.restaurant.mapper;
+
+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.data.access.restaurant.entity.RestaurantEntity;
+import com.food.order.system.data.access.restaurant.exception.RestaurantDataAccessException;
+import com.food.order.system.domain.entity.Product;
+import com.food.order.system.domain.entity.Restaurant;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.UUID;
+
+@Component
+public class RestaurantDataAccessMapper {
+
+ public List restaurantToRestaurantProducts(Restaurant restaurant) {
+ return restaurant.getProducts()
+ .stream()
+ .map(product -> product.getId().getValue())
+ .toList();
+ }
+
+ public Restaurant restaurantEntityToRestaurant(List restaurantEntities) {
+ var restaurantEntity =
+ restaurantEntities.stream().findFirst()
+ .orElseThrow(() -> new RestaurantDataAccessException("No restaurant found"));
+ var restaurantProducts = restaurantEntities.stream()
+ .map(entity -> new Product(new ProductId(entity.getProductId()),
+ entity.getProductName(),
+ new Money(entity.getProductPrice()))).toList();
+ return Restaurant.builder()
+ .id(new RestaurantId(restaurantEntity.getRestaurantId()))
+ .products(restaurantProducts)
+ .isActive(restaurantEntity.getRestaurantActive())
+ .build();
+
+ }
+}
diff --git a/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/repository/RestaurantJpaRepository.java b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/repository/RestaurantJpaRepository.java
new file mode 100644
index 0000000..def551d
--- /dev/null
+++ b/order-service/order-data-access/src/main/java/com/food/order/system/data/access/restaurant/repository/RestaurantJpaRepository.java
@@ -0,0 +1,14 @@
+package com.food.order.system.data.access.restaurant.repository;
+
+import com.food.order.system.data.access.restaurant.entity.RestaurantEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+@Repository
+public interface RestaurantJpaRepository extends JpaRepository {
+ Optional> findByRestaurantIdAndProductIdIn(UUID restaurantId, List productIds);
+}
diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java
index 3fa1d62..7ba2a43 100644
--- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java
+++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java
@@ -1,8 +1,6 @@
package com.food.order.domain.dto.create;
-import lombok.AllArgsConstructor;
import lombok.Builder;
-import lombok.Getter;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java
index 7a96a60..d0db11a 100644
--- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java
+++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java
@@ -1,6 +1,5 @@
package com.food.order.domain.dto.track;
-import lombok.AllArgsConstructor;
import lombok.Builder;
import javax.validation.constraints.NotNull;
diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Customer.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Customer.java
index 626e8cd..978f5c6 100644
--- a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Customer.java
+++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Customer.java
@@ -4,4 +4,11 @@ import com.food.order.domain.entity.AggregateRoot;
import com.food.order.domain.valueobject.CustomerId;
public class Customer extends AggregateRoot {
+
+ public Customer(){
+
+ }
+ public Customer (CustomerId id) {
+ super.setId(id);
+ }
}
diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Order.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Order.java
index 509eced..f74a770 100644
--- a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Order.java
+++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/Order.java
@@ -13,6 +13,8 @@ import java.util.UUID;
public class Order extends AggregateRoot {
+ public static final String FAILURE_MESSAGE_DELIMITER = ",";
+
private final CustomerId customerId;
private final RestaurantId restaurantId;
private final StreetAddress deliveryAddress;
diff --git a/pom.xml b/pom.xml
index fb3ce3a..88843bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,11 @@
${project.version}
+
+ com.food.order
+ common-application
+ ${project.version}
+
com.food.order