Kyc approved then RD create and mail send
43
Utils/generatepassword.js
Normal file
@ -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;
|
||||||
|
};
|
BIN
public/temp/tmp-1-1725865675324
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-1-1725865720729
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-1-1725866035097
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-1-1725866756642
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-10-1725865734490
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-10-1725866667847
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-10-1725866813645
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-11-1725865734493
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-11-1725866667850
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-11-1725866813648
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-12-1725865734496
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-12-1725866667853
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-12-1725866813651
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-2-1725865675329
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-2-1725865720732
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-2-1725866035100
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-2-1725866756647
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-3-1725865675334
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-3-1725865720736
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-3-1725866035104
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-3-1725866756651
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-4-1725865675338
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-4-1725865720739
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-4-1725866035107
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-4-1725866756655
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-5-1725865675341
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-5-1725865720741
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-5-1725866035109
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-5-1725866756657
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-6-1725865675345
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-6-1725865720743
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-6-1725866035112
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-6-1725866756670
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-7-1725865734472
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-7-1725866667838
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-7-1725866813627
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-8-1725865734474
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-8-1725866667841
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-8-1725866813629
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-9-1725865734476
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-9-1725866667845
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
public/temp/tmp-9-1725866813631
Normal file
After Width: | Height: | Size: 197 KiB |
@ -6,10 +6,13 @@ import { rejectKYC } from "../../Utils/rejectKyc.js";
|
|||||||
import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js";
|
import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js";
|
||||||
import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js";
|
import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js";
|
||||||
import { Notification } from "../Notification/notificationModal.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) => {
|
export const createKyc = async (req, res) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
email,
|
||||||
trade_name,
|
trade_name,
|
||||||
address,
|
address,
|
||||||
state,
|
state,
|
||||||
@ -76,6 +79,7 @@ export const createKyc = async (req, res) => {
|
|||||||
// Create KYC document
|
// Create KYC document
|
||||||
const kyc = await KYC.create({
|
const kyc = await KYC.create({
|
||||||
name,
|
name,
|
||||||
|
email,
|
||||||
trade_name,
|
trade_name,
|
||||||
address,
|
address,
|
||||||
state,
|
state,
|
||||||
@ -113,6 +117,7 @@ export const createKyc = async (req, res) => {
|
|||||||
export const createretaildistributor = async (req, res) => {
|
export const createretaildistributor = async (req, res) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
email,
|
||||||
trade_name,
|
trade_name,
|
||||||
address,
|
address,
|
||||||
state,
|
state,
|
||||||
@ -187,6 +192,7 @@ export const createretaildistributor = async (req, res) => {
|
|||||||
// Create KYC document
|
// Create KYC document
|
||||||
const kycData = {
|
const kycData = {
|
||||||
name,
|
name,
|
||||||
|
email,
|
||||||
trade_name,
|
trade_name,
|
||||||
address,
|
address,
|
||||||
state,
|
state,
|
||||||
@ -207,12 +213,41 @@ export const createretaildistributor = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const kyc = await KYC.create(kycData);
|
const kyc = await KYC.create(kycData);
|
||||||
|
if (!kyc) {
|
||||||
if (kyc) {
|
return res.status(400).json({ message: "Failed to create KYC." });
|
||||||
return res
|
|
||||||
.status(201)
|
|
||||||
.json({ success: true, kyc, message: "KYC created" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
<br/>name is: <strong>${name}</strong>
|
||||||
|
<br/>
|
||||||
|
<br/>MobileNumber is: <strong>${mobile_number}</strong><br/>
|
||||||
|
<br/>Email is: <strong>${email}</strong><br/>
|
||||||
|
<br/>password is: <strong>${password}</strong><br/><br/>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) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
@ -276,12 +311,17 @@ export const getAllKycApproved = async (req, res) => {
|
|||||||
// If a principal distributor name is provided, find the matching distributor IDs
|
// If a principal distributor name is provided, find the matching distributor IDs
|
||||||
let principalDistributerIds = [];
|
let principalDistributerIds = [];
|
||||||
if (principaldistributor) {
|
if (principaldistributor) {
|
||||||
const matchingDistributors = await mongoose.model('User').find({
|
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
|
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 matching distributors are found, add the IDs to the main query
|
||||||
if (principalDistributerIds.length > 0) {
|
if (principalDistributerIds.length > 0) {
|
||||||
query.principal_distributer = { $in: principalDistributerIds };
|
query.principal_distributer = { $in: principalDistributerIds };
|
||||||
@ -312,7 +352,6 @@ export const getAllKycApproved = async (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Get Single KYC
|
// Get Single KYC
|
||||||
export const getKycById = async (req, res) => {
|
export const getKycById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@ -368,6 +407,35 @@ export const updateKycStatus = async (req, res) => {
|
|||||||
added_for: kyc.addedBy,
|
added_for: kyc.addedBy,
|
||||||
// userType: req.userType,
|
// 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.
|
||||||
|
<br/>name is: <strong>${kyc.name}</strong>
|
||||||
|
<br/>
|
||||||
|
<br/>MobileNumber is: <strong>${kyc.mobile_number}</strong><br/>
|
||||||
|
<br/>Email is: <strong>${kyc.email}</strong><br/>
|
||||||
|
<br/>password is: <strong>${password}</strong><br/><br/>If you have not requested this email, please ignore it.`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (status === "reject") {
|
if (status === "reject") {
|
||||||
console.log("inside reject ");
|
console.log("inside reject ");
|
||||||
@ -428,7 +496,7 @@ export const getAllPrincipalDistributers = async (req, res) => {
|
|||||||
// console.log(filter);
|
// console.log(filter);
|
||||||
// Fetch the principal distributors based on the filter
|
// Fetch the principal distributors based on the filter
|
||||||
const principalDistributers = await User.find(filter);
|
const principalDistributers = await User.find(filter);
|
||||||
// console.log(principalDistributers);
|
// console.log(principalDistributers);
|
||||||
// Send the fetched data as a response
|
// Send the fetched data as a response
|
||||||
if (principalDistributers.length > 0) {
|
if (principalDistributers.length > 0) {
|
||||||
res.status(200).json(principalDistributers);
|
res.status(200).json(principalDistributers);
|
||||||
|
@ -7,6 +7,11 @@ const KycSchema = new Schema(
|
|||||||
required: true,
|
required: true,
|
||||||
maxlength: [50, "Name cannot be more than 50 characters"],
|
maxlength: [50, "Name cannot be more than 50 characters"],
|
||||||
},
|
},
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
trade_name: {
|
trade_name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
@ -95,14 +100,6 @@ const KycSchema = new Schema(
|
|||||||
// required: true,
|
// required: true,
|
||||||
enum: ["SalesCoOrdinator", "TerritoryManager"],
|
enum: ["SalesCoOrdinator", "TerritoryManager"],
|
||||||
},
|
},
|
||||||
mappedTM: {
|
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
|
||||||
ref: "TerritoryManager",
|
|
||||||
},
|
|
||||||
mappedSC: {
|
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
|
||||||
ref: "SalesCoOrdinator",
|
|
||||||
},
|
|
||||||
notes: [
|
notes: [
|
||||||
{
|
{
|
||||||
message: {
|
message: {
|
||||||
@ -128,12 +125,4 @@ const KycSchema = new Schema(
|
|||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
// Pre-save middleware to set 'mapped' based on 'userType'
|
// 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);
|
export const KYC = model("KYC", KycSchema);
|
||||||
|
131
resources/RetailDistributor/RetailDistributorModel.js
Normal file
@ -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;
|
@ -14,50 +14,50 @@ import fs from "fs";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import validator from "validator";
|
import validator from "validator";
|
||||||
import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js";
|
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) => {
|
// // Define character pools
|
||||||
// Combine name and email, and convert to lowercase
|
// const specialChars = "@#*";
|
||||||
const combinedStr = (name + email).toLowerCase();
|
// const numbers = "0123456789";
|
||||||
|
// const alphaLower = combinedStr.match(/[a-z]/g) || [];
|
||||||
|
// const alphaUpper = combinedStr.match(/[A-Z]/g) || [];
|
||||||
|
|
||||||
// Define character pools
|
// // Ensure at least one character from each category
|
||||||
const specialChars = "@#*";
|
// const specialChar = specialChars.charAt(
|
||||||
const numbers = "0123456789";
|
// Math.floor(Math.random() * specialChars.length)
|
||||||
const alphaLower = combinedStr.match(/[a-z]/g) || [];
|
// );
|
||||||
const alphaUpper = combinedStr.match(/[A-Z]/g) || [];
|
// 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
|
// // Combine required characters
|
||||||
const specialChar = specialChars.charAt(
|
// let passwordChars = [specialChar, numberChar, lowerChar, upperChar];
|
||||||
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
|
// // Fill remaining positions with random characters from the combined string
|
||||||
let passwordChars = [specialChar, numberChar, lowerChar, upperChar];
|
// 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
|
// // Shuffle characters to ensure randomness
|
||||||
const allChars = combinedStr + specialChars + numbers;
|
// passwordChars = passwordChars.sort(() => Math.random() - 0.5);
|
||||||
while (passwordChars.length < 8) {
|
|
||||||
passwordChars.push(
|
|
||||||
allChars.charAt(Math.floor(Math.random() * allChars.length))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shuffle characters to ensure randomness
|
// // Generate password of length 8
|
||||||
passwordChars = passwordChars.sort(() => Math.random() - 0.5);
|
// const password = passwordChars.slice(0, 8).join("");
|
||||||
|
|
||||||
// Generate password of length 8
|
// return password;
|
||||||
const password = passwordChars.slice(0, 8).join("");
|
// };
|
||||||
|
|
||||||
return password;
|
|
||||||
};
|
|
||||||
|
|
||||||
// export const uploadPrincipaldistributors = async (req, res) => {
|
// export const uploadPrincipaldistributors = async (req, res) => {
|
||||||
// try {
|
// 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) => {
|
export const mappedbyTM = catchAsyncErrors(async (req, res, next) => {
|
||||||
const { id } = req.params; // SalesCoOrdinator ID from URL parameters
|
const { id } = req.params; // SalesCoOrdinator ID from URL parameters
|
||||||
const { mappedby } = req.body; // TerritoryManager ID from request body
|
const { mappedby } = req.body; // TerritoryManager ID from request body
|
||||||
@ -1120,6 +1166,34 @@ export const mappedbyTM = catchAsyncErrors(async (req, res, next) => {
|
|||||||
principalDistributor,
|
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(
|
export const unmappedTMinPrincipalDistributor = catchAsyncErrors(
|
||||||
async (req, res, next) => {
|
async (req, res, next) => {
|
||||||
const { id } = req.params; // Principal Distributor ID from URL parameters
|
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) => {
|
export const getAllEmployee = catchAsyncErrors(async (req, res, next) => {
|
||||||
// Assuming your User model is imported as 'User'
|
// Assuming your User model is imported as 'User'
|
||||||
const employee = await User.find({ role: "Employee" });
|
const employee = await User.find({ role: "Employee" });
|
||||||
|
@ -62,6 +62,10 @@ const userSchema = new mongoose.Schema(
|
|||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: "TerritoryManager",
|
ref: "TerritoryManager",
|
||||||
},
|
},
|
||||||
|
mappedbySC: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: "SalesCoOrdinator",
|
||||||
|
},
|
||||||
accessTo: {},
|
accessTo: {},
|
||||||
resetPasswordToken: String,
|
resetPasswordToken: String,
|
||||||
resetPasswordExpire: Date,
|
resetPasswordExpire: Date,
|
||||||
|
@ -18,6 +18,9 @@ import {
|
|||||||
getAllPrincipalDistributorbytmId,
|
getAllPrincipalDistributorbytmId,
|
||||||
mappedbyTM,
|
mappedbyTM,
|
||||||
unmappedTMinPrincipalDistributor,
|
unmappedTMinPrincipalDistributor,
|
||||||
|
unmappedSCinPrincipalDistributor,
|
||||||
|
mappedbySC,
|
||||||
|
getAllPrincipalDistributorbyscId,
|
||||||
} from "./userController.js";
|
} from "./userController.js";
|
||||||
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
||||||
|
|
||||||
@ -51,18 +54,37 @@ router
|
|||||||
authorizeRoles("admin"),
|
authorizeRoles("admin"),
|
||||||
getAllPrincipalDistributorbytmId
|
getAllPrincipalDistributorbytmId
|
||||||
);
|
);
|
||||||
|
router
|
||||||
|
.route("/getbySCId/:id")
|
||||||
|
.get(
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
getAllPrincipalDistributorbyscId
|
||||||
|
);
|
||||||
router.put(
|
router.put(
|
||||||
"/mappedtm/:id",
|
"/mappedtm/:id",
|
||||||
isAuthenticatedUser,
|
isAuthenticatedUser,
|
||||||
authorizeRoles("admin"),
|
authorizeRoles("admin"),
|
||||||
mappedbyTM
|
mappedbyTM
|
||||||
);
|
);
|
||||||
|
router.put(
|
||||||
|
"/mappedSC/:id",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
mappedbySC
|
||||||
|
);
|
||||||
router.patch(
|
router.patch(
|
||||||
"/unmap/:id",
|
"/unmap/:id",
|
||||||
isAuthenticatedUser,
|
isAuthenticatedUser,
|
||||||
authorizeRoles("admin"),
|
authorizeRoles("admin"),
|
||||||
unmappedTMinPrincipalDistributor
|
unmappedTMinPrincipalDistributor
|
||||||
);
|
);
|
||||||
|
router.patch(
|
||||||
|
"/unmapSC/:id",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
unmappedSCinPrincipalDistributor
|
||||||
|
);
|
||||||
router
|
router
|
||||||
.route("/admin/delete-employee/:id")
|
.route("/admin/delete-employee/:id")
|
||||||
.delete(
|
.delete(
|
||||||
|