PD mapped with TM
This commit is contained in:
parent
23e87f3bca
commit
f805f3b1f8
@ -294,6 +294,40 @@ export const mappedbyTM = async (req, res) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
export const unmapSalesCoOrdinator = async (req, res) => {
|
||||
try {
|
||||
if (!req.params.id) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "Please provide SalesCoOrdinator ID!",
|
||||
});
|
||||
}
|
||||
|
||||
const getSalesCoOrdinator = await SalesCoOrdinator.findById(req.params.id);
|
||||
if (!getSalesCoOrdinator) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: "Sales Coordinator not found!",
|
||||
});
|
||||
}
|
||||
|
||||
// Set mappedby field to null
|
||||
getSalesCoOrdinator.mappedby = null;
|
||||
|
||||
// Save the updated sales coordinator
|
||||
await getSalesCoOrdinator.save();
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: "Sales Coordinator unmapped successfully!",
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message ? error.message : "Something went wrong!",
|
||||
});
|
||||
}
|
||||
};
|
||||
export const getOneSalesCoOrdinator = async (req, res) => {
|
||||
try {
|
||||
if (!req.params.id) {
|
||||
|
@ -59,7 +59,6 @@ const salescoordinatorSchema = new mongoose.Schema(
|
||||
mappedby: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "TerritoryManager",
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
{ timestamps: true }
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
logout,
|
||||
getAllSalesCoOrdinatorbytmId,
|
||||
mappedbyTM,
|
||||
unmapSalesCoOrdinator,
|
||||
} from "./SalesCoOrdinatorController.js";
|
||||
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
||||
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
|
||||
@ -51,6 +52,12 @@ router.put(
|
||||
authorizeRoles("admin"),
|
||||
mappedbyTM
|
||||
);
|
||||
router.delete(
|
||||
"/unmap/:id",
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles("admin"),
|
||||
unmapSalesCoOrdinator
|
||||
);
|
||||
router.get(
|
||||
"/getOne/:id",
|
||||
isAuthenticatedUser,
|
||||
|
@ -12,7 +12,7 @@ import { Config } from "../setting/Configration/Config_model.js";
|
||||
import XLSX from "xlsx";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import validator from 'validator';
|
||||
import validator from "validator";
|
||||
import ShippingAddress from "../ShippingAddresses/ShippingAddressModel.js";
|
||||
|
||||
const generatePassword = (name, email) => {
|
||||
@ -356,7 +356,9 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
const data = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
|
||||
|
||||
if (data.length <= 1) {
|
||||
return res.status(400).json({ message: "Empty spreadsheet or no data found" });
|
||||
return res
|
||||
.status(400)
|
||||
.json({ message: "Empty spreadsheet or no data found" });
|
||||
}
|
||||
|
||||
const headers = data[0];
|
||||
@ -364,23 +366,25 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
// Map headers from the Excel file to your schema
|
||||
const headerMapping = {
|
||||
"PD ID (From SAP)": "uniqueId",
|
||||
"SBU":"SBU",
|
||||
SBU: "SBU",
|
||||
"Principal Distributor Name": "name",
|
||||
"Email": "email",
|
||||
Email: "email",
|
||||
"Phone Number": "phone",
|
||||
"PAN Number": "panNumber",
|
||||
"Trade Name": "tradeName",
|
||||
"GST Number": "gstNumber",
|
||||
"State": "state",
|
||||
"City": "city",
|
||||
"Street": "street",
|
||||
"Pincode": "postalCode",
|
||||
State: "state",
|
||||
City: "city",
|
||||
Street: "street",
|
||||
Pincode: "postalCode",
|
||||
};
|
||||
|
||||
const requiredHeaders = Object.keys(headerMapping);
|
||||
|
||||
if (!requiredHeaders.every((header) => headers.includes(header))) {
|
||||
return res.status(400).json({ message: "Missing required columns in spreadsheet" });
|
||||
return res
|
||||
.status(400)
|
||||
.json({ message: "Missing required columns in spreadsheet" });
|
||||
}
|
||||
|
||||
const errors = [];
|
||||
@ -393,7 +397,8 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
|
||||
headers.forEach((header, index) => {
|
||||
if (headerMapping[header]) {
|
||||
item[headerMapping[header]] = row[index] !== undefined ? row[index] : "";
|
||||
item[headerMapping[header]] =
|
||||
row[index] !== undefined ? row[index] : "";
|
||||
}
|
||||
});
|
||||
|
||||
@ -403,7 +408,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
|
||||
// Validate required fields
|
||||
if (!item.uniqueId) missingFields.add("uniqueId");
|
||||
if(!item.SBU) missingFields.add("SBU");
|
||||
if (!item.SBU) missingFields.add("SBU");
|
||||
if (!item.name) missingFields.add("name");
|
||||
if (!item.email) missingFields.add("email");
|
||||
if (!item.phone) missingFields.add("phone");
|
||||
@ -430,12 +435,18 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
item.gstNumber = item.gstNumber ? item.gstNumber.toUpperCase() : "";
|
||||
|
||||
// Validate PAN Number
|
||||
if (item.panNumber && !/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(item.panNumber)) {
|
||||
if (
|
||||
item.panNumber &&
|
||||
!/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(item.panNumber)
|
||||
) {
|
||||
validationErrors.add("Invalid PAN Number");
|
||||
}
|
||||
|
||||
// Validate GST Number
|
||||
if (item.gstNumber && !/^(\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z]{1}[A-Z\d]{1})$/.test(item.gstNumber)) {
|
||||
if (
|
||||
item.gstNumber &&
|
||||
!/^(\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d[Z]{1}[A-Z\d]{1})$/.test(item.gstNumber)
|
||||
) {
|
||||
validationErrors.add("Invalid GST Number");
|
||||
}
|
||||
|
||||
@ -447,17 +458,21 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
// Combine all errors into a single message
|
||||
let errorMessage = "";
|
||||
if (missingFields.size > 0) {
|
||||
errorMessage += `Missing fields: ${Array.from(missingFields).join(", ")}. `;
|
||||
errorMessage += `Missing fields: ${Array.from(missingFields).join(
|
||||
", "
|
||||
)}. `;
|
||||
}
|
||||
if (validationErrors.size > 0) {
|
||||
errorMessage += `Validation errors: ${Array.from(validationErrors).join(", ")}.`;
|
||||
errorMessage += `Validation errors: ${Array.from(validationErrors).join(
|
||||
", "
|
||||
)}.`;
|
||||
}
|
||||
|
||||
// If there are errors, push them to the errors array
|
||||
if (errorMessage.trim()) {
|
||||
errors.push({
|
||||
uniqueId: item.uniqueId || "N/A",
|
||||
SBU:item.SBU || "N/A",
|
||||
SBU: item.SBU || "N/A",
|
||||
name: item.name || "N/A",
|
||||
email: item.email || "N/A",
|
||||
phone: item.phone || "N/A",
|
||||
@ -478,8 +493,18 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
if (distributor) {
|
||||
// Track updated fields
|
||||
const updatedFields = [];
|
||||
const addressFields = ['panNumber', 'gstNumber', 'state', 'city', 'street', 'tradeName', 'postalCode'];
|
||||
const existingAddress = await ShippingAddress.findOne({ user: distributor._id });
|
||||
const addressFields = [
|
||||
"panNumber",
|
||||
"gstNumber",
|
||||
"state",
|
||||
"city",
|
||||
"street",
|
||||
"tradeName",
|
||||
"postalCode",
|
||||
];
|
||||
const existingAddress = await ShippingAddress.findOne({
|
||||
user: distributor._id,
|
||||
});
|
||||
|
||||
// Check for changes in user details
|
||||
let userUpdated = false;
|
||||
@ -493,7 +518,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
distributor.email = item.email;
|
||||
userUpdated = true;
|
||||
}
|
||||
if(distributor.SBU !== item.SBU){
|
||||
if (distributor.SBU !== item.SBU) {
|
||||
updatedFields.push("SBU");
|
||||
distributor.SBU = item.SBU;
|
||||
userUpdated = true;
|
||||
@ -525,7 +550,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
let addressUpdated = false;
|
||||
if (existingAddress) {
|
||||
const addressUpdates = [];
|
||||
addressFields.forEach(field => {
|
||||
addressFields.forEach((field) => {
|
||||
if (existingAddress[field] !== addressData[field]) {
|
||||
addressUpdates.push(field);
|
||||
addressUpdated = true;
|
||||
@ -533,9 +558,14 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
});
|
||||
|
||||
if (addressUpdated) {
|
||||
await ShippingAddress.updateOne({ user: distributor._id }, addressData);
|
||||
await ShippingAddress.updateOne(
|
||||
{ user: distributor._id },
|
||||
addressData
|
||||
);
|
||||
if (addressUpdates.length > 0) {
|
||||
updatedFields.push(`Address fields: ${addressUpdates.join(", ")}`);
|
||||
updatedFields.push(
|
||||
`Address fields: ${addressUpdates.join(", ")}`
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -548,7 +578,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
if (updatedFields.length > 0) {
|
||||
updatedDistributors.push({
|
||||
...distributor._doc,
|
||||
updatedFields: updatedFields.join(", ")
|
||||
updatedFields: updatedFields.join(", "),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -613,7 +643,7 @@ export const uploadPrincipaldistributors = async (req, res) => {
|
||||
// 1.Register a User
|
||||
export const registerUser = async (req, res) => {
|
||||
try {
|
||||
const { name, email, phone, accessTo, role,PD_ID,SBU } = req.body;
|
||||
const { name, email, phone, accessTo, role, PD_ID, SBU } = req.body;
|
||||
// console.log(req.body);
|
||||
const password = generatePassword(name, email);
|
||||
// console.log(password);
|
||||
@ -627,7 +657,7 @@ export const registerUser = async (req, res) => {
|
||||
user.phone = phone;
|
||||
user.role = role;
|
||||
user.accessTo = accessTo;
|
||||
user.SBU=SBU;
|
||||
user.SBU = SBU;
|
||||
// Save updates
|
||||
await user.save();
|
||||
// console.log("finduser", user);
|
||||
@ -967,14 +997,130 @@ export const updateProfile = catchAsyncErrors(async (req, res, next) => {
|
||||
// 9.Get all users(admin)
|
||||
export const getAllUser = catchAsyncErrors(async (req, res, next) => {
|
||||
// Assuming your User model is imported as 'User'
|
||||
const users = await User.find({ role: "principal-Distributor" })
|
||||
.sort({ createdAt: -1 });
|
||||
const { page = 1, show = 10, name, mobileNumber } = req.query;
|
||||
// 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;
|
||||
}
|
||||
// Calculate pagination values
|
||||
const limit = parseInt(show, 10);
|
||||
const skip = (parseInt(page, 10) - 1) * limit;
|
||||
// Count total users matching the filter
|
||||
|
||||
// Find users with pagination and filters
|
||||
const users = await User.find(filter)
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(skip)
|
||||
.limit(limit);
|
||||
const totalUsers = await User.countDocuments(filter);
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
users,
|
||||
totalUsers,
|
||||
});
|
||||
});
|
||||
export const getAllPrincipalDistributorbytmId = catchAsyncErrors(
|
||||
async (req, res, next) => {
|
||||
const { page = 1, show = 10, name, mobileNumber } = req.query;
|
||||
const tmId = req.params.id;
|
||||
if(!tmId){
|
||||
return res.status(400).json({ message: "Please provide Territory Manager 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;
|
||||
}
|
||||
|
||||
// Filter based on the mapped Territory Manager ID if provided
|
||||
if (tmId) {
|
||||
filter.mappedby = tmId;
|
||||
}
|
||||
|
||||
// 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
|
||||
// console.log(id, mappedby);
|
||||
// Validate that the TerritoryManager ID is provided
|
||||
if (!mappedby) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "Territory Manager 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 mappedby field
|
||||
principalDistributor.mappedby = mappedby;
|
||||
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
|
||||
// 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 mappedby field
|
||||
principalDistributor.mappedby = 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" });
|
||||
|
@ -58,6 +58,10 @@ const userSchema = new mongoose.Schema(
|
||||
type: String,
|
||||
default: "user",
|
||||
},
|
||||
mappedby: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "TerritoryManager",
|
||||
},
|
||||
accessTo: {},
|
||||
resetPasswordToken: String,
|
||||
resetPasswordExpire: Date,
|
||||
|
@ -15,6 +15,9 @@ import {
|
||||
deleteEmployeeById,
|
||||
updateEmployeeById,
|
||||
uploadPrincipaldistributors,
|
||||
getAllPrincipalDistributorbytmId,
|
||||
mappedbyTM,
|
||||
unmappedTMinPrincipalDistributor,
|
||||
} from "./userController.js";
|
||||
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
||||
|
||||
@ -32,14 +35,34 @@ router.route("/user/logout").get(logout);
|
||||
|
||||
router.route("/user/details").get(isAuthenticatedUser, getUserDetails);
|
||||
router
|
||||
.route('/principaldistributor/upload').post(
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles('admin'),
|
||||
uploadPrincipaldistributors
|
||||
);
|
||||
.route("/principaldistributor/upload")
|
||||
.post(
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles("admin"),
|
||||
uploadPrincipaldistributors
|
||||
);
|
||||
router
|
||||
.route("/admin/users")
|
||||
.get(isAuthenticatedUser, authorizeRoles("admin", "Employee"), getAllUser);
|
||||
router
|
||||
.route("/getbyTmId/:id")
|
||||
.get(
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles("admin"),
|
||||
getAllPrincipalDistributorbytmId
|
||||
);
|
||||
router.put(
|
||||
"/mappedtm/:id",
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles("admin"),
|
||||
mappedbyTM
|
||||
);
|
||||
router.patch(
|
||||
"/unmap/:id",
|
||||
isAuthenticatedUser,
|
||||
authorizeRoles("admin"),
|
||||
unmappedTMinPrincipalDistributor
|
||||
);
|
||||
router
|
||||
.route("/admin/delete-employee/:id")
|
||||
.delete(
|
||||
|
Loading…
Reference in New Issue
Block a user