import mongoose from "mongoose"; import RetailDistributor from "./RetailDistributorModel.js"; import validator from "validator"; import password from "secure-random-password"; import crypto from "crypto"; import { RdOrder } from "../RD_Ordes/rdOrderModal.js"; import sendEmail, { sendOtp } from "../../Utils/sendEmail.js"; export const loginRD = async (req, res) => { const { email, password } = req.body; try { if (!email || !password) { return res.status(400).json({ message: "Please Enter Email & Password" }); } const retailDistributor = await RetailDistributor.findOne({ email }).select( "+password" ); if (!retailDistributor) { return res.status(400).json({ message: "Invalid Email or Password" }); } const isPasswordMatched = await retailDistributor.comparePassword(password); if (!isPasswordMatched) { return res.status(400).json({ message: "Invalid Email or Password" }); } const token = retailDistributor.getJWTToken(); return res.status(200).json({ success: true, token, message: "Login Successfully", }); } catch (error) { return res.status(500).json({ message: error.message ? error.message : "Something went wrong!", }); } }; export const ChangePasswordRD = async (req, res) => { // Retrieve id from req.params const { oldPassword, newPassword, confirmPassword } = req.body; const userId = req.user._id; // Use the ID from the URL or from the authenticated user // console.log(userId); if (!oldPassword) { return res.status(400).json({ message: "Please Enter Old password" }); } if (!newPassword) { return res.status(400).json({ message: "Please Enter New Password " }); } if (!confirmPassword) { return res.status(400).json({ message: "Please Enter Confirm Password" }); } try { const retailDistributor = await RetailDistributor.findById(userId).select( "+password" ); if (!retailDistributor) { return res.status(404).json({ message: "Retail Distributer not found" }); } const isPasswordMatched = await retailDistributor.comparePassword( oldPassword ); if (!isPasswordMatched) { return res.status(400).json({ message: "Old password is incorrect" }); } if (newPassword !== confirmPassword) { return res .status(400) .json({ message: "New password and confirm Password do not match" }); } retailDistributor.password = newPassword; await retailDistributor.save(); return res .status(200) .json({ success: true, message: "Password updated successfully" }); } catch (error) { console.error("Error updating password:", error); return res.status(500).json({ message: error.message ? error.message : "Server error!", }); } }; export const forgotPasswordRD = async (req, res) => { try { // Check if email is provided const { email } = req.body; if (!email) { return res.status(400).json({ message: "Please Enter Email!" }); } // Find the Retail Distributor by email const retailDistributor = await RetailDistributor.findOne({ email }); if (!retailDistributor) { return res.status(404).json({ message: "Retail Distributor not found" }); } // Generate a random password const newPassword = password.randomPassword({ length: 12, characters: [ { characters: password.upper, exactly: 1 }, // At least 1 uppercase letter { characters: password.symbols, exactly: 1 }, // At least 1 symbol password.lower, // Lowercase letters password.digits, // Digits ], }); // Update the retail distributor's password retailDistributor.password = newPassword; await retailDistributor.save(); // The pre-save hook in your schema will handle password hashing // Send an email to the retail distributor with the new password await sendEmail({ to: retailDistributor.email, from: process.env.SEND_EMAIL_FROM, subject: `Cheminova Password Recovery`, html: `Your new password is: ${newPassword}

If you did not request this, please ignore this email.`, }); // Respond with success message return res.status(200).json({ success: true, message: `Email sent to ${retailDistributor.email} successfully`, }); } catch (error) { console.error("Error during password reset:", error); return res.status(500).json({ message: error.message || "Something went wrong!", }); } }; export const UpdateProfileRD = async (req, res) => { const { name, mobile_number } = req.body; // Only expecting name from the request body const userId = req.user._id; // User ID from authenticated user try { // Find the RetailDistributor by user ID const retailDistributor = await RetailDistributor.findById(userId); if (!retailDistributor) { return res.status(404).json({ message: "Retail Distributor not found" }); } // Assuming you have an 'isVerified' field in your RetailDistributor schema // Update name if provided if (name) { retailDistributor.name = name; retailDistributor.mobile_number = mobile_number ? mobile_number : retailDistributor.mobile_number; } else { return res.status(400).json({ message: "Name is required" }); } // Save the updated RetailDistributor await retailDistributor.save(); return res.status(200).json({ retailDistributor, message: "Profile updated successfully", }); } catch (error) { return res.status(500).json({ message: error.message || "Server error!", }); } }; export const getmyProfileRD = async (req, res) => { try { // Fetch the profile data using the authenticated user's ID const myData = await RetailDistributor.findById(req.user?._id); if (myData) { return res.status(200).json({ success: true, message: "Profile fetched successfully!", myData, }); } else { return res.status(404).json({ success: false, message: "Retail Distributor not found", }); } } catch (error) { return res.status(500).json({ success: false, message: error.message || "Something went wrong!", }); } }; //reatil distributor mapping export const getAllRetailDistributorApproved = async (req, res) => { try { // Extract query parameters const { page = 1, show = 10, tradename, name, mobile_number, principaldistributor, } = req.query; const skip = (page - 1) * show; // Build the aggregation pipeline let pipeline = [ { $lookup: { from: "kycs", // Assuming your KYC collection is named "kycs" localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, // Unwind kycDetails and allow null/empty arrays { $lookup: { from: "users", // Assuming your User collection is named "users" localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, // Unwind principalDetails and allow null/empty arrays // Lookup for mappedTM (Territory Manager) { $lookup: { from: "territorymanagers", // Assuming your Territory Manager collection localField: "mappedTM", foreignField: "_id", as: "mappedTMDetails", }, }, { $unwind: { path: "$mappedTMDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedTMDetails and allow null/empty arrays // Lookup for mappedSC (Sales Coordinator) { $lookup: { from: "salescoordinators", // Assuming your Sales Coordinator collection localField: "mappedSC", foreignField: "_id", as: "mappedSCDetails", }, }, { $unwind: { path: "$mappedSCDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedSCDetails and allow null/empty arrays // Filter to ensure data exists in kyc or principalDetails { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, // Ensure KYC exists { "principalDetails.name": { $exists: true } }, // Ensure Principal Distributor exists ], }, }, ]; // Add filters based on query parameters // Filter by KYC trade_name (case-insensitive) if (tradename) { pipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name (case-insensitive) if (principaldistributor) { pipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name (RetailDistributor model's name) if (name) { pipeline.push({ $match: { name: new RegExp(name, "i") }, // Case-insensitive search for name }); } // Filter by mobile_number (RetailDistributor model's mobile number) if (mobile_number) { pipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, // Case-insensitive search for mobile_number }); } // Project only the required fields pipeline.push({ $project: { _id: 1, // RetailDistributor ID uniqueId: 1, // RetailDistributor uniqueId name: 1, // RetailDistributor name mobile_number: 1, // RetailDistributor mobile_number email: 1, // RetailDistributor email "kycDetails.trade_name": 1, // Only trade_name from kyc "principalDetails.name": 1, // Only name from principal_distributer "mappedTMDetails.name": 1, // Only name from mappedTM (Territory Manager) "mappedSCDetails.name": 1, // Only name from mappedSC (Sales Coordinator) createdAt: 1, // For sorting }, }); // Pagination and sorting pipeline.push({ $sort: { createdAt: -1 } }); pipeline.push({ $skip: skip }); pipeline.push({ $limit: parseInt(show) }); // Execute the aggregation pipeline const Retaildistributor = await RetailDistributor.aggregate(pipeline); // Get total count of documents matching the query const countPipeline = [ { $lookup: { from: "kycs", localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, { $lookup: { from: "users", localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, { "principalDetails.name": { $exists: true } }, ], }, }, ]; // Apply search filters to count query // Filter by KYC trade_name if (tradename) { countPipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name if (principaldistributor) { countPipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name if (name) { countPipeline.push({ $match: { name: new RegExp(name, "i") }, }); } // Filter by mobile_number if (mobile_number) { countPipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, }); } // Get the total count of filtered documents const total_data = await RetailDistributor.aggregate([ ...countPipeline, { $count: "total" }, ]); const totalCount = total_data[0]?.total || 0; // Ensure count is zero if no data found // Send the response with pagination data res.status(200).json({ success: true, total_data: totalCount, total_pages: Math.ceil(totalCount / show), Retaildistributor, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; export const getAllRetailDistributorwithTotalorder = async (req, res) => { try { const { page = 1, show = 10, tradename, name, mobile_number, principaldistributor, } = req.query; const skip = (page - 1) * show; // Build the aggregation pipeline let pipeline = [ { $lookup: { from: "kycs", // KYC collection localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, { $lookup: { from: "users", // Principal Distributor collection localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: "territorymanagers", // Territory Manager collection localField: "mappedTM", foreignField: "_id", as: "mappedTMDetails", }, }, { $unwind: { path: "$mappedTMDetails", preserveNullAndEmptyArrays: true }, }, { $lookup: { from: "salescoordinators", // Sales Coordinator collection localField: "mappedSC", foreignField: "_id", as: "mappedSCDetails", }, }, { $unwind: { path: "$mappedSCDetails", preserveNullAndEmptyArrays: true }, }, ]; // Add filters based on query parameters const matchConditions = {}; if (tradename) matchConditions["kycDetails.trade_name"] = new RegExp(tradename, "i"); if (name) matchConditions["name"] = new RegExp(name, "i"); if (mobile_number) matchConditions["mobile_number"] = new RegExp(mobile_number, "i"); if (principaldistributor) matchConditions["principalDetails.name"] = new RegExp( principaldistributor, "i" ); if (Object.keys(matchConditions).length) { pipeline.push({ $match: matchConditions }); } // Project required fields early pipeline.push({ $project: { _id: 1, uniqueId: 1, name: 1, mobile_number: 1, email: 1, "kycDetails.trade_name": 1, "principalDetails.name": 1, "mappedTMDetails.name": 1, "mappedSCDetails.name": 1, createdAt: 1, }, }); // Pagination and sorting pipeline.push({ $sort: { createdAt: -1 } }); pipeline.push({ $skip: skip }); pipeline.push({ $limit: parseInt(show) }); // Execute the main aggregation pipeline const Retaildistributor = await RetailDistributor.aggregate(pipeline); // Aggregate orders data for each distributor const orderStats = await RdOrder.aggregate([ { $match: { addedBy: { $in: Retaildistributor.map((user) => user._id) } }, }, { $group: { _id: "$addedBy", // Group by distributor ID totalOrders: { $sum: 1 }, // Count total orders lastOrderDate: { $max: "$createdAt" }, // Get last order date }, }, ]); // Combine order stats with Retaildistributor data const usersWithOrderStats = Retaildistributor.map((user) => { const orderData = orderStats.find( (order) => order._id.toString() === user._id.toString() ); return { ...user, totalOrders: orderData ? orderData.totalOrders : 0, lastOrderDate: orderData ? orderData.lastOrderDate : null, }; }); // Get total count of documents matching the query const countPipeline = [{ $match: matchConditions }, { $count: "total" }]; const total_data = await RetailDistributor.aggregate(countPipeline); const totalCount = total_data[0]?.total || 0; // Send the response res.status(200).json({ success: true, total_data: totalCount, total_pages: Math.ceil(totalCount / show), Retaildistributor: usersWithOrderStats, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; //get RD by Id export const getRDId = async (req, res) => { try { const { id } = req.params; // console.log(id); // Fetch the KYC document from the database by ID const RD = await RetailDistributor.findById(id) .populate("principal_distributer", "name email phone") .populate("addedBy") .populate("kyc") .populate("mappedTM") .populate("mappedSC"); // Check if the KYC document exists if (!RD) { return res.status(404).json({ message: "No RetailDistributor found" }); } // console.log(RD); // Send the fetched KYC document as a response res.status(200).json(RD); } catch (error) { // Handle any errors that occur during the fetch operation res.status(500).json({ message: "Server Error", error }); } }; //mapping export const getAllRDbytmid = async (req, res) => { try { // Extract query parameters const { page = 1, show = 10, tradename, name, mobile_number, principaldistributor, } = req.query; const { mappedTMId } = req.params; // Extract mappedTM ID from request params // Convert mappedTMId to ObjectId if it's a valid ObjectId string let mappedTMObjectId; try { mappedTMObjectId = mongoose.Types.ObjectId(mappedTMId); } catch (error) { return res.status(400).json({ message: "Invalid mappedTM ID format" }); } const skip = (page - 1) * show; // Build the aggregation pipeline let pipeline = [ { $match: { mappedTM: mappedTMObjectId, // Filter by mappedTM ObjectId }, }, { $lookup: { from: "kycs", // Assuming your KYC collection is named "kycs" localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, // Unwind kycDetails and allow null/empty arrays { $lookup: { from: "users", // Assuming your User collection is named "users" localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, // Unwind principalDetails and allow null/empty arrays // Lookup for mappedTM (Territory Manager) { $lookup: { from: "territorymanagers", // Assuming your Territory Manager collection localField: "mappedTM", foreignField: "_id", as: "mappedTMDetails", }, }, { $unwind: { path: "$mappedTMDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedTMDetails and allow null/empty arrays // Lookup for mappedSC (Sales Coordinator) { $lookup: { from: "salescoordinators", // Assuming your Sales Coordinator collection localField: "mappedSC", foreignField: "_id", as: "mappedSCDetails", }, }, { $unwind: { path: "$mappedSCDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedSCDetails and allow null/empty arrays // Filter to ensure data exists in kyc or principalDetails { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, // Ensure KYC exists { "principalDetails.name": { $exists: true } }, // Ensure Principal Distributor exists ], }, }, ]; // Add filters based on query parameters // Filter by KYC trade_name (case-insensitive) if (tradename) { pipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name (case-insensitive) if (principaldistributor) { pipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name (RetailDistributor model's name) if (name) { pipeline.push({ $match: { name: new RegExp(name, "i") }, // Case-insensitive search for name }); } // Filter by mobile_number (RetailDistributor model's mobile number) if (mobile_number) { pipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, // Case-insensitive search for mobile_number }); } // Project only the required fields pipeline.push({ $project: { _id: 1, // RetailDistributor ID uniqueId: 1, // RetailDistributor uniqueId name: 1, // RetailDistributor name mobile_number: 1, // RetailDistributor mobile_number email: 1, // RetailDistributor email "kycDetails.trade_name": 1, // Only trade_name from kyc "principalDetails.name": 1, // Only name from principal_distributer "mappedTMDetails.name": 1, // Only name from mappedTM (Territory Manager) "mappedSCDetails.name": 1, // Only name from mappedSC (Sales Coordinator) createdAt: 1, // For sorting }, }); // Pagination and sorting pipeline.push({ $sort: { createdAt: -1 } }); pipeline.push({ $skip: skip }); pipeline.push({ $limit: parseInt(show) }); // Execute the aggregation pipeline const Retaildistributor = await RetailDistributor.aggregate(pipeline); // Get total count of documents matching the query const countPipeline = [ { $match: { mappedTM: mappedTMObjectId, // Filter by mappedTM ObjectId }, }, { $lookup: { from: "kycs", localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, { $lookup: { from: "users", localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, { "principalDetails.name": { $exists: true } }, ], }, }, ]; // Apply search filters to count query // Filter by KYC trade_name if (tradename) { countPipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name if (principaldistributor) { countPipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name if (name) { countPipeline.push({ $match: { name: new RegExp(name, "i") }, }); } // Filter by mobile_number if (mobile_number) { countPipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, }); } // Get the total count of filtered documents const total_data = await RetailDistributor.aggregate([ ...countPipeline, { $count: "total" }, ]); const totalCount = total_data[0]?.total || 0; // Ensure count is zero if no data found // Send the response with pagination data res.status(200).json({ success: true, total_data: totalCount, total_pages: Math.ceil(totalCount / show), Retaildistributor, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; export const getAllRDbyscid = async (req, res) => { try { // Extract query parameters const { page = 1, show = 10, tradename, name, mobile_number, principaldistributor, } = req.query; const { mappedSCId } = req.params; // Extract mappedTM ID from request params // Convert mappedSCId to ObjectId if it's a valid ObjectId string let mappedSCObjectId; try { mappedSCObjectId = mongoose.Types.ObjectId(mappedSCId); } catch (error) { return res.status(400).json({ message: "Invalid mappedSC ID format" }); } const skip = (page - 1) * show; // Build the aggregation pipeline let pipeline = [ { $match: { mappedSC: mappedSCObjectId, // Filter by mappedSC ObjectId }, }, { $lookup: { from: "kycs", // Assuming your KYC collection is named "kycs" localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, // Unwind kycDetails and allow null/empty arrays { $lookup: { from: "users", // Assuming your User collection is named "users" localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, // Unwind principalDetails and allow null/empty arrays // Lookup for mappedTM (Territory Manager) { $lookup: { from: "territorymanagers", // Assuming your Territory Manager collection localField: "mappedTM", foreignField: "_id", as: "mappedTMDetails", }, }, { $unwind: { path: "$mappedTMDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedTMDetails and allow null/empty arrays // Lookup for mappedSC (Sales Coordinator) { $lookup: { from: "salescoordinators", // Assuming your Sales Coordinator collection localField: "mappedSC", foreignField: "_id", as: "mappedSCDetails", }, }, { $unwind: { path: "$mappedSCDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedSCDetails and allow null/empty arrays // Filter to ensure data exists in kyc or principalDetails { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, // Ensure KYC exists { "principalDetails.name": { $exists: true } }, // Ensure Principal Distributor exists ], }, }, ]; // Add filters based on query parameters // Filter by KYC trade_name (case-insensitive) if (tradename) { pipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name (case-insensitive) if (principaldistributor) { pipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name (RetailDistributor model's name) if (name) { pipeline.push({ $match: { name: new RegExp(name, "i") }, // Case-insensitive search for name }); } // Filter by mobile_number (RetailDistributor model's mobile number) if (mobile_number) { pipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, // Case-insensitive search for mobile_number }); } // Project only the required fields pipeline.push({ $project: { _id: 1, // RetailDistributor ID uniqueId: 1, // RetailDistributor uniqueId name: 1, // RetailDistributor name mobile_number: 1, // RetailDistributor mobile_number email: 1, // RetailDistributor email "kycDetails.trade_name": 1, // Only trade_name from kyc "principalDetails.name": 1, // Only name from principal_distributer "mappedTMDetails.name": 1, // Only name from mappedTM (Territory Manager) "mappedSCDetails.name": 1, // Only name from mappedSC (Sales Coordinator) createdAt: 1, // For sorting }, }); // Pagination and sorting pipeline.push({ $sort: { createdAt: -1 } }); pipeline.push({ $skip: skip }); pipeline.push({ $limit: parseInt(show) }); // Execute the aggregation pipeline const Retaildistributor = await RetailDistributor.aggregate(pipeline); // Get total count of documents matching the query const countPipeline = [ { $match: { mappedSC: mappedSCObjectId, // Filter by mappedTM ObjectId }, }, { $lookup: { from: "kycs", localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, { $lookup: { from: "users", localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, { "principalDetails.name": { $exists: true } }, ], }, }, ]; // Apply search filters to count query // Filter by KYC trade_name if (tradename) { countPipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by principal_distributer name if (principaldistributor) { countPipeline.push({ $match: { "principalDetails.name": new RegExp(principaldistributor, "i"), }, }); } // Filter by name if (name) { countPipeline.push({ $match: { name: new RegExp(name, "i") }, }); } // Filter by mobile_number if (mobile_number) { countPipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, }); } // Get the total count of filtered documents const total_data = await RetailDistributor.aggregate([ ...countPipeline, { $count: "total" }, ]); const totalCount = total_data[0]?.total || 0; // Ensure count is zero if no data found // Send the response with pagination data res.status(200).json({ success: true, total_data: totalCount, total_pages: Math.ceil(totalCount / show), Retaildistributor, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; export const getAllRDbypdid = async (req, res) => { try { // Extract query parameters const { page = 1, show = 10, tradename, name, mobile_number } = req.query; const { mappedPDId } = req.params; // Extract mappedTM ID from request params // Convert mappedPDId to ObjectId if it's a valid ObjectId string let mappedPDObjectId; try { mappedPDObjectId = mongoose.Types.ObjectId(mappedPDId); } catch (error) { return res.status(400).json({ message: "Invalid mappedPD ID format" }); } const skip = (page - 1) * show; // Build the aggregation pipeline let pipeline = [ { $match: { principal_distributer: mappedPDObjectId, // Filter by principal_distributer ObjectId }, }, { $lookup: { from: "kycs", // Assuming your KYC collection is named "kycs" localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, // Unwind kycDetails and allow null/empty arrays { $lookup: { from: "users", // Assuming your User collection is named "users" localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, // Unwind principalDetails and allow null/empty arrays // Lookup for mappedTM (Territory Manager) { $lookup: { from: "territorymanagers", // Assuming your Territory Manager collection localField: "mappedTM", foreignField: "_id", as: "mappedTMDetails", }, }, { $unwind: { path: "$mappedTMDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedTMDetails and allow null/empty arrays // Lookup for mappedSC (Sales Coordinator) { $lookup: { from: "salescoordinators", // Assuming your Sales Coordinator collection localField: "mappedSC", foreignField: "_id", as: "mappedSCDetails", }, }, { $unwind: { path: "$mappedSCDetails", preserveNullAndEmptyArrays: true }, }, // Unwind mappedSCDetails and allow null/empty arrays // Filter to ensure data exists in kyc or principalDetails { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, // Ensure KYC exists { "principalDetails.name": { $exists: true } }, // Ensure Principal Distributor exists ], }, }, ]; // Add filters based on query parameters // Filter by KYC trade_name (case-insensitive) if (tradename) { pipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by name (RetailDistributor model's name) if (name) { pipeline.push({ $match: { name: new RegExp(name, "i") }, // Case-insensitive search for name }); } // Filter by mobile_number (RetailDistributor model's mobile number) if (mobile_number) { pipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, // Case-insensitive search for mobile_number }); } // Project only the required fields pipeline.push({ $project: { _id: 1, // RetailDistributor ID uniqueId: 1, // RetailDistributor uniqueId name: 1, // RetailDistributor name mobile_number: 1, // RetailDistributor mobile_number email: 1, // RetailDistributor email "kycDetails.trade_name": 1, // Only trade_name from kyc "mappedTMDetails.name": 1, // Only name from mappedTM (Territory Manager) "mappedSCDetails.name": 1, // Only name from mappedSC (Sales Coordinator) "principalDetails.name": 1, // Only name from principal_distributer createdAt: 1, // For sorting }, }); // Pagination and sorting pipeline.push({ $sort: { createdAt: -1 } }); pipeline.push({ $skip: skip }); pipeline.push({ $limit: parseInt(show) }); // Execute the aggregation pipeline const Retaildistributor = await RetailDistributor.aggregate(pipeline); // Get total count of documents matching the query const countPipeline = [ { $match: { principal_distributer: mappedPDObjectId, // Filter by mappedTM ObjectId }, }, { $lookup: { from: "kycs", localField: "kyc", foreignField: "_id", as: "kycDetails", }, }, { $unwind: { path: "$kycDetails", preserveNullAndEmptyArrays: true } }, { $lookup: { from: "users", localField: "principal_distributer", foreignField: "_id", as: "principalDetails", }, }, { $unwind: { path: "$principalDetails", preserveNullAndEmptyArrays: true, }, }, { $match: { $or: [ { "kycDetails.trade_name": { $exists: true } }, { "principalDetails.name": { $exists: true } }, ], }, }, ]; // Apply search filters to count query // Filter by KYC trade_name if (tradename) { countPipeline.push({ $match: { "kycDetails.trade_name": new RegExp(tradename, "i") }, }); } // Filter by name if (name) { countPipeline.push({ $match: { name: new RegExp(name, "i") }, }); } // Filter by mobile_number if (mobile_number) { countPipeline.push({ $match: { mobile_number: new RegExp(mobile_number, "i") }, }); } // Get the total count of filtered documents const total_data = await RetailDistributor.aggregate([ ...countPipeline, { $count: "total" }, ]); const totalCount = total_data[0]?.total || 0; // Ensure count is zero if no data found // Send the response with pagination data res.status(200).json({ success: true, total_data: totalCount, total_pages: Math.ceil(totalCount / show), Retaildistributor, }); } catch (error) { console.error(error); res.status(500).json({ message: "Server Error", error }); } }; export const updateRDMapped = async (req, res) => { try { const { id } = req.params; const { principal_distributor, mappedTM, mappedSC } = req.body; // console.log(principal_distributor); // Find the RetailDistributor document by ID const RD = await RetailDistributor.findById(id); if (!RD) { return res.status(404).json({ message: "RetailDistributor not found" }); } // Update the fields if provided in the request body if (principal_distributor) { RD.principal_distributer = principal_distributor; } if (mappedTM) { RD.mappedTM = mappedTM; } if (mappedSC) { RD.mappedSC = mappedSC; } // Save the updated document await RD.save(); res.status(200).json({ message: "RetailDistributor record updated successfully", data: RD, }); } catch (error) { // Handle any errors during the update res.status(500).json({ message: "Error updating RD record", error: error.message, }); } }; export const updateunmapRD = async (req, res) => { try { const { id } = req.params; const { principal_distributor, mappedTM, mappedSC } = req.body; // Find the RetailDistributor document by ID const RD = await RetailDistributor.findById(id); if (!RD) { return res.status(404).json({ message: "RetailDistributor not found" }); } // Update the fields if provided in the request body if (principal_distributor) { RD.principal_distributer = null; } if (mappedTM) { RD.mappedTM = null; } if (mappedSC) { RD.mappedSC = null; } // Save the updated document await RD.save(); res.status(200).json({ message: "RetailDistributor record updated successfully", data: RD, }); } catch (error) { // Handle any errors during the update res.status(500).json({ message: "Error updating RD record", error: error.message, }); } }; export const saveFCMTokenForRD = async (req, res) => { const { fcmToken } = req.body; const userId = req.user._id; try { // Fetch the current FCM token for the user const user = await RetailDistributor.findById(userId); if (!user) { return res.status(404).send("User not found"); } // Check if the new FCM token is different from the current one if (user.fcm_token && user.fcm_token === fcmToken) { return res.status(200).send("FCM Token is already up to date"); } // Update the FCM token user.fcm_token = fcmToken; await user.save(); res.status(200).send("FCM Token saved successfully"); } catch (error) { console.error("Error saving FCM Token:", error); res.status(500).send("Internal Server Error"); } };