Skip to content
37 changes: 0 additions & 37 deletions src/main/java/com/podzilla/order/controller/OrderController.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package com.podzilla.order.controller;

import com.podzilla.mq.EventPublisher;
import com.podzilla.mq.EventsConstants;
import com.podzilla.mq.events.CartCheckedoutEvent;
import com.podzilla.mq.events.ConfirmationType;
import com.podzilla.mq.events.DeliveryAddress;
import com.podzilla.mq.events.OrderItem;
import com.podzilla.order.model.Order;
import com.podzilla.order.model.OrderLocation;
import com.podzilla.order.model.OrderStatus;
Expand All @@ -26,10 +21,6 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
Expand Down Expand Up @@ -89,34 +80,6 @@ public ResponseEntity<Order> getOrderById(@PathVariable final UUID id) {
}


@GetMapping("/testEventPublisher")
public ResponseEntity<String> testEventPublisher() {
LOGGER.info("Testing Event Publisher");
List<OrderItem> orderItems = new ArrayList<>();
orderItems.add(new OrderItem(UUID.randomUUID().toString(), 5, new BigDecimal(100.0)));
DeliveryAddress deliveryAddress = new DeliveryAddress(
"123 Main St",
"Springfield",
"IL",
"USA",
"62701"
);
CartCheckedoutEvent event = new CartCheckedoutEvent(
UUID.randomUUID().toString(),
UUID.randomUUID().toString(),
orderItems,
new BigDecimal(500.0),
deliveryAddress,
10.0,
20.0,
"signature",
ConfirmationType.SIGNATURE
);
eventPublisher.publishEvent(EventsConstants.CART_CHECKEDOUT, event);
return ResponseEntity.ok("Event published successfully");
}


@PatchMapping("/{id}")
@Operation(summary = "Update an order",
description = "Updates an existing order and returns the updated "
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//package com.podzilla.order.controller;
//
//import com.podzilla.mq.EventPublisher;
//import com.podzilla.mq.EventsConstants;
//import com.podzilla.mq.events.*;
//import com.podzilla.order.model.Order;
//import com.podzilla.order.model.OrderLocation;
//import com.podzilla.order.model.OrderStatus;
//import com.podzilla.order.service.OrderService;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.http.ResponseEntity;
//import org.springframework.web.bind.annotation.DeleteMapping;
//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.PutMapping;
//import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.PatchMapping;
//import org.springframework.web.bind.annotation.RestController;
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.responses.ApiResponse;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//
//import java.math.BigDecimal;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Optional;
//import java.util.UUID;
//
//@RestController
//@RequestMapping("/testOrders")
//@Tag(name = "Order API", description = "Order management operations")
//public class OrderPublisherController {
// private final OrderService orderService;
// private final EventPublisher eventPublisher;
// private static final Logger LOGGER =
// LoggerFactory.getLogger(OrderController.class);
//
// @Autowired
// public OrderPublisherController(final OrderService orderService, final EventPublisher eventPublisher) {
// this.orderService = orderService;
// this.eventPublisher = eventPublisher;
// }
//
// @GetMapping("/testPublishCartCheckoutEvent")
// public ResponseEntity<String> testPublishCartCheckoutEvent() {
// LOGGER.info("Testing Event Publisher");
// List<OrderItem> orderItems = new ArrayList<>();
// orderItems.add(new OrderItem(UUID.randomUUID().toString(), 5, new BigDecimal(100.0)));
// DeliveryAddress deliveryAddress = new DeliveryAddress(
// "123 Main St",
// "Springfield",
// "IL",
// "USA",
// "62701"
// );
// CartCheckedoutEvent event = new CartCheckedoutEvent(
// UUID.randomUUID().toString(),
// UUID.randomUUID().toString(),
// orderItems,
// new BigDecimal(500.0),
// deliveryAddress,
// 10.0,
// 20.0,
// "signature",
// ConfirmationType.SIGNATURE
// );
// eventPublisher.publishEvent(EventsConstants.CART_CHECKEDOUT, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testPublishWarehouseStockReservedEvent/{id}")
// public ResponseEntity<String> testPublishWarehouseStockReservedEvent(@PathVariable final UUID id) {
// LOGGER.info("Testing Event Publisher");
//
// WarehouseStockReservedEvent event = new WarehouseStockReservedEvent(
// id.toString());
// eventPublisher.publishEvent(EventsConstants.WAREHOUSE_STOCK_RESERVED, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testPublishWarehouseOrderFulfillmentFailedEvent/{id}")
// public ResponseEntity<String> testWarehouseOrderFulfillmentFailedEvent(@PathVariable final UUID id) {
// LOGGER.info("Testing Event Publisher");
//
// WarehouseOrderFulfillmentFailedEvent event = new WarehouseOrderFulfillmentFailedEvent(
// id.toString(), "Order Fulfillment Failed");
// eventPublisher.publishEvent(EventsConstants.WAREHOUSE_ORDER_FULFILLMENT_FAILED, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testOrderAssignedToCourierEvent/{id}")
// public ResponseEntity<String> testOrderAssignedToCourierEvent(@PathVariable final UUID id) {
// LOGGER.info("Testing Event Publisher");
//
// OrderAssignedToCourierEvent event = new OrderAssignedToCourierEvent(
// id.toString(), UUID.randomUUID().toString(), new BigDecimal(150.9), 10.0, 20.0, "signature",
// ConfirmationType.SIGNATURE);
// eventPublisher.publishEvent(EventsConstants.ORDER_ASSIGNED_TO_COURIER, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testOrderDeliveredEvent/{id}/{courierId}")
// public ResponseEntity<String> testOrderDeliveredEvent(@PathVariable final UUID id,
// @PathVariable final String courierId) {
// LOGGER.info("Testing Event Publisher");
//
// OrderDeliveredEvent event = new OrderDeliveredEvent(
// id.toString(), courierId.toString(), new BigDecimal(150.9));
// eventPublisher.publishEvent(EventsConstants.ORDER_DELIVERED, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testOrderOutForDeliveryEvent/{id}/{courierId}")
// public ResponseEntity<String> testOrderOutForDeliveryEvent(@PathVariable final UUID id,
// @PathVariable final String courierId) {
// LOGGER.info("Testing Event Publisher");
//
// OrderOutForDeliveryEvent event = new OrderOutForDeliveryEvent(
// id.toString(), courierId.toString());
// eventPublisher.publishEvent(EventsConstants.ORDER_OUT_FOR_DELIVERY, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testOrderPackagedEvent/{id}")
// public ResponseEntity<String> testOrderPackagedEvent(@PathVariable final UUID id) {
// LOGGER.info("Testing Event Publisher");
//
// OrderPackagedEvent event = new OrderPackagedEvent(
// id.toString());
// eventPublisher.publishEvent(EventsConstants.ORDER_PACKAGED, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
// @GetMapping("/testOrderDeliveryFailedEvent/{id}/{courierId}")
// public ResponseEntity<String> testOrderDeliveryFailedEvent(@PathVariable final UUID id,
// @PathVariable final UUID courierId) {
// LOGGER.info("Testing Event Publisher");
//
// OrderDeliveryFailedEvent event = new OrderDeliveryFailedEvent(
// id.toString(), courierId.toString(), "Delivery failed");
// eventPublisher.publishEvent(EventsConstants.ORDER_DELIVERY_FAILED, event);
// return ResponseEntity.ok("Event published successfully");
// }
//
//}
4 changes: 2 additions & 2 deletions src/main/java/com/podzilla/order/messaging/OrderConsumer.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ private void handleWarehouseOrderFulfillmentFailedEvent(
log.info("❌ Order fulfillment failed for order: {}, reason: {}",
warehouseOrderFulfillmentFailedEvent.getOrderId(),
warehouseOrderFulfillmentFailedEvent.getReason());
orderService.cancelOrder(
orderService.updateOrderStatus(
UUID.fromString(warehouseOrderFulfillmentFailedEvent.getOrderId()),
warehouseOrderFulfillmentFailedEvent.getReason());
OrderStatus.FULFILLMENT_FAILED);
}

private void handleCartCheckoutEvent(
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/podzilla/order/model/Address.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.podzilla.order.model;


import jakarta.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -26,6 +33,7 @@ public class Address {
private String postalCode;

@OneToOne
@JsonIgnore
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
3 changes: 3 additions & 0 deletions src/main/java/com/podzilla/order/model/Order.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.podzilla.order.model;


import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Table;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -42,6 +43,7 @@ public class Order {
private BigDecimal totalAmount;

@OneToOne(cascade = CascadeType.ALL)
@JsonIgnore
private Address shippingAddress;

@Enumerated(EnumType.STRING)
Expand All @@ -61,6 +63,7 @@ public class Order {

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL,
orphanRemoval = true)
@JsonIgnore
private List<OrderProduct> orderProducts = new ArrayList<>();

public static class Builder {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/podzilla/order/model/OrderProduct.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.podzilla.order.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
Expand Down Expand Up @@ -39,6 +40,7 @@ public class OrderProduct {
private BigDecimal pricePerUnit;

@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
24 changes: 20 additions & 4 deletions src/main/java/com/podzilla/order/service/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import com.podzilla.order.service.statusstrategy.OrderStatusStrategy;
import com.podzilla.order.service.statusstrategy.OrderStatusStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -110,9 +112,9 @@ public Order updateOrder(final UUID id, final Order updatedOrder) {
Optional<Order> existingOrder = orderRepository.findById(id);
if (existingOrder.isPresent()) {
Order order = existingOrder.get();
BeanUtils.copyProperties(updatedOrder, order, "id");
copyNonNullProperties(updatedOrder, order);
order.setUpdatedAt(LocalDateTime.now());
log.info("Order with id: {} was found and updated", id);
log.info("Order with id: {} was found and updated to status: {}", id, updatedOrder.getStatus());
return orderRepository.save(order);
}
log.warn("Order with id: {} was not found", id);
Expand Down Expand Up @@ -170,7 +172,7 @@ public Order cancelOrder(final UUID id, final String reason) {

public Order updateOrderStatus(final UUID id,
final OrderStatus status) {
log.info("Updating order status with ID: {}", id);
log.info("Updating order status with ID: {} to status: {}", id, status);

Optional<Order> existingOrder = orderRepository.findById(id);

Expand Down Expand Up @@ -219,4 +221,18 @@ private List<OrderItem> getOrderItems(final Order order) {
product.getPricePerUnit()))
.toList();
}

public void copyNonNullProperties(final Object src, final Object target) {
BeanWrapper srcWrap = new BeanWrapperImpl(src);
BeanWrapper trgWrap = new BeanWrapperImpl(target);

for (java.beans.PropertyDescriptor descriptor : srcWrap.getPropertyDescriptors()) {
String propertyName = descriptor.getName();
Object propertyValue = srcWrap.getPropertyValue(propertyName);

if (propertyValue != null && trgWrap.isWritableProperty(propertyName)) {
trgWrap.setPropertyValue(propertyName, propertyValue);
}
}
}
}