diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/Address.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/Address.java new file mode 100644 index 00000000..6c4f4f30 --- /dev/null +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/Address.java @@ -0,0 +1,13 @@ +package com.example.retailstore.webapp.clients.order; + +import jakarta.validation.constraints.NotBlank; +import java.io.Serializable; + +public record Address( + @NotBlank(message = "AddressLine1 is required") String addressLine1, + String addressLine2, + @NotBlank(message = "City is required") String city, + @NotBlank(message = "State is required") String state, + @NotBlank(message = "ZipCode is required") String zipCode, + @NotBlank(message = "Country is required") String country) + implements Serializable {} diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/CreateOrderRequest.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/CreateOrderRequest.java new file mode 100644 index 00000000..2700dc0b --- /dev/null +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/CreateOrderRequest.java @@ -0,0 +1,13 @@ +package com.example.retailstore.webapp.clients.order; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Positive; +import java.io.Serializable; +import java.util.List; + +public record CreateOrderRequest( + @NotEmpty(message = "Items cannot be empty.") List items, + @Positive Long customerId, + @Valid Address deliveryAddress) + implements Serializable {} diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderConfirmationDTO.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderConfirmationDTO.java new file mode 100644 index 00000000..d70787ec --- /dev/null +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderConfirmationDTO.java @@ -0,0 +1,3 @@ +package com.example.retailstore.webapp.clients.order; + +public record OrderConfirmationDTO(String orderNumber, OrderStatus status) {} diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderItemRequest.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderItemRequest.java new file mode 100644 index 00000000..830a9441 --- /dev/null +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderItemRequest.java @@ -0,0 +1,5 @@ +package com.example.retailstore.webapp.clients.order; + +import java.math.BigDecimal; + +public record OrderItemRequest(String productCode, int quantity, BigDecimal productPrice) {} diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java index 335b61f9..c491ce15 100644 --- a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java @@ -1,10 +1,12 @@ package com.example.retailstore.webapp.clients.order; import com.example.retailstore.webapp.clients.PagedResult; +import jakarta.validation.Valid; import java.util.Map; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.PostExchange; public interface OrderServiceClient { @@ -13,4 +15,7 @@ public interface OrderServiceClient { @GetExchange("/api/orders/{id}") OrderResponse getOrder(@RequestHeader Map headers, @PathVariable String id); + + @PostExchange("/api/orders") + OrderConfirmationDTO createOrder(Map headers, @Valid CreateOrderRequest orderRequest); } diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderStatus.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderStatus.java new file mode 100644 index 00000000..e58e0bc3 --- /dev/null +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderStatus.java @@ -0,0 +1,9 @@ +package com.example.retailstore.webapp.clients.order; + +public enum OrderStatus { + NEW, + IN_PROCESS, + DELIVERED, + CANCELLED, + ERROR +} diff --git a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/OrderController.java b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/OrderController.java index 61cab6e3..8c0ffbee 100644 --- a/retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/OrderController.java +++ b/retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/OrderController.java @@ -1,9 +1,12 @@ package com.example.retailstore.webapp.web.controller; import com.example.retailstore.webapp.clients.PagedResult; +import com.example.retailstore.webapp.clients.order.CreateOrderRequest; +import com.example.retailstore.webapp.clients.order.OrderConfirmationDTO; import com.example.retailstore.webapp.clients.order.OrderResponse; import com.example.retailstore.webapp.clients.order.OrderServiceClient; import com.example.retailstore.webapp.services.SecurityHelper; +import jakarta.validation.Valid; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,6 +14,8 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; @Controller @@ -60,4 +65,11 @@ PagedResult getOrders() { String accessToken = securityHelper.getAccessToken(); return Map.of("Authorization", "Bearer " + accessToken); } + + @PostMapping("/api/orders") + @ResponseBody + OrderConfirmationDTO createOrder(@Valid @RequestBody CreateOrderRequest orderRequest) { + log.info("Creating order: {}", orderRequest); + return orderServiceClient.createOrder(getHeaders(), orderRequest); + } }