151 lines
4.4 KiB
JavaScript
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 };
|
|
|