diff --git a/public/uploads/Add-SC.xlsx b/public/uploads/Add-SC.xlsx index 744e40a..eab142e 100644 Binary files a/public/uploads/Add-SC.xlsx and b/public/uploads/Add-SC.xlsx differ diff --git a/public/uploads/Add-TM.xlsx b/public/uploads/Add-TM.xlsx index 49e6ae6..1e7d554 100644 Binary files a/public/uploads/Add-TM.xlsx and b/public/uploads/Add-TM.xlsx differ diff --git a/resources/SalesCoOrdinators/SalesCoOrdinatorController.js b/resources/SalesCoOrdinators/SalesCoOrdinatorController.js index bef5b45..965df20 100644 --- a/resources/SalesCoOrdinators/SalesCoOrdinatorController.js +++ b/resources/SalesCoOrdinators/SalesCoOrdinatorController.js @@ -47,6 +47,7 @@ export const uploadSalesCoordinators = async (req, res) => { // Map headers from the Excel file to your schema const headerMapping = { + "Employee Code": "uniqueId", "Sales Coordinator Name": "name", Email: "email", "Phone Number": "mobileNumber", @@ -67,7 +68,7 @@ export const uploadSalesCoordinators = async (req, res) => { for (let i = 1; i < data.length; i++) { const row = data[i]; // Skip the row if it's completely empty - if (row.every(cell => cell === undefined || cell === "")) { + if (row.every((cell) => cell === undefined || cell === "")) { continue; } const item = {}; @@ -84,6 +85,7 @@ export const uploadSalesCoordinators = async (req, res) => { const validationErrors = new Set(); // Validate required fields + if (!item.uniqueId) missingFields.add("Employee Code"); if (!item.name) missingFields.add("name"); if (!item.email) missingFields.add("email"); if (!item.mobileNumber) missingFields.add("mobileNumber"); @@ -93,9 +95,33 @@ export const uploadSalesCoordinators = async (req, res) => { validationErrors.add("incorrect mail"); } - // Validate mobile number - if (item.mobileNumber && !/^\d{10}$/.test(item.mobileNumber)) { - validationErrors.add("Invalid Mobile Number (should be 10 digits)"); + // Normalize the mobileNumber + if (item.mobileNumber) { + item.mobileNumber = item.mobileNumber.toString().trim(); + + // Check if it already has +91 + if (item.mobileNumber.startsWith("+91")) { + // If it has +91, remove it for validation + const strippedNumber = item.mobileNumber.substring(3); + + // Validate that the remaining number is 10 digits + if (/^\d{10}$/.test(strippedNumber)) { + // Keep the mobile number with +91 for storage + item.mobileNumber = `+91${strippedNumber}`; + } else { + validationErrors.add( + "Invalid Mobile Number (should be 10 digits after +91)" + ); + } + } else { + // If not prefixed with +91, check if it is exactly 10 digits + if (/^\d{10}$/.test(item.mobileNumber)) { + // Add +91 for storage + item.mobileNumber = `+91${item.mobileNumber}`; + } else { + validationErrors.add("Invalid Mobile Number (should be 10 digits)"); + } + } } // Combine all errors into a single message @@ -114,6 +140,7 @@ export const uploadSalesCoordinators = async (req, res) => { // If there are errors, push them to the errors array if (errorMessage.trim()) { errors.push({ + uniqueId: item.uniqueId || "N/A", name: item.name || "N/A", email: item.email || "N/A", phone: item.mobileNumber || "N/A", @@ -126,37 +153,75 @@ export const uploadSalesCoordinators = async (req, res) => { const password = generatePassword(item.name, item.email); // Check for existing user by uniqueId - let salesCoordinator = await SalesCoOrdinator.findOne({ - email: item.email, + let salesCoordinatorByUniqueId = await SalesCoOrdinator.findOne({ + uniqueId: item.uniqueId, }); - if (salesCoordinator) { - // Track updated fields - const updatedFields = []; + // Search for sales coordinator by mobile number + let salesCoordinatorByMobileNumber = await SalesCoOrdinator.findOne({ + $or: [ + { mobileNumber: item.mobileNumber }, // Check stored mobile number with +91 + { mobileNumber: item.mobileNumber.substring(3) }, // Check 10-digit number (remove +91) + ], + }); - // Check for changes in user details - let territoryManagerUpdated = false; - for (let field in item) { - const currentValue = salesCoordinator[field]?.toString(); - const newValue = item[field]?.toString(); + // Case 1: Both uniqueId and mobileNumber exist + if (salesCoordinatorByUniqueId && salesCoordinatorByMobileNumber) { + if ( + salesCoordinatorByUniqueId._id.equals( + salesCoordinatorByMobileNumber._id + ) + ) { + // Both match and are the same person, proceed to update + let salescoordinatorUpdated = false; - if (currentValue !== newValue) { - updatedFields.push(field); - salesCoordinator[field] = item[field]; - territoryManagerUpdated = true; + for (let field in item) { + const currentValue = salesCoordinatorByUniqueId[field]?.toString(); + const newValue = item[field]?.toString(); + + if (currentValue !== newValue) { + salesCoordinatorByUniqueId[field] = item[field]; + salescoordinatorUpdated = true; + } } - } - if (territoryManagerUpdated) { - await salesCoordinator.save(); - updatedsalesCoordinators.push({ - ...salesCoordinator._doc, - updatedFields: updatedFields.join(", "), + if (salescoordinatorUpdated) { + await salesCoordinatorByUniqueId.save(); + updatedsalesCoordinators.push({ + ...salesCoordinatorByUniqueId._doc, + updatedFields: updatedFields.join(", "), + }); + } + } else { + // Both exist but refer to different users + errors.push({ + uniqueId: item.uniqueId, + name: item.name, + email: item.email, + phone: item.mobileNumber, + message: ` Employee Code (${salesCoordinatorByUniqueId.uniqueId}) is refer to (${salesCoordinatorByUniqueId.name}) and Mobile Number (${salesCoordinatorByMobileNumber.mobileNumber}) refer to (${salesCoordinatorByMobileNumber.name}) Sales Coordinator. Please provide the correct employee code or mobile number.`, }); } + } else if (salesCoordinatorByUniqueId) { + // Case 2: uniqueId exists, but mobileNumber is new + salesCoordinatorByUniqueId.mobileNumber = item.mobileNumber; // Update mobile number + await salesCoordinatorByUniqueId.save(); + updatedsalesCoordinators.push({ + ...salesCoordinatorByUniqueId._doc, + updatedFields: "mobileNumber", + }); + } else if (salesCoordinatorByMobileNumber) { + // Case 3: mobileNumber exists but uniqueId is new + errors.push({ + uniqueId: item.uniqueId, + name: item.name, + email: item.email, + phone: item.mobileNumber, + message: `Mobile number already exists for ${salesCoordinatorByMobileNumber.name} user.`, + }); } else { - // Create a new salesCoordinator - salesCoordinator = new SalesCoOrdinator({ + // Case 4: Both uniqueId and mobileNumber are new, create a new salesCoordinator + const salesCoordinator = new SalesCoOrdinator({ ...item, password, isVerified: true, @@ -168,9 +233,9 @@ export const uploadSalesCoordinators = async (req, res) => { from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender subject: `Cheminova Account Created`, html: `Your Sales Coordinator Account is created successfully. -
name is: ${item?.name}
-
MobileNumber is: ${item?.mobileNumber}
-
password is: ${password}

If you have not requested this email, please ignore it.`, +
Name: ${item?.name}
+
Mobile Number: ${item?.mobileNumber}
+
Password: ${password}

If you have not requested this email, please ignore it.`, }); newlyCreated.push({ salesCoordinator }); } @@ -188,7 +253,8 @@ export const uploadSalesCoordinators = async (req, res) => { } }; export const register = async (req, res) => { - let { name, email, countryCode, mobileNumber, territoryManager } = req.body; + let { name, email, countryCode, mobileNumber, territoryManager, uniqueId } = + req.body; // console.log(req.body); countryCode = countryCode?.trim(); mobileNumber = mobileNumber?.trim(); @@ -196,6 +262,7 @@ export const register = async (req, res) => { try { let salesCoordinator = await SalesCoOrdinator.findOne({ + uniqueId, mobileNumber: fullMobileNumber, }); @@ -221,14 +288,9 @@ export const register = async (req, res) => { otp, otpExpires, mappedby: territoryManager, + uniqueId, }); } - // Generate uniqueId if not already present - if (!salesCoordinator.uniqueId) { - const currentYear = new Date().getFullYear().toString().slice(-2); - const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); - salesCoordinator.uniqueId = `${currentYear}-${randomChars}`; - } await salesCoordinator.save(); // await sendOtp( // fullMobileNumber, diff --git a/resources/TerritoryManagers/TerritoryManagerController.js b/resources/TerritoryManagers/TerritoryManagerController.js index 3194761..e083a5e 100644 --- a/resources/TerritoryManagers/TerritoryManagerController.js +++ b/resources/TerritoryManagers/TerritoryManagerController.js @@ -47,6 +47,7 @@ export const uploadTerritoryManagers = async (req, res) => { // Map headers from the Excel file to your schema const headerMapping = { + "Employee Code": "uniqueId", "Territory Manager Name": "name", Email: "email", "Phone Number": "mobileNumber", @@ -84,6 +85,7 @@ export const uploadTerritoryManagers = async (req, res) => { const validationErrors = new Set(); // Validate required fields + if (!item.uniqueId) missingFields.add("Employee Code"); if (!item.name) missingFields.add("name"); if (!item.email) missingFields.add("email"); if (!item.mobileNumber) missingFields.add("mobileNumber"); @@ -93,9 +95,33 @@ export const uploadTerritoryManagers = async (req, res) => { validationErrors.add("incorrect mail"); } - // Validate mobile number - if (item.mobileNumber && !/^\d{10}$/.test(item.mobileNumber)) { - validationErrors.add("Invalid Mobile Number (should be 10 digits)"); + // Normalize the mobileNumber + if (item.mobileNumber) { + item.mobileNumber = item.mobileNumber.toString().trim(); + + // Check if it already has +91 + if (item.mobileNumber.startsWith("+91")) { + // If it has +91, remove it for validation + const strippedNumber = item.mobileNumber.substring(3); + + // Validate that the remaining number is 10 digits + if (/^\d{10}$/.test(strippedNumber)) { + // Keep the mobile number with +91 for storage + item.mobileNumber = `+91${strippedNumber}`; + } else { + validationErrors.add( + "Invalid Mobile Number (should be 10 digits after +91)" + ); + } + } else { + // If not prefixed with +91, check if it is exactly 10 digits + if (/^\d{10}$/.test(item.mobileNumber)) { + // Add +91 for storage + item.mobileNumber = `+91${item.mobileNumber}`; + } else { + validationErrors.add("Invalid Mobile Number (should be 10 digits)"); + } + } } // Combine all errors into a single message @@ -114,6 +140,7 @@ export const uploadTerritoryManagers = async (req, res) => { // If there are errors, push them to the errors array if (errorMessage.trim()) { errors.push({ + uniqueId: item.uniqueId || "N/A", name: item.name || "N/A", email: item.email || "N/A", phone: item.mobileNumber || "N/A", @@ -126,37 +153,73 @@ export const uploadTerritoryManagers = async (req, res) => { const password = generatePassword(item.name, item.email); // Check for existing user by uniqueId - let territoryManager = await TerritoryManager.findOne({ - email: item.email, + let territotymanagerByUniqueId = await TerritoryManager.findOne({ + uniqueId: item.uniqueId, }); + // Search for Territory Manager by mobile number + let territorymanagerByMobileNumber = await TerritoryManager.findOne({ + $or: [ + { mobileNumber: item.mobileNumber }, // Check stored mobile number with +91 + { mobileNumber: item.mobileNumber.substring(3) }, // Check 10-digit number (remove +91) + ], + }); + // Case 1: Both uniqueId and mobileNumber exist + if (territotymanagerByUniqueId && territorymanagerByMobileNumber) { + if ( + territotymanagerByUniqueId._id.equals( + territorymanagerByMobileNumber._id + ) + ) { + // Both match and are the same person, proceed to update + let territorymanagerUpdated = false; - if (territoryManager) { - // Track updated fields - const updatedFields = []; + for (let field in item) { + const currentValue = territotymanagerByUniqueId[field]?.toString(); + const newValue = item[field]?.toString(); - // Check for changes in user details - let territoryManagerUpdated = false; - for (let field in item) { - const currentValue = territoryManager[field]?.toString(); - const newValue = item[field]?.toString(); - - if (currentValue !== newValue) { - updatedFields.push(field); - territoryManager[field] = item[field]; - territoryManagerUpdated = true; + if (currentValue !== newValue) { + territotymanagerByUniqueId[field] = item[field]; + territorymanagerUpdated = true; + } } - } - if (territoryManagerUpdated) { - await territoryManager.save(); - updatedtrritoryManagers.push({ - ...territoryManager._doc, - updatedFields: updatedFields.join(", "), + if (territorymanagerUpdated) { + await territotymanagerByUniqueId.save(); + updatedtrritoryManagers.push({ + ...territotymanagerByUniqueId._doc, + updatedFields: updatedFields.join(", "), + }); + } + } else { + // Both exist but refer to different users + errors.push({ + uniqueId: item.uniqueId, + name: item.name, + email: item.email, + phone: item.mobileNumber, + message: ` Employee Code (${territotymanagerByUniqueId.uniqueId}) is refer to (${territotymanagerByUniqueId.name}) and Mobile Number (${territorymanagerByMobileNumber.mobileNumber}) refer to (${territorymanagerByMobileNumber.name}) Territory Manager. Please provide the correct employee code or mobile number.`, }); } + } else if (territotymanagerByUniqueId) { + // Case 2: uniqueId exists, but mobileNumber is new + territotymanagerByUniqueId.mobileNumber = item.mobileNumber; // Update mobile number + await territotymanagerByUniqueId.save(); + updatedtrritoryManagers.push({ + ...territotymanagerByUniqueId._doc, + updatedFields: "mobileNumber", + }); + } else if (territorymanagerByMobileNumber) { + // Case 3: mobileNumber exists but uniqueId is new + errors.push({ + uniqueId: item.uniqueId, + name: item.name, + email: item.email, + phone: item.mobileNumber, + message: `Mobile number already exists for ${territorymanagerByMobileNumber.name} user.`, + }); } else { - // Create a new territoryManager - territoryManager = new TerritoryManager({ + // Case 4: Both uniqueId and mobileNumber are new, create a new salesCoordinator + const territoryManager = new TerritoryManager({ ...item, password, isVerified: true, @@ -188,13 +251,14 @@ export const uploadTerritoryManagers = async (req, res) => { } }; export const register = async (req, res) => { - let { name, email, countryCode, mobileNumber } = req.body; + let { name, email, countryCode, mobileNumber, uniqueId } = req.body; countryCode = countryCode?.trim(); mobileNumber = mobileNumber?.trim(); const fullMobileNumber = `${countryCode}${mobileNumber}`; try { let territoryManager = await TerritoryManager.findOne({ + uniqueId, mobileNumber: fullMobileNumber, }); @@ -218,14 +282,9 @@ export const register = async (req, res) => { mobileNumber: fullMobileNumber, otp, otpExpires, + uniqueId, }); } - // Generate uniqueId if not already present - if (!territoryManager.uniqueId) { - const currentYear = new Date().getFullYear().toString().slice(-2); - const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); - territoryManager.uniqueId = `${currentYear}-${randomChars}`; - } await territoryManager.save(); // await sendOtp( // fullMobileNumber, @@ -390,7 +449,32 @@ export const getAllTerritoryManager = async (req, res) => { }); } }; +//for dropdown +export const getAllTerritoryManagerdropdown = async (req, res) => { + try { + let filter = {}; + if (req.query?.name) { + filter.name = { + $regex: new RegExp(req.query.name, "i"), + }; + } + const total = await TerritoryManager.countDocuments(filter); + const territoryManager = await TerritoryManager.find(filter).sort({ + createdAt: -1, + }); + return res.status(200).json({ + success: true, + total_data: total, + territoryManager, + }); + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went wrong!", + }); + } +}; export const getOneTerritoryManager = async (req, res) => { try { if (!req.params.id) { diff --git a/resources/TerritoryManagers/TerritoryManagerRoute.js b/resources/TerritoryManagers/TerritoryManagerRoute.js index 8c24a17..ded5955 100644 --- a/resources/TerritoryManagers/TerritoryManagerRoute.js +++ b/resources/TerritoryManagers/TerritoryManagerRoute.js @@ -17,6 +17,7 @@ import { getOneTerritoryManager, logout, uploadTerritoryManagers, + getAllTerritoryManagerdropdown, } from "./TerritoryManagerController.js"; import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js"; import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; @@ -35,6 +36,12 @@ router.get( authorizeRoles("admin"), getAllTerritoryManager ); +router.get( + "/getAll-dropdown", + isAuthenticatedUser, + authorizeRoles("admin"), + getAllTerritoryManagerdropdown +); router.get( "/getOne/:id", isAuthenticatedUser,