ajinkya-mhetre-mern
Version:
A MERN starter with frontend and backend folders
223 lines (183 loc) • 5.42 kB
JavaScript
// ===== src/controllers/customerController.js =====
const Product = require('../models/Product');
const Order = require('../models/Order');
const User = require('../models/User');
const getAllProducts = async (req, res) => {
try {
const { category, search, page = 1, limit = 12, sortBy = 'createdAt' } = req.query;
const query = { isActive: true, availableQuantity: { $gt: 0 } };
if (category) {
query.category = category;
}
if (search) {
query.$text = { $search: search };
}
const skip = (page - 1) * limit;
const products = await Product.find(query)
.populate('farmer', 'name farmDetails.farmName')
.sort({ [sortBy]: -1 })
.limit(limit * 1)
.skip(skip);
const total = await Product.countDocuments(query);
res.json({
success: true,
products,
pagination: {
page: parseInt(page),
pages: Math.ceil(total / limit),
total
}
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const getProduct = async (req, res) => {
try {
const { productId } = req.params;
const product = await Product.findById(productId)
.populate('farmer', 'name email phone farmDetails');
if (!product) {
return res.status(404).json({ message: 'Product not found' });
}
res.json({
success: true,
product
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const placeOrder = async (req, res) => {
try {
const { items, shippingAddress } = req.body;
let totalAmount = 0;
const orderItems = [];
// Validate and calculate order
for (const item of items) {
const product = await Product.findById(item.productId);
if (!product) {
return res.status(404).json({
message: `Product ${item.productId} not found`
});
}
if (product.availableQuantity < item.quantity) {
return res.status(400).json({
message: `Insufficient stock for ${product.name}. Available: ${product.availableQuantity}`
});
}
const itemTotal = product.price * item.quantity;
totalAmount += itemTotal;
orderItems.push({
product: product._id,
quantity: item.quantity,
price: product.price,
farmer: product.farmer
});
// Update product quantity
product.availableQuantity -= item.quantity;
await product.save();
}
const order = await Order.create({
customer: req.user._id,
items: orderItems,
totalAmount,
shippingAddress,
statusHistory: [{
status: 'placed',
timestamp: new Date(),
note: 'Order placed successfully'
}]
});
await order.populate([
{ path: 'customer', select: 'name email' },
{ path: 'items.product', select: 'name images' },
{ path: 'items.farmer', select: 'name' }
]);
res.status(201).json({
success: true,
message: 'Order placed successfully',
order
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const getMyOrders = async (req, res) => {
try {
const orders = await Order.find({ customer: req.user._id })
.populate('items.product', 'name images')
.populate('items.farmer', 'name')
.sort({ createdAt: -1 });
res.json({
success: true,
orders
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const getOrder = async (req, res) => {
try {
const { orderId } = req.params;
const order = await Order.findOne({
_id: orderId,
customer: req.user._id
})
.populate('items.product', 'name images')
.populate('items.farmer', 'name phone');
if (!order) {
return res.status(404).json({ message: 'Order not found' });
}
res.json({
success: true,
order
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const cancelOrder = async (req, res) => {
try {
const { orderId } = req.params;
const order = await Order.findOne({
_id: orderId,
customer: req.user._id
}).populate('items.product');
if (!order) {
return res.status(404).json({ message: 'Order not found' });
}
if (order.status !== 'placed') {
return res.status(400).json({
message: 'Order cannot be cancelled at this stage'
});
}
// Restore product quantities
for (const item of order.items) {
await Product.findByIdAndUpdate(item.product._id, {
$inc: { availableQuantity: item.quantity }
});
}
order.status = 'cancelled';
order.statusHistory.push({
status: 'cancelled',
timestamp: new Date(),
note: 'Order cancelled by customer'
});
await order.save();
res.json({
success: true,
message: 'Order cancelled successfully'
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = {
getAllProducts,
getProduct,
placeOrder,
getMyOrders,
getOrder,
cancelOrder
};