39647-vm/backend/controllers/cartController.js
2026-04-08 14:28:58 +04:00

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 });
}
};