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 ? ` ` : 'No Image'}
+ ${
+ item.image && item.image.length > 0
+ ? ` `
+ : "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 ? ` ` : 'No Image'}
+ ${
+ item.image && item.image.length > 0
+ ? ` `
+ : "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.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.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
+ }
+
+
+
+ S No. |
+ Product Name |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${details.processedItems}
+
+ Total Amount: |
+ ₹${details.totalAmount.toFixed(
+ 2
+ )} |
+
+
+
+ `
+ )
+ .join("")}
+
+ Cancelled Items:
+
+
+
+ S No. |
+ Product Name |
+ Image |
+ Quantity |
+ Price |
+ GST Amount |
+ SubTotal |
+
+
+
+ ${cancelItems}
+
+ 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(