first commit
This commit is contained in:
822
src/controllers/orderController.js
Normal file
822
src/controllers/orderController.js
Normal file
@@ -0,0 +1,822 @@
|
||||
const { prisma } = require('../config/database');
|
||||
const Product = require('../models/mongodb/Product');
|
||||
const {
|
||||
RETURN_WINDOW_DAYS,
|
||||
ALLOWED_STATUSES,
|
||||
} = require('../config/returnPolicy');
|
||||
const {
|
||||
calculateDeliveryDate,
|
||||
} = require('../services/deliveryEstimationService');
|
||||
const { reduceStockOnDelivery } = require('../services/inventoryService');
|
||||
|
||||
// @desc Create new order
|
||||
// @route POST /api/orders
|
||||
// @access Private
|
||||
exports.createOrder = async (req, res, next) => {
|
||||
try {
|
||||
const { items, shippingAddressId, paymentMethod, couponCode } = req.body;
|
||||
const userId = req.user.id;
|
||||
console.log('=================================');
|
||||
console.log('🎟️ COUPON DEBUG');
|
||||
console.log('Received couponCode:', req.body.couponCode);
|
||||
console.log('Full body:', req.body);
|
||||
console.log('=================================');
|
||||
console.log('📦 Creating order for user:', userId);
|
||||
console.log('🎟️ Coupon code:', couponCode);
|
||||
|
||||
// Validate items
|
||||
if (!items || items.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'No items in the order',
|
||||
});
|
||||
}
|
||||
|
||||
// Validate shipping address
|
||||
const address = await prisma.address.findUnique({
|
||||
where: { id: shippingAddressId },
|
||||
});
|
||||
const deliveryEstimation = calculateDeliveryDate(
|
||||
address.postalCode,
|
||||
new Date(),
|
||||
'STANDARD'
|
||||
);
|
||||
|
||||
console.log(
|
||||
'📅 Estimated delivery:',
|
||||
deliveryEstimation.estimatedDelivery.formatted
|
||||
);
|
||||
|
||||
if (!address || address.userId !== userId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Invalid shipping address',
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch product details from MongoDB
|
||||
const productIds = items.map(item => item.productId);
|
||||
const products = await Product.find({ _id: { $in: productIds } });
|
||||
|
||||
if (products.length !== productIds.length) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Some products not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate totals
|
||||
let subtotal = 0;
|
||||
const orderItems = [];
|
||||
|
||||
for (const item of items) {
|
||||
const product = products.find(p => p._id.toString() === item.productId);
|
||||
|
||||
if (!product) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `Product ${item.productId} not found`,
|
||||
});
|
||||
}
|
||||
|
||||
let price = product.basePrice;
|
||||
let sku = product.slug;
|
||||
|
||||
if (product.hasVariants && product.variants?.length > 0) {
|
||||
const variant = product.variants.find(v => v.sku === item.sku);
|
||||
if (variant) {
|
||||
price = variant.price;
|
||||
sku = variant.sku;
|
||||
}
|
||||
}
|
||||
|
||||
const itemTotal = price * item.quantity;
|
||||
subtotal += itemTotal;
|
||||
|
||||
orderItems.push({
|
||||
productId: item.productId,
|
||||
productName: product.name,
|
||||
productSku: sku,
|
||||
price: price,
|
||||
quantity: item.quantity,
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate tax and shipping
|
||||
const taxRate = 0.18; // 18% GST
|
||||
const taxAmount = subtotal * taxRate;
|
||||
let shippingAmount = subtotal > 500 ? 0 : 50; // Free shipping above ₹500
|
||||
let discountAmount = 0;
|
||||
let appliedCoupon = null;
|
||||
|
||||
// ==========================================
|
||||
// VALIDATE AND APPLY COUPON
|
||||
// ==========================================
|
||||
if (couponCode) {
|
||||
console.log('🎟️ Validating coupon:', couponCode);
|
||||
|
||||
const coupon = await prisma.coupon.findUnique({
|
||||
where: { code: couponCode.toUpperCase() },
|
||||
});
|
||||
|
||||
if (coupon) {
|
||||
// Validate coupon
|
||||
const now = new Date();
|
||||
let couponError = null;
|
||||
|
||||
if (!coupon.isActive) {
|
||||
couponError = 'Coupon is not active';
|
||||
} else if (now < new Date(coupon.validFrom)) {
|
||||
couponError = 'Coupon is not yet valid';
|
||||
} else if (now > new Date(coupon.validUntil)) {
|
||||
couponError = 'Coupon has expired';
|
||||
} else if (coupon.maxUses && coupon.usedCount >= coupon.maxUses) {
|
||||
couponError = 'Coupon usage limit reached';
|
||||
} else if (
|
||||
coupon.minOrderAmount &&
|
||||
subtotal < parseFloat(coupon.minOrderAmount)
|
||||
) {
|
||||
couponError = `Minimum order amount of ₹${coupon.minOrderAmount} required`;
|
||||
}
|
||||
|
||||
if (couponError) {
|
||||
console.log('❌ Coupon validation failed:', couponError);
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: couponError,
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate discount
|
||||
if (coupon.type === 'PERCENTAGE') {
|
||||
discountAmount = (subtotal * parseFloat(coupon.value)) / 100;
|
||||
} else if (coupon.type === 'FIXED_AMOUNT') {
|
||||
discountAmount = Math.min(parseFloat(coupon.value), subtotal);
|
||||
} else if (coupon.type === 'FREE_SHIPPING') {
|
||||
discountAmount = shippingAmount;
|
||||
shippingAmount = 0;
|
||||
}
|
||||
|
||||
appliedCoupon = coupon;
|
||||
console.log('✅ Coupon applied:', {
|
||||
code: coupon.code,
|
||||
type: coupon.type,
|
||||
discount: discountAmount,
|
||||
});
|
||||
} else {
|
||||
console.log('❌ Coupon not found');
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Invalid coupon code',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate final total
|
||||
const totalAmount = subtotal + taxAmount + shippingAmount - discountAmount;
|
||||
|
||||
// Generate unique order number
|
||||
const orderNumber = `ORD${Date.now()}${Math.floor(Math.random() * 1000)}`;
|
||||
|
||||
// ==========================================
|
||||
// CREATE ORDER IN TRANSACTION
|
||||
// ==========================================
|
||||
const result = await prisma.$transaction(async tx => {
|
||||
// Create order
|
||||
const order = await tx.order.create({
|
||||
data: {
|
||||
orderNumber,
|
||||
userId,
|
||||
status: 'PENDING',
|
||||
subtotal,
|
||||
taxAmount,
|
||||
shippingAmount,
|
||||
discountAmount,
|
||||
totalAmount,
|
||||
paymentStatus: 'PENDING',
|
||||
paymentMethod: paymentMethod || 'PAYTM',
|
||||
shippingAddressId,
|
||||
items: {
|
||||
create: orderItems,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
items: true,
|
||||
address: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
phone: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// ✅ INCREMENT COUPON USAGE COUNT
|
||||
if (appliedCoupon) {
|
||||
await tx.coupon.update({
|
||||
where: { id: appliedCoupon.id },
|
||||
data: {
|
||||
usedCount: {
|
||||
increment: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log('✅ Coupon usage incremented:', {
|
||||
code: appliedCoupon.code,
|
||||
previousCount: appliedCoupon.usedCount,
|
||||
newCount: appliedCoupon.usedCount + 1,
|
||||
});
|
||||
}
|
||||
|
||||
return order;
|
||||
});
|
||||
|
||||
console.log('✅ Order created:', result.id);
|
||||
|
||||
// Clear user's cart after order creation
|
||||
await prisma.cartItem.deleteMany({
|
||||
where: { userId },
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Order created successfully',
|
||||
order: result,
|
||||
appliedCoupon: appliedCoupon
|
||||
? {
|
||||
code: appliedCoupon.code,
|
||||
discount: discountAmount,
|
||||
}
|
||||
: null,
|
||||
deliveryEstimation,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Create order error:', error);
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get user orders
|
||||
exports.getUserOrders = async (req, res, next) => {
|
||||
try {
|
||||
const { page = 1, limit = 10, status } = req.query;
|
||||
const skip = (page - 1) * limit;
|
||||
const where = { userId: req.user.id };
|
||||
if (status) where.status = status;
|
||||
|
||||
const [orders, total] = await Promise.all([
|
||||
prisma.order.findMany({
|
||||
where,
|
||||
include: { items: true, address: true },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: parseInt(skip),
|
||||
take: parseInt(limit),
|
||||
}),
|
||||
prisma.order.count({ where }),
|
||||
]);
|
||||
|
||||
// res.json({
|
||||
// success: true,
|
||||
// data: {
|
||||
// orders,
|
||||
// pagination: {
|
||||
// page: parseInt(page),
|
||||
// limit: parseInt(limit),
|
||||
// total,
|
||||
// pages: Math.ceil(total / limit),
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
return res.status(200).json({
|
||||
statusCode: 200,
|
||||
status: true,
|
||||
message: 'Orders fetched successfully',
|
||||
data: {
|
||||
orders,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total,
|
||||
pages: Math.ceil(total / limit),
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get single order
|
||||
exports.getOrderById = async (req, res, next) => {
|
||||
try {
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id: req.params.id, userId: req.user.id },
|
||||
include: { items: true, address: true },
|
||||
});
|
||||
|
||||
if (!order) {
|
||||
return res.status(404).json({
|
||||
// statusCode: 404,
|
||||
status: false,
|
||||
message: 'Order not found',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
// 2️⃣ Collect productIds
|
||||
const productIds = order.items.map(item => item.productId);
|
||||
|
||||
// 3️⃣ Fetch products from MongoDB
|
||||
const products = await Product.find({
|
||||
_id: { $in: productIds },
|
||||
}).select('name images');
|
||||
|
||||
// 4️⃣ Convert products array to map for quick lookup
|
||||
const productMap = {};
|
||||
products.forEach(product => {
|
||||
productMap[product._id.toString()] = product;
|
||||
});
|
||||
|
||||
// 5️⃣ Attach product image to each order item
|
||||
const updatedItems = order.items.map(item => {
|
||||
const product = productMap[item.productId];
|
||||
|
||||
return {
|
||||
...item,
|
||||
productImage: product?.images?.primary || null,
|
||||
productGallery: product?.images?.gallery || [],
|
||||
};
|
||||
});
|
||||
|
||||
order.items = updatedItems;
|
||||
|
||||
// res.json({ success: true, data: { order } });
|
||||
return res.status(200).json({
|
||||
statusCode: 200,
|
||||
status: true,
|
||||
message: 'Order fetched successfully',
|
||||
data: { order },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Update order status (Admin)
|
||||
exports.updateOrderStatus = async (req, res, next) => {
|
||||
try {
|
||||
const { status, trackingNumber } = req.body;
|
||||
// if (!status)
|
||||
// return res
|
||||
// .status(400)
|
||||
// .json({ success: false, message: 'Status is required' });
|
||||
|
||||
if (!status) {
|
||||
return res.status(400).json({
|
||||
statusCode: 400,
|
||||
status: false,
|
||||
message: 'Status is required',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
const order = await prisma.order.findUnique({
|
||||
where: { id: req.params.id },
|
||||
});
|
||||
// if (!order)
|
||||
// return res
|
||||
// .status(404)
|
||||
// .json({ success: false, message: 'Order not found' });
|
||||
|
||||
if (!order) {
|
||||
return res.status(404).json({
|
||||
statusCode: 404,
|
||||
status: false,
|
||||
message: 'Order not found',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
const updateData = { status };
|
||||
if (trackingNumber) updateData.trackingNumber = trackingNumber;
|
||||
if (status === 'SHIPPED') updateData.shippedAt = new Date();
|
||||
if (status === 'DELIVERED') updateData.deliveredAt = new Date();
|
||||
|
||||
const updatedOrder = await prisma.order.update({
|
||||
where: { id: req.params.id },
|
||||
data: updateData,
|
||||
include: { items: true, address: true },
|
||||
});
|
||||
|
||||
// res.json({
|
||||
// success: true,
|
||||
// message: 'Order status updated',
|
||||
// data: { order: updatedOrder },
|
||||
// });
|
||||
return res.status(200).json({
|
||||
statusCode: 200,
|
||||
status: true,
|
||||
message: 'Order status updated successfully',
|
||||
data: { order: updatedOrder },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Cancel order
|
||||
exports.cancelOrder = async (req, res, next) => {
|
||||
try {
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id: req.params.id, userId: req.user.id },
|
||||
});
|
||||
|
||||
// if (!order)
|
||||
// return res
|
||||
// .status(404)
|
||||
// .json({ success: false, message: 'Order not found' });
|
||||
if (!order) {
|
||||
return res.status(404).json({
|
||||
statusCode: 404,
|
||||
status: false,
|
||||
message: 'Order not found',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
// if (!['PENDING', 'CONFIRMED'].includes(order.status))
|
||||
// return res
|
||||
// .status(400)
|
||||
// .json({ success: false, message: 'Order cannot be cancelled' });
|
||||
|
||||
if (!['PENDING', 'CONFIRMED'].includes(order.status)) {
|
||||
return res.status(400).json({
|
||||
statusCode: 400,
|
||||
status: false,
|
||||
message: 'Order cannot be cancelled',
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
const updatedOrder = await prisma.order.update({
|
||||
where: { id: req.params.id },
|
||||
data: { status: 'CANCELLED' },
|
||||
include: { items: true, address: true },
|
||||
});
|
||||
|
||||
// res.json({
|
||||
// success: true,
|
||||
// message: 'Order cancelled',
|
||||
// data: { order: updatedOrder },
|
||||
// });
|
||||
return res.status(200).json({
|
||||
statusCode: 200,
|
||||
status: true,
|
||||
message: 'Order cancelled successfully',
|
||||
data: { order: updatedOrder },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// exports.returnOrder = async (req, res, next) => {
|
||||
// try {
|
||||
// const order = await prisma.order.findFirst({
|
||||
// where: {
|
||||
// id: req.params.id,
|
||||
// userId: req.user.id,
|
||||
// },
|
||||
// });
|
||||
|
||||
// if (!order) {
|
||||
// return res.status(404).json({
|
||||
// status: false,
|
||||
// message: 'Order not found',
|
||||
// });
|
||||
// }
|
||||
|
||||
// // ✅ RETURN STATUS CHECK (YOUR CODE GOES HERE)
|
||||
// if (!ALLOWED_STATUSES.includes(order.status)) {
|
||||
// return res.status(400).json({
|
||||
// status: false,
|
||||
// message: 'Order not eligible for return',
|
||||
// });
|
||||
// }
|
||||
|
||||
// // ✅ RETURN WINDOW CHECK
|
||||
// const deliveredAt = order.deliveredAt || order.updatedAt;
|
||||
// const diffDays =
|
||||
// (Date.now() - new Date(deliveredAt)) / (1000 * 60 * 60 * 24);
|
||||
|
||||
// if (diffDays > RETURN_WINDOW_DAYS) {
|
||||
// return res.status(400).json({
|
||||
// status: false,
|
||||
// message: `Return allowed within ${RETURN_WINDOW_DAYS} days only`,
|
||||
// });
|
||||
// }
|
||||
|
||||
// // ✅ UPDATE ORDER
|
||||
// const updatedOrder = await prisma.order.update({
|
||||
// where: { id: order.id },
|
||||
// data: {
|
||||
// status: 'RETURN_REQUESTED',
|
||||
// returnRequestedAt: new Date(),
|
||||
// },
|
||||
// });
|
||||
|
||||
// return res.status(200).json({
|
||||
// status: true,
|
||||
// message: 'Return request submitted successfully',
|
||||
// data: { order: updatedOrder },
|
||||
// });
|
||||
// } catch (error) {
|
||||
// next(error);
|
||||
// }
|
||||
// };
|
||||
|
||||
// @desc Return order
|
||||
// @route PUT /api/orders/:id/return
|
||||
// @access Private
|
||||
exports.returnOrder = async (req, res, next) => {
|
||||
try {
|
||||
// Find the order belonging to the logged-in user
|
||||
const order = await prisma.order.findFirst({
|
||||
where: {
|
||||
id: req.params.id,
|
||||
userId: req.user.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!order) {
|
||||
return res.status(404).json({
|
||||
status: false,
|
||||
message: 'Order not found',
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Check if order status allows return
|
||||
const ALLOWED_STATUSES = ['DELIVERED']; // only delivered orders can be returned
|
||||
if (!ALLOWED_STATUSES.includes(order.status)) {
|
||||
return res.status(400).json({
|
||||
status: false,
|
||||
message: 'Order not eligible for return',
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Check return window (e.g., 7 days)
|
||||
const RETURN_WINDOW_DAYS = 7;
|
||||
const deliveredAt = order.deliveredAt || order.updatedAt;
|
||||
const diffDays =
|
||||
(Date.now() - new Date(deliveredAt)) / (1000 * 60 * 60 * 24);
|
||||
|
||||
if (diffDays > RETURN_WINDOW_DAYS) {
|
||||
return res.status(400).json({
|
||||
status: false,
|
||||
message: `Return allowed within ${RETURN_WINDOW_DAYS} days only`,
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ Update order: set both status and returnStatus
|
||||
const updatedOrder = await prisma.order.update({
|
||||
where: { id: order.id },
|
||||
data: {
|
||||
status: 'RETURN_REQUESTED', // OrderStatus
|
||||
returnStatus: 'REQUESTED', // ReturnStatus (admin will use this)
|
||||
returnRequestedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
status: true,
|
||||
message: 'Return request submitted successfully',
|
||||
data: { order: updatedOrder },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get all orders (Admin)
|
||||
exports.getAllOrdersAdmin = async (req, res, next) => {
|
||||
try {
|
||||
const { page = 1, limit = 20, status, paymentStatus } = req.query;
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
const where = {};
|
||||
if (status) where.status = status;
|
||||
if (paymentStatus) where.paymentStatus = paymentStatus;
|
||||
|
||||
const [orders, total] = await Promise.all([
|
||||
prisma.order.findMany({
|
||||
where,
|
||||
include: {
|
||||
items: true,
|
||||
address: true,
|
||||
user: {
|
||||
select: { id: true, email: true, firstName: true, lastName: true },
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: parseInt(skip),
|
||||
take: parseInt(limit),
|
||||
}),
|
||||
prisma.order.count({ where }),
|
||||
]);
|
||||
|
||||
// res.json({
|
||||
// success: true,
|
||||
// data: {
|
||||
// orders,
|
||||
// pagination: {
|
||||
// page: parseInt(page),
|
||||
// limit: parseInt(limit),
|
||||
// total,
|
||||
// pages: Math.ceil(total / limit),
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
return res.status(200).json({
|
||||
statusCode: 200,
|
||||
status: true,
|
||||
message: 'Orders fetched successfully',
|
||||
data: {
|
||||
orders,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total,
|
||||
pages: Math.ceil(total / limit),
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Approve or reject a return request
|
||||
// @route PUT /api/orders/:id/return/status
|
||||
// @access Private/Admin
|
||||
exports.updateReturnStatus = async (req, res, next) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { action } = req.body; // "APPROVE" or "REJECT"
|
||||
|
||||
const order = await prisma.order.findUnique({ where: { id } });
|
||||
|
||||
if (!order) {
|
||||
return res
|
||||
.status(404)
|
||||
.json({ status: false, message: 'Order not found' });
|
||||
}
|
||||
|
||||
if (order.returnStatus !== 'REQUESTED') {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ status: false, message: 'No return request pending' });
|
||||
}
|
||||
|
||||
let newStatus;
|
||||
if (action === 'APPROVE') newStatus = 'APPROVED';
|
||||
else if (action === 'REJECT') newStatus = 'REJECTED';
|
||||
else
|
||||
return res.status(400).json({ status: false, message: 'Invalid action' });
|
||||
|
||||
const updatedOrder = await prisma.order.update({
|
||||
where: { id },
|
||||
data: { returnStatus: newStatus },
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
status: true,
|
||||
message: `Return request ${action.toLowerCase()}ed successfully`,
|
||||
data: { order: updatedOrder },
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get all return requests (Admin only)
|
||||
// @route GET /api/orders/admin/returns
|
||||
// @access Private/Admin
|
||||
exports.getAdminReturnRequests = async (req, res) => {
|
||||
try {
|
||||
const page = Number(req.query.page) || 1;
|
||||
const limit = Number(req.query.limit) || 10;
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
const [returns, count] = await Promise.all([
|
||||
prisma.order.findMany({
|
||||
where: {
|
||||
returnStatus: {
|
||||
in: ['REQUESTED', 'APPROVED', 'REJECTED', 'COMPLETED'],
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
address: true,
|
||||
items: true,
|
||||
},
|
||||
orderBy: { returnRequestedAt: 'desc' },
|
||||
skip,
|
||||
take: limit,
|
||||
}),
|
||||
prisma.order.count({
|
||||
where: {
|
||||
returnStatus: {
|
||||
in: ['REQUESTED', 'APPROVED', 'REJECTED', 'COMPLETED'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
res.json({
|
||||
status: true,
|
||||
count,
|
||||
data: returns,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Admin return list error:', error);
|
||||
res.status(500).json({
|
||||
status: false,
|
||||
message: 'Failed to fetch return requests',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// @desc Get all returned products (Admin only)
|
||||
// @route GET /api/orders/admin/returns/list
|
||||
// @access Private/Admin
|
||||
exports.getReturnedProducts = async (req, res, next) => {
|
||||
try {
|
||||
const returnedOrders = await prisma.order.findMany({
|
||||
where: {
|
||||
returnStatus: { in: ['APPROVED', 'COMPLETED'] },
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
address: true,
|
||||
items: true,
|
||||
},
|
||||
orderBy: {
|
||||
returnRequestedAt: 'desc',
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
status: true,
|
||||
count: returnedOrders.length,
|
||||
data: returnedOrders,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getReturnRequestById = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
// Fetch the order with related user, address, and items
|
||||
const order = await prisma.order.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
user: true,
|
||||
address: true,
|
||||
items: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!order) {
|
||||
return res
|
||||
.status(404)
|
||||
.json({ status: false, message: 'Return request not found' });
|
||||
}
|
||||
|
||||
// Ensure this order is a return request
|
||||
if (
|
||||
!['RETURN_REQUESTED', 'APPROVED', 'REJECTED', 'COMPLETED'].includes(
|
||||
order.returnStatus
|
||||
)
|
||||
) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ status: false, message: 'This order is not a return request' });
|
||||
}
|
||||
|
||||
res.json({ status: true, data: order });
|
||||
} catch (error) {
|
||||
console.error('Error fetching return request:', error);
|
||||
res.status(500).json({ status: false, message: 'Server error' });
|
||||
}
|
||||
};
|
||||
|
||||
// module.exports = { getReturnRequestById };
|
||||
Reference in New Issue
Block a user