// Adjust the path to where your PdOrder model is located import mongoose from "mongoose"; import { PdOrder } from "./pdOrderModal.js"; import sendEmail from "../../Utils/sendEmail.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, 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, }); // 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", }) .populate({ path: "addedBy" }); 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 getPlacedNewOrderAdmin = 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 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: "No new orders placed yet" }); } catch (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:

${order?.orderItem ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name Category Brand Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${ product.categoryName } ${ product.brandName } ${
                    product.name
                  } ${ product.quantity } ₹${ product.price } ₹${ (product.GST * product.price) / 100 } ₹${ (product.price + (product.GST * product.price) / 100) * product.quantity }
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:

${order?.orderItem ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${
                    product.name
                  } ${ product.quantity } ₹${ product.price } ₹${ (product.GST * product.price) / 100 } ₹${ (product.price + (product.GST * product.price) / 100) * product.quantity }
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:

${order?.orderItem ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name SKU Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${ product.SKU } ${
                    product.name
                  } ${ product.quantity } ₹${ product.price } ₹${ (product.GST * product.price) / 100 } ₹${ (product.price + (product.GST * product.price) / 100) * product.quantity }
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 formattedDate = formatDate(req.body.DDate); console.log(formattedDate); 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:

${order?.orderItem ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name SKU Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${ product.SKU } ${
                    product.name
                  } ${ product.quantity } ₹${ product.price } ₹${ (product.GST * product.price) / 100 } ₹${ (product.price + (product.GST * product.price) / 100) * product.quantity }
Total Amount: ₹${ order?.grandTotal }

Delivery Date: ${formattedDate}

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!" }); } }; const formatDate = (date) => { const options = { weekday: "short", year: "numeric", month: "short", day: "2-digit", // hour: "2-digit", // minute: "2-digit", // hour12: true, }; return new Intl.DateTimeFormat("en-US", options).format(new Date(date)); }; export const getOrderCounts = async (req, res) => { try { const statusCounts = await PdOrder.aggregate([ { $group: { _id: "$status", // Group by status count: { $sum: 1 }, // Count the number of orders per status }, }, ]); // Restructure the result to make it easier to consume const result = { new: 0, dispatched: 0, cancelled: 0, processing: 0, delivered: 0, }; statusCounts.forEach((status) => { result[status._id] = status.count; }); res.status(200).json({ counts: result }); } catch (error) { console.log(error.message); res .status(500) .json({ message: error?.message || "Something went wrong!" }); } };