samoulla-backend / controllers /cartController.js
Samoulla Sync Bot
Auto-deploy Samoulla Backend: 2a08fc5a79dbc98f629756769f4164ea9c56ce1a
3ab344a
const Cart = require('../models/cartModel');
const Product = require('../models/productModel');
// add to cart function
exports.addToCart = async (req, res) => {
try {
const userId = req.user.id;
const { productId, quantity } = req.body;
const product = await Product.findById(productId);
if (!product) {
return res.status(404).json({ message: 'Product not found' });
}
let cart = await Cart.findOne({ user: userId });
if (!cart) {
cart = await Cart.create({
user: userId,
items: [{ product: productId, quantity }],
});
} else {
const existingItem = cart.items.find(
(item) => item.product.toString() === productId,
);
if (existingItem) {
existingItem.quantity += quantity;
} else {
cart.items.push({ product: productId, quantity });
}
await cart.save();
}
// Populate product details before returning
await cart.populate({
path: 'items.product',
select: 'nameAr nameEn price salePrice imageCover stock',
});
res.status(200).json({
status: 'success',
message: 'Product added to cart',
cart,
});
} catch (err) {
res
.status(500)
.json({ message: 'Failed to add product', error: err.message });
}
};
exports.getCart = async (req, res) => {
try {
const userId = req.user.id;
// Find the cart associated with the user
const cart = await Cart.findOne({ user: userId }).populate({
path: 'items.product',
select: 'nameAr nameEn price salePrice imageCover',
});
if (!cart || cart.items.length === 0) {
return res.status(200).json({
status: 'success',
message: 'Cart is empty',
cart: { items: [] },
});
}
// Calculate the total price
const totalPrice = cart.items.reduce((acc, item) => {
const price = item.product.salePrice || item.product.price;
return acc + price * item.quantity;
}, 0);
res.status(200).json({
status: 'success',
cart,
totalPrice,
});
} catch (err) {
res
.status(500)
.json({ message: 'Failed to fetch cart', error: err.message });
}
};
// PATCH /samoulla/v1/cart/update-quantity
exports.updateQuantity = async (req, res) => {
try {
const userId = req.user.id;
const { productId, action } = req.body;
const cart = await Cart.findOne({ user: userId }).populate({
path: 'items.product',
select: 'nameAr nameEn price salePrice imageCover',
});
if (!cart) {
return res.status(404).json({ message: 'Cart not found' });
}
const cartItem = cart.items.find(
(el) => el.product._id.toString() === productId,
);
if (!cartItem) {
return res.status(404).json({ message: 'Product not found in cart' });
}
if (action === 'increase') {
cartItem.quantity += 1;
} else if (action === 'decrease') {
cartItem.quantity -= 1;
if (cartItem.quantity <= 0) {
cart.items = cart.items.filter(
(el) => el.product._id.toString() !== productId,
);
}
} else {
return res.status(400).json({ message: 'Invalid action' });
}
await cart.save();
const totalPrice = cart.items.reduce((acc, item) => {
const price = item.product.salePrice || item.product.price;
return acc + price * item.quantity;
}, 0);
res.status(200).json({
status: 'success',
cart,
totalPrice,
});
} catch (err) {
res
.status(500)
.json({ message: 'Error updating quantity', error: err.message });
}
};
// PATCH /samoulla/v1/cart/update-quantity
// {
// "productId": "ID_OF_PRODUCT",
// "action": "increase"
// }
// {
// "productId": "ID_OF_PRODUCT",
// "action": "decrease"
// }
// DELETE /samoulla/v1/cart/remove-item
exports.removeFromCart = async (req, res) => {
try {
const userId = req.user.id;
const { productId } = req.params;
const cart = await Cart.findOne({ user: userId }).populate({
path: 'items.product',
select: 'nameAr nameEn price salePrice imageCover',
});
if (!cart) {
return res.status(404).json({ message: 'Cart not found' });
}
const itemExists = cart.items.find(
(el) => el.product._id.toString() === productId,
);
if (!itemExists) {
return res.status(404).json({ message: 'Product not found in cart' });
}
cart.items = cart.items.filter(
(el) => el.product._id.toString() !== productId,
);
await cart.save();
const totalPrice = cart.items.reduce((acc, item) => {
const price = item.product.salePrice || item.product.price;
return acc + price * item.quantity;
}, 0);
res.status(200).json({
status: 'success',
message: 'Product removed from cart',
cart,
totalPrice,
});
} catch (err) {
res
.status(500)
.json({ message: 'Error removing product', error: err.message });
}
};
exports.clearCart = async (req, res) => {
try {
const cart = await Cart.findOne({ user: req.user._id });
if (!cart) {
return res.status(404).json({ message: 'Cart not found' });
}
cart.items = [];
await cart.save();
res.status(200).json({
status: 'success',
message: 'Cart cleared successfully',
cart,
});
} catch (err) {
res
.status(500)
.json({ message: 'Something went wrong', error: err.message });
}
};
// GET /samoulla/v1/cart/all (Admin only)
exports.getAllCarts = async (req, res) => {
try {
// Find all carts that are not empty and belong to a user
const carts = await Cart.find({
user: { $exists: true, $ne: null },
items: { $exists: true, $not: { $size: 0 } },
})
.populate({
path: 'user',
select: 'name email phone',
})
.populate({
path: 'items.product',
select: 'nameAr nameEn price salePrice imageCover',
})
.sort('-updatedAt');
res.status(200).json({
status: 'success',
results: carts.length,
data: {
carts,
},
});
} catch (err) {
res.status(500).json({
status: 'error',
message: 'Failed to fetch carts',
error: err.message,
});
}
};
// DELETE /samoulla/v1/cart/:id (Admin only)
exports.deleteCart = async (req, res) => {
try {
const cart = await Cart.findByIdAndDelete(req.params.id);
if (!cart) {
return res.status(404).json({
status: 'fail',
message: 'No cart found with that ID',
});
}
res.status(204).json({
status: 'success',
data: null,
});
} catch (err) {
res.status(500).json({
status: 'error',
message: 'Failed to delete cart',
error: err.message,
});
}
};