Files
Guitar-Ecommerce/server/controllers/cartController.js
2026-09-16 17:36:46 +05:30

151 lines
4.4 KiB
JavaScript

const Cart = require('../models/Cart');
const Product = require('../models/Product');
const Coupon = require('../models/Coupon');
const { successResponse, errorResponse } = require('../utils/apiResponse');
const getCart = async (req, res, next) => {
try {
const userId = req.user ? req.user._id : null;
const sessionId = req.headers['x-session-id'] || null;
let cart = null;
if (userId) {
cart = await Cart.findOne({ user: userId }).populate('items.product');
} else if (sessionId) {
cart = await Cart.findOne({ sessionId }).populate('items.product');
}
if (!cart) {
cart = { items: [], couponCode: '', discountAmount: 0 };
}
return successResponse(res, 'Cart retrieved', cart);
} catch (error) {
next(error);
}
};
const addToCart = async (req, res, next) => {
try {
const { productId, quantity = 1, variantColor = '', variantFinish = '' } = req.body;
const userId = req.user ? req.user._id : null;
const sessionId = req.headers['x-session-id'] || 'guest-' + Date.now();
const product = await Product.findById(productId);
if (!product) {
return errorResponse(res, 'Product not found', [], 404);
}
// Inventory check
if (product.stock < quantity) {
return errorResponse(res, `Only ${product.stock} items remaining in stock`, [], 400);
}
let cart;
if (userId) {
cart = await Cart.findOne({ user: userId });
} else {
cart = await Cart.findOne({ sessionId });
}
const price = product.salePrice > 0 ? product.salePrice : product.price;
if (!cart) {
cart = new Cart({
user: userId,
sessionId,
items: [{ product: productId, quantity, variantColor, variantFinish, price }]
});
} else {
const existingItemIndex = cart.items.findIndex(
item => item.product.toString() === productId && item.variantColor === variantColor
);
if (existingItemIndex > -1) {
cart.items[existingItemIndex].quantity += Number(quantity);
} else {
cart.items.push({ product: productId, quantity, variantColor, variantFinish, price });
}
}
await cart.save();
const updatedCart = await Cart.findById(cart._id).populate('items.product');
return successResponse(res, 'Product added to cart', updatedCart);
} catch (error) {
next(error);
}
};
const updateCartItem = async (req, res, next) => {
try {
const { itemId, quantity } = req.body;
const userId = req.user ? req.user._id : null;
const sessionId = req.headers['x-session-id'];
const cart = userId
? await Cart.findOne({ user: userId })
: await Cart.findOne({ sessionId });
if (!cart) return errorResponse(res, 'Cart not found', [], 404);
const item = cart.items.id(itemId);
if (!item) return errorResponse(res, 'Item not found in cart', [], 404);
if (quantity <= 0) {
cart.items.pull(itemId);
} else {
item.quantity = quantity;
}
await cart.save();
const updatedCart = await Cart.findById(cart._id).populate('items.product');
return successResponse(res, 'Cart updated', updatedCart);
} catch (error) {
next(error);
}
};
const removeCartItem = async (req, res, next) => {
try {
const userId = req.user ? req.user._id : null;
const sessionId = req.headers['x-session-id'];
const cart = userId
? await Cart.findOne({ user: userId })
: await Cart.findOne({ sessionId });
if (cart) {
cart.items = cart.items.filter(item => item._id.toString() !== req.params.itemId);
await cart.save();
}
const updatedCart = cart ? await Cart.findById(cart._id).populate('items.product') : { items: [] };
return successResponse(res, 'Item removed from cart', updatedCart);
} catch (error) {
next(error);
}
};
const applyCoupon = async (req, res, next) => {
try {
const { code } = req.body;
const coupon = await Coupon.findOne({ code: code.toUpperCase(), isActive: true });
if (!coupon || coupon.endDate < new Date()) {
return errorResponse(res, 'Invalid or expired coupon code', [], 400);
}
return successResponse(res, 'Coupon applied successfully', {
code: coupon.code,
discountType: coupon.discountType,
discountValue: coupon.discountValue,
minPurchaseAmount: coupon.minPurchaseAmount
});
} catch (error) {
next(error);
}
};
module.exports = { getCart, addToCart, updateCartItem, removeCartItem, applyCoupon };