Open In App

Inventory Management System using Spring Boot

Last Updated : 03 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Inventory Management System plays an important role in Business for tracking the Inventory, and It is used for tracking and movement of goods. In this article, we have provided some basic functionality for the Inventory Management System like an Analysis report of goods, adding new Products to the System, Searching the existing product details, and other one is deleting an existing product from the System. In this article, we have mentioned an Inventory Management System as an IMS App, for this tool we have used Spring Boot with an MVC pattern with Thymeleaf for front-end integration.

This Application handles the product details and performs different operations on every record in the Inventory Management System Application.

Prerequisites

  • Spring Boot
  • Thymeleaf
  • MongoDB
  • Spring MVC Pattern
  • Bootstrap Framework
  • Project Type is Gradle
  • Spring Tool Suite IDE (STS)

This Spring Boot Inventory Management System Web Application with MVC Pattern and the Thymeleaf is used for providing Dynamic HTML content in this tool, The MongoDB is used for data storage purposes, and the other one is Bootstrap framework used for creating responsive web applications.

Product Details

For a Product, we have different attributes like:

  • Product ID
  • Product Category
  • Product Name
  • Product Rating
  • Quality
  • Maximum number of Products
  • Minimum number of Products
  • Username (Product Added by)
  • User Email Address
  • User Phone Number

In this Inventory Management System Project, the Product ID is dynamically Generated which have String and Number format. After Generating Product ID then Inserted Other product detail with ID in the Database.

Project Creation Steps

  • Create a Spring Stater Project using Spring Tool Suite IDE ( reference )
  • After successfully creation of Project, then create Package for different layers in this web Application namely packages for Controller, POJO, Repository and other packages if you want.
  • In Controller Package create one ProductController class after that create one Project POJO class in POJO package, After Create one Product Repository interface in Repository package. After that create one HTML file in the Templates which is placed in project resource folder.
  • Now Implement Controller layer code after that develop pojo class code, after that develop repository class code.
  • After completion of Back-end functionalities then develop the front-end page for visibility.
  • After successfully completion of Front-End and Back-End then Integrate both of them by using Thymeleaf Framework.
  • After that Run this Application as Spring Boot App.

Required Project Dependencies

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Note: These Project Dependencies are available in Spring Stater Project While creating the Project. After Creation of this Project You can see These Dependencies in build.gradle file in the Project.

Project Folder Structure

Project Structure

Code Development Process

Now we will see the development Process of Inventory Management System using Spring Boot, Spring MVC. In development process first we create one POJO class for Products. In this POJO class we keep Attributes of Product like Product ID, Like Product Category, Product Name, Product Rating, Quality, Maximum number of Products, Minimum number of Products, Username (Product Added by), User Email Address, User Phone Number. This POJO class also have Setters and Getters methods for data handling with Parameterized and non-Parameterized constructors in Product POJO class.

Database Connection

In Inventory Management System Application, We perform different Operation on data. That’s why we need a data storage for storing the data. For this I Selected MongoDB Database for data Storage. In Database Connection We need three attribute values those Host name, Port number of MongoDB, And the other one is Database Name. The Database Connection Attributes keep in application properties file. We have already provided the folder structure. In that application properties file is available.

# database properties
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=ims

# thymeleaf configuration
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

Note : Here ims is the Database name, 27017 is the port number of MongoDB, And we have used Localhost for running the system on my local system.

Model Layer

For this, we have created one POJO class in pojo package that is Product.class, this POJO class contains all the attributes of the Product and It have Setters and Getters and also two different constructors like Parameterized and non-Parameterized constructors. And I used one dependency that is lombok which is available in Spring Boot. This Annotation is used for Parameterized and non-Parameterized constructors by using @Data, @AllArgsConstructor, @NoArgsConstructor, @Document.

Product.class:

Java




package com.ims.app.model;
  
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
  
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
  
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "productdetails")
public class Product {
    @Id
    private String id;
    private String productCategory;
    private String productName;
    private Long rating;
    private Long quality;
    private Long maximumProducts;
    private Long minimumProducts;
    private String userName;
    private String emailAddress;
    private Long phoneNumber;
  
}


@Data Annotation is used for managing Setters and Getters methods in Product POJO class , The @Document is used for creating Collection name in the Database, @AllArgsConstructor is used for managing parameterized constructor and @NoArgsConstructor is used for managing default constructor.

View Layer

For View Purpose we have created one HTML page in Templates folder in the Project Folder Structure. And we have used Thymeleaf for Providing Dynamic Content of The HTML page in the Inventory Management System Project.

index.html:

HTML




<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" href="https://cdn-icons-png.flaticon.com/512/7656/7656409.png">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <title>Inventory Management System</title>
</head>
  
<style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@1,800&display=swap');
  
    body {
        font-weight: 600 !important;
        overflow-x: hidden;
    }
  
    .navbar-brand {
        font-family: 'Noto Serif', serif;
        margin-left: 1rem;
        color: white !important;
        font-weight: 700;
        font-size: x-large !important;
    }
  
    .nav-link {
        font-weight: 600;
        font-size: 16px !important;
    }
  
    .nav-link:active,
    .nav-link.active {
        background-color: #198754 !important;
        color: white !important;
    }
  
    .nav-link:hover {
        color: white !important;
        background-color: #198754 !important;
    }
  
    .content {
        padding: 15px;
    }
  
    ::placeholder {
        font-size: 14px;
        font-weight: 400;
        font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    }
  
    td {
        font-size: 13px;
    }
  
    label {
        font-family: 'Noto Serif', serif;
    }
</style>
  
<body>
  
    <nav class="navbar navbar-expand-md navbar-light bg-success">
        <div class="container-fluid">
            <a class="navbar-brand" href="#"><i class="fa fa-align-center" aria-hidden="true"></i>  Inventory</a>
        </div>
    </nav>
  
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-2 bg-light">
                <div class="bg-light min-vh-100">
                    <div class="sidebar-sticky">
                        <ul class="nav flex-column nav-pills">
                            <li class="nav-item p-2">
                                <a class="nav-link text-success mt-5" data-bs-toggle="pill" href="#home"><i
                                        class="fa fa-home"></i>  Home</a>
                            </li>
                            <li class="nav-item p-2">
                                <a class="nav-link text-success mt-2" data-bs-toggle="pill" href="#products"><i
                                        class="fa fa-database"></i>  Products</a>
                            </li>
                            <li class="nav-item p-2">
                                <a class="nav-link text-success mt-2" data-bs-toggle="pill" href="#addProduct"><i
                                        class="fa fa-plus"></i>  Add Product</a>
                            </li>
                            <li class="nav-item p-2">
                                <a class="nav-link text-success mt-2" data-bs-toggle="pill" href="#searchProduct"><i
                                        class="fa fa-search"></i>  Search Product</a>
                            </li>
                            <li class="nav-item p-2">
                                <a class="nav-link text-success mt-2" data-bs-toggle="pill" href="#removeProduct"><i
                                        class="fa fa-trash"></i>  Remove Product</a>
                            </li>
  
                        </ul>
                    </div>
                </div>
            </div>
  
            <div class="col-md-10">
                <div class="content tab-content">
                    <div class="tab-pane fade show active" id="home">
                        <h5 class="text-left text-success p-3">Welcome to the Inventory Management System ( Report )
                            </h4>
                            <br>
                            <div class="row p-2">
                                <div class="col-sm-6">
                                    <p class="p-2 text-left">Maximum Number of Products & Their Category
                                    </p>
                                    <div style="margin: auto;">
                                        <canvas id="maxproductChart"></canvas>
                                    </div>
                                    <script th:inline="javascript">
                                        var products = /*[[${products}]]*/[];
  
                                        var data = {};
                                        products.forEach(function (product) {
                                            var key = product.productName;
                                            data[key] = (data[key] || 0) + product.maximumProducts;
                                        });
  
                                        var labels = Object.keys(data);
                                        var values = Object.values(data);
  
                                        // Generate an array of dynamic colors
                                        var dynamicColors = [];
                                        for (var i = 0; i < labels.length; i++) {
                                            var r = Math.floor(Math.random() * 255);
                                            var g = Math.floor(Math.random() * 255);
                                            var b = Math.floor(Math.random() * 255);
                                            dynamicColors.push('rgba(' + r + ',' + g + ',' + b + ', 0.6)');
                                        }
  
                                        var ctx = document.getElementById('maxproductChart').getContext('2d');
                                        var productChart = new Chart(ctx, {
                                            type: 'bar',
                                            data: {
                                                labels: labels,
                                                datasets: [{
                                                    label: 'Maximum Products Count',
                                                    data: values,
                                                    backgroundColor: dynamicColors,
                                                    borderColor: dynamicColors.map(color => color.replace(', 0.6)', ', 1)')),
                                                    borderWidth: 2
                                                }]
                                            },
                                            options: {
                                                scales: {
                                                    x: {
                                                        title: {
                                                            display: true,
                                                            text: 'Product Name'
                                                        }
                                                    },
                                                    y: {
                                                        beginAtZero: true,
                                                        title: {
                                                            display: true,
                                                            text: 'Maximum number of Products'
                                                        }
                                                    }
                                                }
                                            }
                                        });
                                    </script>
                                </div>
                                <div class="col-sm-6">
                                    <p class="p-2 text-left">Minimum Number of Products & Their Category
                                    </p>
                                    <div style="margin: auto;">
                                        <canvas id="minproductChart"></canvas>
                                    </div>
                                    <script th:inline="javascript">
                                        var products = /*[[${products}]]*/[];
  
                                        var data = {};
                                        products.forEach(function (product) {
                                            var key = product.productName;
                                            data[key] = (data[key] || 0) + product.minimumProducts;
                                        });
  
                                        var labels = Object.keys(data);
                                        var values = Object.values(data);
  
                                        // Generate an array of dynamic colors
                                        var dynamicColors = [];
                                        for (var i = 0; i < labels.length; i++) {
                                            var r = Math.floor(Math.random() * 255);
                                            var g = Math.floor(Math.random() * 255);
                                            var b = Math.floor(Math.random() * 255);
                                            dynamicColors.push('rgba(' + r + ',' + g + ',' + b + ', 0.6)');
                                        }
  
                                        var ctx = document.getElementById('minproductChart').getContext('2d');
                                        var productChart = new Chart(ctx, {
                                            type: 'bar',
                                            data: {
                                                labels: labels,
                                                datasets: [{
                                                    label: 'Minimum Products Count',
                                                    data: values,
                                                    backgroundColor: dynamicColors,
                                                    borderColor: dynamicColors.map(color => color.replace(', 0.6)', ', 1)')),
                                                    borderWidth: 2
                                                }]
                                            },
                                            options: {
                                                scales: {
                                                    x: {
                                                        title: {
                                                            display: true,
                                                            text: 'Product Name'
                                                        }
                                                    },
                                                    y: {
                                                        beginAtZero: true,
                                                        title: {
                                                            display: true,
                                                            text: 'Minimum number of Products'
                                                        }
                                                    }
                                                }
                                            }
                                        });
                                    </script>
                                </div>
                            </div>
                    </div>
                    <div class="tab-pane fade" id="products">
                        <h4 class="text-success p-2">All Products Data</h4>
                        <div class="table-responsive mt-5">
                            <table class="table table-hover table-bordered">
                                <thead class="bg-success text-light">
                                    <th>SN</th>
                                    <th>ID</th>
                                    <th>Category</th>
                                    <th>Name</th>
                                    <th>Rating</th>
                                    <th>Quality</th>
                                    <th>Max Size</th>
                                    <th>Min Size</th>
                                    <th>User</th>
                                    <th>Email</th>
                                    <th>Phone</th>
                                </thead>
                                <tbody>
                                    <tr th:each="product, index : ${products}" }>
                                        <td th:text="${index.index + 1}"></td>
                                        <td th:text="${product.id}"></td>
                                        <td th:text="${product.productCategory}"></td>
                                        <td th:text="${product.productName}"></td>
                                        <td th:text="${product.rating}"></td>
                                        <td th:text="${product.quality}"></td>
                                        <td th:text="${product.maximumProducts}"></td>
                                        <td th:text="${product.minimumProducts}"></td>
                                        <td th:text="${product.userName}"></td>
                                        <td th:text="${product.emailAddress}"></td>
                                        <td th:text="${product.phoneNumber}"></td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                    <div class="tab-pane fade" id="addProduct">
                        <h4 class="text-success p-2">Add New Product</h4>
                        <br>
                        <div class="container">
                            <form class="p-1" th:action="@{/newProduct}" th:object="${product}" method="post">
                                <div class="row p-4 justify-content-center">
                                    <div th:if="${insertSuccess}">
                                        <div class="alert alert-success alert-dismissible fade show p-2 mt-1 mb-3"
                                            role="alert">
                                            <strong>Product Added successfully!
                                                <button type="button" class="btn-close" data-bs-dismiss="alert"
                                                    aria-label="Close"></button>
                                            </strong>
                                        </div>
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>product Category</label>
                                        <select th:field="*{productCategory}" class="form-select mt-3" required>
                                            <option value=""></option>
                                            <option value="Electronics">Electronics</option>
                                            <option value="Fashion">Fashion</option>
                                            <option value="Furniture">Furniture</option>
                                            <option value="Home&Kitchen">Home & Kitchen</option>
                                            <option value="Grocery">Grocery</option>
                                        </select>
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>product Name</label>
                                        <input type="text" th:field="*{productName}" class="form-control mt-3" required
                                            placeholder="name of the product">
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>product Rating</label>
                                        <select th:field="*{rating}" class="form-select mt-3" required>
                                            <option value=""></option>
                                            <option value="1">1</option>
                                            <option value="2">2</option>
                                            <option value="3">3</option>
                                            <option value="4">4</option>
                                            <option value="5">5</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="row p-4 justify-content-center">
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>product Quality</label>
                                        <select th:field="*{quality}" class="form-select mt-3" required>
                                            <option value=""></option>
                                            <option value="1">1</option>
                                            <option value="2">2</option>
                                            <option value="3">3</option>
                                            <option value="4">4</option>
                                            <option value="5">5</option>
                                        </select>
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>Maximum Products</label>
                                        <input type="number" th:field="*{maximumProducts}" class="form-control mt-3"
                                            required placeholder="maximum number of products">
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>Minimum Products</label>
                                        <input type="number" th:field="*{minimumProducts}" class="form-control mt-3"
                                            required placeholder="minimum number of products">
                                    </div>
                                </div>
                                <div class="row p-4 justify-content-center">
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>Product Added By</label>
                                        <input type="text" th:field="*{userName}" class="form-control mt-3" required
                                            placeholder="user name">
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>User Email Address</label>
                                        <input type="email" th:field="*{emailAddress}" class="form-control mt-3"
                                            required placeholder="user email address">
                                    </div>
                                    <div class="col-sm-3 offset-sm-1 p-2">
                                        <label>Phone Number</label>
                                        <input type="tel" th:field="*{phoneNumber}" class="form-control mt-3" required
                                            placeholder="phone number">
                                    </div>
                                </div>
                                <br>
                                <button type="submit" class="btn btn-success text-light" style="margin-left: 7rem;">Add
                                    Product</button>
                            </form>
                        </div>
  
                    </div>
                    <div class="tab-pane fade" id="searchProduct">
                        <h4 class="text-success p-2">Search Product Details</h4>
                        <br>
                        <div class="container p-1">
                            <form th:action="@{/searchProduct}" th:object="${product}" method="post" class="p-2">
                                <div class="row">
                                    <div class="col-sm-9 offset-sm-1">
                                        <input type="text" name="id" th:field="*{id}" class="form-control" required
                                            placeholder="Product ID"
                                            style="text-align: center; border-radius: 30px; border: 2px solid green;">
                                    </div>
  
                                    <div class="col-sm-2">
                                        <button type="submit" class="btn btn-success"
                                            style="border-radius: 20px;">Search Product</button>
                                    </div>
                                </div>
                                <br>
                                <div th:if="${foundProduct}">
                                    <div class="table-responsive mt-4">
                                        <table class="table table-hover table-bordered">
                                            <thead class="bg-success text-light">
                                                <th>ID</th>
                                                <th>Category</th>
                                                <th>Name</th>
                                                <th>Rating</th>
                                                <th>Quality</th>
                                                <th>Max Size</th>
                                                <th>Min Size</th>
                                                <th>User</th>
                                                <th>Email</th>
                                                <th>Phone</th>
                                            </thead>
                                            <tbody>
                                                <tr>
                                                    <td th:text="${foundProduct.get().id}"></td>
                                                    <td th:text="${foundProduct.get().productCategory}"></td>
                                                    <td th:text="${foundProduct.get().productName}"></td>
                                                    <td th:text="${foundProduct.get().rating}"></td>
                                                    <td th:text="${foundProduct.get().quality}"></td>
                                                    <td th:text="${foundProduct.get().maximumProducts}"></td>
                                                    <td th:text="${foundProduct.get().minimumProducts}"></td>
                                                    <td th:text="${foundProduct.get().userName}"></td>
                                                    <td th:text="${foundProduct.get().emailAddress}"></td>
                                                    <td th:text="${foundProduct.get().phoneNumber}"></td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
  
                                <div th:if="${notFound}" class="mt-3">
                                    <div class="alert alert-warning alert-dismissible fade show" role="alert">
                                        <strong>Product Details Not Found!
                                            <button type="button" class="btn-close" data-bs-dismiss="alert"
                                                aria-label="Close"></button>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                    <div class="tab-pane fade" id="removeProduct">
                        <h4 class="text-success p-2">Remove Existing Product</h4>
                        <br>
                        <div class="container p-1">
                            <form th:action="@{/deleteProduct}" method="post" class="p-2">
                                <div class="row">
                                    <div class="col-sm-9 offset-sm-1">
                                        <input type="text" name="id" class="form-control" required
                                            placeholder="Product ID"
                                            style="text-align: center; border-radius: 30px; border: 2px solid green;">
                                    </div>
                                    <div class="col-sm-2">
                                        <button type="submit" class="btn btn-success"
                                            style="border-radius: 20px;">Delete Product</button>
                                    </div>
                                </div>
                                <br>
                                <div th:if="${deleteSuccess}">
                                    <div class="alert alert-success alert-dismissible fade show" role="alert">
                                        <strong>Product deleted successfully!
                                            <button type="button" class="btn-close" data-bs-dismiss="alert"
                                                aria-label="Close"></button>
                                    </div>
                                </div>
  
                                <div th:if="${notFound}">
                                    <div class="alert alert-warning alert-dismissible fade show" role="alert">
                                        <strong>Product not found. Please check the ID and try again.
                                            <button type="button" class="btn-close" data-bs-dismiss="alert"
                                                aria-label="Close"></button>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
  
</body>
  
</html>


In above HTML code, we keep Thymeleaf URL in HTML element. We have used th:action, th:object, th:if and others for performing different operations on HTML page. And the Back-End logic is also handled by Thymeleaf, that result is visible on HTML page.

Repository

We have already mentioned in the above creation repository package. In this Web Application we have created one Mongo Repository by @Repository Annotation for Handling crud operations in this application, this is interact with Database. This Interface extends to MongoRepository.

ProductRepo.class:

Java




package com.ims.app.repo;
  
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
  
import com.ims.app.model.Product;
  
@Repository
public interface ProductRepo extends MongoRepository<Product, String>{
  
}


In this Repository, We provide Product.class ( POJO Class ) and product ID data type as Arguments to the MongoRepository. In Product pojo the ID type is String that’s why we have passed String as argument. This ProducRepo interface used for performing CRUD operations on the data.

Controller Layer

In Inventory Management System, The Controller class is created by using @Controller Annotation. This class is handled the incoming API requests, based on the request type it can provide like post,get,delete like that. It can trigger the business logic and provide the output on the web page by using Thymeleaf Framework.

ProductController.class:

Java




package com.ims.app.controller;
  
import java.util.List;
import java.util.Optional;
import java.util.Random;
  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
  
import com.ims.app.model.Product;
import com.ims.app.service.ProductService;
  
@Controller
public class ProductController {
  
    @Autowired
    private ProductService productService;
  
    @GetMapping("/")
    public String getIndexPage(Model model) {
        List<Product> productList = productService.getAllProducts();
        model.addAttribute("products", productList);
        model.addAttribute("product", new Product());
        return "index";
    }
  
    @PostMapping("/newProduct")
    public String newProduct(@ModelAttribute("product") Product product, RedirectAttributes redirectAttributes) {
        // Creating dynamic product ID
        String productId = "PD" + (1000 + new Random().nextInt(9000));
        product.setId(productId);
        productService.addProduct(product);
        redirectAttributes.addFlashAttribute("insertSuccess", true);
        return "redirect:/";
    }
  
    @PostMapping("/searchProduct")
    public String searchProduct(@RequestParam(name = "id") String id, RedirectAttributes redirectAttributes,
            Model model) {
        Optional<Product> foundProduct = productService.getProductById(id);
        model.addAttribute("product", new Product());
        if (foundProduct.isPresent()) {
            redirectAttributes.addFlashAttribute("foundProduct", foundProduct);
        } else {
            redirectAttributes.addFlashAttribute("notFound", true);
        }
  
        return "redirect:/";
    }
  
    @PostMapping("/deleteProduct")
    public String deleteProduct(@RequestParam(name = "id") String id, RedirectAttributes redirectAttributes) {
        boolean deleteSuccess = productService.deleteProductById(id);
        if (deleteSuccess) {
            redirectAttributes.addFlashAttribute("deleteSuccess", true);
        } else {
            redirectAttributes.addFlashAttribute("notFound", true);
        }
  
        return "redirect:/";
    }
  
    @GetMapping("/productAnalysis")
    public String productAnalysis(Model model) {
        List<Product> products = productService.getAllProducts();
        model.addAttribute("products", products);
        return "productAnalysis"; // Thymeleaf template name
    }
      
}


The above code performs different operations like display the HTML index page, adding product details as well as display the analysis report of the Product.

  • @GetMapping(“/productAnalysis”) is used for displaying the Product Analysis report
  • @GetMapping(“/”) is used for displaying the entire html page
  • @PostMapping(“/newProduct”) is used for inserting new product details into system
  • @PostMapping(“/searchProduct”) is used for searching an existing product detail by using product ID
  • @PostMapping(“/deleteProduct”) is used for deleting a product from database using product ID

Display HTML Page:

For displaying the index.html page I used Thymeleaf for integrating back-end logic with front-end view. By using GET API request.

Java




@GetMapping("/")
    public String getIndexPage(Model model) {
        List<Product> productList = productService.getAllProducts();
        model.addAttribute("products", productList);
        model.addAttribute("product", new Product());
        return "index";
    }


index page:

index page

Insert New Product Details

We can able to insert new product data by the help of ProductRepo interface. This Repository provide one method that is save method. This method is used for save data in database.

Java




@PostMapping("/newProduct")
    public String newProduct(@ModelAttribute("product") Product product, RedirectAttributes redirectAttributes) {
        // Creating dynamic product ID
        String productId = "PD" + (1000 + new Random().nextInt(9000));
        product.setId(productId);
        productService.addProduct(product);
        redirectAttributes.addFlashAttribute("insertSuccess", true);
        return "redirect:/";
    }


Add product:

addproduct

For Inserting Product details, here we have created one POST mapping for saving product data. When You call this API one HTML Form is opened and it will ask some detail about the product once submitted that data. By using Random method, we have generated one Unique number for that number as PD as prefix, after that con-cat both of them then we get Unique Product ID.

Search Product Details

We can search a product detail by using product ID. If Product details are existed, It display the product details otherwise The Thymeleaf show one Alert message for no data exist.

Java




@PostMapping("/searchProduct")
    public String searchProduct(@RequestParam(name = "id") String id, RedirectAttributes redirectAttributes,
            Model model) {
        Optional<Product> foundProduct = productService.getProductById(id);
        model.addAttribute("product", new Product());
        if (foundProduct.isPresent()) {
            redirectAttributes.addFlashAttribute("foundProduct", foundProduct);
        } else {
            redirectAttributes.addFlashAttribute("notFound", true);
        }
  
        return "redirect:/";
    }


Search Product Details:

search product

If want to search any product detail, we need product ID then only we able search product details. For this we have created one POST API, that is searchProduct. When we hit this API, it will open one form and ask product ID then Click on Search Button. If product ID is not existed, it will show one alert message to you.

Delete Product

Delete a product by using Its ID, for this we have created one POST method API. When you hit API, it will ask you product ID. If you provide valid ID, then product is removed from database otherwise it will show one error message like alert message.

Java




@PostMapping("/deleteProduct")
    public String deleteProduct(@RequestParam(name = "id") String id, RedirectAttributes redirectAttributes) {
        boolean deleteSuccess = productService.deleteProductById(id);
        if (deleteSuccess) {
            redirectAttributes.addFlashAttribute("deleteSuccess", true);
        } else {
            redirectAttributes.addFlashAttribute("notFound", true);
        }
  
        return "redirect:/";
    }


Delete Product:

delete product

After Deleting Existing Product:

after deletion of product

After successful product deletion It will redirect to Home page tab.

Product Report

Here we have created one basic product report on maximum and minimum number of product items with their category. For charts creation we have used chart js cdn.

Java




@GetMapping("/productAnalysis")
    public String productAnalysis(Model model) {
        List<Product> products = productService.getAllProducts();
        model.addAttribute("products", products);
        return "productAnalysis"; // Thymeleaf template name
    }


Report Page:

report page

Conclusion

The Inventory Management System basically used in Business tracking and their counting, and it provides the in-detail report about the Available Inventory. Here we have created a basic The Inventory Management System using Spring Boot with Spring MVC Pattern. Your Basic knowledge about annotations, working process of Spring MVC pattern and others for Better Understanding this Article.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads