diff --git a/app.js b/app.js
index df86780..6f12e23 100644
--- a/app.js
+++ b/app.js
@@ -202,6 +202,8 @@ import RDOrderRoute from "./resources/RD_Ordes/rdOrderRoutes.js"
import TaskRoute from "./resources/Task/TaskRoute.js";
// visit RD and PD
import VisitRDandPDRoute from "./resources/VisitRD&PD/VisitRD&PDRoute.js";
+//Stock
+import Stock from "./resources/Stock/PdStockRoute.js";
app.use("/api/v1", user);
//Product
@@ -293,7 +295,8 @@ app.use("/api", VisitRDandPDRoute);
//short urls
// app.use("/api/shorturl", ShortUrlRouter);
//Support
-
+//Stock
+app.use("/api", Stock);
// Email CMS
// app.use("/api", RegisterEmail);
export default app;
diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js
index b531f6a..93b93a6 100644
--- a/resources/PD_Orders/pdOrderController.js
+++ b/resources/PD_Orders/pdOrderController.js
@@ -2,7 +2,7 @@ import mongoose from "mongoose";
import { PdOrder } from "./pdOrderModal.js";
import sendEmail from "../../Utils/sendEmail.js";
import { Invoice } from "./invoiceModel.js";
-
+import { PDStock } from "../Stock/PdStockModel.js";
// Controller for placing an order
export const createOrder = async (req, res) => {
try {
@@ -731,7 +731,8 @@ export const getCancelledOrdersAdmin = async (req, res) => {
.limit(limit)
.populate({ path: "orderItem.productId" })
.populate({ path: "invoices" })
- .populate({ path: "addedBy" });
+ .populate({ path: "addedBy" })
+ .sort({ createdAt: -1 });
if (cancelledOrders.length > 0) {
return res.status(200).json({ cancelledOrders, totalOrders });
@@ -815,13 +816,13 @@ export const getProcessingInvoices = async (req, res) => {
query.invoiceId = { $regex: invoiceId, $options: "i" };
}
const invoices = await Invoice.find(query)
- .sort({ createdAt: -1 })
.skip(skip)
.limit(limit)
.populate({
path: "orderId",
select: "uniqueId",
- });
+ })
+ .sort({ "courierstatus_timeline.processing": -1 });
if (orderId) {
const filteredInvoices = invoices.filter(
@@ -1025,7 +1026,8 @@ export const getDispatchedInvoices = async (req, res) => {
.populate({
path: "orderId",
select: "uniqueId",
- });
+ })
+ .sort({ "courierstatus_timeline.dispatched": -1 });
if (orderId) {
const filteredInvoices = invoices.filter(
@@ -1065,7 +1067,6 @@ export const updateCourierStatusToDelivered = async (req, res) => {
select: "email",
},
});
-
if (!invoice) {
return res.status(404).json({ error: "Invoice not found" });
}
@@ -1086,7 +1087,44 @@ export const updateCourierStatusToDelivered = async (req, res) => {
order.status = "delivered";
await order.save();
}
+ // Get the userId from the order's addedBy
+ const userId = order?.addedBy?._id;
+ if (!userId) {
+ return res.status(400).json({ error: "User not found for the order" });
+ }
+ // Check if PDStock exists for the user
+ let pdStock = await PDStock.findOne({ userId });
+
+ if (!pdStock) {
+ // If no stock record exists, create a new one
+ pdStock = new PDStock({
+ userId,
+ products: [], // Initialize with empty products array
+ });
+ }
+ // Iterate over each item in the invoice
+ for (let item of invoice.items) {
+ const { productId, processquantity } = item;
+
+ // Check if the product already exists in the PDStock for the user
+ const existingProduct = pdStock.products.find(
+ (p) => p.productid.toString() === productId.toString()
+ );
+
+ if (existingProduct) {
+ // If the product exists, update the stock by adding the processquantity
+ existingProduct.Stock += processquantity;
+ } else {
+ // If the product doesn't exist, add a new entry for the product
+ pdStock.products.push({
+ productid: productId,
+ Stock: processquantity,
+ });
+ }
+ }
+ // Save the updated PDStock
+ await pdStock.save();
// Format the current date for display
const formattedDate = formatDate(new Date());
@@ -1212,7 +1250,8 @@ export const getDeliveredInvoices = async (req, res) => {
.populate({
path: "orderId",
select: "uniqueId",
- });
+ })
+ .sort({ "courierstatus_timeline.delivered": -1 });
if (orderId) {
const filteredInvoices = invoices.filter(
@@ -1323,418 +1362,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:
-
-
-
- S No. |
- Product Name |
- Category |
- Brand |
- Image |
- Quantity |
- Price |
- GST Amount |
- SubTotal |
-
-
-
- ${order?.orderItem
- ?.map(
- (product, index) => `
-
- ${
- index + 1
- } |
- ${
- product.name
- } |
- ${
- product.categoryName
- } |
- ${
- product.brandName
- } |
-  |
- ${
- product.quantity
- } |
- ₹${
- product.price
- } |
- ₹${
- (product.GST * product.price) / 100
- } |
- ₹${
- (product.price + (product.GST * product.price) / 100) *
- product.quantity
- } |
-
- `
- )
- .join("")}
-
- 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:
-
-
-
- S No. |
- Product Name |
-
- Image |
- Quantity |
- Price |
- GST Amount |
- SubTotal |
-
-
-
- ${order?.orderItem
- ?.map(
- (product, index) => `
-
- ${
- index + 1
- } |
- ${
- product.name
- } |
-
-
-
- |
- ${
- product.quantity
- } |
- ₹${
- product.price
- } |
- ₹${
- (product.GST * product.price) / 100
- } |
- ₹${
- (product.price + (product.GST * product.price) / 100) *
- product.quantity
- } |
-
- `
- )
- .join("")}
-
- 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:
-
-
-
- S No. |
- Product Name |
- SKU |
- Image |
- Quantity |
- Price |
- GST Amount |
- SubTotal |
-
-
-
- ${order?.orderItem
- ?.map(
- (product, index) => `
-
- ${
- index + 1
- } |
- ${
- product.name
- } |
- ${
- product.SKU
- } |
-
-
- |
- ${
- product.quantity
- } |
- ₹${
- product.price
- } |
- ₹${
- (product.GST * product.price) / 100
- } |
- ₹${
- (product.price + (product.GST * product.price) / 100) *
- product.quantity
- } |
-
- `
- )
- .join("")}
-
- 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:
-
-
-
- S No. |
- Product Name |
- SKU |
- Image |
- Quantity |
- Price |
- GST Amount |
- SubTotal |
-
-
-
- ${order?.orderItem
- ?.map(
- (product, index) => `
-
- ${
- index + 1
- } |
- ${
- product.name
- } |
- ${
- product.SKU
- } |
-
-
- |
- ${
- product.quantity
- } |
- ₹${
- product.price
- } |
- ₹${
- (product.GST * product.price) / 100
- } |
- ₹${
- (product.price + (product.GST * product.price) / 100) *
- product.quantity
- } |
-
- `
- )
- .join("")}
-
- 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/Stock/PdStockController.js b/resources/Stock/PdStockController.js
new file mode 100644
index 0000000..0aebe55
--- /dev/null
+++ b/resources/Stock/PdStockController.js
@@ -0,0 +1,103 @@
+import mongoose from "mongoose";
+import { PDStock } from "./PdStockModel.js";
+import { Product } from "../Products/ProductModel.js";
+
+export const getProductsAndStockByUser = async (req, res) => {
+ try {
+ const { userId } = req.params;
+
+ // Pagination parameters
+ const PAGE_SIZE = parseInt(req.query.show) || 10;
+ const page = parseInt(req.query.page) || 1;
+ const skip = (page - 1) * PAGE_SIZE;
+
+ // Filtering criteria
+ const filter = {};
+ if (req.query.name) {
+ filter.name = {
+ $regex: new RegExp(req.query.name, "i"),
+ };
+ }
+ if (req.query.category) {
+ filter.category = mongoose.Types.ObjectId(req.query.category);
+ }
+ if (req.query.brand) {
+ filter.brand = mongoose.Types.ObjectId(req.query.brand);
+ }
+
+ // Fetch user's PDStock data and products concurrently
+ const [userStock, products] = await Promise.all([
+ PDStock.findOne({ userId: mongoose.Types.ObjectId(userId) }),
+ Product.aggregate([
+ { $match: filter },
+ {
+ $lookup: {
+ from: "categorymodels",
+ localField: "category",
+ foreignField: "_id",
+ as: "categoryDetails",
+ },
+ },
+ {
+ $lookup: {
+ from: "brandmodels",
+ localField: "brand",
+ foreignField: "_id",
+ as: "brandDetails",
+ },
+ },
+ {
+ $project: {
+ category: { $arrayElemAt: ["$categoryDetails.categoryName", 0] },
+ brand: { $arrayElemAt: ["$brandDetails.brandName", 0] },
+ GST: 1,
+ HSN_Code: 1,
+ SKU: 1,
+ addedBy: 1,
+ createdAt: 1,
+ description: 1,
+ image: 1,
+ name: 1,
+ price: 1,
+ product_Status: 1,
+ updatedAt: 1,
+ },
+ },
+ { $skip: skip },
+ { $limit: PAGE_SIZE },
+ ]),
+ ]);
+
+ // Create a stock map for easy lookup
+ const stockMap = {};
+ if (userStock && userStock.products) {
+ userStock.products.forEach((product) => {
+ stockMap[product.productid.toString()] = product.Stock;
+ });
+ }
+
+ // Combine products with their respective stock
+ const productsWithStock = products.map((product) => ({
+ ...product,
+ stock: stockMap[product._id.toString()] || 0,
+ }));
+
+ // Get total count for pagination purposes
+ const total = await Product.countDocuments(filter);
+
+ return res.status(200).json({
+ success: true,
+ totalProducts: total,
+ totalPages: Math.ceil(total / PAGE_SIZE),
+ currentPage: page,
+ products: productsWithStock,
+ });
+ } catch (error) {
+ console.error("Error fetching products with stock:", error);
+ return res.status(500).json({
+ success: false,
+ message: "Error fetching products and stock",
+ });
+ }
+};
+
diff --git a/resources/Stock/PdStockModel.js b/resources/Stock/PdStockModel.js
new file mode 100644
index 0000000..689c73e
--- /dev/null
+++ b/resources/Stock/PdStockModel.js
@@ -0,0 +1,26 @@
+import mongoose from 'mongoose';
+
+// Define Product record schema
+const ProductRecordSchema = new mongoose.Schema({
+ productid: {
+ type: mongoose.Schema.Types.ObjectId,
+ ref: 'Product',
+ required: true,
+ },
+ Stock: {
+ type: Number,
+ default: 0,
+ },
+});
+
+// Define main Stock schema
+const StockSchema = new mongoose.Schema({
+ userId: {
+ type: mongoose.Schema.Types.ObjectId,
+ refPath: 'User',
+ required: true,
+ },
+ products: [ProductRecordSchema],
+}, { timestamps: true, versionKey: false });
+
+export const PDStock = mongoose.model('PDStock', StockSchema);
diff --git a/resources/Stock/PdStockRoute.js b/resources/Stock/PdStockRoute.js
new file mode 100644
index 0000000..d49a778
--- /dev/null
+++ b/resources/Stock/PdStockRoute.js
@@ -0,0 +1,12 @@
+import express from "express";
+import { getProductsAndStockByUser } from "./PdStockController.js";
+import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
+const router = express.Router();
+
+router.get(
+ "/pd/stock/:userId",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ getProductsAndStockByUser
+);
+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(