From 3fd8ed3f333c3ad75ce38f2317a7ca1b7074f4b5 Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Wed, 25 Sep 2024 18:07:49 +0530 Subject: [PATCH] pd maped order --- resources/PD_Orders/pdOrderController.js | 516 +++++------------------ resources/PD_Orders/pdOrderRoute.js | 11 +- resources/user/userController.js | 80 +++- resources/user/userRoute.js | 6 +- 4 files changed, 192 insertions(+), 421 deletions(-) diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js index bebadc9..1626dc8 100644 --- a/resources/PD_Orders/pdOrderController.js +++ b/resources/PD_Orders/pdOrderController.js @@ -816,13 +816,13 @@ export const getProcessingInvoices = async (req, res) => { query.invoiceId = { $regex: invoiceId, $options: "i" }; } const invoices = await Invoice.find(query) - .skip(skip) - .limit(limit) - .populate({ - path: "orderId", - select: "uniqueId", - }) - .sort({ "courierstatus_timeline.processing": -1 }); + .skip(skip) + .limit(limit) + .populate({ + path: "orderId", + select: "uniqueId", + }) + .sort({ "courierstatus_timeline.processing": -1 }); if (orderId) { const filteredInvoices = invoices.filter( @@ -1326,418 +1326,128 @@ export const getOrderCounts = async (req, res) => { } }; -// no need -export const updateOrderStatusById = async (req, res) => { +export const getAllOrdersByDistributor = async (req, res) => { + const { distributorId } = req.params; + const { orderId, status } = req.query; // Added status to query parameters + // console.log(distributorId, orderId, status); + + // Handle pagination parameters + const page = parseInt(req.query.page, 10) || 1; + const limit = parseInt(req.query.limit, 10) || 5; + const skip = (page - 1) * limit; + try { - let body = { status: req.body.status }; + let orders; - const currentDate = new Date(); - body["status_timeline." + req.body.status] = currentDate; + // Search by orderId + if (orderId) { + const id = new RegExp(orderId, "i"); + orders = await PdOrder.find({ + addedBy: distributorId, + uniqueId: { $regex: id }, + }) + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit); - const order = await PdOrder.findById(req.params.id).populate({ - path: "addedBy", - select: "name email _id", - }); + // console.log(orders); - if (req.body.status === "cancelled") { - console.log("req came here "); - body["order_Cancelled_Reason"] = req.body?.ReasonforCancellation; - body["iscancelled"] = true; + // Return empty array if no orders are found + if (!orders || orders.length === 0) { + return res.status(200).json([]); + } - const updatedCan = await PdOrder.findByIdAndUpdate(order._id, body); - - await sendEmail({ - to: `${order?.addedBy?.email}`, // Change to your recipient - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `Order #${order?.uniqueId} Update: Cancellation and Refund Process`, - html: ` - Hi ${ - order?.addedBy.name - }, -

We hope this message finds you well. We're writing to inform you that your order ${ - order?.uniqueId - } has been canceled. We understand that circumstances may change, and we're here to assist you throughout the process.

- -

Cancellation Reason: ${ - order?.order_Cancelled_Reason || "No specific reason provided." - }

- -

Items:

- - - - - - - - - - - - - - - - ${order?.orderItem - ?.map( - (product, index) => ` - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameCategoryBrandImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${ - product.categoryName - }${ - product.brandName - }${
-                    product.name
-                  }${ - product.quantity - }₹${ - product.price - }₹${ - (product.GST * product.price) / 100 - }₹${ - (product.price + (product.GST * product.price) / 100) * - product.quantity - }
Total Amount :₹${ - order?.grandTotal - }
- -

Refund Information: The amount from your canceled order will be processed for a refund. Please allow up to 7 working days for the amount to be transferred back to your original payment method.

- -
If you have any concerns or further questions, please feel free to reply to this email. We appreciate your understanding and hope to serve you better in the future.
-
- Best regards,
- Team Cheminova - `, + // Get total count for pagination + const totalOrders = await PdOrder.countDocuments({ + addedBy: distributorId, + status: { $regex: id }, }); + // Send response with pagination info return res.status(200).json({ - status: "ok", - message: "Order status updated successfully!", - updatedCan, + totalOrders, + totalPages: Math.ceil(totalOrders / limit), + currentPage: page, + orders, }); - } else if (req.body.status === "processing") { - const updatedPro = await PdOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.addedBy?.email}`, // Recipient's email address from order model - from: `${process.env.SEND_EMAIL_FROM}`, // Sender's email address - subject: `Your Order #${order?.uniqueId} is in Processing!`, - html: ` -
-

Exciting news! Your order #${ - order?.uniqueId - } has entered the processing phase. Our team is diligently preparing your items for dispatch. Rest assured, we're working hard to ensure everything is perfect for you.

- Hi ${ - order?.addedBy.name - }, -

Order Status: ${ - order?.status.charAt(0).toUpperCase() + order?.status.slice(1) - }

- - - -

Order Items:

- - - - - - - - - - - - - - - ${order?.orderItem - ?.map( - (product, index) => ` - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - } - ${
-                    product.name
-                  } - ${ - product.quantity - }₹${ - product.price - }₹${ - (product.GST * product.price) / 100 - }₹${ - (product.price + (product.GST * product.price) / 100) * - product.quantity - }
Total Amount:₹${ - order?.grandTotal - }
- -
We'll send you another email with the tracking details as soon as your order is dispatched. If you have any questions or need assistance, feel free to reply to this email.
-
Thank you for choosing Cheminova!
-
- Best regards,
- Team Cheminova -
- `, + } + + // Search by status + else if (status) { + // Create a regex for case-insensitive search + const regex = new RegExp(status, "i"); + + orders = await PdOrder.find({ + addedBy: distributorId, + status: { $regex: regex }, + }) + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit); + + // console.log(orders); + + // Return empty array if no orders are found + if (!orders || orders.length === 0) { + return res.status(200).json([]); + } + + // Get total count for pagination + const totalOrders = await PdOrder.countDocuments({ + addedBy: distributorId, + status: { $regex: regex }, }); + + // Send response with pagination info return res.status(200).json({ - status: "ok", - message: "Order status updated successfully!", - updatedPro, + totalOrders, + totalPages: Math.ceil(totalOrders / limit), + currentPage: page, + orders, }); - } else if (req.body.status === "dispatched") { - body["courier_name"] = req.body.courierName; - body["courier_tracking_id"] = req.body.TrackingID; - const disRes = await PdOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.addedBy?.email}`, // Assuming 'addedBy' references the user who placed the order - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `Your Order #${order?.uniqueId} is On Its Way!`, - html: ` - Hi, -

Exciting news! Your order #${ - order?.uniqueId - } has been dispatched and is en route to you. 🚚 Here are the details:

- -

Courier Name: ${ - order?.courier_name || "N/A" - }

-

Courier Tracking ID: ${ - order?.courier_tracking_id || "N/A" - }

- - - -

Items:

- - - - - - - - - - - - - - - ${order?.orderItem - ?.map( - (product, index) => ` - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameSKUImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${ - product.SKU - } - ${
-                    product.name
-                  } - ${ - product.quantity - }₹${ - product.price - }₹${ - (product.GST * product.price) / 100 - }₹${ - (product.price + (product.GST * product.price) / 100) * - product.quantity - }
Total Amount:₹${ - order?.grandTotal - }
- -

Order Status: Dispatched

-

If you have any questions or need assistance, feel free to reply to this email.

-
Thanks for choosing Cheminova! We hope you enjoy your purchase.
-
- Best regards,
- Team Cheminova - `, + } + + // Default behavior to return all orders + else { + orders = await PdOrder.find({ addedBy: distributorId }) + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit); + + // Return empty array if no orders are found + if (!orders || orders.length === 0) { + return res.status(200).json([]); + } + + // Get total count for pagination + const totalOrders = await PdOrder.countDocuments({ + addedBy: distributorId, }); + + // Send response with pagination info return res.status(200).json({ - status: "ok", - message: "Order status updated successfully!", - disRes, + totalOrders, + totalPages: Math.ceil(totalOrders / limit), + currentPage: page, + orders, }); - } else if (req.body.status === "delivered") { - body["isDelivered"] = true; - body["DeliveredDate"] = req.body.DDate; - const formattedDate = formatDate(req.body.DDate); - console.log(formattedDate); - const updatedDeli = await PdOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.addedBy?.email}`, // Using 'addedBy' to reference the user's email - from: `${process.env.SEND_EMAIL_FROM}`, // Your verified sender - subject: `Your Order #${order?.uniqueId} Has Been Delivered!`, - html: ` - Hi, -

- Great news! Your order #${ - order?.uniqueId - } has been successfully delivered to your doorstep. We hope everything is just as you expected! -

- - - -

Items:

- - - - - - - - - - - - - - - ${order?.orderItem - ?.map( - (product, index) => ` - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameSKUImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${ - product.SKU - } - ${
-                    product.name
-                  } - ${ - product.quantity - }₹${ - product.price - }₹${ - (product.GST * product.price) / 100 - }₹${ - (product.price + (product.GST * product.price) / 100) * - product.quantity - }
Total Amount:₹${ - order?.grandTotal - }
- -

Delivery Date: ${formattedDate}

- -

- Your satisfaction is our priority, and we'd love to hear about your experience. Please take a moment to share your thoughts by leaving a review. Your feedback is invaluable to us! -

- -
- If you have any questions or concerns about your order, feel free to reply to this email. -
- -
- Thank you for choosing Cheminova! We hope to serve you again soon. -
- -
- Best regards,
- Team Cheminova - `, - }); - return res.status(200).json({ - status: "ok", - message: "Order status updated successfully!", - updatedDeli, - }); - } else { - // await Order.findByIdAndUpdate(order._id, body); - // console.log(order); - res - .status(200) - .json({ status: "ok", message: "Order status updated successfully!" }); } } catch (error) { - console.log(error); - res - .status(500) - .json({ message: error?.message || "Something went wrong!" }); + console.error("Error fetching orders:", error); + res.status(500).json({ message: "Server error", error }); + } +}; + +export const gettotalorderandvalueofpd = async (req, res) => { + const { distributorId } = req.params; + try { + const orders = await PdOrder.find({ addedBy: distributorId }); + const totalOrders = orders.length; + const totalValue = orders.reduce((acc, order) => acc + order.grandTotal, 0); + + res.status(200).json({ totalOrders, totalValue }); + } catch (error) { + console.error("Error fetching orders:", error); + res.status(500).json({ message: "Server error", error }); } }; diff --git a/resources/PD_Orders/pdOrderRoute.js b/resources/PD_Orders/pdOrderRoute.js index 33d1be8..48703d1 100644 --- a/resources/PD_Orders/pdOrderRoute.js +++ b/resources/PD_Orders/pdOrderRoute.js @@ -10,7 +10,6 @@ import { getPlacedOrder, getPlacedOrderById, getProcessingOrdersAdmin, - updateOrderStatusById, processOrder, cancelOrderController, getPlacedPendingOrderAdmin, @@ -20,6 +19,8 @@ import { getDeliveredInvoices, getDispatchedInvoices, updateCourierStatusToDelivered, + getAllOrdersByDistributor, + gettotalorderandvalueofpd, } from "./pdOrderController.js"; const router = express.Router(); @@ -98,9 +99,11 @@ router updateCourierStatusToDelivered ); router - .route("/change/status/:id") - .patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById); - + .route("/single-pd-order/:distributorId") + .get(isAuthenticatedUser, authorizeRoles("admin"), getAllOrdersByDistributor); + router + .route("/single-pd-ordercount/:distributorId") + .get(isAuthenticatedUser, authorizeRoles("admin"), gettotalorderandvalueofpd); router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts); export default router; diff --git a/resources/user/userController.js b/resources/user/userController.js index b6008a8..1cc566e 100644 --- a/resources/user/userController.js +++ b/resources/user/userController.js @@ -15,6 +15,7 @@ import path from "path"; import validator from "validator"; import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js"; import { generatePassword } from "../../Utils/generatepassword.js"; +import { PdOrder } from "../PD_Orders/pdOrderModal.js"; // const generatePassword = (name, email) => { // // Combine name and email, and convert to lowercase // const combinedStr = (name + email).toLowerCase(); @@ -997,43 +998,33 @@ export const updateProfile = catchAsyncErrors(async (req, res, next) => { // 9.Get all users(admin) export const getAllUser = catchAsyncErrors(async (req, res, next) => { try { - // Extract query parameters const { page = 1, show = 10, name, mobileNumber, SBU } = req.query; - // Create a filter object const filter = { role: "principal-Distributor" }; - // Add case-insensitive name search if (name) { - filter.name = { $regex: name, $options: "i" }; // Case-insensitive regex search + filter.name = { $regex: name, $options: "i" }; } - // Add mobileNumber search if (mobileNumber) { filter.phone = mobileNumber; } - // Add SBU filter if provided if (SBU) { - filter.SBU = { $regex: SBU, $options: "i" }; // Case-insensitive regex search for SBU + filter.SBU = { $regex: SBU, $options: "i" }; } - // Calculate pagination values const limit = parseInt(show, 10); const skip = (parseInt(page, 10) - 1) * limit; - // Find users with the filter, pagination, and sorting const users = await User.find(filter) .populate("mappedby", "name") .populate("mappedbySC", "name") .sort({ createdAt: -1 }) .skip(skip) .limit(limit); - - // Count total users matching the filter const totalUsers = await User.countDocuments(filter); - // Respond with users and pagination info res.status(200).json({ success: true, users, @@ -1041,12 +1032,75 @@ export const getAllUser = catchAsyncErrors(async (req, res, next) => { total_pages: Math.ceil(totalUsers / limit), }); } catch (error) { - // Handle errors console.error(error); res.status(500).json({ message: "Server Error", error }); } }); +export const getAllPD = catchAsyncErrors(async (req, res, next) => { + try { + const { page = 1, show = 10, name, mobileNumber, SBU } = req.query; + const filter = { role: "principal-Distributor" }; + + if (name) { + filter.name = { $regex: name, $options: "i" }; + } + + if (mobileNumber) { + filter.phone = mobileNumber; + } + + if (SBU) { + filter.SBU = { $regex: SBU, $options: "i" }; + } + + const limit = parseInt(show, 10); + const skip = (parseInt(page, 10) - 1) * limit; + + // Fetch users with the given filter and pagination + const users = await User.find(filter) + .populate("mappedby", "name") + .populate("mappedbySC", "name") + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit); + + // Fetch total count of users matching the filter + const totalUsers = await User.countDocuments(filter); + + // Aggregate orders data for each user + const orderStats = await PdOrder.aggregate([ + { $match: { addedBy: { $in: users.map(user => user._id) } } }, // Match orders for the listed distributors + { + $group: { + _id: "$addedBy", // Group by addedBy (distributor ID) + totalOrders: { $sum: 1 }, // Calculate total number of orders + lastOrderDate: { $max: "$createdAt" }, // Get the date of the last order + }, + }, + ]); + + // Map orders data to corresponding users + const usersWithOrderStats = users.map(user => { + const orderData = orderStats.find(order => order._id.toString() === user._id.toString()); + return { + ...user.toObject(), + totalOrders: orderData ? orderData.totalOrders : 0, + lastOrderDate: orderData ? orderData.lastOrderDate : null, + }; + }); + + res.status(200).json({ + success: true, + users: usersWithOrderStats, + total_data: totalUsers, + total_pages: Math.ceil(totalUsers / limit), + }); + } catch (error) { + console.error('Error fetching Principal Distributors:', error); + res.status(500).json({ message: "Server Error", error }); + } +}); export const getAllPrincipalDistributorbytmId = catchAsyncErrors( async (req, res, next) => { const { page = 1, show = 10, name, mobileNumber } = req.query; diff --git a/resources/user/userRoute.js b/resources/user/userRoute.js index 96d83cf..875a6c0 100644 --- a/resources/user/userRoute.js +++ b/resources/user/userRoute.js @@ -22,6 +22,7 @@ import { mappedbySC, getAllPrincipalDistributorbyscId, saveFCMTokenForUser, + getAllPD, } from "./userController.js"; import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; @@ -48,7 +49,10 @@ router //mapping start router .route("/admin/users") - .get(isAuthenticatedUser, authorizeRoles("admin", "Employee"), getAllUser); + .get(isAuthenticatedUser, authorizeRoles("admin"), getAllUser); + router + .route("/admin/pd") + .get(isAuthenticatedUser, authorizeRoles("admin"), getAllPD); router .route("/getbyTmId/:id") .get(