Merge branch 'main' of https://git.cnapp.co.in/gitadmin/api
This commit is contained in:
commit
ec4284bfc4
@ -1,5 +1,6 @@
|
|||||||
import SalesCoOrdinator from "../resources/SalesCoOrdinators/SalesCoOrdinatorModel.js";
|
import SalesCoOrdinator from "../resources/SalesCoOrdinators/SalesCoOrdinatorModel.js";
|
||||||
import TerritoryManager from "../resources/TerritoryManagers/TerritoryManagerModel.js";
|
import TerritoryManager from "../resources/TerritoryManagers/TerritoryManagerModel.js";
|
||||||
|
import User from "../resources/user/userModel.js";
|
||||||
import { sendPushNotification } from "./sendPushNotification.js";
|
import { sendPushNotification } from "./sendPushNotification.js";
|
||||||
|
|
||||||
export const rejectKYC = async (userId, title, message) => {
|
export const rejectKYC = async (userId, title, message) => {
|
||||||
@ -25,3 +26,24 @@ export const rejectKYC = async (userId, title, message) => {
|
|||||||
console.error("No FCM token found for user:", userId);
|
console.error("No FCM token found for user:", userId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createKYC = async (userId, title, message) => {
|
||||||
|
// Try to find the user in SalesCoordinator model
|
||||||
|
console.log(userId);
|
||||||
|
let user = await User.findById(userId);
|
||||||
|
|
||||||
|
console.log(user);
|
||||||
|
// Get the user's FCM token
|
||||||
|
const userToken = user ? user.fcm_token : null;
|
||||||
|
// const userToken =
|
||||||
|
// "dRnjl8F3S8GA6_BnBfloWZ:APA91bFvuiA4pEQr03Kymqtw2N207VDHwzLlfz_OPWzhTtdAAWmPLF8cQSx0WYmiaL9g-PIbzvGrmzDzxNiyq58w9Gws6p2tDlDeqycqU17W74gi36xkGSUqlzNiFoTiDDNp7OFDdVPK";
|
||||||
|
console.log(userToken);
|
||||||
|
if (userToken) {
|
||||||
|
// Send the push notification
|
||||||
|
// const message = `Your KYC has been rejected. Reason: ${reason}`;
|
||||||
|
await sendPushNotification(userToken, title, message);
|
||||||
|
console.log("sent to device ");
|
||||||
|
} else {
|
||||||
|
console.error("No FCM token found for user:", userId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
6
app.js
6
app.js
@ -197,6 +197,8 @@ import SalesRoute from "./resources/Sales/SalesRoute.js";
|
|||||||
|
|
||||||
import PdOrderRoute from './resources/PD_Orders/pdOrderRoute.js'
|
import PdOrderRoute from './resources/PD_Orders/pdOrderRoute.js'
|
||||||
|
|
||||||
|
import RDOrderRoute from "./resources/RD_Ordes/rdOrderRoutes.js"
|
||||||
|
|
||||||
import TaskRoute from "./resources/Task/TaskRoute.js";
|
import TaskRoute from "./resources/Task/TaskRoute.js";
|
||||||
// visit RD and PD
|
// visit RD and PD
|
||||||
import VisitRDandPDRoute from "./resources/VisitRD&PD/VisitRD&PDRoute.js";
|
import VisitRDandPDRoute from "./resources/VisitRD&PD/VisitRD&PDRoute.js";
|
||||||
@ -276,8 +278,10 @@ app.use("/api/inventory", InventoryRoute);
|
|||||||
app.use("/api/sales", SalesRoute);
|
app.use("/api/sales", SalesRoute);
|
||||||
//Task
|
//Task
|
||||||
app.use("/api/task", TaskRoute);
|
app.use("/api/task", TaskRoute);
|
||||||
// RD Rotuts
|
// RD Rotuts auth
|
||||||
app.use("/api",RDRoute)
|
app.use("/api",RDRoute)
|
||||||
|
// RD Order routes
|
||||||
|
app.use("/api",RDOrderRoute)
|
||||||
// visit RD and PD
|
// visit RD and PD
|
||||||
app.use("/api", VisitRDandPDRoute);
|
app.use("/api", VisitRDandPDRoute);
|
||||||
//config specialty
|
//config specialty
|
||||||
|
@ -12,6 +12,7 @@ export const isAuthenticatedRD = async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const getToken = req.headers;
|
const getToken = req.headers;
|
||||||
|
console.log(getToken);
|
||||||
// console.log(getToken);
|
// console.log(getToken);
|
||||||
//remove Bearer from token
|
//remove Bearer from token
|
||||||
const fronttoken = getToken.authorization.slice(7);
|
const fronttoken = getToken.authorization.slice(7);
|
||||||
@ -23,8 +24,8 @@ export const isAuthenticatedRD = async (req, res, next) => {
|
|||||||
message: "incorrect token",
|
message: "incorrect token",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// console.log(frontdecoded);
|
console.log(frontdecoded);
|
||||||
const fuser = await RetailDistributor.findById(frontdecoded.id);
|
const fuser = await RetailDistributor.findById(frontdecoded._id);
|
||||||
// console.log(fuser);
|
// console.log(fuser);
|
||||||
req.user = fuser;
|
req.user = fuser;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import mongoose from "mongoose";
|
|||||||
import cloudinary from "../../Utils/cloudinary.js";
|
import cloudinary from "../../Utils/cloudinary.js";
|
||||||
import { KYC } from "./KycModel.js";
|
import { KYC } from "./KycModel.js";
|
||||||
import User from "../user/userModel.js";
|
import User from "../user/userModel.js";
|
||||||
import { rejectKYC } from "../../Utils/rejectKyc.js";
|
import { createKYC, 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";
|
||||||
@ -105,6 +105,19 @@ export const createKyc = async (req, res) => {
|
|||||||
notes,
|
notes,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (principal_distributer) {
|
||||||
|
await createKYC(
|
||||||
|
kyc.principal_distributer,
|
||||||
|
"KYC Created",
|
||||||
|
`${trade_name} sent request to approve the KYC .`
|
||||||
|
);
|
||||||
|
await Notification.create({
|
||||||
|
title: "KYC Created",
|
||||||
|
msg: `KYC created for the trade name ${name}`,
|
||||||
|
kyc_ref: kyc._id,
|
||||||
|
added_for: kyc.principal_distributer,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (kyc) {
|
if (kyc) {
|
||||||
return res
|
return res
|
||||||
.status(201)
|
.status(201)
|
||||||
@ -573,4 +586,3 @@ export const saveFCMTokenForTM = async (req, res) => {
|
|||||||
res.status(500).send("Internal Server Error");
|
res.status(500).send("Internal Server Error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { Notification } from "./notificationModal.js";
|
|||||||
export const getNotification = async (req, res) => {
|
export const getNotification = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Ensure req.user._id is defined and valid
|
// Ensure req.user._id is defined and valid
|
||||||
|
console.log("req came here ");
|
||||||
if (!req.user || !req.user._id) {
|
if (!req.user || !req.user._id) {
|
||||||
return res.status(400).json({ return_message: "Invalid user ID" });
|
return res.status(400).json({ return_message: "Invalid user ID" });
|
||||||
}
|
}
|
||||||
@ -18,7 +19,7 @@ export const getNotification = async (req, res) => {
|
|||||||
.json({ return_message: "Fetched notifications", notifications });
|
.json({ return_message: "Fetched notifications", notifications });
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(404).json({ return_message: "No notifications found" });
|
return res.status(402).json({ return_message: "No notifications found" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return res
|
return res
|
||||||
.status(500)
|
.status(500)
|
||||||
|
@ -2,6 +2,7 @@ import express from "express";
|
|||||||
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
||||||
import { getNotification } from "./notificationController.js";
|
import { getNotification } from "./notificationController.js";
|
||||||
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
|
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
|
||||||
|
import { isAuthenticatedUser } from "../../middlewares/auth.js";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@ -21,4 +22,6 @@ router
|
|||||||
.route("/get-notification-tm/:id")
|
.route("/get-notification-tm/:id")
|
||||||
.get(isAuthenticatedTerritoryManager, getNotification);
|
.get(isAuthenticatedTerritoryManager, getNotification);
|
||||||
|
|
||||||
|
router.route("/get-notification-pd").get(isAuthenticatedUser, getNotification);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
194
resources/RD_Ordes/rdOrderController.js
Normal file
194
resources/RD_Ordes/rdOrderController.js
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
import RetailDistributor from "../RetailDistributor/RetailDistributorModel.js";
|
||||||
|
import { RdOrder } from "./rdOrderModal.js";
|
||||||
|
|
||||||
|
// Controller to create a new order by RD
|
||||||
|
export const createOrderRD = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
paymentMode,
|
||||||
|
shipTo,
|
||||||
|
billTo,
|
||||||
|
orderItems,
|
||||||
|
subtotal,
|
||||||
|
gstTotal,
|
||||||
|
grandTotal,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
const rdId = req.user._id;
|
||||||
|
// Fetch the Retail Distributor (RD) to find the associated Principal Distributor (PD)
|
||||||
|
const rd = await RetailDistributor.findById(rdId).populate(
|
||||||
|
"principal_distributer"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!rd) {
|
||||||
|
return res.status(404).json({ message: "Retail Distributor not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const pdId = rd.principal_distributer._id; // Get the associated PD
|
||||||
|
|
||||||
|
// Create the order
|
||||||
|
const newOrder = new RdOrder({
|
||||||
|
paymentMode,
|
||||||
|
shipTo,
|
||||||
|
billTo,
|
||||||
|
orderItem: orderItems.map((item) => ({
|
||||||
|
productId: item._id,
|
||||||
|
SKU: item.SKU,
|
||||||
|
name: item.name,
|
||||||
|
categoryName: item.category.categoryName, // Store category name
|
||||||
|
|
||||||
|
brandName: item.brand.brandName, // Store brand name
|
||||||
|
|
||||||
|
price: item.price,
|
||||||
|
GST: item.GST,
|
||||||
|
HSN_Code: item.HSN_Code,
|
||||||
|
description: item.description,
|
||||||
|
image: item.image,
|
||||||
|
quantity: item.count,
|
||||||
|
})),
|
||||||
|
subtotal,
|
||||||
|
gstTotal,
|
||||||
|
grandTotal,
|
||||||
|
addedBy: rdId, // The RD who placed the order (Retail Distributor)
|
||||||
|
pd: pdId, // Reference to the PD associated with the RD
|
||||||
|
});
|
||||||
|
|
||||||
|
await newOrder.save();
|
||||||
|
|
||||||
|
res
|
||||||
|
.status(201)
|
||||||
|
.json({ message: "Order placed successfully", order: newOrder });
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export const getPlacedOrdersForRD = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const rdId = req.user?._id; // Assuming the Retail Distributor's ID is obtained from the authenticated request
|
||||||
|
if (!rdId) {
|
||||||
|
return res.status(401).json({ message: "Unauthorized access" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract page and limit from query parameters, with default values
|
||||||
|
const page = parseInt(req.query.page, 10) || 1;
|
||||||
|
const limit = parseInt(req.query.limit, 10) || 5;
|
||||||
|
|
||||||
|
// Calculate how many documents to skip for pagination
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Fetch total count of orders for this RD (for pagination purposes)
|
||||||
|
const totalOrders = await RdOrder.countDocuments({ addedBy: rdId });
|
||||||
|
|
||||||
|
// Fetch orders for the logged-in RD
|
||||||
|
const placedOrders = await RdOrder.find({ addedBy: rdId })
|
||||||
|
.sort({ createdAt: -1 }) // Sort by creation date, newest first
|
||||||
|
.skip(skip) // Skip documents for pagination
|
||||||
|
.limit(limit); // Limit number of documents returned
|
||||||
|
|
||||||
|
if (!placedOrders || placedOrders.length === 0) {
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json({ message: "No orders found for this Retail Distributor" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the paginated order list and total count of orders
|
||||||
|
res.status(200).json({ placedOrders, totalOrders });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export const getSinglePlacedOrderForRD = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const rdId = req.user?._id;
|
||||||
|
if (!rdId) {
|
||||||
|
return res.status(401).json({ message: "Unauthorized access" });
|
||||||
|
} // Assuming the Retail Distributor's ID is obtained from the authenticated request
|
||||||
|
const orderId = req.params.id; // Assuming the order ID is passed in the URL as a parameter
|
||||||
|
|
||||||
|
if (!rdId) {
|
||||||
|
return res.status(401).json({ message: "Unauthorized access" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!orderId) {
|
||||||
|
return res.status(400).json({ message: "Order ID is required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the specific order for the logged-in RD
|
||||||
|
const order = await RdOrder.findOne({ _id: orderId, addedBy: rdId });
|
||||||
|
|
||||||
|
if (!order) {
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json({ message: "Order not found for this Retail Distributor" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the single order document
|
||||||
|
res.status(200).json({ singleOrder: order });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPlacedOrdersForPD = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const pdId = req.user?._id;
|
||||||
|
if (!pdId) {
|
||||||
|
return res.status(401).json({ return_message: "Unauthorized access " });
|
||||||
|
}
|
||||||
|
// Extract page and limit from query parameters
|
||||||
|
const page = parseInt(req.query.page, 10) || 1;
|
||||||
|
const limit = parseInt(req.query.limit, 10) || 5;
|
||||||
|
|
||||||
|
// Calculate the number of documents to skip
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
const totalOrders = await RdOrder.countDocuments({ pd: pdId });
|
||||||
|
|
||||||
|
// Fetch all orders where the PD is associated with the order
|
||||||
|
const plcaedOrders = await RdOrder.find({ pd: pdId })
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.skip(skip)
|
||||||
|
.limit(limit);
|
||||||
|
|
||||||
|
if (!plcaedOrders || plcaedOrders.length === 0) {
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json({ message: "No orders found for this Principal Distributor" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ plcaedOrders, totalOrders });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export const getSinglePlacedOrderForPD = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const pdId = req.user?._id; // Assuming the Principal Distributor's ID is obtained from the authenticated request
|
||||||
|
const orderId = req.params.id; // Assuming the order ID is passed in the URL as a parameter
|
||||||
|
|
||||||
|
if (!pdId) {
|
||||||
|
return res.status(401).json({ message: "Unauthorized access" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!orderId) {
|
||||||
|
return res.status(400).json({ message: "Order ID is required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the specific order for the logged-in PD
|
||||||
|
const order = await RdOrder.findOne({ _id: orderId, pd: pdId });
|
||||||
|
|
||||||
|
if (!order) {
|
||||||
|
return res
|
||||||
|
.status(404)
|
||||||
|
.json({ message: "Order not found for this Principal Distributor" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the single order document
|
||||||
|
res.status(200).json({ singleOrder: order });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ message: "Server error", error });
|
||||||
|
}
|
||||||
|
};
|
156
resources/RD_Ordes/rdOrderModal.js
Normal file
156
resources/RD_Ordes/rdOrderModal.js
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
import mongoose, { Schema } from "mongoose";
|
||||||
|
import { nanoid } from "nanoid"; // To generate unique 6-char IDs
|
||||||
|
|
||||||
|
const orderItemSchema = new Schema({
|
||||||
|
productId: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: "Product",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
SKU: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
categoryName: {
|
||||||
|
type: String, // Directly store category name
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
brandName: {
|
||||||
|
type: String, // Directly store brand name
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
GST: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
HSN_Code: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
image: [
|
||||||
|
{
|
||||||
|
public_id: String,
|
||||||
|
url: String,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
quantity: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const StatusHistorySchema = new mongoose.Schema({
|
||||||
|
status: {
|
||||||
|
type: String,
|
||||||
|
enum: ["new", "dispatched", "cancelled", "processing", "delivered"], // Ensure this matches your status enum
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const rdOrderSchema = new Schema(
|
||||||
|
{
|
||||||
|
paymentMode: {
|
||||||
|
type: String,
|
||||||
|
enum: ["cheque", "online-transfer", "credit"],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
shipTo: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
billTo: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
orderItem: [orderItemSchema],
|
||||||
|
subtotal: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
gstTotal: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
grandTotal: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: String,
|
||||||
|
enum: ["new", "dispatched", "cancelled", "processing", "delivered"],
|
||||||
|
default: "new",
|
||||||
|
},
|
||||||
|
statusUpdatedAt: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now,
|
||||||
|
},
|
||||||
|
uniqueId: {
|
||||||
|
type: String,
|
||||||
|
unique: true,
|
||||||
|
default: () => nanoid(6), // Generates a 6-character unique ID
|
||||||
|
},
|
||||||
|
addedBy: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: "RetailDistributor", // Reference to the RD placing the order
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
pd: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: "User", // Reference to the PD associated with the RD
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
status_timeline: {
|
||||||
|
new: { type: Date },
|
||||||
|
paid: { type: Date },
|
||||||
|
processing: { type: Date },
|
||||||
|
dispatched: { type: Date },
|
||||||
|
delivered: { type: Date },
|
||||||
|
cancelled: { type: Date },
|
||||||
|
returned: { type: Date },
|
||||||
|
},
|
||||||
|
iscancelled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
order_Cancelled_Reason: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
courier_name: { type: String },
|
||||||
|
courier_tracking_id: { type: String },
|
||||||
|
isDelivered: { type: Boolean, required: true, default: false },
|
||||||
|
DeliveredDate: { type: String, default: "" },
|
||||||
|
statusHistory: [StatusHistorySchema], // Add this field to store the status history
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Middleware to update the statusUpdatedAt field whenever status changes
|
||||||
|
rdOrderSchema.pre("save", function (next) {
|
||||||
|
if (this.isModified("status")) {
|
||||||
|
this.statusUpdatedAt = Date.now();
|
||||||
|
// Add the new status and timestamp to statusHistory
|
||||||
|
this.statusHistory.push({
|
||||||
|
status: this.status,
|
||||||
|
timestamp: this.statusUpdatedAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
export const RdOrder = mongoose.model("RdOrder", rdOrderSchema);
|
28
resources/RD_Ordes/rdOrderRoutes.js
Normal file
28
resources/RD_Ordes/rdOrderRoutes.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import express from "express";
|
||||||
|
import {
|
||||||
|
createOrderRD,
|
||||||
|
getPlacedOrdersForPD,
|
||||||
|
getPlacedOrdersForRD,
|
||||||
|
getSinglePlacedOrderForPD,
|
||||||
|
getSinglePlacedOrderForRD,
|
||||||
|
} from "./rdOrderController.js";
|
||||||
|
import { isAuthenticatedRD } from "../../middlewares/rdAuth.js";
|
||||||
|
import { isAuthenticatedUser } from "../../middlewares/auth.js";
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.route("/rd-place-order").post(isAuthenticatedRD, createOrderRD);
|
||||||
|
router.route("/rd-place-order").get(isAuthenticatedRD, getPlacedOrdersForRD);
|
||||||
|
router
|
||||||
|
.route("/rd-place-order/:id")
|
||||||
|
.get(isAuthenticatedRD, getSinglePlacedOrderForRD);
|
||||||
|
|
||||||
|
// routes for the PD
|
||||||
|
router
|
||||||
|
.route("/pd-get-all-place-order")
|
||||||
|
.get(isAuthenticatedUser, getPlacedOrdersForPD);
|
||||||
|
|
||||||
|
router
|
||||||
|
.route("/pd-get-all-place-order/:id")
|
||||||
|
.get(isAuthenticatedUser, getSinglePlacedOrderForPD);
|
||||||
|
|
||||||
|
export default router;
|
@ -78,10 +78,18 @@ const RetailDistributorSchema = new mongoose.Schema(
|
|||||||
RetailDistributorSchema.pre("save", function (next) {
|
RetailDistributorSchema.pre("save", function (next) {
|
||||||
// Only set defaults if the document is new (not yet saved)
|
// Only set defaults if the document is new (not yet saved)
|
||||||
if (this.isNew) {
|
if (this.isNew) {
|
||||||
if (!this.mappedSC && this.userType === "SalesCoOrdinator" && this.addedBy) {
|
if (
|
||||||
|
!this.mappedSC &&
|
||||||
|
this.userType === "SalesCoOrdinator" &&
|
||||||
|
this.addedBy
|
||||||
|
) {
|
||||||
this.mappedSC = this.addedBy;
|
this.mappedSC = this.addedBy;
|
||||||
}
|
}
|
||||||
if (!this.mappedTM && this.userType === "TerritoryManager" && this.addedBy) {
|
if (
|
||||||
|
!this.mappedTM &&
|
||||||
|
this.userType === "TerritoryManager" &&
|
||||||
|
this.addedBy
|
||||||
|
) {
|
||||||
this.mappedTM = this.addedBy;
|
this.mappedTM = this.addedBy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +114,7 @@ RetailDistributorSchema.pre("save", function (next) {
|
|||||||
|
|
||||||
// JWT TOKEN
|
// JWT TOKEN
|
||||||
RetailDistributorSchema.methods.getJWTToken = function () {
|
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
|
expiresIn: "1d", // Token will expire in 1 day
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1320,3 +1320,30 @@ export const updateEmployeeById = catchAsyncErrors(async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
export const saveFCMTokenForUser = async (req, res) => {
|
||||||
|
const { fcmToken } = req.body;
|
||||||
|
const userId = req.user._id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the current FCM token for the user
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(404).send("User not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the new FCM token is different from the current one
|
||||||
|
if (user.fcm_token && user.fcm_token === fcmToken) {
|
||||||
|
return res.status(200).send("FCM Token is already up to date");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the FCM token
|
||||||
|
user.fcm_token = fcmToken;
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
res.status(200).send("FCM Token saved successfully");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error saving FCM Token:", error);
|
||||||
|
res.status(500).send("Internal Server Error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -87,6 +87,10 @@ const userSchema = new mongoose.Schema(
|
|||||||
accessTo: {},
|
accessTo: {},
|
||||||
resetPasswordToken: String,
|
resetPasswordToken: String,
|
||||||
resetPasswordExpire: Date,
|
resetPasswordExpire: Date,
|
||||||
|
fcm_token: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
@ -123,7 +127,10 @@ userSchema.methods.comparePassword = async function (password) {
|
|||||||
// Generating Reset Token
|
// Generating Reset Token
|
||||||
userSchema.methods.getResetPasswordToken = function () {
|
userSchema.methods.getResetPasswordToken = function () {
|
||||||
const resetToken = crypto.randomBytes(20).toString("hex");
|
const resetToken = crypto.randomBytes(20).toString("hex");
|
||||||
this.resetPasswordToken = crypto.createHash("sha256").update(resetToken).digest("hex");
|
this.resetPasswordToken = crypto
|
||||||
|
.createHash("sha256")
|
||||||
|
.update(resetToken)
|
||||||
|
.digest("hex");
|
||||||
this.resetPasswordExpire = Date.now() + 15 * 60 * 1000; // 15 minutes
|
this.resetPasswordExpire = Date.now() + 15 * 60 * 1000; // 15 minutes
|
||||||
return resetToken;
|
return resetToken;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
unmappedSCinPrincipalDistributor,
|
unmappedSCinPrincipalDistributor,
|
||||||
mappedbySC,
|
mappedbySC,
|
||||||
getAllPrincipalDistributorbyscId,
|
getAllPrincipalDistributorbyscId,
|
||||||
|
saveFCMTokenForUser,
|
||||||
} from "./userController.js";
|
} from "./userController.js";
|
||||||
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ router
|
|||||||
authorizeRoles("admin"),
|
authorizeRoles("admin"),
|
||||||
uploadPrincipaldistributors
|
uploadPrincipaldistributors
|
||||||
);
|
);
|
||||||
//mapping start
|
//mapping start
|
||||||
router
|
router
|
||||||
.route("/admin/users")
|
.route("/admin/users")
|
||||||
.get(isAuthenticatedUser, authorizeRoles("admin", "Employee"), getAllUser);
|
.get(isAuthenticatedUser, authorizeRoles("admin", "Employee"), getAllUser);
|
||||||
@ -55,7 +56,7 @@ router
|
|||||||
authorizeRoles("admin"),
|
authorizeRoles("admin"),
|
||||||
getAllPrincipalDistributorbytmId
|
getAllPrincipalDistributorbytmId
|
||||||
);
|
);
|
||||||
router
|
router
|
||||||
.route("/getbySCId/:id")
|
.route("/getbySCId/:id")
|
||||||
.get(
|
.get(
|
||||||
isAuthenticatedUser,
|
isAuthenticatedUser,
|
||||||
@ -123,5 +124,6 @@ router
|
|||||||
router.route("/user/password/update").put(isAuthenticatedUser, updatePassword);
|
router.route("/user/password/update").put(isAuthenticatedUser, updatePassword);
|
||||||
|
|
||||||
router.route("/user/update/profile").put(isAuthenticatedUser, updateProfile);
|
router.route("/user/update/profile").put(isAuthenticatedUser, updateProfile);
|
||||||
|
router.route("/user/fcm-token").post(isAuthenticatedUser, saveFCMTokenForUser);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -4,7 +4,7 @@ import app from "./app.js";
|
|||||||
import connectDatabase from "./database/db.js";
|
import connectDatabase from "./database/db.js";
|
||||||
import cloudinary from "cloudinary";
|
import cloudinary from "cloudinary";
|
||||||
import cron from "node-cron";
|
import cron from "node-cron";
|
||||||
import {updateOverdueTasks} from "./resources/Task/TaskController.js ";
|
import { updateOverdueTasks } from "./resources/Task/TaskController.js ";
|
||||||
// Connecting to database
|
// Connecting to database
|
||||||
connectDatabase();
|
connectDatabase();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user