import mongoose from "mongoose"; import { PdOrder } from "./pdOrderModal.js"; import sendEmail from "../../Utils/sendEmail.js"; import { Invoice } from "./invoiceModel.js"; // Controller for placing an order export const createOrder = async (req, res) => { try { // Destructure the request body const { paymentMode, shipTo, billTo, orderItems, subtotal, gstTotal, grandTotal, } = req.body; // Check for required fields if ( !paymentMode || !shipTo || !billTo || !orderItems || !subtotal || !gstTotal || !grandTotal ) { return res.status(400).json({ error: "Missing required fields" }); } const addedBy = req.user._id; // Create a new PdOrder instance 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, remainingQuantity: item.count, })), subtotal, gstTotal, grandTotal, addedBy, }); // Save the new order const savedOrder = await newOrder.save(); // console.log(savedOrder); return res.status(201).json({ message: "Order placed successfully", placedOrder: savedOrder, }); } catch (error) { console.error(error); return res.status(500).json({ error: "Internal server error" }); } }; // Controller for processing an order and generating invoice export const processOrder = async (req, res) => { try { const { orderId, invoiceItems } = req.body; if (!orderId || !invoiceItems || !Array.isArray(invoiceItems)) { return res .status(400) .json({ error: "Missing required fields or invalid data" }); } // Find the order by ID const order = await PdOrder.findById(orderId).populate("addedBy"); if (!order) { return res.status(404).json({ error: "Order not found" }); } // Validate quantities const exceededItems = []; // Check each item in invoiceItems for quantity limits for (const item of invoiceItems) { const orderItem = order.orderItem.find( (i) => i.productId.toString() === item.productId.toString() ); // If processquantity exceeds remainingQuantity, add the item name to exceededItems if (orderItem && item.processquantity > orderItem.remainingQuantity) { exceededItems.push(item.name); } } // If there are any exceeded items, return an error with their names if (exceededItems.length > 0) { return res.status(400).json({ error: `The following items have more quantity than remaining in the order: ${exceededItems.join( ", " )}`, }); } // Continue with the rest of the logic if no quantity limits are exceeded // Generate unique invoice number const existingInvoices = await Invoice.find({ orderId }); const invoiceNumber = existingInvoices.length + 1; const invoiceId = `ch/${order.uniqueId}/${invoiceItems.length}/${invoiceNumber}`; // Calculate subtotal, gstTotal, and invoiceAmount for processed items let subtotal = 0; let gstTotal = 0; let invoiceAmount = 0; invoiceItems.forEach((item) => { const itemSubtotal = item.price * item.processquantity; const itemGST = ((item.price * item.GST) / 100) * item.processquantity; subtotal += itemSubtotal; gstTotal += itemGST; invoiceAmount += itemSubtotal + itemGST; }); // Create a new invoice const newInvoice = new Invoice({ invoiceId, orderId, items: invoiceItems, subtotal, gstTotal, invoiceAmount, }); // Save the invoice const savedInvoice = await newInvoice.save(); // Update the order's order items with the remaining quantity let allItemsProcessed = true; // Flag to check if all items are processed order.orderItem.forEach((item) => { const invoicedItem = invoiceItems.find( (i) => i.productId.toString() === item.productId.toString() ); // If the item was invoiced, update the remaining quantity if (invoicedItem) { // Deduct the processed quantity from remaining quantity item.remainingQuantity -= invoicedItem.processquantity; // Ensure remaining quantity does not go negative if (item.remainingQuantity < 0) { item.remainingQuantity = 0; } } // Check if the remaining quantity is greater than 0, even for items not invoiced if (item.remainingQuantity > 0) { allItemsProcessed = false; } }); // Calculate total amount for pending items let pendingTotalAmount = 0; order.orderItem.forEach((item) => { if (item.remainingQuantity > 0) { const itemPendingSubtotal = item.price * item.remainingQuantity; const itemPendingGST = ((item.price * item.GST) / 100) * item.remainingQuantity; pendingTotalAmount += itemPendingSubtotal + itemPendingGST; } }); // Only update order status if all items have been fully processed if (allItemsProcessed) { order.status = "processing"; // All items are fully processed } else { order.status = "pending"; // There are still remaining quantities } // Add the invoice to the order order.invoices.push(savedInvoice._id); // Save the updated order await order.save(); // Prepare the email content const processedItems = invoiceItems .map( (item, index) => ` ${ index + 1 } ${ item.name } ${ item.image && item.image.length > 0 ? `${item.name}` : "No Image" } ${ item.processquantity } ₹${ item.price } ₹${ (item.GST * item.price) / 100 } ₹${ (item.price + (item.GST * item.price) / 100) * item.processquantity } ` ) .join(""); const pendingItems = order.orderItem .filter((item) => item.remainingQuantity > 0) .map( (item, index) => ` ${ index + 1 } ${ item.name } ${ item.image && item.image.length > 0 ? `${item.name}` : "No Image" } ${ item.remainingQuantity } ₹${ item.price } ₹${ (item.GST * item.price) / 100 } ₹${ (item.price + (item.GST * item.price) / 100) * item.remainingQuantity } ` ) .join(""); // Dynamic email subject and message based on the order status const emailSubject = allItemsProcessed ? `Your Order #${order.uniqueId} is in Processing!` : `Your Order #${order.uniqueId} is Partially Processed!`; const emailMessage = allItemsProcessed ? `

Exciting news! Your order #${order.uniqueId} has entered the processing phase. We're working hard to ensure everything is perfect for you.

Your invoice ID is: ${savedInvoice.invoiceId}

` : `

Good news! Some items of your order #${order.uniqueId} have been processed. The remaining items will be processed soon.

Your invoice ID is: ${savedInvoice.invoiceId}

`; await sendEmail({ to: order.addedBy.email, from: process.env.SEND_EMAIL_FROM, subject: emailSubject, html: `
${emailMessage} Hi ${ order.addedBy.name },

Order Status: ${ order.status.charAt(0).toUpperCase() + order.status.slice(1) }

Processed Items:

${processedItems}
S No. Product Name Image Quantity Price GST Amount SubTotal
Total Amount: ₹${savedInvoice.invoiceAmount.toFixed( 2 )}
${ pendingItems.length > 0 ? `

Pending Items:

${pendingItems}
S No. Product Name Image Quantity Price GST Amount SubTotal
Pending Amount: ₹${pendingTotalAmount.toFixed( 2 )}
` : "" }
If you have any concerns or further questions, please feel free to reply to this email.

Best regards,
Team Cheminova
`, }); res.status(200).json({ message: "Order processed and invoice created successfully", invoiceId: savedInvoice.invoiceId, }); } catch (error) { console.error("Error processing order:", error); res .status(500) .json({ error: "An error occurred while processing the order" }); } }; export const cancelOrderController = async (req, res) => { // const { cancellationReason, id: _id } = req.bodyconst const cancellationReason = req.body.cancellationReason; const _id = req.params.id; try { // Find the order by ID const order = await PdOrder.findById(_id) .populate("invoices") .populate("addedBy"); if (!order) { return res.status(404).json({ message: "Order not found" }); } // Update the order status to 'cancelled' order.status = "cancelled"; order.iscancelled = true; order.order_Cancelled_Reason = cancellationReason || "No specific reason provided."; await order.save(); if (order.invoices.length === 0) { // If no invoices are associated with the order 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} Cancellation Confirmation`, html: ` Hi ${order.addedBy.name},

We regret to inform you that your order #${order.uniqueId} has been fully cancelled.

Cancellation Reason: ${order.order_Cancelled_Reason}

If you have any concerns or further questions, please feel free to reply to this email.

Best regards,
Team Cheminova `, }); } else { // If invoices are present const invoices = await Invoice.find({ _id: { $in: order.invoices } }); // Collect all invoice data const invoiceDetails = invoices.map((invoice) => { let subtotal = 0; let gstTotal = 0; let totalAmount = 0; const processedItems = invoice.items .map((item) => { const itemSubtotal = item.price * item.processquantity; const itemGST = ((item.price * item.GST) / 100) * item.processquantity; subtotal += itemSubtotal; gstTotal += itemGST; totalAmount += itemSubtotal + itemGST; const itemImage = item.image && Array.isArray(item.image) ? item.image[0]?.url : ""; return ` ${ item.SKU } ${ item.name } ${
              item.name
            } ${ item.processquantity } ₹${ item.price } ₹${ (item.price * item.GST) / 100 } ₹${ itemSubtotal + itemGST } `; }) .join(""); return { invoiceId: invoice.invoiceId, processedItems, totalAmount, }; }); // Collect all delivered and remaining items let cancelItems = ""; let totalCancelAmount = 0; if (Array.isArray(order.orderItem)) { order.orderItem.forEach((item) => { if (item.remainingQuantity > 0) { const itemSubtotal = item.price * item.remainingQuantity; const itemGST = ((item.price * item.GST) / 100) * item.remainingQuantity; totalCancelAmount += itemSubtotal + itemGST; const itemImage = item.image && Array.isArray(item.image) ? item.image[0]?.url : ""; cancelItems += ` ${ item.SKU } ${ item.name } ${
              item.name
            } ${ item.remainingQuantity } ₹${ item.price } ₹${ (item.price * item.GST) / 100 } ₹${ itemSubtotal + itemGST } `; } }); } 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} is Partially Cancelled!`, html: ` Hi ${ order.addedBy.name },

We would like to inform you that your order #${ order.uniqueId } has been partially cancelled.

Cancellation Reason: ${ order.order_Cancelled_Reason }

Delivered Items:

${invoiceDetails .map( (details) => `
Invoice ID: ${ details.invoiceId }
${details.processedItems}
S No. Product Name Image Quantity Price GST Amount SubTotal
Total Amount: ₹${details.totalAmount.toFixed( 2 )}
` ) .join("")}

Cancelled Items:

${cancelItems}
S No. Product Name Image Quantity Price GST Amount SubTotal
Total Refund Amount: ₹${totalCancelAmount.toFixed( 2 )}

If you have any concerns or further questions, please feel free to reply to this email.

Best regards,
Team Cheminova `, }); } res.status(200).json({ message: "Order cancelled successfully" }); } catch (error) { console.error("Error cancelling order:", error); res .status(500) .json({ message: "An error occurred while cancelling the order" }); } }; 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" }) .populate({ path: "invoices" }); 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 getPlacedPendingOrderAdmin = 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 pending orders const totalOrders = await PdOrder.countDocuments({ status: "pending" }); // Fetch paginated new orders const placedOrders = await PdOrder.find({ status: "pending" }) .skip(skip) .limit(limit) .populate({ path: "orderItem.productId" }) .populate({ path: "invoices" }) .populate({ path: "addedBy" }) .sort({ createdAt: -1 }); 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 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" }) .skip(skip) .limit(limit) .populate({ path: "orderItem.productId" }) .populate({ path: "invoices" }) .populate({ path: "addedBy" }) .sort({ createdAt: -1 }); 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 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: "invoices" }) .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 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: "invoices" }) .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 getProcessingInvoices = async (req, res) => { try { const page = parseInt(req.query.page, 10) || 1; const limit = parseInt(req.query.limit, 10) || 5; const { invoiceId, orderId } = req.query; const skip = (page - 1) * limit; let query = { courierStatus: "processing" }; if (invoiceId) { query.invoiceId = { $regex: invoiceId, $options: "i" }; } const invoices = await Invoice.find(query) .skip(skip) .limit(limit) .populate({ path: "orderId", select: "uniqueId", }) .sort({ "courierstatus_timeline.processing": -1 }); if (orderId) { const filteredInvoices = invoices.filter( (invoice) => invoice.orderId && invoice.orderId.uniqueId && invoice.orderId.uniqueId.toLowerCase().includes(orderId.toLowerCase()) ); res.status(200).json({ totalCount: filteredInvoices.length, currentPage: page, totalPages: Math.ceil(filteredInvoices.length / limit), invoices: filteredInvoices, }); } else { res.status(200).json({ totalCount: invoices.length, currentPage: page, totalPages: Math.ceil(invoices.length / limit), invoices, }); } } catch (error) { res.status(500).json({ error: error.message }); } }; export const getInvoiceDetailsById = async (req, res) => { const { invoiceId } = req.params; try { // Find the invoice by ID and populate the orderId and addedBy fields const invoice = await Invoice.findById(invoiceId).populate({ path: "orderId", model: "PdOrder", populate: { path: "addedBy", model: "User", select: "name email phone SBU", // Select only specific fields }, }); if (!invoice) { return res.status(404).json({ error: "Invoice not found" }); } res.status(200).json(invoice); } catch (error) { res.status(500).json({ error: error.message }); } }; export const updateCourierStatusToDispatched = async (req, res) => { const { invoiceId } = req.params; const { courierName, couriertrackingId } = req.body; try { // Find the invoice by ID const invoice = await Invoice.findById(invoiceId).populate({ path: "orderId", populate: { path: "addedBy", select: "email", }, }); if (!invoice) { return res.status(404).json({ error: "Invoice not found" }); } invoice.courierStatus = "dispatched"; invoice.courierstatus_timeline.dispatched = new Date(); invoice.courier_name = courierName; invoice.courier_tracking_id = couriertrackingId; // Save the updated invoice await invoice.save(); const order = invoice.orderId; const allItemsDispatched = order.orderItem.every( (item) => item.remainingQuantity === 0 ); if (allItemsDispatched) { order.status = "dispatched"; await order.save(); } // Send email to the user 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: ${ invoice?.courier_name || "N/A" }

Courier Tracking ID: ${ invoice?.courier_tracking_id || "N/A" }

Items:

${invoice?.items ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name SKU Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${ product.SKU } ${ product.image && product.image.length > 0 ? `${product.name}` : "No Image" } ${ product.processquantity } ₹${ product.price } ₹${( (product.GST * product.price) / 100 ).toFixed(2)} ₹${( (product.price + (product.GST * product.price) / 100) * product.processquantity ).toFixed(2)}
Total Amount: ₹${ invoice.invoiceAmount }

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 `, }); res.status(200).json({ message: "Courier status updated to dispatched", orderStatus: order.status, }); } catch (error) { res.status(500).json({ error: error.message }); } }; export const getDispatchedInvoices = async (req, res) => { try { const page = parseInt(req.query.page, 10) || 1; const limit = parseInt(req.query.limit, 10) || 5; const { invoiceId, orderId } = req.query; const skip = (page - 1) * limit; let query = { courierStatus: "dispatched" }; if (invoiceId) { query.invoiceId = { $regex: invoiceId, $options: "i" }; } const invoices = await Invoice.find(query) .sort({ createdAt: -1 }) .skip(skip) .limit(limit) .populate({ path: "orderId", select: "uniqueId", }) .sort({ "courierstatus_timeline.dispatched": -1 }); if (orderId) { const filteredInvoices = invoices.filter( (invoice) => invoice.orderId && invoice.orderId.uniqueId && invoice.orderId.uniqueId.toLowerCase().includes(orderId.toLowerCase()) ); res.status(200).json({ totalCount: filteredInvoices.length, currentPage: page, totalPages: Math.ceil(filteredInvoices.length / limit), invoices: filteredInvoices, }); } else { res.status(200).json({ totalCount: invoices.length, currentPage: page, totalPages: Math.ceil(invoices.length / limit), invoices, }); } } catch (error) { res.status(500).json({ error: error.message }); } }; export const updateCourierStatusToDelivered = async (req, res) => { const { invoiceId } = req.params; try { // Find the invoice by ID const invoice = await Invoice.findById(invoiceId).populate({ path: "orderId", populate: { path: "addedBy", select: "email", }, }); if (!invoice) { return res.status(404).json({ error: "Invoice not found" }); } // Update courier status and timeline invoice.courierStatus = "delivered"; invoice.courierstatus_timeline.delivered = new Date(); // Save the updated invoice await invoice.save(); const order = invoice.orderId; const allItemsDelivered = order.orderItem.every( (item) => item.remainingQuantity === 0 ); if (allItemsDelivered) { order.status = "delivered"; await order.save(); } // Format the current date for display const formattedDate = formatDate(new Date()); // Send email to the user 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:

${invoice?.items ?.map( (product, index) => ` ` ) .join("")}
S No. Product Name SKU Image Quantity Price GST Amount SubTotal
${ index + 1 } ${ product.name } ${ product.SKU } ${ product.image && product.image.length > 0 ? `${product.name}` : "No Image" } ${ product.processquantity } ₹${ product.price } ₹${( (product.GST * product.price) / 100 ).toFixed(2)} ₹${( (product.price + (product.GST * product.price) / 100) * product.processquantity ).toFixed(2)}
Total Amount: ₹${invoice.invoiceAmount.toFixed( 2 )}

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 `, }); res.status(200).json({ message: "Courier status updated to delivered", orderStatus: order.status, }); } catch (error) { res.status(500).json({ error: error.message }); } }; export const getDeliveredInvoices = async (req, res) => { try { const page = parseInt(req.query.page, 10) || 1; const limit = parseInt(req.query.limit, 10) || 5; const { invoiceId, orderId } = req.query; const skip = (page - 1) * limit; let query = { courierStatus: "delivered" }; if (invoiceId) { query.invoiceId = { $regex: invoiceId, $options: "i" }; } const invoices = await Invoice.find(query) .sort({ createdAt: -1 }) .skip(skip) .limit(limit) .populate({ path: "orderId", select: "uniqueId", }) .sort({ "courierstatus_timeline.delivered": -1 }); if (orderId) { const filteredInvoices = invoices.filter( (invoice) => invoice.orderId && invoice.orderId.uniqueId && invoice.orderId.uniqueId.toLowerCase().includes(orderId.toLowerCase()) ); res.status(200).json({ totalCount: filteredInvoices.length, currentPage: page, totalPages: Math.ceil(filteredInvoices.length / limit), invoices: filteredInvoices, }); } else { res.status(200).json({ totalCount: invoices.length, currentPage: page, totalPages: Math.ceil(invoices.length / limit), invoices, }); } } catch (error) { res.status(500).json({ error: error.message }); } }; 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: "invoices" }) .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" }); } }; 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 { // 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 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!" }); } }; export const getAllOrdersByDistributor = async (req, res) => { const { distributorId } = req.params; const { orderId, status } = req.query; // Added status to query parameters // console.log(distributorId, orderId, status); // Handle pagination parameters const page = parseInt(req.query.page, 10) || 1; const limit = parseInt(req.query.limit, 10) || 5; const skip = (page - 1) * limit; try { let orders; // Search by orderId if (orderId) { const id = new RegExp(orderId, "i"); orders = await PdOrder.find({ addedBy: distributorId, uniqueId: { $regex: id }, }) .sort({ createdAt: -1 }) .skip(skip) .limit(limit); // console.log(orders); // Return empty array if no orders are found if (!orders || orders.length === 0) { return res.status(200).json([]); } // Get total count for pagination const totalOrders = await PdOrder.countDocuments({ addedBy: distributorId, status: { $regex: id }, }); // Send response with pagination info return res.status(200).json({ totalOrders, totalPages: Math.ceil(totalOrders / limit), currentPage: page, orders, }); } // Search by status else if (status) { // Create a regex for case-insensitive search const regex = new RegExp(status, "i"); orders = await PdOrder.find({ addedBy: distributorId, status: { $regex: regex }, }) .sort({ createdAt: -1 }) .skip(skip) .limit(limit); // console.log(orders); // Return empty array if no orders are found if (!orders || orders.length === 0) { return res.status(200).json([]); } // Get total count for pagination const totalOrders = await PdOrder.countDocuments({ addedBy: distributorId, status: { $regex: regex }, }); // Send response with pagination info return res.status(200).json({ totalOrders, totalPages: Math.ceil(totalOrders / limit), currentPage: page, orders, }); } // Default behavior to return all orders else { orders = await PdOrder.find({ addedBy: distributorId }) .sort({ createdAt: -1 }) .skip(skip) .limit(limit); // Return empty array if no orders are found if (!orders || orders.length === 0) { return res.status(200).json([]); } // Get total count for pagination const totalOrders = await PdOrder.countDocuments({ addedBy: distributorId, }); // Send response with pagination info return res.status(200).json({ totalOrders, totalPages: Math.ceil(totalOrders / limit), currentPage: page, orders, }); } } catch (error) { console.error("Error fetching orders:", error); res.status(500).json({ message: "Server error", error }); } }; export const gettotalorderandvalueofpd = async (req, res) => { const { distributorId } = req.params; try { const orders = await PdOrder.find({ addedBy: distributorId }); const totalOrders = orders.length; const totalValue = orders.reduce((acc, order) => acc + order.grandTotal, 0); res.status(200).json({ totalOrders, totalValue }); } catch (error) { console.error("Error fetching orders:", error); res.status(500).json({ message: "Server error", error }); } };