diff --git a/Utils/generatepassword.js b/Utils/generatepassword.js new file mode 100644 index 0000000..e97752a --- /dev/null +++ b/Utils/generatepassword.js @@ -0,0 +1,43 @@ +export const generatePassword = (name, email) => { + // Combine name and email, and convert to lowercase + const combinedStr = (name + email).toLowerCase(); + + // Define character pools + const specialChars = "@#*"; + const numbers = "0123456789"; + const alphaLower = combinedStr.match(/[a-z]/g) || []; + const alphaUpper = combinedStr.match(/[A-Z]/g) || []; + + // Ensure at least one character from each category + const specialChar = specialChars.charAt( + Math.floor(Math.random() * specialChars.length) + ); + const numberChar = numbers.charAt(Math.floor(Math.random() * numbers.length)); + const lowerChar = + alphaLower.length > 0 + ? alphaLower[Math.floor(Math.random() * alphaLower.length)] + : String.fromCharCode(Math.floor(Math.random() * 26) + 97); + const upperChar = + alphaUpper.length > 0 + ? alphaUpper[Math.floor(Math.random() * alphaUpper.length)] + : String.fromCharCode(Math.floor(Math.random() * 26) + 65); + + // Combine required characters + let passwordChars = [specialChar, numberChar, lowerChar, upperChar]; + + // Fill remaining positions with random characters from the combined string + const allChars = combinedStr + specialChars + numbers; + while (passwordChars.length < 8) { + passwordChars.push( + allChars.charAt(Math.floor(Math.random() * allChars.length)) + ); + } + + // Shuffle characters to ensure randomness + passwordChars = passwordChars.sort(() => Math.random() - 0.5); + + // Generate password of length 8 + const password = passwordChars.slice(0, 8).join(""); + + return password; +}; \ No newline at end of file diff --git a/public/temp/tmp-1-1725865675324 b/public/temp/tmp-1-1725865675324 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-1-1725865675324 differ diff --git a/public/temp/tmp-1-1725865720729 b/public/temp/tmp-1-1725865720729 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-1-1725865720729 differ diff --git a/public/temp/tmp-1-1725866035097 b/public/temp/tmp-1-1725866035097 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-1-1725866035097 differ diff --git a/public/temp/tmp-1-1725866756642 b/public/temp/tmp-1-1725866756642 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-1-1725866756642 differ diff --git a/public/temp/tmp-10-1725865734490 b/public/temp/tmp-10-1725865734490 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-10-1725865734490 differ diff --git a/public/temp/tmp-10-1725866667847 b/public/temp/tmp-10-1725866667847 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-10-1725866667847 differ diff --git a/public/temp/tmp-10-1725866813645 b/public/temp/tmp-10-1725866813645 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-10-1725866813645 differ diff --git a/public/temp/tmp-11-1725865734493 b/public/temp/tmp-11-1725865734493 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-11-1725865734493 differ diff --git a/public/temp/tmp-11-1725866667850 b/public/temp/tmp-11-1725866667850 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-11-1725866667850 differ diff --git a/public/temp/tmp-11-1725866813648 b/public/temp/tmp-11-1725866813648 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-11-1725866813648 differ diff --git a/public/temp/tmp-12-1725865734496 b/public/temp/tmp-12-1725865734496 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-12-1725865734496 differ diff --git a/public/temp/tmp-12-1725866667853 b/public/temp/tmp-12-1725866667853 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-12-1725866667853 differ diff --git a/public/temp/tmp-12-1725866813651 b/public/temp/tmp-12-1725866813651 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-12-1725866813651 differ diff --git a/public/temp/tmp-2-1725865675329 b/public/temp/tmp-2-1725865675329 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-2-1725865675329 differ diff --git a/public/temp/tmp-2-1725865720732 b/public/temp/tmp-2-1725865720732 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-2-1725865720732 differ diff --git a/public/temp/tmp-2-1725866035100 b/public/temp/tmp-2-1725866035100 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-2-1725866035100 differ diff --git a/public/temp/tmp-2-1725866756647 b/public/temp/tmp-2-1725866756647 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-2-1725866756647 differ diff --git a/public/temp/tmp-3-1725865675334 b/public/temp/tmp-3-1725865675334 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-3-1725865675334 differ diff --git a/public/temp/tmp-3-1725865720736 b/public/temp/tmp-3-1725865720736 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-3-1725865720736 differ diff --git a/public/temp/tmp-3-1725866035104 b/public/temp/tmp-3-1725866035104 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-3-1725866035104 differ diff --git a/public/temp/tmp-3-1725866756651 b/public/temp/tmp-3-1725866756651 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-3-1725866756651 differ diff --git a/public/temp/tmp-4-1725865675338 b/public/temp/tmp-4-1725865675338 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-4-1725865675338 differ diff --git a/public/temp/tmp-4-1725865720739 b/public/temp/tmp-4-1725865720739 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-4-1725865720739 differ diff --git a/public/temp/tmp-4-1725866035107 b/public/temp/tmp-4-1725866035107 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-4-1725866035107 differ diff --git a/public/temp/tmp-4-1725866756655 b/public/temp/tmp-4-1725866756655 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-4-1725866756655 differ diff --git a/public/temp/tmp-5-1725865675341 b/public/temp/tmp-5-1725865675341 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-5-1725865675341 differ diff --git a/public/temp/tmp-5-1725865720741 b/public/temp/tmp-5-1725865720741 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-5-1725865720741 differ diff --git a/public/temp/tmp-5-1725866035109 b/public/temp/tmp-5-1725866035109 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-5-1725866035109 differ diff --git a/public/temp/tmp-5-1725866756657 b/public/temp/tmp-5-1725866756657 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-5-1725866756657 differ diff --git a/public/temp/tmp-6-1725865675345 b/public/temp/tmp-6-1725865675345 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-6-1725865675345 differ diff --git a/public/temp/tmp-6-1725865720743 b/public/temp/tmp-6-1725865720743 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-6-1725865720743 differ diff --git a/public/temp/tmp-6-1725866035112 b/public/temp/tmp-6-1725866035112 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-6-1725866035112 differ diff --git a/public/temp/tmp-6-1725866756670 b/public/temp/tmp-6-1725866756670 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-6-1725866756670 differ diff --git a/public/temp/tmp-7-1725865734472 b/public/temp/tmp-7-1725865734472 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-7-1725865734472 differ diff --git a/public/temp/tmp-7-1725866667838 b/public/temp/tmp-7-1725866667838 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-7-1725866667838 differ diff --git a/public/temp/tmp-7-1725866813627 b/public/temp/tmp-7-1725866813627 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-7-1725866813627 differ diff --git a/public/temp/tmp-8-1725865734474 b/public/temp/tmp-8-1725865734474 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-8-1725865734474 differ diff --git a/public/temp/tmp-8-1725866667841 b/public/temp/tmp-8-1725866667841 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-8-1725866667841 differ diff --git a/public/temp/tmp-8-1725866813629 b/public/temp/tmp-8-1725866813629 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-8-1725866813629 differ diff --git a/public/temp/tmp-9-1725865734476 b/public/temp/tmp-9-1725865734476 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-9-1725865734476 differ diff --git a/public/temp/tmp-9-1725866667845 b/public/temp/tmp-9-1725866667845 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-9-1725866667845 differ diff --git a/public/temp/tmp-9-1725866813631 b/public/temp/tmp-9-1725866813631 new file mode 100644 index 0000000..3e58726 Binary files /dev/null and b/public/temp/tmp-9-1725866813631 differ diff --git a/resources/KYC/KycController.js b/resources/KYC/KycController.js index ae1191b..a12cb84 100644 --- a/resources/KYC/KycController.js +++ b/resources/KYC/KycController.js @@ -6,10 +6,13 @@ import { rejectKYC } from "../../Utils/rejectKyc.js"; import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js"; import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js"; import { Notification } from "../Notification/notificationModal.js"; - +import RetailDistributor from "../RetailDistributor/RetailDistributorModel.js"; +import { generatePassword } from "../../Utils/generatepassword.js"; +import sendEmail, { sendOtp } from "../../Utils/sendEmail.js"; export const createKyc = async (req, res) => { const { name, + email, trade_name, address, state, @@ -76,6 +79,7 @@ export const createKyc = async (req, res) => { // Create KYC document const kyc = await KYC.create({ name, + email, trade_name, address, state, @@ -113,6 +117,7 @@ export const createKyc = async (req, res) => { export const createretaildistributor = async (req, res) => { const { name, + email, trade_name, address, state, @@ -187,6 +192,7 @@ export const createretaildistributor = async (req, res) => { // Create KYC document const kycData = { name, + email, trade_name, address, state, @@ -207,12 +213,41 @@ export const createretaildistributor = async (req, res) => { }; const kyc = await KYC.create(kycData); - - if (kyc) { - return res - .status(201) - .json({ success: true, kyc, message: "KYC created" }); + if (!kyc) { + return res.status(400).json({ message: "Failed to create KYC." }); } + + // Generate password + const password = generatePassword(name, email); + // Create RetailDistributor document + const retailDistributorData = { + name, + email, + mobile_number, + kyc: kyc._id, + password, + }; + const retailDistributor = new RetailDistributor(retailDistributorData); + await retailDistributor.save(); + // Send email with the new password + await sendEmail({ + to: `${email}`, // Change to your recipient + from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender + subject: `Cheminova Account Created`, + html: `Your Retail Distributor Account is created successfully. +
name is: ${name} +
+
MobileNumber is: ${mobile_number}
+
Email is: ${email}
+
password is: ${password}

If you have not requested this email, please ignore it.`, + }); + // Send response + res.status(201).json({ + success: true, + kyc, + retailDistributor, + message: "Retail Distributor created successfully", + }); } catch (error) { res.status(500).json({ success: false, @@ -276,12 +311,17 @@ export const getAllKycApproved = async (req, res) => { // If a principal distributor name is provided, find the matching distributor IDs let principalDistributerIds = []; if (principaldistributor) { - const matchingDistributors = await mongoose.model('User').find({ - name: new RegExp(principaldistributor, "i") // Case-insensitive search for principal distributor name - }, '_id'); // Only return the _id field + const matchingDistributors = await mongoose.model("User").find( + { + name: new RegExp(principaldistributor, "i"), // Case-insensitive search for principal distributor name + }, + "_id" + ); // Only return the _id field + + principalDistributerIds = matchingDistributors.map( + (distributor) => distributor._id + ); - principalDistributerIds = matchingDistributors.map(distributor => distributor._id); - // If matching distributors are found, add the IDs to the main query if (principalDistributerIds.length > 0) { query.principal_distributer = { $in: principalDistributerIds }; @@ -312,7 +352,6 @@ export const getAllKycApproved = async (req, res) => { } }; - // Get Single KYC export const getKycById = async (req, res) => { try { @@ -368,6 +407,35 @@ export const updateKycStatus = async (req, res) => { added_for: kyc.addedBy, // userType: req.userType, }); + // Generate a secure password for RetailDistributor + const password = generatePassword(kyc.name, kyc.email); + + // Create RetailDistributor document + const retailDistributorData = { + name: kyc.name, + email: kyc.email, + mobile_number: kyc.mobile_number, + principal_distributer: kyc.principal_distributer, + addedBy: kyc.addedBy, + userType: kyc.userType, + kyc: kyc._id, + password, + }; + + const retailDistributor = new RetailDistributor(retailDistributorData); + await retailDistributor.save(); + // Send email with the new password + await sendEmail({ + to: `${kyc.email}`, // Change to your recipient + from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender + subject: `Cheminova Account Created`, + html: `Your Retail Distributor Account is created successfully. +
name is: ${kyc.name} +
+
MobileNumber is: ${kyc.mobile_number}
+
Email is: ${kyc.email}
+
password is: ${password}

If you have not requested this email, please ignore it.`, + }); } if (status === "reject") { console.log("inside reject "); @@ -428,7 +496,7 @@ export const getAllPrincipalDistributers = async (req, res) => { // console.log(filter); // Fetch the principal distributors based on the filter const principalDistributers = await User.find(filter); -// console.log(principalDistributers); + // console.log(principalDistributers); // Send the fetched data as a response if (principalDistributers.length > 0) { res.status(200).json(principalDistributers); diff --git a/resources/KYC/KycModel.js b/resources/KYC/KycModel.js index a40517d..00461a0 100644 --- a/resources/KYC/KycModel.js +++ b/resources/KYC/KycModel.js @@ -7,6 +7,11 @@ const KycSchema = new Schema( required: true, maxlength: [50, "Name cannot be more than 50 characters"], }, + email: { + type: String, + required: true, + unique: true, + }, trade_name: { type: String, required: true, @@ -95,14 +100,6 @@ const KycSchema = new Schema( // required: true, enum: ["SalesCoOrdinator", "TerritoryManager"], }, - mappedTM: { - type: mongoose.Schema.Types.ObjectId, - ref: "TerritoryManager", - }, - mappedSC: { - type: mongoose.Schema.Types.ObjectId, - ref: "SalesCoOrdinator", - }, notes: [ { message: { @@ -128,12 +125,4 @@ const KycSchema = new Schema( { timestamps: true } ); // Pre-save middleware to set 'mapped' based on 'userType' -KycSchema.pre("save", function (next) { - if (this.userType === "SalesCoOrdinator" && this.addedBy) { - this.mappedSC = this.addedBy; - } else if (this.userType === "TerritoryManager" && this.addedBy) { - this.mappedTM = this.addedBy; - } - next(); -}); export const KYC = model("KYC", KycSchema); diff --git a/resources/RetailDistributor/RetailDistributorController.js b/resources/RetailDistributor/RetailDistributorController.js new file mode 100644 index 0000000..e69de29 diff --git a/resources/RetailDistributor/RetailDistributorModel.js b/resources/RetailDistributor/RetailDistributorModel.js new file mode 100644 index 0000000..a44164f --- /dev/null +++ b/resources/RetailDistributor/RetailDistributorModel.js @@ -0,0 +1,131 @@ +import dotenv from "dotenv"; +dotenv.config(); +import mongoose from "mongoose"; +import validator from "validator"; +import bcrypt from "bcryptjs"; +import jwt from "jsonwebtoken"; +import crypto from "crypto"; + +const RetailDistributorSchema = new mongoose.Schema( + { + uniqueId: { + type: String, + unique: true, + }, + designation: { + type: String, + required: true, + default: "Retail Distributor", + }, + name: { + type: String, + required: true, + maxlength: [50, "Name cannot be more than 50 characters"], + }, + email: { + type: String, + required: false, + unique: true, + validate: [validator.isEmail, "Please enter a valid Email"], + }, + password: { + type: String, + minLength: [6, "Password should be greater than 6 characters"], + select: false, + }, + mobile_number: { + type: String, + required: true, + }, + principal_distributer: { + type: mongoose.Schema.Types.ObjectId, + ref: "User", + // required: true, + }, + addedBy: { + type: mongoose.Schema.Types.ObjectId, + refPath: "userType", + // required: true, + }, + userType: { + type: String, + // required: true, + enum: ["SalesCoOrdinator", "TerritoryManager"], + }, + mappedTM: { + type: mongoose.Schema.Types.ObjectId, + ref: "TerritoryManager", + }, + mappedSC: { + type: mongoose.Schema.Types.ObjectId, + ref: "SalesCoOrdinator", + }, + kyc: { + type: mongoose.Schema.Types.ObjectId, + ref: "KYC", + }, + resetPasswordToken: String, + resetPasswordExpire: Date, + fcm_token: { + type: String, + unique: true, + }, + + }, + { timestamps: true } +); +// Pre-save middleware to set 'mapped' based on 'userType' +RetailDistributorSchema.pre("save", function (next) { + if (this.userType === "SalesCoOrdinator" && this.addedBy) { + this.mappedSC = this.addedBy; + } else if (this.userType === "TerritoryManager" && this.addedBy) { + this.mappedTM = this.addedBy; + } + next(); +}); +RetailDistributorSchema.pre("save", async function (next) { + if (!this.isModified("password")) { + next(); + } + + this.password = await bcrypt.hash(this.password, 10); +}); + +RetailDistributorSchema.pre("save", function (next) { + if (!this.uniqueId) { + const currentYear = new Date().getFullYear().toString().slice(-2); + const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); + this.uniqueId = `${currentYear}-${randomChars}`; + } + next(); +}); + +// JWT TOKEN +RetailDistributorSchema.methods.getJWTToken = function () { + return jwt.sign({ id: this._id }, process.env.JWT_SECRET); +}; + +// Compare Password +RetailDistributorSchema.methods.comparePassword = async function (password) { + return await bcrypt.compare(password, this.password); +}; + +// Generating Reset Token +RetailDistributorSchema.methods.getResetPasswordToken = function () { + const resetToken = crypto.randomBytes(20).toString("hex"); + + this.resetPasswordToken = crypto + .createHash("sha256") + .update(resetToken) + .digest("hex"); + + this.resetPasswordExpire = Date.now() + 15 * 60 * 1000; // 15 minutes + + return resetToken; +}; + +const RetailDistributor = mongoose.model( + "RetailDistributor", + RetailDistributorSchema +); +export default RetailDistributor; \ No newline at end of file diff --git a/resources/user/userController.js b/resources/user/userController.js index dc3510e..ab3614f 100644 --- a/resources/user/userController.js +++ b/resources/user/userController.js @@ -14,50 +14,50 @@ import fs from "fs"; import path from "path"; import validator from "validator"; import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js"; +import {generatePassword} from "../../Utils/generatepassword.js"; +// const generatePassword = (name, email) => { +// // Combine name and email, and convert to lowercase +// const combinedStr = (name + email).toLowerCase(); -const generatePassword = (name, email) => { - // Combine name and email, and convert to lowercase - const combinedStr = (name + email).toLowerCase(); +// // Define character pools +// const specialChars = "@#*"; +// const numbers = "0123456789"; +// const alphaLower = combinedStr.match(/[a-z]/g) || []; +// const alphaUpper = combinedStr.match(/[A-Z]/g) || []; - // Define character pools - const specialChars = "@#*"; - const numbers = "0123456789"; - const alphaLower = combinedStr.match(/[a-z]/g) || []; - const alphaUpper = combinedStr.match(/[A-Z]/g) || []; +// // Ensure at least one character from each category +// const specialChar = specialChars.charAt( +// Math.floor(Math.random() * specialChars.length) +// ); +// const numberChar = numbers.charAt(Math.floor(Math.random() * numbers.length)); +// const lowerChar = +// alphaLower.length > 0 +// ? alphaLower[Math.floor(Math.random() * alphaLower.length)] +// : String.fromCharCode(Math.floor(Math.random() * 26) + 97); +// const upperChar = +// alphaUpper.length > 0 +// ? alphaUpper[Math.floor(Math.random() * alphaUpper.length)] +// : String.fromCharCode(Math.floor(Math.random() * 26) + 65); - // Ensure at least one character from each category - const specialChar = specialChars.charAt( - Math.floor(Math.random() * specialChars.length) - ); - const numberChar = numbers.charAt(Math.floor(Math.random() * numbers.length)); - const lowerChar = - alphaLower.length > 0 - ? alphaLower[Math.floor(Math.random() * alphaLower.length)] - : String.fromCharCode(Math.floor(Math.random() * 26) + 97); - const upperChar = - alphaUpper.length > 0 - ? alphaUpper[Math.floor(Math.random() * alphaUpper.length)] - : String.fromCharCode(Math.floor(Math.random() * 26) + 65); +// // Combine required characters +// let passwordChars = [specialChar, numberChar, lowerChar, upperChar]; - // Combine required characters - let passwordChars = [specialChar, numberChar, lowerChar, upperChar]; +// // Fill remaining positions with random characters from the combined string +// const allChars = combinedStr + specialChars + numbers; +// while (passwordChars.length < 8) { +// passwordChars.push( +// allChars.charAt(Math.floor(Math.random() * allChars.length)) +// ); +// } - // Fill remaining positions with random characters from the combined string - const allChars = combinedStr + specialChars + numbers; - while (passwordChars.length < 8) { - passwordChars.push( - allChars.charAt(Math.floor(Math.random() * allChars.length)) - ); - } +// // Shuffle characters to ensure randomness +// passwordChars = passwordChars.sort(() => Math.random() - 0.5); - // Shuffle characters to ensure randomness - passwordChars = passwordChars.sort(() => Math.random() - 0.5); +// // Generate password of length 8 +// const password = passwordChars.slice(0, 8).join(""); - // Generate password of length 8 - const password = passwordChars.slice(0, 8).join(""); - - return password; -}; +// return password; +// }; // export const uploadPrincipaldistributors = async (req, res) => { // try { @@ -1092,6 +1092,52 @@ export const getAllPrincipalDistributorbytmId = catchAsyncErrors( }); } ); +export const getAllPrincipalDistributorbyscId = catchAsyncErrors( + async (req, res, next) => { + const { page = 1, show = 10, name, mobileNumber } = req.query; + const scId = req.params.id; + if (!scId) { + return res + .status(400) + .json({ message: "Please provide Sales coordinator ID" }); + } + // Create a filter object + const filter = { role: "principal-Distributor" }; + + if (name) { + filter.name = { $regex: name, $options: "i" }; // Case-insensitive regex search + } + + if (mobileNumber) { + filter.phone = mobileNumber; + } + + if (scId) { + filter.mappedbySC = scId; + } + + // Calculate pagination values + const limit = parseInt(show, 10); + const skip = (parseInt(page, 10) - 1) * limit; + + // Find users with pagination and filters + const users = await User.find(filter) + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit); + + // Count total users matching the filter + const totalUsers = await User.countDocuments(filter); + + res.status(200).json({ + success: true, + principaldistributor: users, + total_data: totalUsers, + page: parseInt(page, 10), + limit, + }); + } +); export const mappedbyTM = catchAsyncErrors(async (req, res, next) => { const { id } = req.params; // SalesCoOrdinator ID from URL parameters const { mappedby } = req.body; // TerritoryManager ID from request body @@ -1120,6 +1166,34 @@ export const mappedbyTM = catchAsyncErrors(async (req, res, next) => { principalDistributor, }); }); +export const mappedbySC = catchAsyncErrors(async (req, res, next) => { + const { id } = req.params; // SalesCoOrdinator ID from URL parameters + const { mappedbySC } = req.body; // TerritoryManager ID from request body + // console.log(id, mappedby); + // Validate that the TerritoryManager ID is provided + if (!mappedbySC) { + return res.status(400).json({ + success: false, + message: "Sales Coordinator ID (mappedby) is required.", + }); + } + const principalDistributor = await User.findById(id); + + if (!principalDistributor) { + return res.status(404).json({ + success: false, + message: "Principal Distributor not found", + }); + } + // Update the mappedbySC field + principalDistributor.mappedbySC = mappedbySC; + await principalDistributor.save(); + return res.status(200).json({ + success: true, + message: "Principal Distributor updated successfully", + principalDistributor, + }); +}); export const unmappedTMinPrincipalDistributor = catchAsyncErrors( async (req, res, next) => { const { id } = req.params; // Principal Distributor ID from URL parameters @@ -1143,6 +1217,29 @@ export const unmappedTMinPrincipalDistributor = catchAsyncErrors( }); } ); +export const unmappedSCinPrincipalDistributor = catchAsyncErrors( + async (req, res, next) => { + const { id } = req.params; // Principal Distributor ID from URL parameters + // console.log(id); + const principalDistributor = await User.findById(id); + + if (!principalDistributor) { + return res.status(404).json({ + success: false, + message: "Principal Distributor not found", + }); + } + + // Remove the mappedbySC field + principalDistributor.mappedbySC = null; + await principalDistributor.save(); + return res.status(200).json({ + success: true, + message: "Principal Distributor updated successfully", + principalDistributor, + }); + } +); export const getAllEmployee = catchAsyncErrors(async (req, res, next) => { // Assuming your User model is imported as 'User' const employee = await User.find({ role: "Employee" }); diff --git a/resources/user/userModel.js b/resources/user/userModel.js index 592e5a0..79f92e2 100644 --- a/resources/user/userModel.js +++ b/resources/user/userModel.js @@ -62,6 +62,10 @@ const userSchema = new mongoose.Schema( type: mongoose.Schema.Types.ObjectId, ref: "TerritoryManager", }, + mappedbySC: { + type: mongoose.Schema.Types.ObjectId, + ref: "SalesCoOrdinator", + }, accessTo: {}, resetPasswordToken: String, resetPasswordExpire: Date, diff --git a/resources/user/userRoute.js b/resources/user/userRoute.js index 4294d4e..4fc11c1 100644 --- a/resources/user/userRoute.js +++ b/resources/user/userRoute.js @@ -18,6 +18,9 @@ import { getAllPrincipalDistributorbytmId, mappedbyTM, unmappedTMinPrincipalDistributor, + unmappedSCinPrincipalDistributor, + mappedbySC, + getAllPrincipalDistributorbyscId, } from "./userController.js"; import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; @@ -51,18 +54,37 @@ router authorizeRoles("admin"), getAllPrincipalDistributorbytmId ); + router + .route("/getbySCId/:id") + .get( + isAuthenticatedUser, + authorizeRoles("admin"), + getAllPrincipalDistributorbyscId + ); router.put( "/mappedtm/:id", isAuthenticatedUser, authorizeRoles("admin"), mappedbyTM ); +router.put( + "/mappedSC/:id", + isAuthenticatedUser, + authorizeRoles("admin"), + mappedbySC +); router.patch( "/unmap/:id", isAuthenticatedUser, authorizeRoles("admin"), unmappedTMinPrincipalDistributor ); +router.patch( + "/unmapSC/:id", + isAuthenticatedUser, + authorizeRoles("admin"), + unmappedSCinPrincipalDistributor +); router .route("/admin/delete-employee/:id") .delete(