Inventory Management System
in PHP and MySQL(Code)
public/index.php
This file will serve as the main entry point and display a dashboard with an overview of products, orders, suppliers, and stock levels.
<?php
session_start();
require '../config/db.php'; // Include database connection
require '../includes/header.php'; // Include header
require '../includes/navbar.php'; // Include navbar
// Fetch summary data
try {
// Count total
products
$stmt = $conn->prepare("SELECT
COUNT(*) AS total_products FROM products");
$stmt->execute();
$totalProducts = $stmt->fetch(PDO::FETCH_ASSOC)['total_products'];
// Count total
suppliers
$stmt = $conn->prepare("SELECT
COUNT(*) AS total_suppliers FROM suppliers");
$stmt->execute();
$totalSuppliers = $stmt->fetch(PDO::FETCH_ASSOC)['total_suppliers'];
// Count total
orders
$stmt = $conn->prepare("SELECT
COUNT(*) AS total_orders FROM orders");
$stmt->execute();
$totalOrders = $stmt->fetch(PDO::FETCH_ASSOC)['total_orders'];
// Calculate total
stock
$stmt = $conn->prepare("SELECT
SUM(stock_level) AS total_stock FROM products");
$stmt->execute();
$totalStock = $stmt->fetch(PDO::FETCH_ASSOC)['total_stock'];
} catch (PDOException $e) {
echo "Error:
" . $e->getMessage();
}
?>
<div class="container">
<h1>Inventory
Management System Dashboard</h1>
<div class="row">
<div class="col-md-3">
<div class="card
text-white bg-primary mb-3">
<div class="card-header">Total
Products</div>
<div
class="card-body">
<h5 class="card-title"><?php echo $totalProducts;
?></h5>
<p class="card-text">Number of products in the inventory.</p>
<a href="templates/products/list.php" class="btn btn-light">View
Products</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card
text-white bg-success mb-3">
<div
class="card-header">Total Suppliers</div>
<div
class="card-body">
<h5 class="card-title"><?php echo $totalSuppliers;
?></h5>
<p class="card-text">Number of suppliers registered.</p>
<a href="templates/suppliers/list.php" class="btn btn-light">View
Suppliers</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card
text-white bg-warning mb-3">
<div
class="card-header">Total Orders</div>
<div
class="card-body">
<h5 class="card-title"><?php echo $totalOrders;
?></h5>
<p class="card-text">Number of orders placed.</p>
<a href="templates/orders/list.php" class="btn btn-light">View
Orders</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card
text-white bg-danger mb-3">
<div
class="card-header">Total Stock</div>
<div
class="card-body">
<h5 class="card-title"><?php echo $totalStock;
?></h5>
<p class="card-text">Total stock available in inventory.</p>
<a href="templates/stock/list.php" class="btn btn-light">View
Stock</a>
</div>
</div>
</div>
</div>
</div>
<?php require '../includes/footer.php'; // Include footer
?>
Explanation:
- Session
Management: The script starts by initiating a session with session_start();
to manage user sessions.
- Database
Connection: It includes the database connection file (config/db.php)
to interact with the database.
- Header
and Navbar Includes: The header (includes/header.php) and navigation
bar (includes/navbar.php) are included for a consistent layout.
- Fetching
Summary Data:
- Four
separate SQL queries are executed to fetch the counts of total products,
suppliers, and orders, as well as the sum of stock levels from the
products table.
- Each
query is prepared and executed using PDO. The results are fetched into
variables.
- HTML
Structure: The main content includes a Bootstrap grid that displays
cards for total products, suppliers, orders, and stock levels. Each card
shows a count and a button linking to the respective sections of the
application.
- Footer
Include: Finally, the footer (includes/footer.php) is included to
close the HTML structure.
Styling:
Ensure you have Bootstrap linked in your includes/header.php
for styling the cards and layout.
This index.php will serve as the dashboard for your inventory management system, providing an overview at a glance.
assets/css/styles.css
This CSS will help you style the layout and components for a more polished look.
/* General styles */
body {
font-family:
Arial, sans-serif;
background-color: #f8f9fa;
/* Light gray background */
margin: 0;
padding: 20px;
}
/* Container styles */
.container {
max-width: 1200px;
/* Maximum width for the container */
margin: auto; /*
Center the container */
padding: 20px; /*
Padding around the container */
}
/* Card styles */
.card {
border-radius: 0.5rem;
/* Rounded corners */
box-shadow: 0 4px 8px
rgba(0, 0, 0, 0.1); /* Subtle shadow */
}
/* Card header styles */
.card-header {
font-weight: bold;
text-align:
center; /* Center text */
}
/* Card body styles */
.card-body {
text-align:
center; /* Center text in card body */
}
/* Button styles */
.btn {
text-decoration:
none; /* Remove underline from links */
border-radius: 0.3rem;
/* Rounded button corners */
padding: 10px 15px;
/* Padding inside buttons */
}
.btn-light {
background-color: #ffffff;
/* Light background */
color: #007bff; /*
Bootstrap primary color */
}
/* Table styles */
.table {
width: 100%; /*
Full width */
border-collapse:
collapse; /* Remove spacing between cells */
}
.table th, .table td {
border: 1px solid #dee2e6;
/* Light gray border */
padding: 10px; /*
Padding inside cells */
text-align: left; /*
Left align text */
}
.table th {
background-color: #007bff;
/* Bootstrap primary color */
color: white; /*
White text color */
}
/* Responsive styles */
@media (max-width: 768px) {
.card {
margin-bottom:
20px; /* Add margin for small screens */
}
}
Explanation:
- General
Styles:
- Sets
the font family, background color, and basic margin and padding for the
body.
- Container
Styles:
- Sets
a maximum width for the container, centers it, and adds padding for
spacing.
- Card
Styles:
- Styles
the Bootstrap card elements with rounded corners and subtle shadow for a
lifted effect.
- Button
Styles:
- Styles
the buttons with rounded corners and padding. The btn-light class is
given a white background with the primary Bootstrap color for text.
- Table
Styles:
- Styles
for table elements, including full width, cell padding, and light gray
borders.
- Responsive
Styles:
- A
media query adjusts the margin for cards on smaller screens to ensure
good spacing.
Integration:
Make sure to link this CSS file in your header file (includes/header.php)
to apply these styles across your application:
<link rel="stylesheet" href="assets/css/styles.css">
assets/js/scripts.js
This JavaScript file can be used to add interactivity and handle any client-side functionality you may need.
// scripts.js
// Function to confirm delete actions
function confirmDelete(message) {
return confirm(message);
// Show confirmation dialog
}
// Event listener for delete buttons
document.querySelectorAll('.btn-delete').forEach(button
=> {
button.addEventListener('click',
function (event) {
const
productName = event.target.dataset.productName; // Get the product name from
data attribute
const
confirmed = confirmDelete(`Are you sure you want to delete "${productName}"?`);
// Confirm delete
if
(!confirmed) {
event.preventDefault();
// Prevent the default action if not confirmed
}
});
});
// Example: Function to toggle visibility of elements (if
needed)
function toggleVisibility(elementId) {
const element = document.getElementById(elementId);
if (element.style.display
=== "none") {
element.style.display
= "block"; // Show the element
} else {
element.style.display
= "none"; // Hide the element
}
}
// Example: Add event listener for toggling visibility
// Uncomment and modify the following lines if you have
elements to toggle
//
document.getElementById('toggleButton').addEventListener('click', function() {
//
toggleVisibility('elementToToggle');
// });
Explanation:
- Confirm
Delete Function:
- A
function called confirmDelete prompts the user for confirmation when they
attempt to delete an item. If the user clicks "OK," the
function returns true; otherwise, it returns false.
- Event
Listener for Delete Buttons:
- The
script selects all elements with the class btn-delete (which you should
assign to your delete buttons). When any of these buttons are clicked, it
retrieves the product name from the data-product-name attribute and shows
a confirmation dialog. If the user does not confirm, it prevents the
default action (form submission).
- Toggle
Visibility Function (Optional):
- This
function toggles the visibility of an HTML element based on its id. This
can be useful if you want to show/hide sections of your interface
dynamically.
- Event
Listener for Toggling Visibility (Optional):
- This
commented-out section shows how you might add an event listener to a
button for toggling the visibility of a specific element.
Integration:
Make sure to link this JavaScript file in your footer file (includes/footer.php)
to ensure that it loads after the HTML content:
<script src="assets/js/scripts.js"></script>
includes/header.php
This file will set up the necessary HTML structure and include links to stylesheets and scripts.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Inventory Management System</title>
<link rel="stylesheet"
href="../assets/css/styles.css"> <!-- Link to your custom CSS
-->
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- Bootstrap CSS -->
</head>
<body>
Explanation:
- DOCTYPE
Declaration: Declares the document type as HTML5.
- HTML
Tag: Starts the HTML document and specifies the language as English.
- Meta
Tags:
- The
charset meta tag specifies the character encoding for the document.
- The
viewport meta tag ensures the website is responsive on different devices.
- Title
Tag: Sets the title of the web page that appears in the browser tab.
- Stylesheets:
- Links
to your custom CSS file (styles.css) for your project-specific styles.
- Links
to the Bootstrap CSS from a CDN for styling components and layout.
- Body
Tag: Opens the body of the HTML document, where the main content will
be placed.
Integration:
This header.php file should be included at the beginning of
each page in your application. For example, in your index.php, you can include
it at the top:
<?php require '../includes/header.php'; ?>
This sets up the structure for your web pages and ensures that all necessary styles are applied consistently across your application.
includes/footer.php
This file will contain closing HTML tags, any JavaScript includes, and any footer content you want to display.
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
<!-- Popper.js for Bootstrap -->
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<!-- Bootstrap JS -->
<script
src="../assets/js/scripts.js"></script> <!-- Link to your
custom JavaScript -->
</body>
</html>
Explanation:
- JavaScript
Includes:
- The
<script> tags load jQuery, Popper.js, and Bootstrap's JavaScript.
These libraries are necessary for Bootstrap's interactive components
(like modals, dropdowns, etc.).
- It
links to your custom JavaScript file (scripts.js) to ensure that any
scripts you’ve written will function as intended.
- Closing
Tags:
- The
</body> tag closes the body of the document.
- The
</html> tag closes the HTML document.
Integration:
This footer.php file should be included at the end of each
page in your application. For example, in your index.php, you can include it at
the bottom:
<?php require '../includes/footer.php'; ?>
This will ensure that all necessary scripts are loaded and that your page structure is properly closed.
includes/navbar.php
This file will create a navigation bar to allow users to navigate between different sections of the application.
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand"
href="index.php">Inventory Management System</a>
<button class="navbar-toggler"
type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse
navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link"
href="templates/products/list.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/suppliers/list.php">Suppliers</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/orders/list.php">Orders</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/stock/list.php">Stock Levels</a>
</li>
<li class="nav-item">
<a class="nav-link" href="templates/reports/generate.php">Reports</a>
</li>
</ul>
</div>
</nav>
Explanation:
- Navbar
Structure:
- Uses
Bootstrap classes for styling the navbar.
- The
<nav> tag defines the navigation bar, and navbar-expand-lg makes it
responsive.
- Brand
Name:
- The
<a> tag with the class navbar-brand serves as the brand name or
logo for the navigation bar, linking back to the index page.
- Toggler
Button:
- The
button with navbar-toggler class is used for mobile responsiveness. It
allows users to toggle the visibility of the navigation links on smaller
screens.
- Navbar
Links:
- Each
<li> element represents a navigation item that links to different
sections of the inventory management system:
- Products
- Suppliers
- Orders
- Stock
Levels
- Reports
Integration:
This navbar.php file should be included after the header in
each page of your application. For example, in your index.php, you can include
it like this:
<?php require '../includes/navbar.php'; ?>
This will ensure that the navigation bar is displayed consistently across all pages, allowing users to navigate easily within your application.
includes/navbar.php(Updated)
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand"
href="index.php">Inventory Management System</a>
<button class="navbar-toggler"
type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse
navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link"
href="templates/products/list.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/orders/list.php">Orders</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/suppliers/list.php">Suppliers</a>
</li>
<li class="nav-item">
<a class="nav-link" href="templates/stock/list.php">Stock
Levels</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="templates/reports/generate.php">Reports</a>
</li>
</ul>
</div>
</nav>
Explanation:
- Navbar
Structure:
- Utilizes
Bootstrap's responsive navbar classes (navbar, navbar-expand-lg, and navbar-light
bg-light) for styling.
- The
<nav> element contains the entire navigation bar.
- Brand
Name:
- The
<a> tag with the navbar-brand class serves as the title/logo of the
application and links back to the main index page.
- Toggler
Button:
- The
button with navbar-toggler class is included for mobile responsiveness,
allowing users to toggle the visibility of the navigation links on
smaller screens.
- Navigation
Links:
- Each
<li> element is a navigation item that links to specific sections
of the inventory management system:
- Products:
Links to the product listing page.
- Orders:
Links to the orders listing page.
- Suppliers:
Links to the suppliers listing page.
- Stock
Levels: Links to the stock levels page.
- Reports:
Links to the report generation page.
Integration:
Include this navbar.php file in your main pages, right after
the header.php file, like this:
<?php require '../includes/header.php'; ?>
<?php require '../includes/navbar.php'; ?>
This setup will create a consistent navigation experience across your application.
includes/sidebar.php
The sidebar can provide additional navigation options or shortcuts for users, making it easier to access various sections of the application.
<div class="sidebar">
<h4 class="sidebar-title">Dashboard</h4>
<ul class="sidebar-nav">
<li class="sidebar-item">
<a class="sidebar-link"
href="templates/products/list.php">Products</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link"
href="templates/orders/list.php">Orders</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link"
href="templates/suppliers/list.php">Suppliers</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link"
href="templates/stock/list.php">Stock Levels</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link"
href="templates/reports/generate.php">Reports</a>
</li>
</ul>
</div>
CSS for Sidebar (Optional)
To style the sidebar, you can add some CSS in your styles.css
file. Here’s a basic style for the sidebar:
.sidebar {
background-color: #f8f9fa;
/* Light gray background */
padding: 15px;
border-radius: 0.5rem;
/* Rounded corners */
box-shadow: 0 4px 8px
rgba(0, 0, 0, 0.1); /* Subtle shadow */
margin-bottom: 20px;
/* Space below the sidebar */
}
.sidebar-title {
font-weight: bold;
margin-bottom: 15px;
/* Space below the title */
}
.sidebar-nav {
list-style-type:
none; /* Remove bullet points */
padding: 0; /*
Remove padding */
}
.sidebar-item {
margin-bottom: 10px;
/* Space between items */
}
.sidebar-link {
text-decoration:
none; /* Remove underline */
color: #007bff; /*
Bootstrap primary color */
font-weight: 500;
}
.sidebar-link:hover {
text-decoration:
underline; /* Underline on hover */
}
Explanation:
- Sidebar
Structure:
- A
<div> container is created for the sidebar with the class sidebar.
- An
<h4> element is used as a title for the sidebar.
- Navigation
Links:
- The
sidebar contains an unordered list (<ul>) of navigation links, each
wrapped in a list item (<li>). Each link (<a>) points to the
relevant pages in the inventory management system:
- Products
- Orders
- Suppliers
- Stock
Levels
- Reports
Integration:
Include this sidebar.php file in your main pages, typically
after the navbar.php file, like this:
<?php require '../includes/header.php'; ?>
<?php require '../includes/navbar.php'; ?>
<?php require '../includes/sidebar.php'; ?>
This will ensure that the sidebar is displayed consistently across your application.
1. list.php: Displays the list of products.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch products from the database
$query = "SELECT * FROM products";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Product List</h2>
<a href="add.php"
class="btn btn-primary mb-3">Add New Product</a>
<table class="table
table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Stock</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['description']; ?></td>
<td><?php echo $row['price']; ?></td>
<td><?php echo $row['stock']; ?></td>
<td>
<a href="edit.php?id=<?php echo $row['id']; ?>" class="btn
btn-warning btn-sm">Edit</a>
<a href="delete.php?id=<?php echo $row['id']; ?>" class="btn
btn-danger btn-sm">Delete</a>
</td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="6" class="text-center">No products
found.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Connection: Connects to the database and fetches the products using a
simple SQL query.
- Table
Structure: Displays products in a table format with columns for ID,
Name, Description, Price, Stock, and Actions (Edit/Delete buttons).
- Condition:
Checks if there are products to display; if not, it shows a message
indicating no products were found.
2. add.php: Form for adding a new product.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$name = $_POST['name'];
$description = $_POST['description'];
$price = $_POST['price'];
$stock = $_POST['stock'];
// Insert new
product into the database
$query = "INSERT
INTO products (name, description, price, stock) VALUES ('$name', '$description',
'$price', '$stock')";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to product list on success
exit();
} else {
echo "Error:
" . $query . "<br>" . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Add New Product</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="name">Product
Name</label>
<input type="text" class="form-control"
name="name" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea
class="form-control" name="description" required></textarea>
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="number"
class="form-control" name="price" step="0.01" required>
</div>
<div class="form-group">
<label for="stock">Stock</label>
<input type="number"
class="form-control" name="stock" required>
</div>
<button type="submit"
class="btn btn-success">Add Product</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Form
Handling: Checks if the form is submitted. If yes, it collects the
input data and executes an INSERT SQL query to add the new product to the
database.
- Form
Fields: Includes fields for the product name, description, price, and
stock.
- Redirection:
Redirects to the product list after successfully adding a product.
3. edit.php: Form for editing an existing product.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
$id = $_GET['id'];
$product = null;
// Fetch the product details from the database
if ($id) {
$query = "SELECT
* FROM products WHERE id = $id";
$result = $conn->query($query);
$product = $result->fetch_assoc();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$name = $_POST['name'];
$description = $_POST['description'];
$price = $_POST['price'];
$stock = $_POST['stock'];
// Update product
in the database
$query = "UPDATE
products SET name = '$name', description = '$description', price = '$price',
stock = '$stock' WHERE id = $id";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to product list on success
exit();
} else {
echo "Error:
" . $query . "<br>" . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Edit Product</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="name">Product
Name</label>
<input type="text"
class="form-control" name="name" value="<?php echo
$product['name']; ?>" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea
class="form-control" name="description" required><?php
echo $product['description']; ?></textarea>
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="number"
class="form-control" name="price" step="0.01" value="<?php
echo $product['price']; ?>" required>
</div>
<div class="form-group">
<label for="stock">Stock</label>
<input type="number"
class="form-control" name="stock" value="<?php echo
$product['stock']; ?>" required>
</div>
<button type="submit"
class="btn btn-success">Update Product</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Product
Fetching: Fetches the product details based on the provided ID from
the URL. If the ID exists, it retrieves the current product data to
populate the form.
- Form
Handling: Similar to add.php, it processes the form submission to
update the product details in the database.
- Form
Fields: Pre-fills the fields with existing product data for the user
to edit.
4. delete.php: Confirmation page for deleting a product.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
$id = $_GET['id'];
// Check if the ID is provided
if ($id) {
// Fetch the
product details for confirmation
$query = "SELECT
* FROM products WHERE id = $id";
$result = $conn->query($query);
$product = $result->fetch_assoc();
}
// Handle delete action
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$query = "DELETE
FROM products WHERE id = $id";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to product list on success
exit();
} else {
echo "Error:
" . $query . "<br>" . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Delete Product</h2>
<?php if ($product):
?>
<p>Are you
sure you want to delete the product "<strong><?php echo $product['name'];
?></strong>"?</p>
<form method="POST"
action="">
<button type="submit" class="btn
btn-danger">Delete</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
<?php else:
?>
<p>Product
not found.</p>
<?php endif;
?>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Product
Confirmation: Fetches the product details based on the ID for
confirmation before deletion.
- Delete
Handling: Executes the DELETE SQL query when the user confirms the
action.
- User
Confirmation: Displays a confirmation message with the product name
and options to either confirm deletion or cancel.
Database Configuration (config/db.php)
Ensure you have a file to handle your database connection.
<?php
$servername = "localhost";
$username = "root"; // Use your MySQL username
$password = ""; // Use your MySQL password
$dbname = "inventory"; // Your database name
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection
failed: " . $conn->connect_error);
}
?>
Conclusion
These PHP scripts will allow you to manage products in your
Inventory Management System, providing functionalities for listing, adding,
editing, and deleting products. Ensure your database schema includes a products
table with appropriate columns (e.g., id, name, description, price, stock) for
this to work correctly.
1. list.php: Displays the list of orders.
Here’s a detailed implementation of the Orders Directory for your Inventory Management System, including list.php, add.php, details.php, and report.php files. Each file will have explanations to help you understand how they work.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch orders from the database
$query = "SELECT o.id, o.order_date, o.total_amount,
s.name AS supplier_name
FROM orders
o
JOIN
suppliers s ON o.supplier_id = s.id";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Order List</h2>
<a href="add.php"
class="btn btn-primary mb-3">Add New Order</a>
<table class="table
table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Order
Date</th>
<th>Total
Amount</th>
<th>Supplier</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['id'];
?></td>
<td><?php echo $row['order_date']; ?></td>
<td><?php echo $row['total_amount']; ?></td>
<td><?php echo $row['supplier_name']; ?></td>
<td>
<a href="details.php?id=<?php echo $row['id']; ?>" class="btn
btn-info btn-sm">View Details</a>
</td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="5" class="text-center">No orders found.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Connection: Connects to the database and fetches orders, joining with
the suppliers table to display supplier names.
- Table
Structure: Displays orders in a table format with columns for ID,
Order Date, Total Amount, Supplier, and Actions (View Details button).
- Condition:
Checks if there are orders to display; if not, it shows a message
indicating no orders were found.
2. add.php: Form for adding a new order.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch suppliers for the dropdown
$suppliers = $conn->query("SELECT * FROM
suppliers");
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$supplier_id = $_POST['supplier_id'];
$order_date = $_POST['order_date'];
$total_amount = $_POST['total_amount'];
// Insert new
order into the database
$query = "INSERT
INTO orders (supplier_id, order_date, total_amount) VALUES ('$supplier_id', '$order_date',
'$total_amount')";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to order list on success
exit();
} else {
echo "Error:
" . $query . "<br>" . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Add New Order</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="supplier_id">Supplier</label>
<select
class="form-control" name="supplier_id" required>
<option
value="">Select Supplier</option>
<?php
while ($supplier = $suppliers->fetch_assoc()): ?>
<option value="<?php echo $supplier['id'];
?>"><?php echo $supplier['name']; ?></option>
<?php
endwhile; ?>
</select>
</div>
<div class="form-group">
<label for="order_date">Order
Date</label>
<input type="date"
class="form-control" name="order_date" required>
</div>
<div class="form-group">
<label for="total_amount">Total
Amount</label>
<input type="number"
class="form-control" name="total_amount" step="0.01"
required>
</div>
<button type="submit"
class="btn btn-success">Add Order</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Supplier
Dropdown: Fetches suppliers from the database and displays them in a
dropdown list for selection.
- Form
Handling: Checks if the form is submitted. If yes, it collects the
input data and executes an INSERT SQL query to add the new order to the
database.
- Form
Fields: Includes fields for selecting a supplier, order date, and
total amount.
- Redirection:
Redirects to the order list after successfully adding an order.
3. details.php: Displays detailed information for a
specific order.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
$id = $_GET['id'];
// Fetch order details
$query = "SELECT o.id, o.order_date, o.total_amount,
s.name AS supplier_name
FROM orders
o
JOIN
suppliers s ON o.supplier_id = s.id
WHERE o.id =
$id";
$result = $conn->query($query);
$order = $result->fetch_assoc();
?>
<div class="container mt-4">
<h2>Order Details</h2>
<?php if ($order):
?>
<p><strong>Order
ID:</strong> <?php echo $order['id']; ?></p>
<p><strong>Order
Date:</strong> <?php echo $order['order_date']; ?></p>
<p><strong>Total
Amount:</strong> <?php echo $order['total_amount']; ?></p>
<p><strong>Supplier:</strong>
<?php echo $order['supplier_name']; ?></p>
<a href="list.php"
class="btn btn-secondary">Back to Orders</a>
<?php else:
?>
<p>Order not found.</p>
<?php endif;
?>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Order
Fetching: Fetches the order details based on the ID from the URL. If
the order exists, it displays its details.
- User
Interface: Presents the order ID, order date, total amount, and
supplier name.
- Back
Button: Provides a button to navigate back to the order list.
4. report.php: Generates and displays sales reports.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch sales report data
$query = "SELECT o.order_date, SUM(o.total_amount) AS
total_sales
FROM orders
o
GROUP BY
o.order_date
ORDER BY
o.order_date DESC";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Sales Report</h2>
<table class="table
table-bordered">
<thead>
<tr>
<th>Order
Date</th>
<th>Total
Sales</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['order_date']; ?></td>
<td><?php echo $row['total_sales']; ?></td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="2" class="text-center">No sales data
found.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
<a href="list.php"
class="btn btn-secondary mt-3">Back to Orders</a>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Sales
Report Query: Fetches total sales grouped by order date, which allows
you to see daily sales figures.
- Report
Display: Presents the report data in a table format with columns for
Order Date and Total Sales.
- No
Data Condition: Checks if there are any sales data; if not, it shows a
message indicating no data found.
- Back
Button: Provides an option to return to the orders list.
1. list.php: Displays the list of suppliers.
Here’s a detailed implementation of the Suppliers Directory for your Inventory Management System, including list.php, add.php, edit.php, and delete.php files. Each file will have explanations to help you understand how they work.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch suppliers from the database
$query = "SELECT * FROM suppliers";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Supplier
List</h2>
<a href="add.php"
class="btn btn-primary mb-3">Add New Supplier</a>
<table class="table
table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['email']; ?></td>
<td><?php echo $row['phone']; ?></td>
<td>
<a href="edit.php?id=<?php echo $row['id']; ?>" class="btn
btn-warning btn-sm">Edit</a>
<a href="delete.php?id=<?php echo $row['id']; ?>" class="btn
btn-danger btn-sm">Delete</a>
</td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="5" class="text-center">No suppliers
found.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Connection: Connects to the database and fetches suppliers from the
suppliers table.
- Table
Structure: Displays suppliers in a table format with columns for ID,
Name, Email, Phone, and Actions (Edit and Delete buttons).
- Condition:
Checks if there are suppliers to display; if not, it shows a message
indicating no suppliers were found.
2. add.php: Form for adding a new supplier.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
// Insert new
supplier into the database
$query = "INSERT
INTO suppliers (name, email, phone) VALUES ('$name', '$email', '$phone')";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to supplier list on success
exit();
} else {
echo "Error:
" . $query . "<br>" . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Add New Supplier</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="name">Supplier
Name</label>
<input type="text"
class="form-control" name="name" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email"
class="form-control" name="email" required>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input type="text"
class="form-control" name="phone" required>
</div>
<button type="submit"
class="btn btn-success">Add Supplier</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Form
Handling: Checks if the form is submitted. If yes, it collects the
input data and executes an INSERT SQL query to add the new supplier to the
database.
- Form
Fields: Includes fields for supplier name, email, and phone.
- Redirection:
Redirects to the supplier list after successfully adding a supplier.
3. edit.php: Form for editing supplier details.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
$id = $_GET['id'];
// Fetch supplier details for editing
$query = "SELECT * FROM suppliers WHERE id = $id";
$result = $conn->query($query);
$supplier = $result->fetch_assoc();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
// Update supplier
in the database
$update_query = "UPDATE
suppliers SET name='$name', email='$email', phone='$phone' WHERE id=$id";
if ($conn->query($update_query)
=== TRUE) {
header("Location:
list.php"); // Redirect to supplier list on success
exit();
} else {
echo "Error
updating supplier: " . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Edit Supplier</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="name">Supplier
Name</label>
<input type="text"
class="form-control" name="name" value="<?php echo
$supplier['name']; ?>" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email"
class="form-control" name="email" value="<?php echo
$supplier['email']; ?>" required>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input type="text"
class="form-control" name="phone" value="<?php echo
$supplier['phone']; ?>" required>
</div>
<button type="submit"
class="btn btn-warning">Update Supplier</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Supplier
Fetching: Fetches the supplier details based on the ID from the URL to
populate the form fields.
- Form
Handling: Checks if the form is submitted. If yes, it collects the
input data and executes an UPDATE SQL query to modify the supplier's
information.
- Form
Fields: Pre-fills fields with existing supplier data to allow editing.
- Redirection:
Redirects to the supplier list after successfully updating a supplier.
4. delete.php: Confirmation page for deleting a supplier.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
$id = $_GET['id'];
// Fetch supplier details for confirmation
$query = "SELECT * FROM suppliers WHERE id = $id";
$result = $conn->query($query);
$supplier = $result->fetch_assoc();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Delete supplier
from the database
$delete_query = "DELETE
FROM suppliers WHERE id = $id";
if ($conn->query($delete_query)
=== TRUE) {
header("Location:
list.php"); // Redirect to supplier list on success
exit();
} else {
echo "Error
deleting supplier: " . $conn->error;
}
}
?>
<div class="container mt-4">
<h2>Delete Supplier</h2>
<?php if ($supplier):
?>
<p>Are you
sure you want to delete the supplier <strong><?php echo $supplier['name'];
?></strong>?</p>
<form method="POST"
action="">
<button
type="submit" class="btn btn-danger">Delete</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
<?php else:
?>
<p>Supplier
not found.</p>
<?php endif;
?>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Supplier
Fetching: Fetches the supplier details based on the ID from the URL to
confirm deletion.
- Confirmation
Handling: When the user confirms deletion, it executes a DELETE SQL
query to remove the supplier from the database.
- User
Interface: Displays a confirmation message with the supplier's name
and options to either confirm deletion or cancel.
1. list.php: Displays an overview of stock levels.
Here's the detailed implementation for the Stock Directory of your Inventory Management System, including list.php, update.php, and report.php. Each file is accompanied by explanations to help you understand how they function.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch stock levels from the database
$query = "SELECT products.id AS product_id,
products.name AS product_name, stock_levels.quantity AS stock_quantity
FROM
products
LEFT JOIN
stock_levels ON products.id = stock_levels.product_id";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Stock Levels</h2>
<a href="update.php"
class="btn btn-primary mb-3">Update Stock Levels</a>
<table class="table
table-bordered">
<thead>
<tr>
<th>Product
ID</th>
<th>Product
Name</th>
<th>Stock
Quantity</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['product_id']; ?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['stock_quantity'] ?? 0; ?></td>
<!-- Default to 0 if no stock -->
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="3" class="text-center">No stock information
found.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Query: Fetches stock levels by joining the products and stock_levels
tables.
- Table
Display: Shows a list of products along with their stock quantities.
- Default
Value: Displays 0 for products with no stock records.
2. update.php: Form for updating stock levels.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Collect form
data
$productId = $_POST['product_id'];
$quantity = $_POST['quantity'];
// Update stock
level in the database
$query = "INSERT
INTO stock_levels (product_id, quantity) VALUES ('$productId', '$quantity')
ON
DUPLICATE KEY UPDATE quantity = '$quantity'";
if ($conn->query($query)
=== TRUE) {
header("Location:
list.php"); // Redirect to stock list on success
exit();
} else {
echo "Error
updating stock level: " . $conn->error;
}
}
// Fetch products for the dropdown
$productQuery = "SELECT * FROM products";
$productResult = $conn->query($productQuery);
?>
<div class="container mt-4">
<h2>Update Stock
Levels</h2>
<form method="POST"
action="">
<div class="form-group">
<label for="product_id">Select
Product</label>
<select
class="form-control" name="product_id" required>
<option
value="">-- Select Product --</option>
<?php
while ($product = $productResult->fetch_assoc()): ?>
<option value="<?php echo $product['id'];
?>"><?php echo $product['name']; ?></option>
<?php
endwhile; ?>
</select>
</div>
<div class="form-group">
<label for="quantity">Stock
Quantity</label>
<input type="number"
class="form-control" name="quantity" required>
</div>
<button type="submit"
class="btn btn-success">Update Stock</button>
<a href="list.php"
class="btn btn-secondary">Cancel</a>
</form>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Form
Handling: When the form is submitted, it collects the product ID and
quantity.
- Upsert
Query: Uses an INSERT ... ON DUPLICATE KEY UPDATE query to insert a
new stock level or update an existing one.
- Product
Dropdown: Populates a dropdown list with products from the database
for the user to select.
3. report.php: Generates and displays stock reports.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch stock levels and products for reporting
$query = "SELECT products.id AS product_id,
products.name AS product_name,
stock_levels.quantity AS stock_quantity
FROM
products
LEFT JOIN
stock_levels ON products.id = stock_levels.product_id";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Stock Report</h2>
<table class="table
table-bordered">
<thead>
<tr>
<th>Product
ID</th>
<th>Product
Name</th>
<th>Stock
Quantity</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['product_id']; ?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['stock_quantity'] ?? 0; ?></td>
<!-- Default to 0 if no stock -->
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="3" class="text-center">No stock information
available for the report.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
<a href="list.php"
class="btn btn-secondary mt-3">Back to Stock List</a>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Report
Generation: Similar to list.php, it fetches stock data for generating
a report.
- Table
Structure: Displays a report of stock levels for all products in a
table format.
- No
Records Handling: Displays a message if no stock information is
available.
Database Structure
Make sure your database has the following tables to work
with this implementation:
- products
table:
- id:
INT, primary key, auto-increment
- name:
VARCHAR(255)
- stock_levels
table:
- id:
INT, primary key, auto-increment
- product_id:
INT, foreign key references products(id)
- quantity:
INT
1. sales.php: Page to generate sales reports.
Here’s the detailed implementation for the Reports Directory of your Inventory Management System, including sales.php, stock.php, and order.php. Each file comes with explanations to enhance your understanding of how they work.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch sales data from the database
$query = "SELECT orders.id AS order_id,
orders.order_date,
products.name AS product_name,
order_details.quantity,
(order_details.quantity * products.price) AS total_price
FROM orders
JOIN
order_details ON orders.id = order_details.order_id
JOIN
products ON order_details.product_id = products.id
ORDER BY
orders.order_date DESC";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Sales Report</h2>
<table class="table
table-bordered">
<thead>
<tr>
<th>Order
ID</th>
<th>Order Date</th>
<th>Product
Name</th>
<th>Quantity</th>
<th>Total
Price</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['order_id']; ?></td>
<td><?php echo date('Y-m-d', strtotime($row['order_date']));
?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['quantity']; ?></td>
<td><?php echo number_format($row['total_price'], 2); ?>
$</td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="5" class="text-center">No sales data
available.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
<a href="index.php"
class="btn btn-secondary mt-3">Back to Reports</a>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Query: Fetches sales data by joining orders, order_details, and products
tables.
- Table
Display: Displays order ID, order date, product name, quantity sold,
and total price in a table format.
- Formatting:
Uses number_format to format total prices for better readability.
2. stock.php: Page to generate stock reports.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch stock levels from the database
$query = "SELECT products.id AS product_id,
products.name AS product_name,
stock_levels.quantity AS stock_quantity
FROM
products
LEFT JOIN
stock_levels ON products.id = stock_levels.product_id";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Stock Report</h2>
<table class="table
table-bordered">
<thead>
<tr>
<th>Product
ID</th>
<th>Product
Name</th>
<th>Stock
Quantity</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['product_id']; ?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['stock_quantity'] ?? 0; ?></td>
<!-- Default to 0 if no stock -->
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="3" class="text-center">No stock information
available for the report.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
<a href="index.php"
class="btn btn-secondary mt-3">Back to Reports</a>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Query:
Retrieves current stock levels of all products.
- Display:
Shows product ID, name, and stock quantity in a structured table format.
- Fallback
Handling: Displays a message when no stock information is available.
3. order.php: Page to generate order history reports.
<?php
require '../../includes/header.php';
require '../../includes/navbar.php';
require '../../includes/sidebar.php';
require '../../config/db.php'; // Include database
configuration
// Fetch order history from the database
$query = "SELECT orders.id AS order_id,
orders.order_date,
customers.name AS customer_name,
(SELECT SUM(quantity) FROM order_details WHERE order_id = orders.id) AS
total_quantity
FROM orders
JOIN
customers ON orders.customer_id = customers.id
ORDER BY
orders.order_date DESC";
$result = $conn->query($query);
?>
<div class="container mt-4">
<h2>Order History
Report</h2>
<table class="table
table-bordered">
<thead>
<tr>
<th>Order
ID</th>
<th>Order
Date</th>
<th>Customer Name</th>
<th>Total
Quantity</th>
</tr>
</thead>
<tbody>
<?php if
($result->num_rows > 0): ?>
<?php
while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?php echo $row['order_id']; ?></td>
<td><?php echo date('Y-m-d', strtotime($row['order_date']));
?></td>
<td><?php echo $row['customer_name']; ?></td>
<td><?php echo $row['total_quantity'];
?></td>
</tr>
<?php
endwhile; ?>
<?php else:
?>
<tr>
<td colspan="4" class="text-center">No order history
available.</td>
</tr>
<?php endif;
?>
</tbody>
</table>
<a href="index.php"
class="btn btn-secondary mt-3">Back to Reports</a>
</div>
<?php require '../../includes/footer.php'; ?>
Explanation:
- Database
Query: Joins orders and customers tables to fetch order details.
- Subquery:
Calculates total quantities of items for each order.
- Display:
Lists order ID, order date, customer name, and total quantity in a
structured table format.
- Handling
No Data: Displays a message when no order history is available.
Conclusion
These scripts provide a comprehensive overview of your inventory management system's reporting features. You can generate sales, stock, and order history reports, allowing for better management and analysis of your inventory data.
Controllers
Below are the detailed implementations for the controllers
in your Inventory Management System, specifically for ProductController.php, OrderController.php,
SupplierController.php, and StockController.php. Each file will include CRUD
(Create, Read, Update, Delete) operations and relevant logic.
1. ProductController.php:
Handles the logic for product
CRUD operations.
<?php
require '../config/db.php'; // Include database
configuration
class ProductController {
// Create a new product
public function createProduct($name,
$price, $description) {
global $conn;
$stmt = $conn->prepare("INSERT
INTO products (name, price, description) VALUES (?, ?, ?)");
$stmt->bind_param("sds",
$name, $price, $description);
return $stmt->execute()
? true : false;
}
// Read all
products
public function getAllProducts()
{
global $conn;
$query = "SELECT
* FROM products";
return $conn->query($query);
}
// Read a specific
product
public function getProductById($id)
{
global $conn;
$stmt = $conn->prepare("SELECT
* FROM products WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Update a
product
public function updateProduct($id,
$name, $price, $description) {
global $conn;
$stmt = $conn->prepare("UPDATE
products SET name = ?, price = ?, description = ? WHERE id = ?");
$stmt->bind_param("sdsi",
$name, $price, $description, $id);
return $stmt->execute()
? true : false;
}
// Delete a
product
public function deleteProduct($id)
{
global $conn;
$stmt = $conn->prepare("DELETE
FROM products WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Database
Connection: Uses a global variable to access the database connection.
- CRUD
Methods: Each method corresponds to a CRUD operation:
- createProduct:
Inserts a new product into the products table.
- getAllProducts:
Fetches all products.
- getProductById:
Fetches a specific product by ID.
- updateProduct:
Updates an existing product.
- deleteProduct:
Deletes a product by ID.
2. OrderController.php:
Handles the logic for managing
orders.
<?php
require '../config/db.php'; // Include database
configuration
class OrderController {
// Create a new order
public function createOrder($customerId,
$orderDetails) {
global $conn;
// Start a transaction
$conn->begin_transaction();
try {
$stmt = $conn->prepare("INSERT
INTO orders (customer_id, order_date) VALUES (?, NOW())");
$stmt->bind_param("i",
$customerId);
$stmt->execute();
$orderId = $conn->insert_id;
// Insert order details
foreach ($orderDetails
as $detail) {
$stmtDetail
= $conn->prepare("INSERT INTO order_details (order_id, product_id,
quantity) VALUES (?, ?, ?)");
$stmtDetail->bind_param("iii",
$orderId, $detail['product_id'], $detail['quantity']);
$stmtDetail->execute();
}
// Commit transaction
$conn->commit();
return $orderId;
} catch (Exception $e) {
//
Rollback transaction on error
$conn->rollback();
return false;
}
}
// Read all orders
public function getAllOrders()
{
global $conn;
$query = "SELECT
* FROM orders";
return $conn->query($query);
}
// Read a specific
order
public function getOrderById($id)
{
global $conn;
$stmt = $conn->prepare("SELECT
* FROM orders WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Delete an order
public function deleteOrder($id)
{
global $conn;
$stmt = $conn->prepare("DELETE
FROM orders WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Transaction
Handling: Uses transactions for order creation to ensure data
integrity.
- CRUD
Methods:
- createOrder:
Creates a new order and its associated order details.
- getAllOrders:
Fetches all orders.
- getOrderById:
Fetches a specific order by ID.
- deleteOrder:
Deletes an order by ID.
3. SupplierController.php:
Handles the logic for managing
suppliers.
<?php
require '../config/db.php'; // Include database
configuration
class SupplierController {
// Create a new supplier
public function createSupplier($name,
$contact) {
global $conn;
$stmt = $conn->prepare("INSERT
INTO suppliers (name, contact) VALUES (?, ?)");
$stmt->bind_param("ss",
$name, $contact);
return $stmt->execute()
? true : false;
}
// Read all suppliers
public function getAllSuppliers()
{
global $conn;
$query = "SELECT
* FROM suppliers";
return $conn->query($query);
}
// Read a specific
supplier
public function getSupplierById($id)
{
global $conn;
$stmt = $conn->prepare("SELECT
* FROM suppliers WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Update a supplier
public function updateSupplier($id,
$name, $contact) {
global $conn;
$stmt = $conn->prepare("UPDATE
suppliers SET name = ?, contact = ? WHERE id = ?");
$stmt->bind_param("ssi",
$name, $contact, $id);
return $stmt->execute()
? true : false;
}
// Delete a supplier
public function deleteSupplier($id)
{
global $conn;
$stmt = $conn->prepare("DELETE
FROM suppliers WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Database
Connection: Similar structure to the previous controllers.
- CRUD
Methods:
- createSupplier:
Inserts a new supplier into the suppliers table.
- getAllSuppliers:
Fetches all suppliers.
- getSupplierById:
Fetches a specific supplier by ID.
- updateSupplier:
Updates supplier information.
- deleteSupplier:
Deletes a supplier by ID.
4. StockController.php:
Handles the logic for stock
management.
<?php
require '../config/db.php'; // Include database
configuration
class StockController {
// Update stock level
public function updateStock($productId,
$quantity) {
global $conn;
$stmt = $conn->prepare("UPDATE
stock_levels SET quantity = ? WHERE product_id = ?");
$stmt->bind_param("ii",
$quantity, $productId);
return $stmt->execute()
? true : false;
}
// Read stock levels
public function getStockLevels()
{
global $conn;
$query = "SELECT
products.id AS product_id, products.name AS product_name,
stock_levels.quantity AS stock_quantity
FROM
products
LEFT
JOIN stock_levels ON products.id = stock_levels.product_id";
return $conn->query($query);
}
// Add new stock
public function addStock($productId,
$quantity) {
global $conn;
$stmt = $conn->prepare("INSERT
INTO stock_levels (product_id, quantity) VALUES (?, ?)");
$stmt->bind_param("ii",
$productId, $quantity);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Stock
Management: Manages the stock levels for products.
- Methods:
- updateStock:
Updates the stock level for a specific product.
- getStockLevels:
Retrieves the current stock levels for all products.
- addStock:
Adds a new stock entry for a product.
Conclusion
These controller classes provide a clean and organized way to handle business logic for managing products, orders, suppliers, and stock in your inventory management system. Each controller follows the principles of CRUD operations, making it easy to maintain and extend as your application grows.
Models
Below are the detailed implementations for the models in your Inventory Management System. Each model handles database operations relevant to its entity.
1. Product.php:
Represents the product model and handles
database operations for products.
<?php
require '../config/db.php'; // Include database
configuration
class Product {
private $conn;
public function __construct($connection) {
$this->conn
= $connection;
}
// Create a new product
public function create($name,
$price, $description) {
$stmt = $this->conn->prepare("INSERT
INTO products (name, price, description) VALUES (?, ?, ?)");
$stmt->bind_param("sds",
$name, $price, $description);
return $stmt->execute()
? true : false;
}
// Read all products
public function readAll()
{
$query = "SELECT
* FROM products";
return $this->conn->query($query);
}
// Read a specific product
public function readById($id)
{
$stmt = $this->conn->prepare("SELECT
* FROM products WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Update a product
public function update($id,
$name, $price, $description) {
$stmt = $this->conn->prepare("UPDATE
products SET name = ?, price = ?, description = ? WHERE id = ?");
$stmt->bind_param("sdsi",
$name, $price, $description, $id);
return $stmt->execute()
? true : false;
}
// Delete a product
public function delete($id)
{
$stmt = $this->conn->prepare("DELETE
FROM products WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Database
Connection: The model accepts a database connection through the
constructor.
- CRUD
Methods:
- create:
Inserts a new product.
- readAll:
Fetches all products.
- readById:
Fetches a specific product by ID.
- update:
Updates an existing product.
- delete:
Deletes a product by ID.
2. Order.php:
Represents the order model and handles
database operations for orders.
<?php
require '../config/db.php'; // Include database
configuration
class Order {
private $conn;
$this->conn
= $connection;
}
public function create($customerId,
$orderDetails) {
$this->conn->begin_transaction();
// Start transaction
try {
$stmt = $this->conn->prepare("INSERT
INTO orders (customer_id, order_date) VALUES (?, NOW())");
$stmt->bind_param("i",
$customerId);
$stmt->execute();
$orderId =
$this->conn->insert_id;
foreach ($orderDetails
as $detail) {
$stmtDetail
= $this->conn->prepare("INSERT INTO order_details (order_id,
product_id, quantity) VALUES (?, ?, ?)");
$stmtDetail->bind_param("iii",
$orderId, $detail['product_id'], $detail['quantity']);
$stmtDetail->execute();
}
$this->conn->commit();
// Commit transaction
return $orderId;
} catch (Exception
$e) {
$this->conn->rollback();
// Rollback on error
return false;
}
}
// Read all orders
public function readAll()
{
$query = "SELECT
* FROM orders";
return $this->conn->query($query);
}
// Read a specific
order
public function readById($id)
{
$stmt = $this->conn->prepare("SELECT
* FROM orders WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Delete an order
public function delete($id)
{
$stmt = $this->conn->prepare("DELETE
FROM orders WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Transaction
Handling: Similar to the previous controller, it handles order
creation with transactions.
- CRUD
Methods:
- create:
Creates a new order with associated details.
- readAll:
Fetches all orders.
- readById:
Fetches a specific order by ID.
- delete:
Deletes an order by ID.
3. Supplier.php:
Represents the supplier model and
handles database operations for suppliers.
<?php
require '../config/db.php'; // Include database
configuration
class Supplier {
private $conn;
public function __construct($connection) {
$this->conn
= $connection;
}
// Create a new supplier
public function create($name,
$contact) {
$stmt = $this->conn->prepare("INSERT
INTO suppliers (name, contact) VALUES (?, ?)");
$stmt->bind_param("ss",
$name, $contact);
return $stmt->execute()
? true : false;
}
// Read all suppliers
public function readAll()
{
$query = "SELECT
* FROM suppliers";
return $this->conn->query($query);
}
// Read a specific supplier
public function readById($id)
{
$stmt = $this->conn->prepare("SELECT
* FROM suppliers WHERE id = ?");
$stmt->bind_param("i",
$id);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Update a supplier
public function update($id,
$name, $contact) {
$stmt = $this->conn->prepare("UPDATE
suppliers SET name = ?, contact = ? WHERE id = ?");
$stmt->bind_param("ssi",
$name, $contact, $id);
return $stmt->execute()
? true : false;
}
// Delete a supplier
public function delete($id)
{
$stmt = $this->conn->prepare("DELETE
FROM suppliers WHERE id = ?");
$stmt->bind_param("i",
$id);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Database
Connection: Uses a constructor to receive the database connection.
- CRUD
Methods:
- create:
Inserts a new supplier.
- readAll:
Fetches all suppliers.
- readById:
Fetches a specific supplier by ID.
- update:
Updates supplier information.
- delete:
Deletes a supplier by ID.
4. Stock.php:
Represents the stock model and handles
database operations for stock.
<?php
require '../config/db.php'; // Include database
configuration
class Stock {
private $conn;
public function __construct($connection) {
$this->conn
= $connection;
}
// Update stock level
public function update($productId,
$quantity) {
$stmt = $this->conn->prepare("UPDATE
stock_levels SET quantity = ? WHERE product_id = ?");
$stmt->bind_param("ii",
$quantity, $productId);
return $stmt->execute()
? true : false;
}
// Read stock levels
public function readLevels()
{
$query = "SELECT
products.id AS product_id, products.name AS product_name,
stock_levels.quantity AS stock_quantity
FROM
products
LEFT
JOIN stock_levels ON products.id = stock_levels.product_id";
return $this->conn->query($query);
}
// Add new stock
public function add($productId,
$quantity) {
$stmt = $this->conn->prepare("INSERT
INTO stock_levels (product_id, quantity) VALUES (?, ?)");
$stmt->bind_param("ii",
$productId, $quantity);
return $stmt->execute()
? true : false;
}
}
?>
Explanation:
- Stock
Management: Manages the stock levels.
- Methods:
- update:
Updates the stock level for a product.
- readLevels:
Retrieves the current stock levels.
- add:
Adds a new stock entry.
5. Report.php:
Handles the logic for generating reports
(sales, stock, and order history).
<?php
require '../config/db.php'; // Include database
configuration
class Report {
private $conn;
public function __construct($connection) {
$this->conn
= $connection;
}
// Generate sales report
public function generateSalesReport($startDate,
$endDate) {
$stmt = $this->conn->prepare("SELECT
SUM(order_details.quantity * products.price) AS total_sales
FROM
orders
JOIN
order_details ON orders.id = order_details.order_id
JOIN
products ON order_details.product_id = products.id
WHERE
orders.order_date BETWEEN ? AND ?");
$stmt->bind_param("ss",
$startDate, $endDate);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
// Generate stock report
public function generateStockReport()
{
$query = "SELECT
products.id, products.name, stock_levels.quantity
FROM
products
LEFT
JOIN stock_levels ON products.id = stock_levels.product_id";
return $this->conn->query($query);
}
// Generate order history report
public function generateOrderHistory()
{
$query = "SELECT
orders.id, orders.order_date, customers.name AS customer_name
FROM
orders
JOIN
customers ON orders.customer_id = customers.id";
return $this->conn->query($query);
}
}
?>
Explanation:
- Report
Generation: Responsible for generating various reports.
- Methods:
- generateSalesReport:
Generates a sales report between two dates.
- generateStockReport:
Retrieves stock levels for all products.
- generateOrderHistory:
Retrieves the order history.
Conclusion:
Each model class is structured to handle the database operations for its corresponding entity in the inventory management system. You can further expand upon these models based on your application needs, such as adding validation, more complex queries, or error handling as required.
SQL files
1. create_tables.sql:
SQL file for creating the database schema.
-- Creating the database
CREATE DATABASE IF NOT EXISTS inventory_management;
USE inventory_management;
-- Creating products table
CREATE TABLE IF NOT EXISTS products (
id INT
AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT
NULL,
price DECIMAL(10, 2)
NOT NULL,
description TEXT,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Creating suppliers table
CREATE TABLE IF NOT EXISTS suppliers (
id INT
AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT
NULL,
contact VARCHAR(100)
NOT NULL,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Creating stock_levels table
CREATE TABLE IF NOT EXISTS stock_levels (
id INT
AUTO_INCREMENT PRIMARY KEY,
product_id INT NOT
NULL,
quantity INT DEFAULT
0,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY
(product_id) REFERENCES products(id) ON DELETE CASCADE
);
-- Creating orders table
CREATE TABLE IF NOT EXISTS orders (
id INT
AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT
NULL,
order_date TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Creating order_details table
CREATE TABLE IF NOT EXISTS order_details (
id INT
AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
product_id INT NOT
NULL,
quantity INT NOT NULL,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY
(order_id) REFERENCES orders(id) ON DELETE CASCADE,
FOREIGN KEY
(product_id) REFERENCES products(id) ON DELETE CASCADE
);
-- Creating customers table
CREATE TABLE IF NOT EXISTS customers (
id INT
AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT
NULL,
email VARCHAR(100)
NOT NULL UNIQUE,
created_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Explanation:
- Database
Creation: The script starts by creating a database named inventory_management
if it doesn't already exist.
- Table
Definitions:
- products:
Contains product details.
- suppliers:
Contains supplier information.
- stock_levels:
Tracks stock quantities associated with products.
- orders:
Holds information about customer orders.
- order_details:
Links orders with specific products and their quantities.
- customers:
Holds customer information, including a unique email.
2. dummy_data.sql:
SQL file for inserting dummy data
(optional).
USE inventory_management;
-- Inserting dummy data into products table
INSERT INTO products (name, price, description) VALUES
('Product A', 19.99, 'Description for Product A'),
('Product B', 29.99, 'Description for Product B'),
('Product C', 9.99, 'Description for Product C'),
('Product D', 49.99, 'Description for Product D');
-- Inserting dummy data into suppliers table
INSERT INTO suppliers (name, contact) VALUES
('Supplier A', 'contact@supplierA.com'),
('Supplier B', 'contact@supplierB.com'),
('Supplier C', 'contact@supplierC.com');
-- Inserting dummy data into stock_levels table
INSERT INTO stock_levels (product_id, quantity) VALUES
(1, 100),
(2, 50),
(3, 200),
(4, 0);
-- Inserting dummy data into customers table
INSERT INTO customers (name, email) VALUES
('Customer A', 'customerA@example.com'),
('Customer B', 'customerB@example.com');
-- Inserting dummy data into orders table
INSERT INTO orders (customer_id) VALUES
(1),
(2);
-- Inserting dummy data into order_details table
INSERT INTO order_details (order_id, product_id, quantity) VALUES
(1, 1, 2),
(1, 2, 1),
(2, 3, 5);
Explanation:
- Dummy
Data Insertion: This script populates the database with sample data
for testing and development purposes.
- Data
Across Tables:
- Products,
suppliers, stock levels, customers, orders, and order details are all
filled with sample records.
3. backup.sql:
SQL file for backing up the database.
-- Backing up the database structure and data
-- This is just an example. Use a database tool or script to
perform real backups.
-- To back up, you can use the following command on the MySQL command line:
-- mysqldump -u [username] -p inventory_management >
backup.sql;
- Alternatively, you can create the SQL dump through PHPMyAdmin or similar tools.
Explanation:
- Backup
Instructions: This file contains instructions on how to back up the
database using the mysqldump command or a tool like PHPMyAdmin.
- Note:
Actual backup commands or methods are not written out as SQL since they
are executed outside of the database context.
Conclusion:
These SQL files will set up your database schema, provide
sample data for testing, and instructions for backing up your database. Ensure
that you run these scripts in the correct order (first create_tables.sql, then dummy_data.sql)
for the system to function properly.
helpers/
Here’s the detailed code for the helpers/ directory of your Inventory Management System project. This directory will contain utility functions that can be reused throughout the application, helping to streamline your code and keep it organized.
1. functions.php: Common utility functions.
helpers/functions.php
<?php
// Redirects to a specified URL
function redirectTo($url) {
header("Location:
$url");
exit();
}
// Formats a date to a specified format
function formatDate($date, $format = 'Y-m-d H:i:s') {
return date($format,
strtotime($date));
}
// Displays flash messages stored in session
function displayFlashMessage() {
if (isset($_SESSION['flash_message']))
{
echo "<div
class='alert alert-success'>" . $_SESSION['flash_message'] . "</div>";
unset($_SESSION['flash_message']);
}
}
// Sets a flash message for the next request
function setFlashMessage($message) {
$_SESSION['flash_message']
= $message;
}
// Sanitizes input data to prevent XSS
function sanitizeInput($data) {
return htmlspecialchars(strip_tags(trim($data)));
}
// Generates a CSRF token
function generateCsrfToken() {
if (empty($_SESSION['csrf_token']))
{
$_SESSION['csrf_token']
= bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
// Validates a CSRF token
function validateCsrfToken($token) {
return hash_equals($_SESSION['csrf_token'],
$token);
}
?>
Explanation:
- redirectTo($url):
Redirects users to a specified URL and exits the script to ensure no
further code is executed.
- formatDate($date,
$format): Formats a date string to a specified format. Defaults to Y-m-d
H:i:s.
- displayFlashMessage():
Displays any flash messages stored in the session and then unsets it to
avoid showing the message again.
- setFlashMessage($message):
Sets a flash message in the session for later display.
- sanitizeInput($data):
Sanitizes user input by stripping tags and converting special characters
to HTML entities, helping to prevent XSS attacks.
- generateCsrfToken():
Generates a CSRF token and stores it in the session to protect against
cross-site request forgery attacks.
- validateCsrfToken($token):
Validates a provided CSRF token against the one stored in the session to
ensure it's valid.
2. validate.php: Form validation functions.
helpers/validate.php
<?php
// Checks if a field is empty
function isEmptyField($field) {
return empty(trim($field));
}
// Validates email format
function isValidEmail($email) {
return filter_var($email,
FILTER_VALIDATE_EMAIL) !== false;
}
// Validates a product price
function isValidPrice($price) {
return is_numeric($price)
&& $price >= 0;
}
// Validates quantity to ensure it's a non-negative integer
function isValidQuantity($quantity) {
return filter_var($quantity,
FILTER_VALIDATE_INT) !== false && $quantity >= 0;
}
// Validates if a field is a non-negative integer
function isNonNegativeInteger($field) {
return filter_var($field,
FILTER_VALIDATE_INT) !== false && $field >= 0;
}
// Collects error messages from an array
function getErrorMessages($errors) {
return implode('<br>',
$errors);
}
// Checks if there are any validation errors
function hasErrors($errors) {
return !empty($errors);
}
?>
Explanation:
- isEmptyField($field):
Checks if a given field is empty, returning true if it is.
- isValidEmail($email):
Validates the format of an email address using PHP's filter_var function.
- isValidPrice($price):
Checks if the price is a numeric value and is non-negative.
- isValidQuantity($quantity):
Validates that the quantity is a non-negative integer.
- isNonNegativeInteger($field):
Ensures the provided field is a non-negative integer.
- getErrorMessages($errors):
Collects error messages from an array and joins them into a single string
for display.
- hasErrors($errors):
Returns true if there are any validation errors.
Conclusion:
The helper functions in these files provide utility methods for common tasks like redirecting users, validating form input, and sanitizing data. This modular approach promotes code reusability and helps maintain cleaner code throughout your application.
1. .htaccess:
Apache server configuration file for URL routing and security.
Each file serves a specific purpose, from server configuration to project documentation.
# Enable URL rewriting
RewriteEngine On
# Redirect to the index.php for all requests
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ public/index.php?url=$1 [QSA,L]
# Prevent access to sensitive files
<FilesMatch "\.(htaccess|ini|log|sh)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Disable directory listing
Options -Indexes
# Set a custom error document
ErrorDocument 404 /public/404.php
Explanation:
- RewriteEngine
On: Enables the rewrite engine for URL routing.
- RewriteCond:
Conditions to check if the requested file or directory does not exist.
- RewriteRule:
Redirects all requests to public/index.php, passing the requested URL as a
query parameter.
- FilesMatch:
Denies access to sensitive files like .htaccess, .ini, .log, and .sh.
- Options
-Indexes: Disables directory listing for security.
- ErrorDocument:
Specifies a custom error page for 404 errors.
2. composer.json:
PHP dependencies list (if using
Composer).
{
"name": "yourname/inventory-management-system",
"description":
"A simple inventory management system built with PHP and MySQL.",
"require":
{
"php":
"^7.4 || ^8.0",
"vlucas/phpdotenv":
"^5.4",
"monolog/monolog":
"^2.0"
},
"autoload":
{
"psr-4":
{
"App\\":
"app/"
}
},
"require-dev":
{
"phpunit/phpunit":
"^9.5"
}
}
Explanation:
- name:
Defines the project name and namespace.
- description:
A brief description of the project.
- require:
Lists the required packages, such as PHP version and libraries.
- vlucas/phpdotenv:
For managing environment variables.
- monolog/monolog:
For logging.
- autoload:
Configures PSR-4 autoloading for classes in the app/ directory.
- require-dev:
Lists development dependencies, such as PHPUnit for testing.
3. README.md:
Project documentation.
# Inventory Management System
## Description
A simple inventory management system built with PHP and
MySQL. This application allows users to manage products, stock levels, orders,
and suppliers, with features for report generation.
## Features
- Product management (CRUD operations)
- Supplier management (CRUD operations)
- Order management (CRUD operations)
- Stock management
- Report generation for sales and stock
## Installation
1. Clone the repository:
```bash
git clone
https://github.com/yourname/inventory-management-system.git
- Navigate
to the project directory:
cd inventory-management-system
- Install
dependencies using Composer:
composer install
- Create
a .env file from the .env.example file and configure your database
settings.
- Run
the SQL scripts in the db/ directory to set up the database.
Usage
- Access
the application via your web server (e.g., Apache or Nginx).
- Navigate
to the appropriate URLs to manage products, orders, and suppliers.
License
This project is licensed under the MIT License. See the
LICENSE file for details.
### **Explanation**:
- **Description**: Overview of the project.
- **Features**: Lists the main features of the system.
- **Installation**: Step-by-step instructions for setting up
the project.
- **Usage**: Basic usage instructions for accessing the
application.
- **License**: References the project’s license.
---
### 4. **LICENSE**: The project’s license file.
#### **LICENSE**
```plaintext
MIT License
Copyright (c) [YEAR] [YOUR NAME]
Permission is hereby granted, free of charge, to any person
obtaining a copy
of this software and associated documentation files (the "Software"),
to deal
in the Software without restriction, including without
limitation the rights
to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is
furnished to do so, subject to the following conditions:
...
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE
SOFTWARE.
Explanation:
- MIT
License: A permissive license that allows users to freely use, modify,
and distribute the software.
- Copyright:
Replace [YEAR] with the current year and [YOUR NAME] with your name.
Conclusion:
These root directory files provide essential configuration and documentation for your Inventory Management System. The .htaccess file enhances security and manages URL routing, while composer.json specifies dependencies.