From a6707d5deaf65e194380a24e2777dd722643f441 Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Thu, 19 Sep 2024 16:06:31 +0530 Subject: [PATCH] order partial and fully processing with sending mail and fully cancel and partial cancel with mail was send successfully --- resources/PD_Orders/pdOrderController.js | 381 ++++++++++++++++++++--- resources/PD_Orders/pdOrderRoute.js | 5 + 2 files changed, 344 insertions(+), 42 deletions(-) diff --git a/resources/PD_Orders/pdOrderController.js b/resources/PD_Orders/pdOrderController.js index 272fa21..4664fb5 100644 --- a/resources/PD_Orders/pdOrderController.js +++ b/resources/PD_Orders/pdOrderController.js @@ -75,21 +75,29 @@ export const processOrder = async (req, res) => { const { orderId, invoiceItems } = req.body; if (!orderId || !invoiceItems || !Array.isArray(invoiceItems)) { - return res.status(400).json({ error: 'Missing required fields or invalid data' }); + 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'); + const order = await PdOrder.findById(orderId).populate("addedBy"); if (!order) { - return res.status(404).json({ error: 'Order not found' }); + return res.status(404).json({ error: "Order not found" }); } // Validate quantities for (const item of invoiceItems) { - const orderItem = order.orderItem.find(i => i.productId.toString() === item.productId.toString()); + const orderItem = order.orderItem.find( + (i) => i.productId.toString() === item.productId.toString() + ); if (orderItem && item.processquantity > orderItem.remainingQuantity) { - return res.status(400).json({ error: `Product '${item.name}' has more quantity than remaining in the order.` }); + return res + .status(400) + .json({ + error: `Product '${item.name}' has more quantity than remaining in the order.`, + }); } } @@ -103,9 +111,9 @@ export const processOrder = async (req, res) => { let gstTotal = 0; let invoiceAmount = 0; - invoiceItems.forEach(item => { + invoiceItems.forEach((item) => { const itemSubtotal = item.price * item.processquantity; - const itemGST = (item.price * item.GST / 100) * item.processquantity; + const itemGST = ((item.price * item.GST) / 100) * item.processquantity; subtotal += itemSubtotal; gstTotal += itemGST; @@ -127,8 +135,10 @@ export const processOrder = async (req, res) => { // Update the order's order items with the remaining quantity let allItemsProcessed = true; - order.orderItem.forEach(item => { - const invoicedItem = invoiceItems.find(i => i.productId.toString() === item.productId.toString()); + order.orderItem.forEach((item) => { + const invoicedItem = invoiceItems.find( + (i) => i.productId.toString() === item.productId.toString() + ); if (invoicedItem) { item.remainingQuantity -= invoicedItem.processquantity; if (item.remainingQuantity < 0) { @@ -142,55 +152,98 @@ export const processOrder = async (req, res) => { // Calculate total amount for pending items let pendingTotalAmount = 0; - order.orderItem.forEach(item => { + order.orderItem.forEach((item) => { if (item.remainingQuantity > 0) { const itemPendingSubtotal = item.price * item.remainingQuantity; - const itemPendingGST = (item.price * item.GST / 100) * item.remainingQuantity; + const itemPendingGST = + ((item.price * item.GST) / 100) * item.remainingQuantity; pendingTotalAmount += itemPendingSubtotal + itemPendingGST; } }); // Update the order status - order.status = allItemsProcessed ? 'processing' : 'pending'; + order.status = allItemsProcessed ? "processing" : "pending"; + order.invoices.push(savedInvoice._id); // Save the updated order await order.save(); // Prepare the email content - const processedItems = invoiceItems.map((item, index) => ` + const processedItems = invoiceItems + .map( + (item, index) => ` - ${index + 1} - ${item.name} + ${ + index + 1 + } + ${ + item.name + } - ${item.image && item.image.length > 0 ? `${item.name}` : 'No Image'} + ${ + 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} + ${ + item.processquantity + } + ₹${ + item.price + } + ₹${ + (item.GST * item.price) / 100 + } + ₹${ + (item.price + (item.GST * item.price) / 100) * item.processquantity + } - `).join(""); + ` + ) + .join(""); - const pendingItems = order.orderItem.filter(item => item.remainingQuantity > 0).map((item, index) => ` + const pendingItems = order.orderItem + .filter((item) => item.remainingQuantity > 0) + .map( + (item, index) => ` - ${index + 1} - ${item.name} + ${ + index + 1 + } + ${ + item.name + } - ${item.image && item.image.length > 0 ? `${item.name}` : 'No Image'} + ${ + 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} + ${ + item.remainingQuantity + } + ₹${ + item.price + } + ₹${ + (item.GST * item.price) / 100 + } + ₹${ + (item.price + (item.GST * item.price) / 100) * item.remainingQuantity + } - `).join(""); + ` + ) + .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 + 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}

@@ -198,7 +251,7 @@ export const processOrder = async (req, res) => { : `

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, @@ -207,8 +260,12 @@ export const processOrder = async (req, res) => { html: `
${emailMessage} - Hi ${order.addedBy.name}, -

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

+ Hi ${ + order.addedBy.name + }, +

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

Processed Items:

@@ -227,12 +284,16 @@ export const processOrder = async (req, res) => { ${processedItems} - +
Total Amount:₹${savedInvoice.invoiceAmount.toFixed(2)}₹${savedInvoice.invoiceAmount.toFixed( + 2 + )}
- ${pendingItems.length > 0 ? ` + ${ + pendingItems.length > 0 + ? `

Pending Items:

@@ -250,20 +311,256 @@ export const processOrder = async (req, res) => { ${pendingItems} - +
Pending Amount:₹${pendingTotalAmount.toFixed(2)}₹${pendingTotalAmount.toFixed( + 2 + )}
- ` : ''} + ` + : "" + }
`, }); - res.status(200).json({ message: 'Order processed and invoice created successfully', invoiceId: savedInvoice.invoiceId }); - + 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' }); + 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.body; + 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 NameImageQuantityPriceGST AmountSubTotal
Total Amount:₹${details.totalAmount.toFixed( + 2 + )}
+ ` + ) + .join("")} + +

Cancelled Items:

+ + + + + + + + + + + + + + ${cancelItems} + + + + + +
S No.Product NameImageQuantityPriceGST AmountSubTotal
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" }); } }; diff --git a/resources/PD_Orders/pdOrderRoute.js b/resources/PD_Orders/pdOrderRoute.js index df87553..0854cbf 100644 --- a/resources/PD_Orders/pdOrderRoute.js +++ b/resources/PD_Orders/pdOrderRoute.js @@ -12,6 +12,7 @@ import { getProcessingOrdersAdmin, updateOrderStatusById, processOrder, + cancelOrderController, } from "./pdOrderController.js"; const router = express.Router(); @@ -27,6 +28,10 @@ router router .route("/processing-order") .post(isAuthenticatedUser, authorizeRoles("admin"), processOrder); + // Define the route for cancel an order +router +.route("/cancel-order") +.post(isAuthenticatedUser, authorizeRoles("admin"), cancelOrderController); router .route("/get-placed-order-pd") .get(