invoice related apis are completed
This commit is contained in:
parent
0f2330db13
commit
f2e99790cc
@ -70,4 +70,11 @@ const invoiceSchema = new mongoose.Schema({
|
|||||||
delivered: { type: Date },
|
delivered: { type: Date },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// Middleware to set the processing date only when the invoice is created
|
||||||
|
invoiceSchema.pre('save', function (next) {
|
||||||
|
if (this.isNew && !this.courierstatus_timeline.processing) {
|
||||||
|
this.courierstatus_timeline.processing = new Date();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
export const Invoice = mongoose.model("Invoice", invoiceSchema);
|
export const Invoice = mongoose.model("Invoice", invoiceSchema);
|
@ -93,9 +93,7 @@ export const processOrder = async (req, res) => {
|
|||||||
(i) => i.productId.toString() === item.productId.toString()
|
(i) => i.productId.toString() === item.productId.toString()
|
||||||
);
|
);
|
||||||
if (orderItem && item.processquantity > orderItem.remainingQuantity) {
|
if (orderItem && item.processquantity > orderItem.remainingQuantity) {
|
||||||
return res
|
return res.status(400).json({
|
||||||
.status(400)
|
|
||||||
.json({
|
|
||||||
error: `Product '${item.name}' has more quantity than remaining in the order.`,
|
error: `Product '${item.name}' has more quantity than remaining in the order.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -329,9 +327,7 @@ export const processOrder = async (req, res) => {
|
|||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
res
|
res.status(200).json({
|
||||||
.status(200)
|
|
||||||
.json({
|
|
||||||
message: "Order processed and invoice created successfully",
|
message: "Order processed and invoice created successfully",
|
||||||
invoiceId: savedInvoice.invoiceId,
|
invoiceId: savedInvoice.invoiceId,
|
||||||
});
|
});
|
||||||
@ -778,7 +774,388 @@ export const getProcessingOrdersAdmin = async (req, res) => {
|
|||||||
return res.status(500).json({ error: "Internal Server 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;
|
||||||
|
|
||||||
|
// Calculate the number of documents to skip
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Get the total count of 'processing' invoices
|
||||||
|
const totalInvoices = await Invoice.countDocuments({
|
||||||
|
courierStatus: "processing",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch the invoices with pagination
|
||||||
|
const invoices = await Invoice.find({ courierStatus: "processing" })
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.skip(skip)
|
||||||
|
.limit(limit);
|
||||||
|
// Respond with the invoices and the total count
|
||||||
|
res.status(200).json({
|
||||||
|
totalCount: totalInvoices,
|
||||||
|
currentPage: page,
|
||||||
|
totalPages: Math.ceil(totalInvoices / 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", // 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: `
|
||||||
|
<strong style="color: #1b03a3; font-size: 16px">Hi,</strong>
|
||||||
|
<h3 style="color: #333; font-family: Arial, sans-serif;">Exciting news! Your order #${
|
||||||
|
order?.uniqueId
|
||||||
|
} has been dispatched and is en route to you. 🚚 Here are the details:</h3>
|
||||||
|
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">Courier Name: ${
|
||||||
|
invoice?.courier_name || "N/A"
|
||||||
|
}</h4>
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">Courier Tracking ID: ${
|
||||||
|
invoice?.courier_tracking_id || "N/A"
|
||||||
|
}</h4>
|
||||||
|
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">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;">SKU</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>
|
||||||
|
${invoice?.items
|
||||||
|
?.map(
|
||||||
|
(product, 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;">${
|
||||||
|
product.name
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${
|
||||||
|
product.SKU
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">
|
||||||
|
${
|
||||||
|
product.image && product.image.length > 0
|
||||||
|
? `<img src="${product.image[0]?.url}" alt="${product.name}" style="max-width: 40px; height: auto;">`
|
||||||
|
: "No Image"
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${
|
||||||
|
product.processquantity
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
product.price
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
((product.GST * product.price) / 100).toFixed(2)
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
((product.price + (product.GST * product.price) / 100) *
|
||||||
|
product.processquantity).toFixed(2)
|
||||||
|
}</td>
|
||||||
|
</tr>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
<tr>
|
||||||
|
<th colspan="7" style="border: 1px solid #555; padding: 2px; text-align: right;">Total Amount:</th>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
invoice.invoiceAmount
|
||||||
|
}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 style="color: #333; font-family: Arial, sans-serif;">Order Status: Dispatched</h3>
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">If you have any questions or need assistance, feel free to reply to this email.</h4>
|
||||||
|
<h5 style="color: #333; font-family: Arial, sans-serif;">Thanks for choosing Cheminova! We hope you enjoy your purchase.</h5>
|
||||||
|
<br/>
|
||||||
|
<span style="color: #555; font-size: 13px;">Best regards,</span><br/>
|
||||||
|
<span style="color: #555; font-size: 13px;">Team Cheminova</span>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Calculate the number of documents to skip
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Get the total count of 'processing' invoices
|
||||||
|
const totalInvoices = await Invoice.countDocuments({
|
||||||
|
courierStatus: "dispatched",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch the invoices with pagination
|
||||||
|
const invoices = await Invoice.find({ courierStatus: "dispatched" })
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.skip(skip)
|
||||||
|
.limit(limit);
|
||||||
|
// Respond with the invoices and the total count
|
||||||
|
res.status(200).json({
|
||||||
|
totalCount: totalInvoices,
|
||||||
|
currentPage: page,
|
||||||
|
totalPages: Math.ceil(totalInvoices / 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: `
|
||||||
|
<strong style="color: #1b03a3; font-size: 16px">Hi,</strong>
|
||||||
|
<h3 style="color: #333; font-family: Arial, sans-serif;">
|
||||||
|
Great news! Your order #${
|
||||||
|
order?.uniqueId
|
||||||
|
} has been successfully delivered to your doorstep. We hope everything is just as you expected!
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">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;">SKU</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>
|
||||||
|
${invoice?.items
|
||||||
|
?.map(
|
||||||
|
(product, 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;">${
|
||||||
|
product.name
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${
|
||||||
|
product.SKU
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">
|
||||||
|
${
|
||||||
|
product.image && product.image.length > 0
|
||||||
|
? `<img src="${product.image[0]?.url}" alt="${product.name}" style="max-width: 40px; height: auto;">`
|
||||||
|
: "No Image"
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">${
|
||||||
|
product.processquantity
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
product.price
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
((product.GST * product.price) / 100).toFixed(2)
|
||||||
|
}</td>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
((product.price + (product.GST * product.price) / 100) *
|
||||||
|
product.processquantity).toFixed(2)
|
||||||
|
}</td>
|
||||||
|
</tr>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
<tr>
|
||||||
|
<th colspan="7" style="border: 1px solid #555; padding: 2px; text-align: right;">Total Amount:</th>
|
||||||
|
<td style="border: 1px solid #555; padding: 2px; text-align: center;">₹${
|
||||||
|
invoice.invoiceAmount.toFixed(2)
|
||||||
|
}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 style="color: #333; font-family: Arial, sans-serif;">Delivery Date: ${formattedDate}</h3>
|
||||||
|
|
||||||
|
<h4 style="color: #333; font-family: Arial, sans-serif;">
|
||||||
|
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!
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<h5 style="color: #333; font-family: Arial, sans-serif;">
|
||||||
|
If you have any questions or concerns about your order, feel free to reply to this email.
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<h5 style="color: #333; font-family: Arial, sans-serif;">
|
||||||
|
Thank you for choosing Cheminova! We hope to serve you again soon.
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<span style="color: #555; font-size: 13px;">Best regards,</span><br/>
|
||||||
|
<span style="color: #555; font-size: 13px;">Team Cheminova</span>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Calculate the number of documents to skip
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Get the total count of 'processing' invoices
|
||||||
|
const totalInvoices = await Invoice.countDocuments({
|
||||||
|
courierStatus: "delivered",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch the invoices with pagination
|
||||||
|
const invoices = await Invoice.find({ courierStatus: "delivered" })
|
||||||
|
.sort({ createdAt: -1 })
|
||||||
|
.skip(skip)
|
||||||
|
.limit(limit);
|
||||||
|
// Respond with the invoices and the total count
|
||||||
|
res.status(200).json({
|
||||||
|
totalCount: totalInvoices,
|
||||||
|
currentPage: page,
|
||||||
|
totalPages: Math.ceil(totalInvoices / limit),
|
||||||
|
invoices,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ error: error.message });
|
||||||
|
}
|
||||||
|
};
|
||||||
export const getDeliveredOrdersAdmin = async (req, res) => {
|
export const getDeliveredOrdersAdmin = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Extract page and limit from query parameters
|
// Extract page and limit from query parameters
|
||||||
@ -809,7 +1186,60 @@ export const getDeliveredOrdersAdmin = async (req, res) => {
|
|||||||
return res.status(500).json({ error: "Internal Server 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!" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// no need
|
||||||
export const updateOrderStatusById = async (req, res) => {
|
export const updateOrderStatusById = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
let body = { status: req.body.status };
|
let body = { status: req.body.status };
|
||||||
@ -1224,55 +1654,3 @@ export const updateOrderStatusById = async (req, res) => {
|
|||||||
.json({ message: error?.message || "Something went wrong!" });
|
.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 {
|
|
||||||
// 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!" });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -14,6 +14,12 @@ import {
|
|||||||
processOrder,
|
processOrder,
|
||||||
cancelOrderController,
|
cancelOrderController,
|
||||||
getPlacedPendingOrderAdmin,
|
getPlacedPendingOrderAdmin,
|
||||||
|
getProcessingInvoices,
|
||||||
|
updateCourierStatusToDispatched,
|
||||||
|
getInvoiceDetailsById,
|
||||||
|
getDeliveredInvoices,
|
||||||
|
getDispatchedInvoices,
|
||||||
|
updateCourierStatusToDelivered,
|
||||||
} from "./pdOrderController.js";
|
} from "./pdOrderController.js";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@ -65,9 +71,36 @@ router
|
|||||||
router
|
router
|
||||||
.route("/get-delivered-order-admin")
|
.route("/get-delivered-order-admin")
|
||||||
.get(isAuthenticatedUser, authorizeRoles("admin"), getDeliveredOrdersAdmin);
|
.get(isAuthenticatedUser, authorizeRoles("admin"), getDeliveredOrdersAdmin);
|
||||||
|
router
|
||||||
|
.route("/get-processing-invoice-admin")
|
||||||
|
.get(isAuthenticatedUser, authorizeRoles("admin"), getProcessingInvoices);
|
||||||
|
router
|
||||||
|
.route("/get-dispatched-invoice-admin")
|
||||||
|
.get(isAuthenticatedUser, authorizeRoles("admin"), getDispatchedInvoices);
|
||||||
|
router
|
||||||
|
.route("/get-delivered-invoice-admin")
|
||||||
|
.get(isAuthenticatedUser, authorizeRoles("admin"), getDeliveredInvoices);
|
||||||
|
router
|
||||||
|
.route("/invoice/details/:invoiceId")
|
||||||
|
.get(isAuthenticatedUser, authorizeRoles("admin"), getInvoiceDetailsById);
|
||||||
|
router
|
||||||
|
.route("/invoice/dispatched/:invoiceId")
|
||||||
|
.put(
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
updateCourierStatusToDispatched
|
||||||
|
);
|
||||||
|
router
|
||||||
|
.route("/invoice/delivered/:invoiceId")
|
||||||
|
.put(
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
updateCourierStatusToDelivered
|
||||||
|
);
|
||||||
router
|
router
|
||||||
.route("/change/status/:id")
|
.route("/change/status/:id")
|
||||||
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
|
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
|
||||||
|
|
||||||
router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts);
|
router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
Loading…
Reference in New Issue
Block a user