Building a Java-based Inventory Management System involves designing a system that can manage products, track stock levels, handle orders, and generate reports. Below is a step-by-step guide to building such a system, including the key components, design considerations, and example code snippets.
1. Requirements Analysis
Before starting, define the requirements for the system:
- Product Management: Add, update, delete, and view products.
- Inventory Tracking: Track stock levels and update them when orders are placed.
- Order Management: Place orders, update order status, and view order history.
- Reporting: Generate reports for low stock, sales, and inventory levels.
- User Roles: Admin (manage products and inventory) and Customer (place orders).
2. System Design
Modules
- Product Management
- Add, update, delete, and view products.
- Inventory Management
- Track stock levels and update inventory.
- Order Management
- Place orders, update order status, and view order history.
- Reporting
- Generate reports for low stock, sales, and inventory levels.
- User Authentication
- Admin and customer login.
Database Design
- Product Table:
product_id
,name
,description
,price
,stock_quantity
- Order Table:
order_id
,user_id
,order_date
,status
- OrderItem Table:
order_item_id
,order_id
,product_id
,quantity
- User Table:
user_id
,username
,password
,role
3. Technology Stack
- Backend: Java (Spring Boot)
- Frontend: Thymeleaf (for simplicity) or Angular/React (for advanced UI)
- Database: MySQL or H2 (for testing)
- Build Tool: Maven or Gradle
- Security: Spring Security for authentication and authorization
4. Implementation
Step 1: Set Up the Project
Create a Spring Boot project using Spring Initializr with the following dependencies:
- Spring Web
- Spring Data JPA
- Spring Security
- Thymeleaf (for UI)
- MySQL Driver (or H2 for testing)
Step 2: Define Entities
Create Java classes for the database tables.
Product.java
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long productId;
private String name;
private String description;
private double price;
private int stockQuantity;
// Getters and Setters
}
Order.java
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
private Long userId;
private LocalDateTime orderDate;
private String status;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems;
// Getters and Setters
}
OrderItem.java
@Entity
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderItemId;
private Long productId;
private int quantity;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
// Getters and Setters
}
User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private String username;
private String password;
private String role; // "ADMIN" or "CUSTOMER"
// Getters and Setters
}
Step 3: Create Repositories
Use Spring Data JPA to create repositories for database operations.
ProductRepository.java
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByStockQuantityLessThan(int stockQuantity); // For low stock report
}
OrderRepository.java
public interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findByUserId(Long userId); // For order history
}
UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username); // For authentication
}
Step 4: Implement Services
Create service classes to handle business logic.
ProductService.java
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> getAllProducts() {
return productRepository.findAll();
}
public void addProduct(Product product) {
productRepository.save(product);
}
public void updateProduct(Long productId, Product product) {
product.setProductId(productId);
productRepository.save(product);
}
public void deleteProduct(Long productId) {
productRepository.deleteById(productId);
}
public List<Product> getLowStockProducts() {
return productRepository.findByStockQuantityLessThan(10); // Example threshold
}
}
OrderService.java
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private ProductRepository productRepository;
public void placeOrder(Order order) {
for (OrderItem item : order.getOrderItems()) {
Product product = productRepository.findById(item.getProductId()).orElseThrow();
product.setStockQuantity(product.getStockQuantity() - item.getQuantity());
productRepository.save(product);
}
order.setOrderDate(LocalDateTime.now());
order.setStatus("PLACED");
orderRepository.save(order);
}
public List<Order> getOrderHistory(Long userId) {
return orderRepository.findByUserId(userId);
}
}
Step 5: Create Controllers
Create controllers to handle HTTP requests.
ProductController.java
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@PostMapping
public void addProduct(@RequestBody Product product) {
productService.addProduct(product);
}
@PutMapping("/{productId}")
public void updateProduct(@PathVariable Long productId, @RequestBody Product product) {
productService.updateProduct(productId, product);
}
@DeleteMapping("/{productId}")
public void deleteProduct(@PathVariable Long productId) {
productService.deleteProduct(productId);
}
}
OrderController.java
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping
public void placeOrder(@RequestBody Order order) {
orderService.placeOrder(order);
}
@GetMapping("/history/{userId}")
public List<Order> getOrderHistory(@PathVariable Long userId) {
return orderService.getOrderHistory(userId);
}
}
Step 6: Implement Security
Use Spring Security to secure the application.
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(username -> userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found")));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/products/**").hasRole("ADMIN")
.antMatchers("/orders/**").hasRole("CUSTOMER")
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
Step 7: Frontend (Optional)
Use Thymeleaf or a frontend framework like Angular/React to create a user interface for the system.
5. Testing
- Use JUnit and Mockito for unit testing.
- Test the application using Postman or Swagger for API testing.
6. Deployment
- Package the application as a JAR/WAR file and deploy it to a server (e.g., Tomcat).
- Use Docker for containerization and Kubernetes for orchestration (optional).
Example Use Cases
- Add a Product
- Admin adds a new product with details like name, description, price, and stock quantity.
- Place an Order
- Customer places an order, and the system updates the stock levels.
- Generate Low Stock Report
- Admin generates a report of products with low stock levels.