From 8095a73c1a37437d0c0fb45c07d08f4365f170c9 Mon Sep 17 00:00:00 2001 From: ROSHAN GARG Date: Fri, 23 Aug 2024 10:21:22 +0530 Subject: [PATCH] pd order done --- app.js | 8 +- package-lock.json | 18 ++++ package.json | 1 + resources/PD_Orders/pdOrderController.js | 131 +++++++++++++++++++++++ resources/PD_Orders/pdOrderModal.js | 114 ++++++++++++++++++++ resources/PD_Orders/pdOrderRoute.js | 31 ++++++ 6 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 resources/PD_Orders/pdOrderController.js create mode 100644 resources/PD_Orders/pdOrderModal.js create mode 100644 resources/PD_Orders/pdOrderRoute.js diff --git a/app.js b/app.js index b5caf77..1c7acff 100644 --- a/app.js +++ b/app.js @@ -189,6 +189,11 @@ import notification from "./resources/Notification/notificationRoute.js" //Inventory import InventoryRoute from "./resources/Inventory/InventoryRoute.js"; + +// PD Order place + +import PdOrderRoute from './resources/PD_Orders/pdOrderRoute.js' + app.use("/api/v1", user); //Product @@ -255,7 +260,8 @@ app.use("/api/v1", leave); // notification route app.use("/api",notification) - +// order routes +app.use("/api",PdOrderRoute) //Inventory app.use("/api/inventory", InventoryRoute); diff --git a/package-lock.json b/package-lock.json index a367381..d23d40a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "mongoose": "^6.3.5", "multer": "^1.4.5-lts.1", "multer-storage-cloudinary": "^4.0.0", + "nanoid": "^5.0.7", "nodemailer": "^6.9.4", "nodemon": "^3.0.1", "pm2": "^5.3.1", @@ -4757,6 +4758,23 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "license": "ISC" }, + "node_modules/nanoid": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, "node_modules/needle": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", diff --git a/package.json b/package.json index 8f87890..3fd5a51 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "mongoose": "^6.3.5", "multer": "^1.4.5-lts.1", "multer-storage-cloudinary": "^4.0.0", + "nanoid": "^5.0.7", "nodemailer": "^6.9.4", "nodemon": "^3.0.1", "pm2": "^5.3.1", diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js new file mode 100644 index 0000000..50c5860 --- /dev/null +++ b/resources/PD_Orders/pdOrderController.js @@ -0,0 +1,131 @@ +// Adjust the path to where your PdOrder model is located + +import mongoose from "mongoose"; +import { PdOrder } from "./pdOrderModal.js"; + +export const createOrder = async (req, res) => { + try { + const { + paymentMode, + shipTo, + billTo, + orderItems, + subtotal, + gstTotal, + grandTotal, + } = req.body; + + if ( + !paymentMode || + !shipTo || + !billTo || + !orderItems || + !subtotal || + !gstTotal || + !grandTotal + ) { + return res.status(400).json({ error: "All fields are required." }); + } + + // Create the order + const addedBy = req.user._id; + const newOrder = new PdOrder({ + paymentMode, + shipTo, + billTo, + orderItem: orderItems.map((item) => ({ + productId: item._id, + quantity: item.count, + })), + subtotal, + gstTotal, + grandTotal, + addedBy, + }); + + // Save the order to the database + const savedOrder = await newOrder.save(); + + // Return the created order as a response + return res.status(201).json({ placedOrder: savedOrder }); + } catch (error) { + console.error("Error creating order:", error); + return res.status(500).json({ error: "Internal Server Error" }); + } +}; + +export const getPlacedOrder = 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 orders + const totalOrders = await PdOrder.countDocuments({ addedBy: req.user._id }); + + // Fetch paginated orders + const plcaedOrders = await PdOrder.find({ addedBy: req.user._id }) + .sort({ createdAt: -1 }) + .skip(skip) + .limit(limit) + .populate({ path: "orderItem.productId" }); + + if (plcaedOrders.length > 0) { + return res.status(200).json({ plcaedOrders, totalOrders }); + } + return res.status(404).json({ return_msg: "Not placed yet" }); + } catch (error) { + console.error("Error fetching orders:", error); + return res.status(500).json({ error: "Internal Server Error" }); + } +}; + +// Get single placed order api + +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", + }); + if (doc) { + return res + .status(200) + .json({ singleOrder: doc, return_msg: "Doc found" }); + } + return res.status(404).json({ return_msg: "Not Found doc " }); + } catch (error) { + console.log(error); + return res.status(500).json({ return_msg: "Internal Server Error" }); + } +}; + +export const getPlacedOrderAdmin = 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 }); + } + return res.status(404).json({ return_msg: "Not placed yet " }); + } catch (error) { + console.error("Error creating order:", error); + return res.status(500).json({ error: "Internal Server Error" }); + } +}; diff --git a/resources/PD_Orders/pdOrderModal.js b/resources/PD_Orders/pdOrderModal.js new file mode 100644 index 0000000..c4ac396 --- /dev/null +++ b/resources/PD_Orders/pdOrderModal.js @@ -0,0 +1,114 @@ +import mongoose, { Schema } from "mongoose"; +import { nanoid } from "nanoid"; // To generate unique 6-char IDs + +const OrderItemSchema = new mongoose.Schema({ + productId: { + type: mongoose.Schema.Types.ObjectId, + ref: "Product", + required: true, + }, + quantity: { + type: Number, + required: true, + min: 1, + }, +}); + +const StatusHistorySchema = new mongoose.Schema({ + status: { + type: String, + enum: ["new", "dispatched", "paid", "process"], // Ensure this matches your status enum + required: true, + }, + timestamp: { + type: Date, + default: Date.now, + }, +}); + +const pdOrderSchema = 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", "paid", "processing"], + 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: "User", + 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 +pdOrderSchema.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 PdOrder = mongoose.model("PdOrder", pdOrderSchema); diff --git a/resources/PD_Orders/pdOrderRoute.js b/resources/PD_Orders/pdOrderRoute.js new file mode 100644 index 0000000..da19842 --- /dev/null +++ b/resources/PD_Orders/pdOrderRoute.js @@ -0,0 +1,31 @@ +import express from "express"; +import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; +import { + createOrder, + getPlacedOrder, + getPlacedOrderAdmin, + getPlacedOrderById, +} from "./pdOrderController.js"; + +const router = express.Router(); + +router + .route("/order-place") + .post( + isAuthenticatedUser, + authorizeRoles("principal-Distributor"), + createOrder + ); +router + .route("/get-placed-order-pd") + .get( + isAuthenticatedUser, + 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); + +export default router;