Skip to content

Commit

Permalink
feat: food recommendation (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aditya062003 authored Apr 3, 2024
1 parent 8af363c commit c143323
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 1 deletion.
69 changes: 69 additions & 0 deletions controllers/userOrderControl.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Order = require("../models/orderModel");
const Vendor = require("../models/vendor.model.js");
const axios = require("axios");
const MenuItem = require("../models/menuItem.model.js");
const { EventEmitter } = require("events");

const eventEmitter = new EventEmitter();
Expand Down Expand Up @@ -94,6 +95,74 @@ exports.getOrderHistory = async (req, res, next) => {
}
};

exports.getRecommendation = async (req, res, next) => {
try {
const userID = req.params.user_id;
let orders = await Order.find({ user_id: userID })
.sort({ createdAt: -1 })
.limit(5); // Get the last 5 orders
let recommendedItems = [];

// Fetch recommendations for default items
const defaultItems = ["Samosa", "Pav Bhaji"];
for (let itemName of defaultItems) {
let foodItemTitleCase = toTitleCase(itemName);
try {
const response = await axios.get(
`https://food-recommendation-yqpc.onrender.com/recommend/${foodItemTitleCase}`
);
console.log(response);
const recommendedRecipes = response.data.recommended_recipes;

// Check if recommended items exist in the database
for (let recipe of recommendedRecipes) {
const dbItem = await MenuItem.findOne({ name: recipe });
if (dbItem) {
recommendedItems.push(dbItem);
}
}
} catch (e) {
console.log(e);
}
}

// Process orders for additional recommendations
for (let order of orders) {
const item = order.items[0]; // Assuming you want the first item of each order
const itemName = item.name;
let foodItemTitleCase = toTitleCase(itemName); // Convert the food item name to Title Case

// Make API call to get recommendations
try {
const response = await axios.get(
`https://food-recommendation-yqpc.onrender.com/recommend/${foodItemTitleCase}`
);
const recommendedRecipes = response.data.recommended_recipes;

// Check if recommended items exist in the database
for (let recipe of recommendedRecipes) {
const dbItem = await MenuItem.findOne({ name: recipe });
if (dbItem) {
recommendedItems.push(dbItem);
}
}
} catch (e) {
console.log(e);
}
}

res.json({ recommendedItems });
} catch (error) {
next(error);
}
};

function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}

exports.getOrderbyId = async (req, res, next) => {
try {
const order = await Order.findOne({ order_id: req.query.order_id });
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ app.use((err, req, res, next) => {
const server = http.createServer(app);
// let server;
if (NODE_ENV != "test") {
server.listen(PORT, () => {
server.listen(8000, () => {
console.log(PORT);
console.log(`Server is running on port ${PORT}`);
});
Expand Down
69 changes: 69 additions & 0 deletions models/menuItem.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const { json } = require("express");
const mongoose = require("mongoose");

// TODO : Apply check on rating cant be changed by restaurant

const MenuItemSchema = mongoose.Schema({
item_id: {
type: String,
unique: true,
required: true,
},
name: {
type: String,
required: [true, "Please enter a valid name"],
},
is_veg: {
type: Boolean,
},
image_url: {
type: String,
required: [true, "Provide url for menu item image"],
},
price: {
type: Number,
required: [true, "Please enter a price"],
},
description: {
type: String,
},
quantity: {
type: Number,
required: [true, "Please enter a quantity"],
},
vendor_id: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Vendor",
},
rating: {
type: Number,
},
number_of_ratings: {
type: Number,
},
tags: {
type: [String],
},
category: {
type: String,
},
is_available: {
type: Boolean,
default: true,
},
nutritional_values: {
type: String,
},
is_healthy: {
type: Boolean,
},
on_offer: {
type: Boolean,
},
offer_price: {
type: Number,
},
});

module.exports = mongoose.model("MenuItem", MenuItemSchema);
3 changes: 3 additions & 0 deletions routes/orderRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const {
getOrderHistory,
getOrderbyId,
listenForNewOrders,
getRecommendation,
} = require("../controllers/userOrderControl");

const {
Expand Down Expand Up @@ -42,6 +43,8 @@ router.get("/order", getOrderbyId);

router.get("/events/:vendorId", listenForNewOrders);

router.get("/user/recommend/:user_id", checkAuth, getRecommendation);

router.get(
"/delivery_boy/orders/:delivery_boy_id",
checkDeliveryPartner,
Expand Down

0 comments on commit c143323

Please sign in to comment.