diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js
index 50c5860..64a5575 100644
--- a/resources/PD_Orders/pdOrderController.js
+++ b/resources/PD_Orders/pdOrderController.js
@@ -2,6 +2,7 @@
import mongoose from "mongoose";
import { PdOrder } from "./pdOrderModal.js";
+import sendEmail from "../../Utils/sendEmail.js";
export const createOrder = async (req, res) => {
try {
@@ -35,6 +36,17 @@ export const createOrder = async (req, res) => {
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,
@@ -88,14 +100,17 @@ export const getPlacedOrder = async (req, res) => {
export const getPlacedOrderById = async (req, res) => {
try {
const id = req.params.id;
+
if (!mongoose.Types.ObjectId.isValid(id)) {
return res
.status(404)
.json({ return_msg: "Not Valid id to search the doc " });
}
- const doc = await PdOrder.findById(id).populate({
- path: "orderItem.productId",
- });
+ const doc = await PdOrder.findById(id)
+ .populate({
+ path: "orderItem.productId",
+ })
+ .populate({ path: "addedBy" });
if (doc) {
return res
.status(200)
@@ -108,24 +123,571 @@ export const getPlacedOrderById = async (req, res) => {
}
};
-export const getPlacedOrderAdmin = async (req, res) => {
+export const getPlacedNewOrderAdmin = async (req, res) => {
try {
- const plcaedOrders = await PdOrder.find()
- .sort({
- createdAt: -1,
- })
- .populate({
- path: "orderItem.productId",
- })
- .populate({
- path: "addedBy",
- });
- if (plcaedOrders) {
- return res.status(200).json({ plcaedOrders });
+ // 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;
+
+ // Get the total count of new orders
+ const totalOrders = await PdOrder.countDocuments({ status: "new" });
+
+ // Fetch paginated new orders
+ const placedOrders = await PdOrder.find({ status: "new" })
+ .sort({ createdAt: -1 })
+ .skip(skip)
+ .limit(limit)
+ .populate({ path: "orderItem.productId" })
+ .populate({ path: "addedBy" });
+
+ if (placedOrders.length > 0) {
+ return res.status(200).json({ placedOrders, totalOrders });
}
- return res.status(404).json({ return_msg: "Not placed yet " });
+ return res.status(404).json({ return_msg: "No new orders placed yet" });
} catch (error) {
- console.error("Error creating order:", error);
+ console.error("Error fetching new orders:", error);
return res.status(500).json({ error: "Internal Server Error" });
}
};
+
+export const getDispatchedOrdersAdmin = async (req, res) => {
+ try {
+ // 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;
+
+ // Get the total count of dispatched orders
+ const totalOrders = await PdOrder.countDocuments({ status: "dispatched" });
+
+ // Fetch paginated dispatched orders
+ const dispatchedOrders = await PdOrder.find({ status: "dispatched" })
+ .sort({ createdAt: -1 })
+ .skip(skip)
+ .limit(limit)
+ .populate({ path: "orderItem.productId" })
+ .populate({ path: "addedBy" });
+
+ if (dispatchedOrders.length > 0) {
+ return res.status(200).json({ dispatchedOrders, totalOrders });
+ }
+ return res.status(404).json({ return_msg: "No dispatched orders yet" });
+ } catch (error) {
+ console.error("Error fetching dispatched orders:", error);
+ return res.status(500).json({ error: "Internal Server Error" });
+ }
+};
+
+export const getCancelledOrdersAdmin = async (req, res) => {
+ try {
+ // 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;
+
+ // Get the total count of cancelled orders
+ const totalOrders = await PdOrder.countDocuments({ status: "cancelled" });
+
+ // Fetch paginated cancelled orders
+ const cancelledOrders = await PdOrder.find({ status: "cancelled" })
+ .sort({ createdAt: -1 })
+ .skip(skip)
+ .limit(limit)
+ .populate({ path: "orderItem.productId" })
+ .populate({ path: "addedBy" });
+
+ if (cancelledOrders.length > 0) {
+ return res.status(200).json({ cancelledOrders, totalOrders });
+ }
+ return res.status(404).json({ return_msg: "No cancelled orders yet" });
+ } catch (error) {
+ console.error("Error fetching cancelled orders:", error);
+ return res.status(500).json({ error: "Internal Server Error" });
+ }
+};
+
+export const getProcessingOrdersAdmin = async (req, res) => {
+ try {
+ // 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;
+
+ // Get the total count of processing orders
+ const totalOrders = await PdOrder.countDocuments({ status: "processing" });
+
+ // Fetch paginated processing orders
+ const processingOrders = await PdOrder.find({ status: "processing" })
+ .sort({ createdAt: -1 })
+ .skip(skip)
+ .limit(limit)
+ .populate({ path: "orderItem.productId" })
+ .populate({ path: "addedBy" });
+
+ if (processingOrders.length > 0) {
+ return res.status(200).json({ processingOrders, totalOrders });
+ }
+ return res.status(404).json({ return_msg: "No processing orders yet" });
+ } catch (error) {
+ console.error("Error fetching processing orders:", error);
+ return res.status(500).json({ error: "Internal Server Error" });
+ }
+};
+
+export const getDeliveredOrdersAdmin = async (req, res) => {
+ try {
+ // 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;
+
+ // Get the total count of delivered orders
+ const totalOrders = await PdOrder.countDocuments({ status: "delivered" });
+
+ // Fetch paginated delivered orders
+ const deliveredOrders = await PdOrder.find({ status: "delivered" })
+ .sort({ createdAt: -1 })
+ .skip(skip)
+ .limit(limit)
+ .populate({ path: "orderItem.productId" })
+ .populate({ path: "addedBy" });
+
+ if (deliveredOrders.length > 0) {
+ return res.status(200).json({ deliveredOrders, totalOrders });
+ }
+ return res.status(404).json({ return_msg: "No delivered orders yet" });
+ } catch (error) {
+ console.error("Error fetching delivered orders:", error);
+ return res.status(500).json({ error: "Internal Server Error" });
+ }
+};
+
+export const updateOrderStatusById = async (req, res) => {
+ try {
+ let body = { status: req.body.status };
+
+ const currentDate = new Date();
+ body["status_timeline." + req.body.status] = currentDate;
+
+ const order = await PdOrder.findById(req.params.id).populate({
+ path: "addedBy",
+ select: "name email _id",
+ });
+
+ if (req.body.status === "cancelled") {
+ console.log("req came here ");
+ body["order_Cancelled_Reason"] = req.body?.ReasonforCancellation;
+ body["iscancelled"] = true;
+
+ const updatedCan = await PdOrder.findByIdAndUpdate(order._id, body);
+
+ await sendEmail({
+ to: `${order?.addedBy?.email}`, // Change to your recipient
+ from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender
+ subject: `Order #${order?.uniqueId} Update: Cancellation and Refund Process`,
+ html: `
+ Hi ${
+ order?.addedBy.name
+ },
+
We hope this message finds you well. We're writing to inform you that your order ${
+ order?.uniqueId
+ } has been canceled. We understand that circumstances may change, and we're here to assist you throughout the process.
+
+ Cancellation Reason: ${
+ order?.order_Cancelled_Reason || "No specific reason provided."
+ }
+
+ Items:
+
+
+
+ S No. |
+ Product Name |
+ Category |
+ Brand |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${order?.orderItem
+ ?.map(
+ (product, index) => `
+
+ ${
+ index + 1
+ } |
+ ${
+ product.name
+ } |
+ ${
+ product.categoryName
+ } |
+ ${
+ product.brandName
+ } |
+  |
+ ${
+ product.quantity
+ } |
+ ₹${
+ product.price
+ } |
+ ₹${
+ (product.GST * product.price) / 100
+ } |
+ ₹${
+ (product.price + (product.GST * product.price) / 100) *
+ product.quantity
+ } |
+
+ `
+ )
+ .join("")}
+
+ Total Amount : |
+ ₹${
+ order?.grandTotal
+ } |
+
+
+
+
+ Refund Information: The amount from your canceled order will be processed for a refund. Please allow up to 7 working days for the amount to be transferred back to your original payment method.
+
+ If you have any concerns or further questions, please feel free to reply to this email. We appreciate your understanding and hope to serve you better in the future.
+
+ Best regards,
+ Team Cheminova
+ `,
+ });
+
+ return res.status(200).json({
+ status: "ok",
+ message: "Order status updated successfully!",
+ updatedCan,
+ });
+ } else if (req.body.status === "processing") {
+ const updatedPro = await PdOrder.findByIdAndUpdate(order._id, body);
+ await sendEmail({
+ to: `${order?.addedBy?.email}`, // Recipient's email address from order model
+ from: `${process.env.SEND_EMAIL_FROM}`, // Sender's email address
+ subject: `Your Order #${order?.uniqueId} is in Processing!`,
+ html: `
+
+
Exciting news! Your order #${
+ order?.uniqueId
+ } has entered the processing phase. Our team is diligently preparing your items for dispatch. Rest assured, we're working hard to ensure everything is perfect for you.
+
Hi ${
+ order?.addedBy.name
+ },
+
Order Status: ${
+ order?.status.charAt(0).toUpperCase() + order?.status.slice(1)
+ }
+
+
+
+
Order Items:
+
+
+
+ S No. |
+ Product Name |
+ Variant |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${order?.orderItem
+ ?.map(
+ (product, index) => `
+
+ ${
+ index + 1
+ } |
+ ${
+ product.name
+ } |
+ ${
+ product.variant_Name || "N/A"
+ } |
+
+
+ |
+ ${
+ product.quantity
+ } |
+ ₹${
+ product.price
+ } |
+ ₹${
+ (product.GST * product.price) / 100
+ } |
+ ₹${
+ (product.price + (product.GST * product.price) / 100) *
+ product.quantity
+ } |
+
+ `
+ )
+ .join("")}
+
+ Total Amount: |
+ ₹${
+ order?.grandTotal
+ } |
+
+
+
+
+
We'll send you another email with the tracking details as soon as your order is dispatched. If you have any questions or need assistance, feel free to reply to this email.
+
Thank you for choosing Cheminova!
+
+
Best regards,
+
Team Cheminova
+
+ `,
+ });
+ return res
+ .status(200)
+ .json({
+ status: "ok",
+ message: "Order status updated successfully!",
+ updatedPro,
+ });
+ } else if (req.body.status === "dispatched") {
+ body["courier_name"] = req.body.courierName;
+ body["courier_tracking_id"] = req.body.TrackingID;
+ const disRes = await PdOrder.findByIdAndUpdate(order._id, body);
+ await sendEmail({
+ to: `${order?.addedBy?.email}`, // Assuming 'addedBy' references the user who placed the order
+ from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender
+ subject: `Your Order #${order?.uniqueId} is On Its Way!`,
+ html: `
+ Hi,
+ Exciting news! Your order #${
+ order?.uniqueId
+ } has been dispatched and is en route to you. 🚚 Here are the details:
+
+ Courier Name: ${
+ order?.courier_name || "N/A"
+ }
+ Courier Tracking ID: ${
+ order?.courier_tracking_id || "N/A"
+ }
+
+
+
+ Items:
+
+
+
+ S No. |
+ Product Name |
+ SKU |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${order?.orderItem
+ ?.map(
+ (product, index) => `
+
+ ${
+ index + 1
+ } |
+ ${
+ product.name
+ } |
+ ${
+ product.SKU
+ } |
+
+
+ |
+ ${
+ product.quantity
+ } |
+ ₹${
+ product.price
+ } |
+ ₹${
+ (product.GST * product.price) / 100
+ } |
+ ₹${
+ (product.price + (product.GST * product.price) / 100) *
+ product.quantity
+ } |
+
+ `
+ )
+ .join("")}
+
+ Total Amount: |
+ ₹${
+ order?.grandTotal
+ } |
+
+
+
+
+ Order Status: Dispatched
+ If you have any questions or need assistance, feel free to reply to this email.
+ Thanks for choosing Cheminova! We hope you enjoy your purchase.
+
+ Best regards,
+ Team Cheminova
+ `,
+ });
+ return res.status(200).json({
+ status: "ok",
+ message: "Order status updated successfully!",
+ disRes,
+ });
+ } else if (req.body.status === "delivered") {
+ body["isDelivered"] = true;
+ body["DeliveredDate"] = req.body.DDate;
+ const updatedDeli = await PdOrder.findByIdAndUpdate(order._id, body);
+ await sendEmail({
+ to: `${order?.addedBy?.email}`, // Using 'addedBy' to reference the user's email
+ from: `${process.env.SEND_EMAIL_FROM}`, // Your verified sender
+ subject: `Your Order #${order?.uniqueId} Has Been Delivered!`,
+ html: `
+ Hi,
+
+ Great news! Your order #${
+ order?.uniqueId
+ } has been successfully delivered to your doorstep. We hope everything is just as you expected!
+
+
+
+
+ Items:
+
+
+
+ S No. |
+ Product Name |
+ SKU |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${order?.orderItem
+ ?.map(
+ (product, index) => `
+
+ ${
+ index + 1
+ } |
+ ${
+ product.name
+ } |
+ ${
+ product.SKU
+ } |
+
+
+ |
+ ${
+ product.quantity
+ } |
+ ₹${
+ product.price
+ } |
+ ₹${
+ (product.GST * product.price) / 100
+ } |
+ ₹${
+ (product.price + (product.GST * product.price) / 100) *
+ product.quantity
+ } |
+
+ `
+ )
+ .join("")}
+
+ Total Amount: |
+ ₹${
+ order?.grandTotal
+ } |
+
+
+
+
+ Delivery Date: ${
+ req.body.DDate
+ }
+
+
+ Your satisfaction is our priority, and we'd love to hear about your experience. Please take a moment to share your thoughts by leaving a review. Your feedback is invaluable to us!
+
+
+
+ If you have any questions or concerns about your order, feel free to reply to this email.
+
+
+
+ Thank you for choosing Cheminova! We hope to serve you again soon.
+
+
+
+ Best regards,
+ Team Cheminova
+ `,
+ });
+ return res.status(200).json({
+ status: "ok",
+ message: "Order status updated successfully!",
+ updatedDeli,
+ });
+ } else {
+ // await Order.findByIdAndUpdate(order._id, body);
+ // console.log(order);
+ res
+ .status(200)
+ .json({ status: "ok", message: "Order status updated successfully!" });
+ }
+ } catch (error) {
+ console.log(error);
+ res
+ .status(500)
+ .json({ message: error?.message || "Something went wrong!" });
+ }
+};
diff --git a/resources/PD_Orders/pdOrderModal.js b/resources/PD_Orders/pdOrderModal.js
index c4ac396..62212aa 100644
--- a/resources/PD_Orders/pdOrderModal.js
+++ b/resources/PD_Orders/pdOrderModal.js
@@ -1,23 +1,60 @@
import mongoose, { Schema } from "mongoose";
import { nanoid } from "nanoid"; // To generate unique 6-char IDs
-const OrderItemSchema = new mongoose.Schema({
+const orderItemSchema = new Schema({
productId: {
- type: mongoose.Schema.Types.ObjectId,
+ 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,
- min: 1,
+ default: 1,
},
});
const StatusHistorySchema = new mongoose.Schema({
status: {
type: String,
- enum: ["new", "dispatched", "paid", "process"], // Ensure this matches your status enum
+ enum: ["new", "dispatched", "cancelled", "processing", "delivered"], // Ensure this matches your status enum
required: true,
},
timestamp: {
@@ -41,7 +78,7 @@ const pdOrderSchema = new Schema(
type: String,
required: true,
},
- orderItem: [OrderItemSchema],
+ orderItem: [orderItemSchema],
subtotal: {
type: Number,
required: true,
@@ -56,7 +93,7 @@ const pdOrderSchema = new Schema(
},
status: {
type: String,
- enum: ["new", "dispatched", "paid", "processing"],
+ enum: ["new", "dispatched", "cancelled", "processing", "delivered"],
default: "new",
},
statusUpdatedAt: {
diff --git a/resources/PD_Orders/pdOrderRoute.js b/resources/PD_Orders/pdOrderRoute.js
index da19842..a10710c 100644
--- a/resources/PD_Orders/pdOrderRoute.js
+++ b/resources/PD_Orders/pdOrderRoute.js
@@ -2,9 +2,14 @@ import express from "express";
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
import {
createOrder,
+ getCancelledOrdersAdmin,
+ getDeliveredOrdersAdmin,
+ getDispatchedOrdersAdmin,
+ getPlacedNewOrderAdmin,
getPlacedOrder,
- getPlacedOrderAdmin,
getPlacedOrderById,
+ getProcessingOrdersAdmin,
+ updateOrderStatusById,
} from "./pdOrderController.js";
const router = express.Router();
@@ -23,9 +28,26 @@ router
authorizeRoles("principal-Distributor"),
getPlacedOrder
);
-router.route("/get-single-placed-order-pd/:id").get(getPlacedOrderById);
router
- .route("/get-placed-order-admin")
- .get(isAuthenticatedUser, authorizeRoles("admin"), getPlacedOrderAdmin);
+ .route("/get-single-placed-order-pd/:id")
+ .get(isAuthenticatedUser, getPlacedOrderById);
+router
+ .route("/get-new-order-admin")
+ .get(isAuthenticatedUser, authorizeRoles("admin"), getPlacedNewOrderAdmin);
+router
+ .route("/get-dispatched-order-admin")
+ .get(isAuthenticatedUser, authorizeRoles("admin"), getDispatchedOrdersAdmin);
+router
+ .route("/get-cancelled-order-admin")
+ .get(isAuthenticatedUser, authorizeRoles("admin"), getCancelledOrdersAdmin);
+router
+ .route("/get-processing-order-admin")
+ .get(isAuthenticatedUser, authorizeRoles("admin"), getProcessingOrdersAdmin);
+router
+ .route("/get-delivered-order-admin")
+ .get(isAuthenticatedUser, authorizeRoles("admin"), getDeliveredOrdersAdmin);
+router
+ .route("/change/status/:id")
+ .patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
export default router;
diff --git a/resources/user/userController.js b/resources/user/userController.js
index 1c700d2..3bffbb6 100644
--- a/resources/user/userController.js
+++ b/resources/user/userController.js
@@ -1029,8 +1029,10 @@ 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" });
+ if (!tmId) {
+ return res
+ .status(400)
+ .json({ message: "Please provide Territory Manager ID" });
}
// Create a filter object
const filter = { role: "principal-Distributor" };