Problem Statement
Design an order and inventory management system that allows sellers to add products, maintain stock levels, and process customer orders. The system should ensure that orders are only placed when sufficient inventory is available and should update stock automatically after each successful purchase.
Functional Requirements
- Sellers should be able to add and manage products
- System should maintain real-time inventory for each product
- Users should be able to place orders for products
- System should validate stock before confirming orders
- Inventory should be updated after every successful order
- Orders should maintain status lifecycle (CREATED → CONFIRMED → CANCELLED)
Objects Required
- Product
- Seller
- Inventory
- Order
- OrderItem
- Customer
- InventoryService
OrderStatus Enum
public enum OrderStatus {
CREATED,
CONFIRMED,
CANCELLED
}
This enum defines the lifecycle of an order. It ensures that every order transitions through a controlled and predictable state flow instead of using free-form strings.
Product Class
public class Product {
private String productId;
private String name;
private double price;
private Seller seller;
public Product(String productId, String name, double price, Seller seller) {
this.productId = productId;
this.name = name;
this.price = price;
this.seller = seller;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public Seller getSeller() {
return seller;
}
}
The constructor initializes a product with its identity, name, price, and owner seller. This ensures every product is traceable to a seller in the marketplace system.
The getName() method allows other components to display or log product information without exposing internal fields.
The getPrice() method is used during order calculation to compute total cost per item.
The getSeller() method ensures we can trace ownership of a product back to its seller, which is essential in marketplace systems.
Seller Class
public class Seller {
private String sellerId;
private String name;
public Seller(String sellerId, String name) {
this.sellerId = sellerId;
this.name = name;
}
}
Seller represents a marketplace entity who owns and manages product listings. A seller can have multiple products under their account.
Inventory Class
import java.util.*;
public class Inventory {
private Map stock = new HashMap<>();
public void addStock(Product product, int quantity) {
stock.put(product.getProductId(),
stock.getOrDefault(product.getProductId(), 0) + quantity);
}
public boolean isAvailable(Product product, int quantity) {
return stock.getOrDefault(product.getProductId(), 0) >= quantity;
}
public void reduceStock(Product product, int quantity) {
if (isAvailable(product, quantity)) {
stock.put(product.getProductId(),
stock.get(product.getProductId()) - quantity);
}
}
}
The constructor initializes an empty stock map that tracks available quantity for each product.
The addStock() method increases inventory when new stock is added by a seller, ensuring the system always reflects real availability.
The isAvailable() method checks whether sufficient quantity exists before allowing an order to proceed, preventing overselling.
The reduceStock() method decreases inventory after a successful order, keeping stock levels consistent with actual sales.
OrderItem Class
public class OrderItem {
private Product product;
private int quantity;
public OrderItem(Product product, int quantity) {
this.product = product;
this.quantity = quantity;
}
public double getTotalPrice() {
return product.getPrice() * quantity;
}
public Product getProduct() {
return product;
}
public int getQuantity() {
return quantity;
}
}
The constructor binds a product with a quantity, representing a single line item in an order.
The getTotalPrice() method calculates the total cost for that item, ensuring pricing logic stays encapsulated inside the class.
The getter methods allow controlled access for inventory validation and order processing.
Order Class
import java.util.*;
public class Order {
private String orderId;
private List items;
private OrderStatus status;
public Order(String orderId, List items) {
this.orderId = orderId;
this.items = items;
this.status = OrderStatus.CREATED;
}
public void confirmOrder() {
this.status = OrderStatus.CONFIRMED;
}
public void cancelOrder() {
this.status = OrderStatus.CANCELLED;
}
public double getOrderTotal() {
double total = 0;
for (OrderItem item : items) {
total += item.getTotalPrice();
}
return total;
}
public List getItems() {
return items;
}
}
The constructor creates an order in the CREATED state with all selected items.
The confirmOrder() method updates the order status when inventory validation succeeds and stock is reserved.
The cancelOrder() method marks the order as cancelled, which can later be used to trigger stock restoration logic if required.
The getOrderTotal() method computes the final payable amount by aggregating all item totals.
InventoryService Class
import java.util.*;
public class InventoryService {
private Inventory inventory;
public InventoryService(Inventory inventory) {
this.inventory = inventory;
}
public boolean placeOrder(Order order) {
for (OrderItem item : order.getItems()) {
if (!inventory.isAvailable(item.getProduct(), item.getQuantity())) {
System.out.println("Insufficient stock for: " + item.getProduct().getName());
return false;
}
}
for (OrderItem item : order.getItems()) {
inventory.reduceStock(item.getProduct(), item.getQuantity());
}
order.confirmOrder();
return true;
}
public void cancelOrder(Order order) {
order.cancelOrder();
}
}
The constructor injects the inventory dependency so that stock operations remain centralized and consistent.
The placeOrder() method first validates stock for all items. If even one product is unavailable, the entire order is rejected to maintain transactional consistency.
Once validation passes, stock is reduced and the order is marked as CONFIRMED.
The cancelOrder() method updates order status to CANCELLED, which can later be extended to restore inventory if needed.
Main Class
public class Main {
public static void main(String[] args) {
Seller seller = new Seller("S1", "John Store");
Product p1 = new Product("P1", "Laptop", 50000, seller);
Product p2 = new Product("P2", "Mouse", 1000, seller);
Inventory inventory = new Inventory();
inventory.addStock(p1, 10);
inventory.addStock(p2, 50);
OrderItem item1 = new OrderItem(p1, 1);
OrderItem item2 = new OrderItem(p2, 2);
Order order = new Order("O1", Arrays.asList(item1, item2));
InventoryService service = new InventoryService(inventory);
boolean success = service.placeOrder(order);
if (success) {
System.out.println("Order confirmed. Total: " + order.getOrderTotal());
} else {
System.out.println("Order failed due to insufficient stock");
}
}
}
Comments
Post a Comment