Skip to content

Commit

Permalink
Add analytics APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
haseebzaki-07 committed Nov 9, 2024
1 parent c0d93a4 commit 3502fbe
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 0 deletions.
84 changes: 84 additions & 0 deletions backend/controllers/rent/AnalyticsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const Analytics = require("../../model/rent/Analytics");
const mongoose = require("mongoose");
exports.productPerformace = async (req, res) => {
try {
const { productId } = req.params;
const productPerformance = await Analytics.aggregate([
{ $match: { productId: mongoose.Types.ObjectId(productId) } },
{
$group: {
_id: '$productId',
totalRentals: { $sum: 1 },
averageRating: { $avg: '$rating' },
totalRevenue: { $sum: '$revenue' },
},
},
]);
res.status(200).json(productPerformance[0] || {});
} catch (error) {
res.status(500).json({ error: error.message });
}
}

exports.rentalInsights = async (req, res) => {
try {
const { userId } = req.params;
const userInsights = await Analytics.aggregate([
{ $match: { userId: mongoose.Types.ObjectId(userId) } },
{
$group: {
_id: '$userId',
totalRentals: { $sum: 1 },
totalSpent: { $sum: '$revenue' },
averageRating: { $avg: '$rating' },
},
},
]);
res.status(200).json(userInsights[0] || {});
} catch (error) {
res.status(500).json({ error: error.message });
}
}

exports.rentalStats = async (req, res) => {
try {
const rentalTrends = await Analytics.aggregate([
{
$group: {
_id: {
year: { $year: "$rentalDate" },
month: { $month: "$rentalDate" }
},
totalRentals: { $sum: 1 },
totalRevenue: { $sum: '$revenue' },
}
},
{ $sort: { "_id.year": 1, "_id.month": 1 } }
]);
res.status(200).json(rentalTrends);
} catch (error) {
res.status(500).json({ error: error.message });
}
}


exports.topCustomers = async (req, res) => {
try {
const topCustomers = await Analytics.aggregate([
{
$group: {
_id: '$userId',
totalRentals: { $sum: 1 },
totalRevenue: { $sum: '$revenue' },
}
},
{ $sort: { totalRevenue: -1 } },
{ $limit: 5 },
]);
res.status(200).json(topCustomers);
} catch (error) {
res.status(500).json({ error: error.message });
}
}


2 changes: 2 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const rentCartRoutes = require('./routes/rent/rentCartRoutes');
const rentalRoutes = require('./routes/rent/rentalRoutes');
const adminOrderRoutes = require('./routes/rent/adminOrderRoutes');
const adminUserControlRoutes = require('./routes/rent/adminUserControlRoutes');
const analyticsRoutes = require('./routes/rent/analyticsRoutes');

const ratingRoutes = require('./routes/rent/ratingRoutes');

Expand Down Expand Up @@ -57,6 +58,7 @@ app.use('/api', rentCartRoutes);
app.use('/api', rentalRoutes);
app.use('/api', adminOrderRoutes);
app.use('/api/admin', adminUserControlRoutes);
app.use('/api', analyticsRoutes);

app.use('/api', ratingRoutes);

Expand Down
18 changes: 18 additions & 0 deletions backend/model/rent/analytics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mongoose = require('mongoose');

// Define schema for tracking rental analytics
const analyticsSchema = new mongoose.Schema({
productId: { type: mongoose.Schema.Types.ObjectId, ref: 'RentProduct' },
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
rentalDate: { type: Date, default: Date.now },
returnDate: { type: Date },
rentalDuration: { type: String },
status: {
type: String,
enum: ['ongoing', 'returned', 'cancelled', 'approved', 'rejected'],
},
rating: { type: Number, min: 0, max: 5 },
revenue: { type: Number, default: 0 },
}, { timestamps: true });

module.exports = mongoose.model('Analytics', analyticsSchema);
50 changes: 50 additions & 0 deletions backend/routes/rent/analyticsRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const express = require('express');
const router = express.Router();
const Analytics = require('../../model/rent/Analytics');
const RentProduct = require('../../model/rent/rentProduct');
const { productPerformace, rentalInsights, rentalStats, topCustomers } = require('../../controllers/rent/AnalyticsController');


// Calculate total rentals, revenue, and rating for a product
router.get('/product-performance/:productId', productPerformace );

// Fetch rental insights by user
router.get('/user-insights/:userId', rentalInsights);

// Fetch rental statistics over time (e.g., weekly, monthly)
router.get('/rental-trends', rentalStats );

// Aggregate customer insights (top customers, most rentals, etc.)
router.get('/top-customers', topCustomers);

// Function to log analytics on rental creation or update
async function logRentalAnalytics(rental) {
try {
// Fetch the product to get rental price
const product = await RentProduct.findById(rental.product);
if (!product) {
throw new Error("Product not found for rental analytics logging");
}

// Calculate revenue based on rental quantity and price
const revenue = rental.quantity * product.rentalPricePerDay;

// Create analytics record
await Analytics.create({
productId: rental.product,
userId: rental.userId,
rentalDate: rental.rentalDate,
returnDate: rental.returnDate,
rentalDuration: rental.rentalDuration,
status: rental.status,
rating: rental.rating || null,
revenue: revenue,
});
console.log("Rental analytics logged successfully");

} catch (error) {
console.error("Failed to log rental analytics:", error);
}
}

module.exports = router;

0 comments on commit 3502fbe

Please sign in to comment.