order partial and fully processing with sending mail

This commit is contained in:
Sibunnayak 2024-09-19 15:11:44 +05:30
parent e53a503ffa
commit 839f942f08
2 changed files with 125 additions and 15 deletions

View File

@ -34,7 +34,7 @@ const orderItemSchema = new Schema({
type: Number,
required: true,
},
quantity: {
processquantity: { //updated quantity
type: Number,
required: true,
default: 1,

View File

@ -79,7 +79,7 @@ export const processOrder = async (req, res) => {
}
// Find the order by ID
const order = await PdOrder.findById(orderId);
const order = await PdOrder.findById(orderId).populate('addedBy');
if (!order) {
return res.status(404).json({ error: 'Order not found' });
@ -88,25 +88,25 @@ export const processOrder = async (req, res) => {
// Validate quantities
for (const item of invoiceItems) {
const orderItem = order.orderItem.find(i => i.productId.toString() === item.productId.toString());
if (orderItem && item.quantity > orderItem.remainingQuantity) {
if (orderItem && item.processquantity > orderItem.remainingQuantity) {
return res.status(400).json({ error: `Product '${item.name}' has more quantity than remaining in the order.` });
}
}
// Generate unique invoice number
const existingInvoices = await Invoice.find({ orderId });
const invoiceNumber = existingInvoices.length + 1;
const invoiceNumber = existingInvoices.length + 1;
const invoiceId = `ch/${order.uniqueId}/${invoiceItems.length}/${invoiceNumber}`;
// Calculate subtotal, gstTotal, and invoiceAmount
// 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.quantity;
const itemGST = (item.price * item.GST) / 100 * item.quantity;
const itemSubtotal = item.price * item.processquantity;
const itemGST = (item.price * item.GST / 100) * item.processquantity;
subtotal += itemSubtotal;
gstTotal += itemGST;
invoiceAmount += itemSubtotal + itemGST;
@ -130,7 +130,7 @@ export const processOrder = async (req, res) => {
order.orderItem.forEach(item => {
const invoicedItem = invoiceItems.find(i => i.productId.toString() === item.productId.toString());
if (invoicedItem) {
item.remainingQuantity -= invoicedItem.quantity;
item.remainingQuantity -= invoicedItem.processquantity;
if (item.remainingQuantity < 0) {
item.remainingQuantity = 0; // Ensure it does not go negative
}
@ -140,20 +140,130 @@ export const processOrder = async (req, res) => {
}
});
// 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;
}
});
// Update the order status
order.status = allItemsProcessed ? 'processing' : 'pending';
// Save the updated order
await order.save();
return res.status(201).json({
message: 'Invoice created and order processed successfully',
invoice: savedInvoice,
order: order,
// Prepare the email content
const processedItems = invoiceItems.map((item, index) => `
<tr>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${index + 1}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.name}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">
${item.image && item.image.length > 0 ? `<img src="${item.image[0]?.url}" alt="${item.name}" style="max-width: 40px; height: auto;">` : 'No Image'}
</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.processquantity}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.price}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${(item.GST * item.price) / 100}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${(item.price + (item.GST * item.price) / 100) * item.processquantity}</td>
</tr>
`).join("");
const pendingItems = order.orderItem.filter(item => item.remainingQuantity > 0).map((item, index) => `
<tr>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${index + 1}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.name}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">
${item.image && item.image.length > 0 ? `<img src="${item.image[0]?.url}" alt="${item.name}" style="max-width: 40px; height: auto;">` : 'No Image'}
</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.remainingQuantity}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${item.price}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${(item.GST * item.price) / 100}</td>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${(item.price + (item.GST * item.price) / 100) * item.remainingQuantity}</td>
</tr>
`).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
? `
<h3>Exciting news! Your order #${order.uniqueId} has entered the processing phase. We're working hard to ensure everything is perfect for you.</h3>
<p>Your invoice ID is: <strong>${savedInvoice.invoiceId}</strong></p>
`
: `
<h3>Good news! Some items of your order #${order.uniqueId} have been processed. The remaining items will be processed soon.</h3>
<p>Your invoice ID is: <strong>${savedInvoice.invoiceId}</strong></p>
`;
await sendEmail({
to: order.addedBy.email,
from: process.env.SEND_EMAIL_FROM,
subject: emailSubject,
html: `
<div style="font-family: Arial, sans-serif; color: #333;">
${emailMessage}
<strong style="color: #1b03a3; font-size: 16px;">Hi ${order.addedBy.name},</strong>
<h4 style="color: #333;">Order Status: ${order.status.charAt(0).toUpperCase() + order.status.slice(1)}</h4>
<h4 style="color: #333;">Processed Items:</h4>
<table style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">S No.</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Product Name</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Image</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Quantity</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Price</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">GST Amount</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">SubTotal</th>
</tr>
</thead>
<tbody>
${processedItems}
<tr>
<th colspan="6" style="border: 1px solid #555; padding: 2px; text-align: right;">Total Amount:</th>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${savedInvoice.invoiceAmount.toFixed(2)}</td>
</tr>
</tbody>
</table>
${pendingItems.length > 0 ? `
<h4 style="color: #333;">Pending Items:</h4>
<table style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">S No.</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Product Name</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Image</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Quantity</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">Price</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">GST Amount</th>
<th style="border: 1px solid #555; padding: 2px; text-align: center;">SubTotal</th>
</tr>
</thead>
<tbody>
${pendingItems}
<tr>
<th colspan="6" style="border: 1px solid #555; padding: 2px; text-align: right;">Pending Amount:</th>
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${pendingTotalAmount.toFixed(2)}</td>
</tr>
</tbody>
</table>
` : ''}
</div>
`,
});
res.status(200).json({ message: 'Order processed and invoice created successfully', invoiceId: savedInvoice.invoiceId });
} catch (error) {
console.error(error);
return res.status(500).json({ error: 'Internal server error' });
console.error('Error processing order:', error);
res.status(500).json({ error: 'An error occurred while processing the order' });
}
};