241 lines
5.9 KiB
JavaScript
241 lines
5.9 KiB
JavaScript
const Cart = require('../models/cartModel');
|
|
const Product = require('../models/productModel');
|
|
|
|
// @desc Get user cart
|
|
// @route GET /api/cart
|
|
// @access Private
|
|
exports.getCart = async (req, res) => {
|
|
try {
|
|
let cart = await Cart.findOne({ user: req.user.id }).populate('items.product');
|
|
|
|
if (!cart) {
|
|
cart = new Cart({ user: req.user.id, items: [] });
|
|
await cart.save();
|
|
}
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Add item to cart
|
|
// @route POST /api/cart/add
|
|
// @access Private
|
|
exports.addToCart = async (req, res) => {
|
|
try {
|
|
const { productId, quantity } = req.body;
|
|
|
|
if (!productId || !quantity) {
|
|
return res.status(400).json({ message: 'Product ID and quantity are required' });
|
|
}
|
|
|
|
// Get product
|
|
const product = await Product.findById(productId);
|
|
if (!product) {
|
|
return res.status(404).json({ message: 'Product not found' });
|
|
}
|
|
|
|
// Check stock
|
|
if (product.stock < quantity) {
|
|
return res.status(400).json({ message: 'Insufficient stock' });
|
|
}
|
|
|
|
// Get or create cart
|
|
let cart = await Cart.findOne({ user: req.user.id });
|
|
if (!cart) {
|
|
cart = new Cart({ user: req.user.id, items: [] });
|
|
}
|
|
|
|
// Use product's sale price if available, otherwise regular price
|
|
const price = product.salePrice || product.price;
|
|
|
|
// Add item to cart
|
|
cart.addItem(productId, quantity, price);
|
|
|
|
// Save cart
|
|
await cart.save();
|
|
await cart.populate('items.product');
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Item added to cart',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Update cart item quantity
|
|
// @route PUT /api/cart/update
|
|
// @access Private
|
|
exports.updateCart = async (req, res) => {
|
|
try {
|
|
const { productId, quantity } = req.body;
|
|
|
|
if (!productId || quantity === undefined) {
|
|
return res.status(400).json({ message: 'Product ID and quantity are required' });
|
|
}
|
|
|
|
// Get cart
|
|
const cart = await Cart.findOne({ user: req.user.id });
|
|
if (!cart) {
|
|
return res.status(404).json({ message: 'Cart not found' });
|
|
}
|
|
|
|
// Check if quantity is valid
|
|
if (quantity < 0) {
|
|
return res.status(400).json({ message: 'Quantity must be greater than 0' });
|
|
}
|
|
|
|
// Get product to check stock
|
|
const product = await Product.findById(productId);
|
|
if (!product) {
|
|
return res.status(404).json({ message: 'Product not found' });
|
|
}
|
|
|
|
if (quantity > 0 && product.stock < quantity) {
|
|
return res.status(400).json({ message: 'Insufficient stock' });
|
|
}
|
|
|
|
// Update quantity
|
|
cart.updateItemQuantity(productId, quantity);
|
|
|
|
// Save cart
|
|
await cart.save();
|
|
await cart.populate('items.product');
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Cart updated',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Remove item from cart
|
|
// @route DELETE /api/cart/remove/:productId
|
|
// @access Private
|
|
exports.removeFromCart = async (req, res) => {
|
|
try {
|
|
const { productId } = req.params;
|
|
|
|
if (!productId) {
|
|
return res.status(400).json({ message: 'Product ID is required' });
|
|
}
|
|
|
|
// Get cart
|
|
const cart = await Cart.findOne({ user: req.user.id });
|
|
if (!cart) {
|
|
return res.status(404).json({ message: 'Cart not found' });
|
|
}
|
|
|
|
// Remove item
|
|
cart.removeItem(productId);
|
|
|
|
// Save cart
|
|
await cart.save();
|
|
await cart.populate('items.product');
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Item removed from cart',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Clear cart
|
|
// @route DELETE /api/cart/clear
|
|
// @access Private
|
|
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.clearCart();
|
|
await cart.save();
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Cart cleared',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Apply discount code
|
|
// @route POST /api/cart/discount
|
|
// @access Private
|
|
exports.applyDiscount = async (req, res) => {
|
|
try {
|
|
const { discountCode, discountAmount } = req.body;
|
|
|
|
if (!discountCode || discountAmount === undefined) {
|
|
return res.status(400).json({ message: 'Discount code and amount are required' });
|
|
}
|
|
|
|
const cart = await Cart.findOne({ user: req.user.id });
|
|
if (!cart) {
|
|
return res.status(404).json({ message: 'Cart not found' });
|
|
}
|
|
|
|
cart.discountCode = discountCode;
|
|
cart.discountAmount = discountAmount;
|
|
cart.calculateTotals();
|
|
|
|
await cart.save();
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Discount applied',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Apply shipping cost
|
|
// @route POST /api/cart/shipping
|
|
// @access Private
|
|
exports.applyShipping = async (req, res) => {
|
|
try {
|
|
const { shippingCost } = req.body;
|
|
|
|
if (shippingCost === undefined) {
|
|
return res.status(400).json({ message: 'Shipping cost is required' });
|
|
}
|
|
|
|
const cart = await Cart.findOne({ user: req.user.id });
|
|
if (!cart) {
|
|
return res.status(404).json({ message: 'Cart not found' });
|
|
}
|
|
|
|
cart.shippingCost = shippingCost;
|
|
cart.calculateTotals();
|
|
|
|
await cart.save();
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
message: 'Shipping cost applied',
|
|
cart,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
};
|