Example input
[ programming language or framework ]: JavaScript (React, Node.js, and MongoDB)
[ specify features like stock tracking, supplier management, low-stock alerts, and reporting ]: stock tracking, supplier management, low-stock alerts, and reporting
Example output
Building an inventory management system using **JavaScript** (with **React** for the frontend, **Node.js** for the backend, and **MongoDB** for the database) will involve creating a full-stack application. Below is an outline of the core features, with key code components for each part. We’ll cover CRUD operations for inventory and suppliers, stock tracking with alerts, and reporting.
### Project Structure
1. **Backend (Node.js + Express + MongoDB)**:
- `/models`: Define data models (Inventory, Supplier, etc.)
- `/routes`: Set up API routes
- `/controllers`: Define the logic for handling inventory, supplier management, and reporting
- `/utils`: Utility functions (e.g., for sending alerts)
2. **Frontend (React)**:
- Components for managing items, suppliers, and viewing reports.
- Context/State management for real-time updates.
### Backend Code
#### 1. Setting Up Models (MongoDB Schemas)
In `/models/Inventory.js`:
```javascript
const mongoose = require('mongoose');
const inventorySchema = new mongoose.Schema({
name: { type: String, required: true },
category: { type: String, required: true },
stock: { type: Number, required: true },
supplier: { type: mongoose.Schema.Types.ObjectId, ref: 'Supplier' },
price: { type: Number, required: true },
lowStockAlert: { type: Boolean, default: false },
});
module.exports = mongoose.model('Inventory', inventorySchema);
```
In `/models/Supplier.js`:
```javascript
const mongoose = require('mongoose');
const supplierSchema = new mongoose.Schema({
name: { type: String, required: true },
contactInfo: {
phone: String,
email: String,
address: String,
},
productsSupplied: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Inventory' }]
});
module.exports = mongoose.model('Supplier', supplierSchema);
```
#### 2. API Endpoints and Controllers
In `/controllers/inventoryController.js`:
```javascript
const Inventory = require('../models/Inventory');
const Supplier = require('../models/Supplier');
// Add a new inventory item
exports.addInventoryItem = async (req, res) => {
try {
const item = new Inventory(req.body);
await item.save();
res.status(201).json(item);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update stock level and set low-stock alert if needed
exports.updateStock = async (req, res) => {
try {
const item = await Inventory.findById(req.params.id);
item.stock = req.body.stock;
item.lowStockAlert = item.stock < 5; // Alert if stock is low
await item.save();
res.status(200).json(item);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get inventory items with low stock
exports.getLowStockItems = async (req, res) => {
try {
const lowStockItems = await Inventory.find({ lowStockAlert: true });
res.status(200).json(lowStockItems);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Generate a report of inventory levels and sales performance
exports.generateReport = async (req, res) => {
try {
const report = await Inventory.aggregate([
{ $group: { _id: "$category", totalStock: { $sum: "$stock" } } }
]);
res.status(200).json(report);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
```
In `/routes/inventoryRoutes.js`:
```javascript
const express = require('express');
const inventoryController = require('../controllers/inventoryController');
const router = express.Router();
router.post('/add', inventoryController.addInventoryItem);
router.put('/update-stock/:id', inventoryController.updateStock);
router.get('/low-stock', inventoryController.getLowStockItems);
router.get('/report', inventoryController.generateReport);
module.exports = router;
```
#### 3. Alerts with Email Notifications
In `/utils/alerts.js`:
```javascript
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'your-email@gmail.com',
pass: 'your-password',
},
});
exports.sendLowStockAlert = async (itemName) => {
const mailOptions = {
from: 'your-email@gmail.com',
to: 'admin@example.com',
subject: `Low Stock Alert for ${itemName}`,
text: `${itemName} is low in stock. Please restock soon.`,
};
try {
await transporter.sendMail(mailOptions);
console.log(`Alert sent for ${itemName}`);
} catch (error) {
console.error(`Error sending alert: ${error.message}`);
}
};
```
#### 4. Integrate Alert in Inventory Controller
In `/controllers/inventoryController.js`:
Add a call to `sendLowStockAlert` in `updateStock`:
```javascript
const { sendLowStockAlert } = require('../utils/alerts');
exports.updateStock = async (req, res) => {
try {
const item = await Inventory.findById(req.params.id);
item.stock = req.body.stock;
item.lowStockAlert = item.stock < 5;
await item.save();
if (item.lowStockAlert) {
await sendLowStockAlert(item.name);
}
res.status(200).json(item);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
```
### Frontend Code (React)
#### 1. Inventory Management Component
In `src/components/Inventory.js`:
```javascript
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const Inventory = () => {
const [inventory, setInventory] = useState([]);
const [lowStock, setLowStock] = useState([]);
// Fetch all inventory items
useEffect(() => {
axios.get('/api/inventory')
.then(response => setInventory(response.data))
.catch(error => console.error(error));
}, []);
// Fetch low-stock items for alerts
useEffect(() => {
axios.get('/api/inventory/low-stock')
.then(response => setLowStock(response.data))
.catch(error => console.error(error));
}, [inventory]);
return (
<div>
<h2>Inventory Management</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
{inventory.map(item => (
<tr key={item._id}>
<td>{item.name}</td>
<td>{item.category}</td>
<td>{item.stock}</td>
</tr>
))}
</tbody>
</table>
<h2>Low Stock Alerts</h2>
{lowStock.length ? (
<ul>
{lowStock.map(item => <li key={item._id}>{item.name} is low on stock!</li>)}
</ul>
) : <p>All items are well-stocked.</p>}
</div>
);
};
export default Inventory;
```
### 2. Reporting Component
In `src/components/Report.js`:
```javascript
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const Report = () => {
const [report, setReport] = useState([]);
useEffect(() => {
axios.get('/api/inventory/report')
.then(response => setReport(response.data))
.catch(error => console.error(error));
}, []);
return (
<div>
<h2>Inventory Report</h2>
<table>
<thead>
<tr>
<th>Category</th>
<th>Total Stock</th>
</tr>
</thead>
<tbody>
{report.map((item, index) => (
<tr key={index}>
<td>{item._id}</td>
<td>{item.totalStock}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Report;
```
### Additional Steps
1. **Test API Endpoints** using Postman or another tool.
2. **Add Authentication** (optional but recommended).
3. **Deploy** the application (backend on a server or cloud service, frontend on platforms like Vercel or Netlify).