diff --git a/app.js b/app.js
index 9cc6e6e..7941c23 100644
--- a/app.js
+++ b/app.js
@@ -138,7 +138,8 @@ import LanguageRoute from "./resources/setting/Language/language_routes.js";
import PurposeRoute from "./resources/setting/Purpose/Purpose_routes.js";
//SalesCoOrdinator Routes
import SalesCoOrdinatorRoute from "./resources/SalesCoOrdinators/SalesCoOrdinatorRoute.js";
-
+//TerritoryManager Routes
+import TerritoryManagerRoute from "./resources/TerritoryManagers/TerritoryManagerRoute.js";
// category Route
import categoryRoute from "./resources/Category/categoryRoutes.js";
import RegistrationImageRoute from "./resources/RegistrationImage/RegistrationImageRoute.js";
@@ -194,7 +195,8 @@ app.use("/api/user-address", UserAddressRoute);
app.use("/api/shipping/address", ShippingAddressRoute);
//SalesCoOrdinator Routes
app.use("/api/salescoordinator", SalesCoOrdinatorRoute);
-
+//TerritoryManager Routes
+app.use("/api/territorymanager", TerritoryManagerRoute);
//Order
app.use("/api/order", orderRoute);
//Departure
diff --git a/middlewares/TerritoryManagerAuth.js b/middlewares/TerritoryManagerAuth.js
new file mode 100644
index 0000000..ab6771e
--- /dev/null
+++ b/middlewares/TerritoryManagerAuth.js
@@ -0,0 +1,44 @@
+import jwt from "jsonwebtoken";
+import TerritoryManager from "../resources/TerritoryManagers/TerritoryManagerModel.js";
+
+export const isAuthenticatedTerritoryManager = async (req, res, next) => {
+ try {
+ if (!req.headers.authorization) {
+ return res.status(401).json({
+ success: false,
+ message: "Please login to access this resource",
+ });
+ }
+ const getToken = req.headers.authorization;
+ const token = getToken.slice(7);
+
+ const decoded = jwt.verify(token, process.env.JWT_SECRET);
+ if (!decoded) {
+ return res.status(400).json({
+ success: false,
+ message: "Incorrect token",
+ });
+ }
+ const territorymanager = await TerritoryManager.findById(decoded.id);
+ if (territorymanager) {
+ req.user = territorymanager;
+ req.userType = 'TerritoryManager';
+ return next();
+ } else {
+ return res.status(401).json({
+ success: false,
+ message: "Unauthorized",
+ });
+ }
+ } catch (error) {
+ if (error.name === "TokenExpiredError") {
+ return res.status(401).json({ message: "Token has expired." });
+ } else if (error.name === "JsonWebTokenError") {
+ return res.status(401).json({ message: "Invalid token." });
+ } else {
+ return res.status(500).json({
+ message: "An internal error occurred while verifying the token.",
+ });
+ }
+ }
+};
diff --git a/resources/Attendance/AttandanceRoute.js b/resources/Attendance/AttandanceRoute.js
index e074d26..5c3cddc 100644
--- a/resources/Attendance/AttandanceRoute.js
+++ b/resources/Attendance/AttandanceRoute.js
@@ -6,7 +6,7 @@ import {
AdmingetAttendanceByUser,
} from "./AttendanceController.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
-// import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
+import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
const router = express.Router();
@@ -31,7 +31,7 @@ router.post(
// Route to mark attendance for Territory Managers
router.post(
"/markattendance/territorymanager",
- // isAuthenticatedTerritoryManager,
+ isAuthenticatedTerritoryManager,
markAttendance
);
@@ -45,7 +45,7 @@ router.get(
// Route to get attendance for the logged-in territory manager
router.get(
"/attendance/territorymanager",
- // isAuthenticatedTerritoryManager,
+ isAuthenticatedTerritoryManager,
getAttendanceByUser
);
diff --git a/resources/Attendance/AttendanceController.js b/resources/Attendance/AttendanceController.js
index 0f371e0..ed70d56 100644
--- a/resources/Attendance/AttendanceController.js
+++ b/resources/Attendance/AttendanceController.js
@@ -227,8 +227,7 @@ export const getTodayAttendance = async (req, res) => {
date: record.records.date,
time: record.records.time,
location: record.records.location,
- reason: record.records.reason,
- leaveType: record.records.leaveType,
+ notes: record.records.notes,
}));
// Send response
diff --git a/resources/Leaves/LeaveRoute.js b/resources/Leaves/LeaveRoute.js
index 9e7ac69..b051b8d 100644
--- a/resources/Leaves/LeaveRoute.js
+++ b/resources/Leaves/LeaveRoute.js
@@ -6,7 +6,7 @@ import {
AdmingetLeaveByUser,
} from "./LeaveController.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
-// import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
+import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
const router = express.Router();
@@ -31,7 +31,7 @@ router.post(
// Route to mark leave for Territory Managers
router.post(
"/markleave/territorymanager",
- // isAuthenticatedTerritoryManager,
+ isAuthenticatedTerritoryManager,
markLeave
);
@@ -45,7 +45,7 @@ router.get(
// Route to get leave for the logged-in territory manager
router.get(
"/leave/territorymanager",
- // isAuthenticatedTerritoryManager,
+ isAuthenticatedTerritoryManager,
getLeaveByUser
);
diff --git a/resources/SalesCoOrdinators/SalesCoOrdinatorController.js b/resources/SalesCoOrdinators/SalesCoOrdinatorController.js
index b300c2d..d99b75d 100644
--- a/resources/SalesCoOrdinators/SalesCoOrdinatorController.js
+++ b/resources/SalesCoOrdinators/SalesCoOrdinatorController.js
@@ -4,6 +4,7 @@ import SalesCoOrdinator from "./SalesCoOrdinatorModel.js";
import sendEmail, { sendOtp } from "../../Utils/sendEmail.js";
import validator from "validator";
import password from "secure-random-password";
+import catchAsyncErrors from "../../middlewares/catchAsyncErrors.js";
export const register = async (req, res) => {
let { name, email, countryCode, mobileNumber } = req.body;
@@ -157,7 +158,18 @@ export const loginSalesCoOrdinator = async (req, res) => {
});
}
};
+// Logout User
+export const logout = catchAsyncErrors(async (req, res, next) => {
+ res.cookie("token", null, {
+ expires: new Date(Date.now()),
+ httpOnly: true,
+ });
+ res.status(200).json({
+ success: true,
+ message: "Logged Out",
+ });
+});
//get All salescoordinator
export const getAllSalesCoOrdinator = async (req, res) => {
try {
@@ -286,13 +298,14 @@ export const forgotPassword = async (req, res) => {
//Update mobile Number
export const updateMobileNumber = async (req, res) => {
const { id } = req.params;
+ const userId = id || req.user._id;
let { newCountryCode, newMobileNumber } = req.body;
newCountryCode = newCountryCode?.trim();
newMobileNumber = newMobileNumber?.trim();
const newFullMobileNumber = `${newCountryCode}${newMobileNumber}`;
try {
- const salescoordinator = await SalesCoOrdinator.findById(id);
+ const salescoordinator = await SalesCoOrdinator.findById(userId);
if (!salescoordinator) {
return res.status(400).json({ message: "SalesCoOrdinator not found" });
}
@@ -441,14 +454,14 @@ export const deleteSalesCoOrdinator = async (req, res) => {
export const UpdateProfile = async (req, res) => {
const { name, email } = req.body;
const { id } = req.params;
-
+ const userId = id || req.user._id;
// Validate email
if (!validator.isEmail(email)) {
return res.status(400).json({ message: "Invalid email address" });
}
try {
- const salesCoordinator = await SalesCoOrdinator.findById(id); // Use the ID from params
+ const salesCoordinator = await SalesCoOrdinator.findById(userId); // Use the ID from params
if (!salesCoordinator) {
return res.status(404).json({ message: "SalesCoOrdinator not found" });
@@ -461,7 +474,7 @@ export const UpdateProfile = async (req, res) => {
// Check if email is being changed and already exists
if (email && email !== salesCoordinator.email) {
const emailExists = await SalesCoOrdinator.findOne({ email });
- if (emailExists && emailExists._id.toString() !== id) {
+ if (emailExists && emailExists._id.toString() !== userId) {
return res.status(400).json({
message:
"This Email ID is already in use by another SalesCoOrdinator",
@@ -493,6 +506,7 @@ export const UpdateProfile = async (req, res) => {
export const ChangePassword = async (req, res) => {
const { id } = req.params; // Retrieve id from req.params
const { oldPassword, newPassword, confirmPassword } = req.body;
+ const userId = id || req.user._id; // Use the ID from the URL or from the authenticated user
if (!oldPassword) {
return res.status(400).json({ message: "Please Enter Old password" });
@@ -504,34 +518,26 @@ export const ChangePassword = async (req, res) => {
return res.status(400).json({ message: "Please Enter Confirm Password" });
}
try {
- const salescoordinator = await SalesCoOrdinator.findById(id).select(
- "+password"
- );
+ const SalesCoOrdinator = await SalesCoOrdinator.findById(userId).select("+password");
- if (!salescoordinator) {
+ if (!SalesCoOrdinator) {
return res.status(404).json({ message: "SalesCoOrdinator not found" });
}
- const isPasswordMatched = await salescoordinator.comparePassword(
- oldPassword
- );
+ const isPasswordMatched = await SalesCoOrdinator.comparePassword(oldPassword);
if (!isPasswordMatched) {
return res.status(400).json({ message: "Old password is incorrect" });
}
if (newPassword !== confirmPassword) {
- return res
- .status(400)
- .json({ message: "New password and confirm Password does not match" });
+ return res.status(400).json({ message: "New password and confirm Password do not match" });
}
- salescoordinator.password = newPassword;
- await salescoordinator.save();
+ SalesCoOrdinator.password = newPassword;
+ await SalesCoOrdinator.save();
- return res
- .status(200)
- .json({ success: true, message: "Password updated successfully" });
+ return res.status(200).json({ success: true, message: "Password updated successfully" });
} catch (error) {
console.error("Error updating password:", error);
return res.status(500).json({
diff --git a/resources/SalesCoOrdinators/SalesCoOrdinatorRoute.js b/resources/SalesCoOrdinators/SalesCoOrdinatorRoute.js
index a1e54b5..190fadf 100644
--- a/resources/SalesCoOrdinators/SalesCoOrdinatorRoute.js
+++ b/resources/SalesCoOrdinators/SalesCoOrdinatorRoute.js
@@ -15,6 +15,7 @@ import {
getmyProfile,
ChangePassword,
getOneSalesCoOrdinator,
+ logout,
} from "./SalesCoOrdinatorController.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
@@ -22,7 +23,7 @@ import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
router.post("/register", register);
router.post("/verify-otp", verifyOtp);
router.post("/login", loginSalesCoOrdinator);
-
+router.route("/logout").get(logout);
//admin
router.get(
"/getAll",
@@ -46,7 +47,7 @@ router.post(
updateMobileNumber
);
router.post(
- "/update-mobile-number/:id",
+ "/update-mobile-number",
isAuthenticatedSalesCoOrdinator,
updateMobileNumber
);
@@ -69,7 +70,7 @@ router.patch(
UpdateProfile
);
router.patch(
- "/profile/update/:id",
+ "/profile/update",
isAuthenticatedSalesCoOrdinator,
UpdateProfile
);
@@ -80,7 +81,7 @@ router.put(
authorizeRoles("admin"),
ChangePassword
);
-router.put("/password/update/:id", isAuthenticatedSalesCoOrdinator, ChangePassword);
+router.put("/password/update", isAuthenticatedSalesCoOrdinator, ChangePassword);
//delete SalesCoOrdinator
router.delete(
"/delete/:id",
diff --git a/resources/TerritoryManagers/TerritoryManagerController.js b/resources/TerritoryManagers/TerritoryManagerController.js
new file mode 100644
index 0000000..45c33e8
--- /dev/null
+++ b/resources/TerritoryManagers/TerritoryManagerController.js
@@ -0,0 +1,590 @@
+// import hashPassword from '../utils/hashPassword';
+import crypto from "crypto";
+import TerritoryManager from "./TerritoryManagerModel.js";
+import sendEmail, { sendOtp } from "../../Utils/sendEmail.js";
+import validator from "validator";
+import password from "secure-random-password";
+import catchAsyncErrors from "../../middlewares/catchAsyncErrors.js";
+
+export const register = async (req, res) => {
+ let { name, email, countryCode, mobileNumber } = req.body;
+ countryCode = countryCode?.trim();
+ mobileNumber = mobileNumber?.trim();
+ const fullMobileNumber = `${countryCode}${mobileNumber}`;
+
+ try {
+ let territoryManager = await TerritoryManager.findOne({
+ mobileNumber: fullMobileNumber,
+ });
+
+ if (territoryManager && territoryManager.isVerified) {
+ return res.status(400).json({
+ message:
+ "TerritoryManager already registered and verified for this mobile number.",
+ });
+ }
+ // const otp = crypto.randomInt(100000, 1000000).toString();
+ const otp = "123456";
+ const otpExpires = Date.now() + 1 * 60 * 1000;
+
+ if (territoryManager) {
+ territoryManager.otp = otp;
+ territoryManager.otpExpires = otpExpires;
+ } else {
+ territoryManager = new TerritoryManager({
+ name,
+ email,
+ mobileNumber: fullMobileNumber,
+ otp,
+ otpExpires,
+ });
+ }
+ // 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,
+ // Your Cheminova verification OTP is: ${otp}
+ // );
+ return res.status(200).json({
+ message: `OTP sent to your mobile number ${fullMobileNumber} successfully`,
+ });
+ } catch (error) {
+ res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+
+export const verifyOtp = async (req, res) => {
+ const { fullMobileNumber, otp } = req.body;
+
+ try {
+ let mobileNmr = fullMobileNumber?.trim();
+ const territoryManager = await TerritoryManager.findOne({
+ mobileNumber: mobileNmr,
+ });
+
+ if (!territoryManager) {
+ return res.status(400).json({ message: "Invalid mobile number or OTP" });
+ }
+
+ if (
+ territoryManager.otp !== otp ||
+ territoryManager.otpExpires < Date.now()
+ ) {
+ return res.status(400).json({ message: "Invalid or expired OTP" });
+ }
+ const name = territoryManager.name;
+ const mobile = territoryManager.mobileNumber;
+ territoryManager.isVerified = true;
+ territoryManager.otp = undefined;
+ territoryManager.otpExpires = undefined;
+
+ // Generate a random password
+ const newPassword = password.randomPassword({
+ length: 12,
+ characters: [
+ { characters: password.upper, exactly: 1 },
+ { characters: password.symbols, exactly: 1 },
+ password.lower,
+ password.digits,
+ ],
+ });
+
+ // Save the new password (hashed)
+ territoryManager.password = newPassword;
+ await territoryManager.save();
+
+ // Send email with the new password
+ await sendEmail({
+ to: `${territoryManager?.email}`, // Change to your recipient
+ from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender
+ subject: `Cheminova Account Created`,
+ html: `Your Territory Manager Account is created successfully.
+
name is: ${name}
+
MobileNumber is: ${mobile}
+
password is: ${newPassword}
If you have not requested this email, please ignore it.`,
+ });
+
+ const token = territoryManager.getJWTToken();
+ res.status(200).json({
+ success: true,
+ token,
+ message: "Mobile number verified and new password sent successfully",
+ });
+ } catch (error) {
+ res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+// Login TerritoryManager
+export const loginTerritoryManager = async (req, res) => {
+ const { email, password } = req.body;
+ // console.log(email, password);
+ try {
+ if (!email || !password) {
+ return res.status(400).json({ message: "Please Enter Email & Password" });
+ }
+
+ const territoryManager = await TerritoryManager.findOne({ email }).select(
+ "+password"
+ );
+
+ if (!territoryManager) {
+ return res.status(400).json({ message: "Invalid Email or Password" });
+ }
+
+ const isPasswordMatched = await territoryManager.comparePassword(password);
+
+ if (!isPasswordMatched) {
+ return res.status(400).json({ message: "Invalid Email or Password" });
+ }
+ const token = territoryManager.getJWTToken();
+
+ return res.status(200).json({
+ success: true,
+ token,
+ message: "Login Successfully",
+ });
+ } catch (error) {
+ return res.status(500).json({
+ message: error.message ? error.message : "Something went wrong!",
+ });
+ }
+};
+// Logout User
+export const logout = catchAsyncErrors(async (req, res, next) => {
+ res.cookie("token", null, {
+ expires: new Date(Date.now()),
+ httpOnly: true,
+ });
+
+ res.status(200).json({
+ success: true,
+ message: "Logged Out",
+ });
+});
+//get All territorymanager
+export const getAllTerritoryManager = async (req, res) => {
+ try {
+ const PAGE_SIZE = parseInt(req.query?.show || "10");
+ const page = parseInt(req.query?.page || "1") - 1;
+ let filter = {};
+ if (req.query?.name) {
+ filter.name = {
+ $regex: new RegExp(req.query.name, "i"),
+ };
+ }
+ if (req.query?.mobileNumber) {
+ filter.mobileNumber = {
+ $regex: new RegExp(req.query.mobileNumber, "i"),
+ };
+ }
+ if (req.query?.isVerified) {
+ filter.isVerified = req.query.isVerified === "true";
+ }
+
+ const total = await TerritoryManager.countDocuments(filter);
+ const salesCoOrinators = await TerritoryManager.find(filter)
+ .limit(PAGE_SIZE)
+ .skip(PAGE_SIZE * page)
+ .sort({ createdAt: -1 });
+
+ return res.status(200).json({
+ success: true,
+ total_data: total,
+ total_pages: Math.ceil(total / PAGE_SIZE),
+ salesCoOrinators,
+ });
+ } 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) {
+ return res
+ .status(400)
+ .json({ message: "Please provide sales coordinator ID" });
+ }
+ const territoryManager = await TerritoryManager.findById(req.params.id);
+ if (territoryManager) {
+ return res.status(200).json({
+ success: true,
+ message: "Fetched successfully",
+ data: territoryManager,
+ });
+ } else {
+ return res.status(404).json({
+ success: false,
+ message: "Sales coordinator not found",
+ });
+ }
+ } catch (error) {
+ return res.status(500).json({
+ success: false,
+ message: error.message ? error.message : "Something went wrong!",
+ });
+ }
+};
+
+// 4.Forgot Password
+
+export const forgotPassword = async (req, res) => {
+ const territorymanager = await TerritoryManager.findOne({
+ email: req.body.email,
+ });
+ if (!req.body.email) {
+ return res.status(400).json({ message: "please Enter Email!" });
+ }
+ if (!territorymanager) {
+ return res.status(404).json({ message: "TerritoryManager not found" });
+ }
+ // Get ResetPassword Token
+ // const resetToken = territorymanager.getResetPasswordToken(); //call function
+
+ //save database reset token
+ // await territorymanager.save({ validateBeforeSave: false });
+
+ const passwords = password.randomPassword({
+ length: 12,
+ characters: [
+ { characters: password.upper, exactly: 1 },
+ { characters: password.symbols, exactly: 1 },
+ password.lower,
+ password.digits,
+ ],
+ });
+ // console.log(passwords);
+ territorymanager.password = passwords;
+ await territorymanager.save();
+ // const message = `Your password reset token are :- \n\n ${resetPasswordUrl} \n\nyour new password is:${password}\n\nIf you have not requested this email then, please ignore it.`;
+ try {
+ await sendEmail({
+ to: `${territorymanager?.email}`, // Change to your recipient
+
+ from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender
+
+ subject: `Cheminova Password Recovery`,
+ html: `your new password is:
${passwords}
If you have not requested this email then, please ignore it.`,
+ });
+
+ res.status(200).json({
+ success: true,
+ message: `Email sent to ${territorymanager?.email} successfully`,
+ });
+ } catch (error) {
+ territorymanager.resetPasswordToken = undefined;
+ territorymanager.resetPasswordExpire = undefined;
+
+ await territorymanager.save({ validateBeforeSave: false });
+
+ return res.status(500).json({
+ message: error.message ? error.message : "Something went wrong!",
+ });
+ }
+};
+
+//Update mobile Number
+export const updateMobileNumber = async (req, res) => {
+ const { id } = req.params;
+ const userId = id || req.user._id;
+ let { newCountryCode, newMobileNumber } = req.body;
+ newCountryCode = newCountryCode?.trim();
+ newMobileNumber = newMobileNumber?.trim();
+ const newFullMobileNumber = `${newCountryCode}${newMobileNumber}`;
+
+ try {
+ const territorymanager = await TerritoryManager.findById(userId);
+ if (!territorymanager) {
+ return res.status(400).json({ message: "TerritoryManager not found" });
+ }
+ if (territorymanager.mobileNumber === newFullMobileNumber) {
+ return res.status(400).json({
+ message:
+ "New mobile number cannot be the same as the old mobile number",
+ });
+ }
+ // Check if the new mobile number already exists in another document
+ const existingTerritoryManager = await TerritoryManager.findOne({
+ mobileNumber: newFullMobileNumber,
+ });
+
+ if (existingTerritoryManager) {
+ return res.status(400).json({
+ message: "Mobile number already registered and verified by someone",
+ });
+ }
+ // const otp = crypto.randomInt(100000, 1000000).toString();
+ const otp = "123456";
+ const otpExpires = Date.now() + 3 * 60 * 1000; // 3 minutes
+
+ territorymanager.newMobileNumber = newFullMobileNumber;
+ territorymanager.otp = otp;
+ territorymanager.otpExpires = otpExpires;
+
+ await territorymanager.save();
+ await sendOtp(
+ newFullMobileNumber,
+ `Your Cheminova verification OTP is: ${otp}`
+ );
+
+ return res.status(200).json({
+ message: `OTP sent to your new mobile number ${newFullMobileNumber} successfully`,
+ });
+ } catch (error) {
+ console.error("Error updating mobile number:", error);
+ return res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+
+//verify Updated Number OTP
+export const verifyUpdatedMobileOtp = async (req, res) => {
+ const { newMobileNumber, otp } = req.body;
+ // console.log(newMobileNumber, otp);
+ try {
+ let mobileNmr = newMobileNumber?.trim();
+ const territoryManager = await TerritoryManager.findOne({
+ newMobileNumber: mobileNmr,
+ });
+
+ if (!territoryManager) {
+ return res.status(400).json({ message: "Invalid mobile number or OTP" });
+ }
+
+ if (
+ territoryManager.otp !== otp ||
+ territoryManager.otpExpires < Date.now()
+ ) {
+ return res.status(400).json({ message: "Invalid or expired OTP" });
+ }
+
+ // Update sales coordinator's mobile number and verification status
+ territoryManager.mobileNumber = territoryManager.newMobileNumber;
+ territoryManager.newMobileNumber = undefined;
+ territoryManager.isVerified = true;
+ territoryManager.otp = undefined;
+ territoryManager.otpExpires = undefined;
+
+ // Save changes to the database
+ await territoryManager.save();
+
+ const token = territoryManager.getJWTToken();
+ return res.status(200).json({
+ success: true,
+ token,
+ message: "Mobile number updated and verified successfully",
+ });
+ } catch (error) {
+ console.error("Error verifying mobile OTP:", error);
+ return res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+
+//getmyProfile
+export const getmyProfile = async (req, res) => {
+ try {
+ const myData = await TerritoryManager.findById(req.user?._id);
+ if (myData) {
+ return res.status(200).json({
+ success: true,
+ message: "feched!",
+ myData,
+ });
+ }
+ } catch (error) {
+ return res.status(500).json({
+ success: false,
+ message: error.message ? error.message : "Something went wrong!",
+ });
+ }
+};
+
+//
+export const deleteTerritoryManager = async (req, res) => {
+ try {
+ if (!req.params.id) {
+ return res.status(400).json({
+ success: false,
+ message: "Please Provide TerritoryManager ID!",
+ });
+ }
+ const getTerritoryManager = await TerritoryManager.findById(req.params.id);
+ if (!getTerritoryManager) {
+ return res.status(404).json({
+ success: false,
+ message: "territorymanager not Found!",
+ });
+ }
+
+ //-------------------------//
+ const territorymanager = await TerritoryManager.findByIdAndDelete(
+ req.params.id
+ );
+ if (!territorymanager) {
+ return res.status(404).json({ message: "territorymanager Not Found" });
+ }
+ await territorymanager.remove();
+ res.status(200).json({
+ success: true,
+ message: "territorymanager Deleted Successfully!!",
+ });
+ } catch (error) {
+ res.status(500).json({
+ success: false,
+ message: error.message ? error.message : "Something went wrong!",
+ });
+ }
+};
+
+export const UpdateProfile = async (req, res) => {
+ const { name, email } = req.body;
+ const { id } = req.params;
+ // console.log(name, email);
+ const userId = id || req.user._id;
+ // console.log(userId);
+ // Validate email
+ if (!validator.isEmail(email)) {
+ return res.status(400).json({ message: "Invalid email address" });
+ }
+
+ try {
+ const territoryManager = await TerritoryManager.findById(userId); // Use the ID from params
+
+ if (!territoryManager) {
+ return res.status(404).json({ message: "TerritoryManager not found" });
+ }
+
+ if (!territoryManager.isVerified) {
+ return res.status(400).json({ message: "TerritoryManager not verified" });
+ }
+
+ // Check if email is being changed and already exists
+ if (email && email !== territoryManager.email) {
+ const emailExists = await TerritoryManager.findOne({ email });
+ if (emailExists && emailExists._id.toString() !== userId) {
+ return res.status(400).json({
+ message:
+ "This Email ID is already in use by another TerritoryManager",
+ });
+ }
+ territoryManager.email = email;
+ }
+
+ // Update name if provided
+ if (name) {
+ territoryManager.name = name;
+ }
+
+ // Save the updated territoryManager
+ await territoryManager.save();
+
+ return res.status(200).json({
+ territoryManager,
+ message: "Profile updated successfully",
+ });
+ } catch (error) {
+ res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+
+//change TerritoryManager password
+export const ChangePassword = async (req, res) => {
+ const { id } = req.params; // Retrieve id from req.params
+ const { oldPassword, newPassword, confirmPassword } = req.body;
+ const userId = id || req.user._id; // Use the ID from the URL or from the authenticated user
+
+ if (!oldPassword) {
+ return res.status(400).json({ message: "Please Enter Old password" });
+ }
+ if (!newPassword) {
+ return res.status(400).json({ message: "Please Enter New Password " });
+ }
+ if (!confirmPassword) {
+ return res.status(400).json({ message: "Please Enter Confirm Password" });
+ }
+ try {
+ const territorymanager = await TerritoryManager.findById(userId).select(
+ "+password"
+ );
+
+ if (!territorymanager) {
+ return res.status(404).json({ message: "TerritoryManager not found" });
+ }
+
+ const isPasswordMatched = await territorymanager.comparePassword(
+ oldPassword
+ );
+
+ if (!isPasswordMatched) {
+ return res.status(400).json({ message: "Old password is incorrect" });
+ }
+
+ if (newPassword !== confirmPassword) {
+ return res
+ .status(400)
+ .json({ message: "New password and confirm Password do not match" });
+ }
+
+ territorymanager.password = newPassword;
+ await territorymanager.save();
+
+ return res
+ .status(200)
+ .json({ success: true, message: "Password updated successfully" });
+ } catch (error) {
+ console.error("Error updating password:", error);
+ return res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
+
+export const Otp = async (req, res) => {
+ // const { name, mobileNumber } = req.body;
+ try {
+ // let territorymanager = await TerritoryManager.findOne({ mobileNumber });
+
+ // if (territorymanager && territorymanager.isVerified) {
+ // return res.status(400).json({ message: 'TerritoryManager already registered and verified for This Mobile No.' });
+ // }
+
+ // const otp = crypto.randomInt(100000, 1000000).toString();
+
+ // // const otp ="123456";
+
+ // const otpExpires = Date.now() + 10 * 60 * 1000; // 10 minutes
+
+ // if (territorymanager) {
+ // territorymanager.otp = otp;
+ // territorymanager.otpExpires = otpExpires;
+ // } else {
+ // territorymanager = new TerritoryManager({ name, mobileNumber, otp, otpExpires });
+ // }
+
+ // await territorymanager.save();
+ await sendOtp();
+
+ // res.status(200).json({territorymanager, message: `OTP ${otp} sent to your mobile number successfully` });
+ } catch (error) {
+ res.status(500).json({
+ message: error.message ? error.message : "Server error!",
+ });
+ }
+};
diff --git a/resources/TerritoryManagers/TerritoryManagerModel.js b/resources/TerritoryManagers/TerritoryManagerModel.js
new file mode 100644
index 0000000..e1a0e10
--- /dev/null
+++ b/resources/TerritoryManagers/TerritoryManagerModel.js
@@ -0,0 +1,100 @@
+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 territorymanagerSchema = new mongoose.Schema(
+ {
+ name: {
+ type: String,
+ required: true,
+ },
+ mobileNumber: {
+ type: String,
+ required: true,
+ unique: true,
+ },
+ otp: {
+ type: String,
+ required: false,
+ },
+ otpExpires: {
+ type: Date,
+ },
+ isVerified: {
+ type: Boolean,
+ default: false,
+ },
+ 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,
+ },
+ newMobileNumber: { type: String },
+ resetPasswordToken: String,
+ resetPasswordExpire: Date,
+ uniqueId: {
+ type: String,
+ unique: true,
+ required: true,
+ },
+ },
+ { timestamps: true }
+);
+
+territorymanagerSchema.pre("save", async function (next) {
+ if (!this.isModified("password")) {
+ next();
+ }
+
+ this.password = await bcrypt.hash(this.password, 10);
+});
+
+territorymanagerSchema.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
+territorymanagerSchema.methods.getJWTToken = function () {
+ return jwt.sign({ id: this._id }, process.env.JWT_SECRET);
+};
+
+// Compare Password
+territorymanagerSchema.methods.comparePassword = async function (password) {
+ return await bcrypt.compare(password, this.password);
+};
+
+// Generating Reset Token
+territorymanagerSchema.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 TerritoryManager = mongoose.model(
+ "TerritoryManager",
+ territorymanagerSchema
+);
+
+export default TerritoryManager;
diff --git a/resources/TerritoryManagers/TerritoryManagerRoute.js b/resources/TerritoryManagers/TerritoryManagerRoute.js
new file mode 100644
index 0000000..82ee8c5
--- /dev/null
+++ b/resources/TerritoryManagers/TerritoryManagerRoute.js
@@ -0,0 +1,100 @@
+import express from "express";
+
+const router = express.Router();
+import {
+ Otp,
+ deleteTerritoryManager,
+ forgotPassword,
+ getAllTerritoryManager,
+ loginTerritoryManager,
+ register,
+ updateMobileNumber,
+ verifyUpdatedMobileOtp,
+ verifyOtp,
+ UpdateProfile,
+ getmyProfile,
+ ChangePassword,
+ getOneTerritoryManager,
+ logout,
+} from "./TerritoryManagerController.js";
+import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
+import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
+
+router.post("/register", register);
+router.post("/verify-otp", verifyOtp);
+router.post("/login", loginTerritoryManager);
+router.route("/logout").get(logout);
+//admin
+router.get(
+ "/getAll",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ getAllTerritoryManager
+);
+router.get(
+ "/getOne/:id",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ getOneTerritoryManager
+);
+router.get("/my-profile", isAuthenticatedTerritoryManager, getmyProfile);
+
+//Update Mobile Number
+router.post(
+ "/update-mobile-number/:id",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ updateMobileNumber
+);
+router.post(
+ "/update-mobile-number",
+ isAuthenticatedTerritoryManager,
+ updateMobileNumber
+);
+router.post(
+ "/verify-updated-mobile-otp",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ verifyUpdatedMobileOtp
+);
+router.post(
+ "/verify-updated-mobilenumber-otp",
+ isAuthenticatedTerritoryManager,
+ verifyUpdatedMobileOtp
+);
+router.post("/forgot-password", forgotPassword);
+router.patch(
+ "/profile/update/:id",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ UpdateProfile
+);
+router.patch(
+ "/profile/update",
+ isAuthenticatedTerritoryManager,
+ UpdateProfile
+);
+//change password
+router.put(
+ "/password/update/:id",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ ChangePassword
+);
+
+router.put(
+ "/password/update",
+ isAuthenticatedTerritoryManager,
+ ChangePassword
+);
+//delete TerritoryManager
+router.delete(
+ "/delete/:id",
+ isAuthenticatedUser,
+ authorizeRoles("admin"),
+ deleteTerritoryManager
+);
+
+router.get("/otp", Otp);
+
+export default router;