Skip to content
Merged

Omar #11

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Server/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require("dotenv").config();
const authService = require("../services/auth.service");

const cartService = require("../services/cart.service");
const authController = {

login: async (req, res) => {
Expand Down Expand Up @@ -34,13 +34,20 @@ const authController = {
// 1. Extract from the request
const { email, password, name, role } = req.body;


try {
// 2. Call the core service function
// 2. Create user first, then create a cart and attach it to avoid orphan carts
const newUser = await authService.registerUser(email, password, name, role);

// create a cart associated with this user
const userCart = await cartService.createCart(newUser.id);
// attach cart to user
const userService = require('../services/user.service');
await userService.setCartId(newUser.id, userCart._id);
const cartId = await userService.getCartId(newUser.id);

res.status(201).json({
message: 'User registered successfully',
user: newUser
user: { ...newUser, cart: cartId }
});

} catch (error) {
Expand Down
97 changes: 97 additions & 0 deletions Server/controllers/cart.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const cartService = require('../services/cart.service');
const userService = require('../services/user.service');

class CartController {

async createCart(req, res) {
try {
// if authenticated, attach cart to user
let customerId = req.user && req.user.id ? req.user.id : null;
const cart = await cartService.createCart(customerId);
// if created for an authenticated user, also persist cart id on user
if (customerId) {
await userService.setCartId(customerId, cart._id);
}
res.status(201).json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}

async getCart(req, res) {
try {
let cartId = req.params.cartId;
if (!cartId && req.user && req.user.id) {
cartId = await userService.getCartId(req.user.id);
}
if (!cartId) return res.status(400).json({ error: 'cartId is required' });
const cart = await cartService.getCart(cartId);
if (!cart) return res.status(404).json({ error: 'Cart not found' });
res.json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}

async addItem(req, res) {
try {
let cartId = req.params.cartId;
if (!cartId && req.user && req.user.id) {
cartId = await userService.getCartId(req.user.id);
}
if (!cartId) return res.status(400).json({ error: 'cartId is required' });
const item = req.body;
const cart = await cartService.addItem(cartId, item);
res.json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}

async removeItem(req, res) {
try {
let cartId = req.params.cartId;
if (!cartId && req.user && req.user.id) {
cartId = await userService.getCartId(req.user.id);
}
if (!cartId) return res.status(400).json({ error: 'cartId is required' });
const { menuItemId } = req.body;
const cart = await cartService.removeItem(cartId, menuItemId);
res.json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}

async updateItemQuantity(req, res) {
try {
let cartId = req.params.cartId;
if (!cartId && req.user && req.user.id) {
cartId = await userService.getCartId(req.user.id);
}
if (!cartId) return res.status(400).json({ error: 'cartId is required' });
const { menuItemId, quantity } = req.body;
const cart = await cartService.updateItemQuantity(cartId, menuItemId, quantity);
res.json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}

async emptyCart(req, res) {
try {
let cartId = req.params.cartId;
if (!cartId && req.user && req.user.id) {
cartId = await userService.getCartId(req.user.id);
}
if (!cartId) return res.status(400).json({ error: 'cartId is required' });
const cart = await cartService.emptyCart(cartId);
res.json(cart);
} catch (err) {
res.status(500).json({ error: err.message });
}
}
}

module.exports = new CartController();

172 changes: 172 additions & 0 deletions Server/controllers/order.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
const orderService = require('../services/order.service');
const cartService = require('../services/cart.service');
const userService = require('../services/user.service');
/**
* Create a new order
* POST /api/orders
*/
async function createOrder(req, res) {
try {
const { items: itemsFromBody, orderType, paymentStatus, customerNotes } = req.body;
const customerId = req.user.id;

// get customer name from user service
const currentUser = await userService.getCurrentUser(customerId);
const customerName = currentUser.name;

// if items aren't provided in the request, use the user's cart
let items = itemsFromBody;
let cartId;
if (!items || items.length === 0) {
cartId = await userService.getCartId(customerId);
if (!cartId) {
const error = new Error('No cart found for user');
error.code = 400;
throw error;
}
const cart = await cartService.getCart(cartId);
if (!cart || !cart.items || cart.items.length === 0) {
const error = new Error('Cart is empty');
error.code = 400;
throw error;
}
items = cart.items;
}

const order = await orderService.createOrder({
customerId,
customerName,
items,
orderType,
paymentStatus,
customerNotes
});

// empty the cart if we used it
try {
if (!cartId) cartId = await userService.getCartId(customerId);
if (cartId) await cartService.emptyCart(cartId);
} catch (err) {
console.error('Failed to empty cart after order:', err.message || err);
}

res.status(201).json({
success: true,
message: 'Order created successfully',
data: order
});
} catch (error) {
const statusCode = error.code || 500;
res.status(statusCode).json({
success: false,
message: error.message
});
}
}



/**
* Get order by ID
* GET /api/orders/:id
*/
async function getOrderById(req, res) {
try {
const { id } = req.params;
const order = await orderService.getOrderById(id);

res.status(200).json({
success: true,
data: order
});
} catch (error) {
const statusCode = error.code || 500;
res.status(statusCode).json({
success: false,
message: error.message
});
}
}

/**
* Get orders by customer ID
* GET /api/orders/customer/:customerId
*/
async function getOrdersByCustomerId(req, res) {
try {
const { customerId } = req.params;
const orders = await orderService.getOrdersByCustomerId(customerId);

res.status(200).json({
success: true,
data: orders
});
} catch (error) {
const statusCode = error.code || 500;
res.status(statusCode).json({
success: false,
message: error.message
});
}
}

/**
* Get all orders
* GET /api/orders
*/
async function getAllOrders(req, res) {
try {
const orders = await orderService.getAllOrders();

res.status(200).json({
success: true,
data: orders
});
} catch (error) {
const statusCode = error.code || 500;
res.status(statusCode).json({
success: false,
message: error.message
});
}
}

/**
* Update order status
* PUT /api/orders/:id/status
*/
async function updateOrderStatus(req, res) {
try {
const { id } = req.params;
const { status, paymentStatus } = req.body;

if (!status && !paymentStatus) {
return res.status(400).json({
success: false,
message: 'Status or PaymentStatus is required'
});
}

const order = await orderService.updateOrderStatus(id, status, paymentStatus);

res.status(200).json({
success: true,
message: 'Order status updated successfully',
data: order
});
} catch (error) {
const statusCode = error.code || 500;
res.status(statusCode).json({
success: false,
message: error.message
});
}
}

module.exports = {
createOrder,
getOrderById,
getOrdersByCustomerId,
getAllOrders,
updateOrderStatus
};
18 changes: 18 additions & 0 deletions Server/controllers/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ const userController = {
}
},

getCartId: async (req, res) => {
try {
const { id } = req.user;
const cartId = await userService.getCartId(id);

res.status(200).json({
status: 'success',
cartId
});
} catch (error) {
res.status(error.code || 500).json({
status: 'error',
message: error.message
});
}
},

updateUserProfile: async (req, res) => {
updateUserProfile: async (req, res) => { //can manager also do it?
try {
const {id} = req.user;
Expand Down
22 changes: 22 additions & 0 deletions Server/models/cart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const mongoose = require('mongoose');

const cartSchema = new mongoose.Schema({
customerId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: false,
index: true
},
items: {
type: [
{
menuItemId: { type: mongoose.Schema.Types.ObjectId, ref: 'MenuItem', required: true },
quantity: { type: Number, required: true, min: 1 }
}
],
default: []
},
totalPrice: { type: Number, default: 0 }
}, { timestamps: true });

module.exports = mongoose.model('Cart', cartSchema);
Loading