diff --git a/.env b/.env
index 0d4aecf..fdbc82a 100644
--- a/.env
+++ b/.env
@@ -32,7 +32,7 @@ RAZERPAY_KEY_ID="rzp_test_2rg1Bq3Ki8xw9e"
RAZERPAY_SECRET_KEY="WFhHbXL7AlLIuull9kKjYiNA"
FRONTEND_URL="https://smellika.com"
-PD_APP_URL="https://principal-distributer-cheminova.netlify.app"
+PD_APP_URL="https://pd.cnapp.co.in/#/login"
SEND_EMAIL_FROM="cheminova2004@gmail.com"
diff --git a/app.js b/app.js
index 1949d2f..429b1ba 100644
--- a/app.js
+++ b/app.js
@@ -159,6 +159,8 @@ import shopImageRoute from "./resources/ShopPageImage/ShopPageImageRoute.js";
import ContentRoute from "./resources/Content/ContentRoutes.js";
import UserAddressRoute from "./resources/userAddress/useAddressRoute.js";
import CurrencyRoute from "./resources/Currency/CurrencyRoute.js";
+// RD Routes
+import RDRoute from './resources/RetailDistributor/RetailDistributerRoutes.js'
//business_Type
// import Business_TypeRoute from "./resources/setting/Business_Type/Business_routes.js";
@@ -272,7 +274,8 @@ app.use("/api/inventory", InventoryRoute);
app.use("/api/sales", SalesRoute);
//Task
app.use("/api/task", TaskRoute);
-
+// RD Rotuts
+app.use("/api",RDRoute)
//config specialty
// app.use("/api/config/specialty", SpecialtiesRouter);
//specialties
diff --git a/middlewares/rdAuth.js b/middlewares/rdAuth.js
new file mode 100644
index 0000000..c51451c
--- /dev/null
+++ b/middlewares/rdAuth.js
@@ -0,0 +1,38 @@
+import jwt from "jsonwebtoken";
+import RetailDistributor from "../resources/RetailDistributor/RetailDistributorModel.js";
+
+// import { Business } from "../resources/Businesses/BusinessModel.js";
+
+export const isAuthenticatedRD = async (req, res, next) => {
+ try {
+ if (!req.headers.authorization) {
+ return res.status(400).json({
+ success: false,
+ message: "Login to Access this resource",
+ });
+ }
+ const getToken = req.headers;
+ // console.log(getToken);
+ //remove Bearer from token
+ const fronttoken = getToken.authorization.slice(7);
+
+ const frontdecoded = jwt.verify(fronttoken, process.env.JWT_SECRET);
+ if (!frontdecoded) {
+ return res.status(400).json({
+ success: false,
+ message: "incorrect token",
+ });
+ }
+ // console.log(frontdecoded);
+ const fuser = await RetailDistributor.findById(frontdecoded.id);
+ // console.log(fuser);
+ req.user = fuser;
+
+ next();
+ } catch (error) {
+ return res.status(400).json({
+ success: false,
+ message: error.message,
+ });
+ }
+};
diff --git a/resources/KYC/KycController.js b/resources/KYC/KycController.js
index a12cb84..8406c91 100644
--- a/resources/KYC/KycController.js
+++ b/resources/KYC/KycController.js
@@ -47,7 +47,10 @@ export const createKyc = async (req, res) => {
if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
return res.status(400).json({ message: "Please login again" });
}
-
+ const isExits = await KYC.find({ email: email });
+ if (isExits.length > 0) {
+ throw new Error("Email already exists");
+ }
// Upload images to Cloudinary and store only public_id and url
const uploadImage = async (image, folder) => {
if (!image) return null;
@@ -378,7 +381,7 @@ export const getKycById = async (req, res) => {
export const updateKycStatus = async (req, res) => {
const { status, rejectionReason, user } = req.body;
- console.log(status);
+
const { id } = req.params;
// console.log(user, rejectionReason, status);
try {
@@ -394,7 +397,7 @@ export const updateKycStatus = async (req, res) => {
const trade_name = kyc.trade_name;
if (status === "approved") {
kyc.status = status;
- console.log("inside Approved ");
+
await rejectKYC(
kyc.addedBy,
"KYC Approved",
@@ -407,6 +410,7 @@ export const updateKycStatus = async (req, res) => {
added_for: kyc.addedBy,
// userType: req.userType,
});
+
// Generate a secure password for RetailDistributor
const password = generatePassword(kyc.name, kyc.email);
diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js
index 26dacfc..335d0d7 100644
--- a/resources/PD_Orders/pdOrderController.js
+++ b/resources/PD_Orders/pdOrderController.js
@@ -702,7 +702,14 @@ const formatDate = (date) => {
export const getOrderCounts = async (req, res) => {
try {
+ // console.log(req.user._id,"");
+ const userId = req.user._id;
const statusCounts = await PdOrder.aggregate([
+ {
+ $match: {
+ addedBy: userId, // Only match orders added by the current user
+ },
+ },
{
$group: {
_id: "$status", // Group by status
diff --git a/resources/PD_Orders/pdOrderRoute.js b/resources/PD_Orders/pdOrderRoute.js
index 647dfa4..513383b 100644
--- a/resources/PD_Orders/pdOrderRoute.js
+++ b/resources/PD_Orders/pdOrderRoute.js
@@ -50,6 +50,6 @@ router
router
.route("/change/status/:id")
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
-router.route("/get-counts-pdOrders").get(getOrderCounts);
+router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts);
export default router;
diff --git a/resources/RetailDistributor/RetailDistributerRoutes.js b/resources/RetailDistributor/RetailDistributerRoutes.js
new file mode 100644
index 0000000..5bbad7b
--- /dev/null
+++ b/resources/RetailDistributor/RetailDistributerRoutes.js
@@ -0,0 +1,28 @@
+import express from "express";
+import {
+ ChangePasswordRD,
+ forgotPassword,
+ getmyProfile,
+ loginRD,
+ UpdateProfile,
+} from "./RetailDistributorController.js";
+import { isAuthenticatedRD } from "../../middlewares/rdAuth.js";
+
+const router = express.Router();
+
+router.route("/rd-login").post(loginRD);
+router.route("/rd-get-me").get(isAuthenticatedRD, getmyProfile);
+router.post("/forgot-password", forgotPassword);
+router.put(
+ "/rd-password/update",
+ isAuthenticatedRD,
+
+ ChangePasswordRD
+);
+router.patch(
+ "/rd-profile/update",
+ isAuthenticatedRD,
+
+ UpdateProfile
+);
+export default router;
diff --git a/resources/RetailDistributor/RetailDistributorController.js b/resources/RetailDistributor/RetailDistributorController.js
index e69de29..aa3c66e 100644
--- a/resources/RetailDistributor/RetailDistributorController.js
+++ b/resources/RetailDistributor/RetailDistributorController.js
@@ -0,0 +1,218 @@
+import RetailDistributor from "./RetailDistributorModel.js";
+import validator from "validator";
+export const loginRD = async (req, res) => {
+ const { email, password } = req.body;
+
+ try {
+ if (!email || !password) {
+ return res.status(400).json({ message: "Please Enter Email & Password" });
+ }
+
+ const retailDistributor = await RetailDistributor.findOne({ email }).select(
+ "+password"
+ );
+
+ if (!retailDistributor) {
+ return res.status(400).json({ message: "Invalid Email or Password" });
+ }
+
+ const isPasswordMatched = await retailDistributor.comparePassword(password);
+
+ if (!isPasswordMatched) {
+ return res.status(400).json({ message: "Invalid Email or Password" });
+ }
+ const token = retailDistributor.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!",
+ });
+ }
+};
+
+export const ChangePasswordRD = async (req, res) => {
+ // Retrieve id from req.params
+ const { oldPassword, newPassword, confirmPassword } = req.body;
+ const userId = req.user._id; // Use the ID from the URL or from the authenticated user
+ // console.log(userId);
+ 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 retailDistributor = await RetailDistributor.findById(userId).select(
+ "+password"
+ );
+
+ if (!retailDistributor) {
+ return res.status(404).json({ message: "Retail Distributer not found" });
+ }
+
+ const isPasswordMatched = await retailDistributor.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" });
+ }
+
+ retailDistributor.password = newPassword;
+ await retailDistributor.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 forgotPassword = async (req, res) => {
+ try {
+ // Check if email is provided
+ const { email } = req.body;
+ if (!email) {
+ return res.status(400).json({ message: "Please Enter Email!" });
+ }
+
+ // Find the Retail Distributor by email
+ const retailDistributor = await RetailDistributor.findOne({ email });
+ if (!retailDistributor) {
+ return res.status(404).json({ message: "Retail Distributor not found" });
+ }
+
+ // Generate a random password
+ const newPassword = password.randomPassword({
+ length: 12,
+ characters: [
+ { characters: password.upper, exactly: 1 }, // At least 1 uppercase letter
+ { characters: password.symbols, exactly: 1 }, // At least 1 symbol
+ password.lower, // Lowercase letters
+ password.digits, // Digits
+ ],
+ });
+
+ // Update the retail distributor's password
+ retailDistributor.password = newPassword;
+ await retailDistributor.save(); // The pre-save hook in your schema will handle password hashing
+
+ // Send an email to the retail distributor with the new password
+ await sendEmail({
+ to: retailDistributor.email,
+ from: process.env.SEND_EMAIL_FROM,
+ subject: `Cheminova Password Recovery`,
+ html: `Your new password is: ${newPassword}
If you did not request this, please ignore this email.`,
+ });
+
+ // Respond with success message
+ return res.status(200).json({
+ success: true,
+ message: `Email sent to ${retailDistributor.email} successfully`,
+ });
+ } catch (error) {
+ console.error("Error during password reset:", error);
+ return res.status(500).json({
+ message: error.message || "Something went wrong!",
+ });
+ }
+};
+
+export const UpdateProfile = async (req, res) => {
+ const { name, email } = req.body;
+
+ const userId = req.user._id; // Use the ID from params or authenticated user
+
+ // Validate email if provided
+ if (email && !validator.isEmail(email)) {
+ return res.status(400).json({ message: "Invalid email address" });
+ }
+
+ try {
+ // Find the RetailDistributor by user ID
+ const retailDistributor = await RetailDistributor.findById(userId);
+
+ if (!retailDistributor) {
+ return res.status(404).json({ message: "Retail Distributor not found" });
+ }
+
+ // Assuming you have an 'isVerified' field in your RetailDistributor schema
+ if (!retailDistributor.isVerified) {
+ return res
+ .status(400)
+ .json({ message: "Retail Distributor not verified" });
+ }
+
+ // Check if email is being changed and if it's already in use
+ if (email && email !== retailDistributor.email) {
+ const emailExists = await RetailDistributor.findOne({ email });
+ if (emailExists && emailExists._id.toString() !== userId) {
+ return res.status(400).json({
+ message:
+ "This Email ID is already in use by another Retail Distributor",
+ });
+ }
+ retailDistributor.email = email;
+ }
+
+ // Update name if provided
+ if (name) {
+ retailDistributor.name = name;
+ }
+
+ // Save the updated RetailDistributor
+ await retailDistributor.save();
+
+ return res.status(200).json({
+ retailDistributor,
+ message: "Profile updated successfully",
+ });
+ } catch (error) {
+ return res.status(500).json({
+ message: error.message || "Server error!",
+ });
+ }
+};
+
+export const getmyProfile = async (req, res) => {
+ try {
+ // Fetch the profile data using the authenticated user's ID
+ const myData = await RetailDistributor.findById(req.user?._id);
+
+ if (myData) {
+ return res.status(200).json({
+ success: true,
+ message: "Profile fetched successfully!",
+ myData,
+ });
+ } else {
+ return res.status(404).json({
+ success: false,
+ message: "Retail Distributor not found",
+ });
+ }
+ } catch (error) {
+ return res.status(500).json({
+ success: false,
+ message: error.message || "Something went wrong!",
+ });
+ }
+};
diff --git a/resources/RetailDistributor/RetailDistributorModel.js b/resources/RetailDistributor/RetailDistributorModel.js
index a44164f..96f5452 100644
--- a/resources/RetailDistributor/RetailDistributorModel.js
+++ b/resources/RetailDistributor/RetailDistributorModel.js
@@ -68,9 +68,8 @@ const RetailDistributorSchema = new mongoose.Schema(
resetPasswordExpire: Date,
fcm_token: {
type: String,
- unique: true,
+ default: null,
},
-
},
{ timestamps: true }
);
@@ -102,7 +101,9 @@ RetailDistributorSchema.pre("save", function (next) {
// JWT TOKEN
RetailDistributorSchema.methods.getJWTToken = function () {
- return jwt.sign({ id: this._id }, process.env.JWT_SECRET);
+ return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
+ expiresIn: "1d", // Token will expire in 1 day
+ });
};
// Compare Password
@@ -128,4 +129,4 @@ const RetailDistributor = mongoose.model(
"RetailDistributor",
RetailDistributorSchema
);
-export default RetailDistributor;
\ No newline at end of file
+export default RetailDistributor;