download report and task show

This commit is contained in:
Sibunnayak 2024-11-13 17:42:43 +05:30
parent 26a924efbb
commit 6ab315c247
6 changed files with 376 additions and 2 deletions

View File

@ -16,6 +16,7 @@ import {
updateunmapRD, updateunmapRD,
uploadRetaildistributors, uploadRetaildistributors,
updateretaildistributorwithKYC, updateretaildistributorwithKYC,
generateRetailerReport,
} from "./RetailDistributorController.js"; } from "./RetailDistributorController.js";
import { isAuthenticatedRD } from "../../middlewares/rdAuth.js"; import { isAuthenticatedRD } from "../../middlewares/rdAuth.js";
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
@ -25,6 +26,9 @@ const router = express.Router();
router router
.route("/retaildistributor/upload") .route("/retaildistributor/upload")
.post(isAuthenticatedUser, authorizeRoles("admin"), uploadRetaildistributors); .post(isAuthenticatedUser, authorizeRoles("admin"), uploadRetaildistributors);
router
.route("/retaildistributor/download-report")
.get(isAuthenticatedUser, authorizeRoles("admin"), generateRetailerReport);
router.route("/rd-login").post(loginRD); router.route("/rd-login").post(loginRD);
router.route("/rd-get-me").get(isAuthenticatedRD, getmyProfileRD); router.route("/rd-get-me").get(isAuthenticatedRD, getmyProfileRD);
router.post("/forgot-password", forgotPasswordRD); router.post("/forgot-password", forgotPasswordRD);

View File

@ -1843,3 +1843,105 @@ export const saveFCMTokenForRD = async (req, res) => {
res.status(500).send("Internal Server Error"); res.status(500).send("Internal Server Error");
} }
}; };
export const generateRetailerReport = async (req, res) => {
try {
// Fetch retailer data and populate required fields
const retailers = await RetailDistributor.find()
.populate("kyc", "trade_name pan_number aadhar_number gst_number state city district address pincode")
.populate("principal_distributer", "name")
.populate("mappedTM", "name")
.populate("mappedSC", "name")
.select("uniqueId name email mobile_number");
if (!retailers.length) {
return res.status(404).json({ message: "No retailers found." });
}
// Prepare data for the sheet
const retailerData = retailers.map((retailer) => ({
"Retailer ID": retailer.uniqueId,
"Retailer Name": retailer.name,
Email: retailer.email,
"Mobile Number": retailer.mobile_number,
"Trade Name": retailer.kyc?.trade_name || "",
"PAN Number": retailer.kyc?.pan_number || "",
"Aadhaar Number": retailer.kyc?.aadhar_number || "",
"GST Number": retailer.kyc?.gst_number || "",
State: retailer.kyc?.state || "",
City: retailer.kyc?.city || "",
District: retailer.kyc?.district || "",
Address: retailer.kyc?.address || "",
Pincode: retailer.kyc?.pincode || "",
PrincipalDistributor: retailer.principal_distributer?.name || "N/A",
TerritoryManager: retailer.mappedTM?.name || "N/A",
SalesCoordinator: retailer.mappedSC?.name || "N/A",
}));
// Define headers for the worksheet
const headers = [
[
"Retailer ID",
"Retailer Name",
"Email",
"Mobile Number",
"Trade Name",
"PAN Number",
"Aadhaar Number",
"GST Number",
"State",
"City",
"District",
"Address",
"Pincode",
"Principal Distributor",
"Territory Manager",
"Sales Coordinator",
],
];
// Create worksheet with headers
const worksheet = XLSX.utils.aoa_to_sheet(headers);
// Append retailer data below headers
XLSX.utils.sheet_add_json(worksheet, retailerData, {
skipHeader: true,
origin: "A2",
});
// Set column widths based on content length
const columnWidths = headers[0].map((header, index) => {
let maxLength = header.length;
for (const row of retailerData) {
const cellContent = row[header]?.toString() || "";
maxLength = Math.max(maxLength, cellContent.length);
}
return { wch: maxLength + 2 };
});
worksheet["!cols"] = columnWidths;
// Create workbook and append worksheet
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "RetailerReport");
// Write workbook to a buffer
const excelBuffer = XLSX.write(workbook, {
bookType: "xlsx",
type: "buffer",
});
// Send Excel file as response
res.setHeader(
"Content-Type",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
res.setHeader(
"Content-Disposition",
"attachment; filename=RetailerReport.xlsx"
);
res.send(excelBuffer);
} catch (error) {
console.error("Error generating retailer report:", error);
res.status(500).json({ message: "Failed to generate report" });
}
};

View File

@ -385,7 +385,7 @@ export const getTodaysTasks = async (req, res) => {
// Find tasks that are due today, with pagination // Find tasks that are due today, with pagination
const tasks = await Task.find({ const tasks = await Task.find({
taskDueDate: { createdAt: {
$gte: startOfToday, $gte: startOfToday,
$lte: endOfToday, $lte: endOfToday,
}, },
@ -395,7 +395,7 @@ export const getTodaysTasks = async (req, res) => {
.skip(skip) // Skip documents for pagination .skip(skip) // Skip documents for pagination
.limit(itemsPerPage) // Limit the number of documents .limit(itemsPerPage) // Limit the number of documents
.exec(); .exec();
// console.log(tasks);
// Populate addedForId conditionally // Populate addedForId conditionally
const populatedTasks = await Promise.all( const populatedTasks = await Promise.all(
tasks.map(async (task) => { tasks.map(async (task) => {
@ -434,3 +434,127 @@ export const getTodaysTasks = async (req, res) => {
res.status(500).json({ message: "Failed to retrieve tasks for today" }); res.status(500).json({ message: "Failed to retrieve tasks for today" });
} }
}; };
export const getTasks = async (req, res) => {
try {
const {
page = 1,
show = 10,
startDate = "",
endDate = "",
TMname = "",
SCname = "",
status = "",
} = req.query;
const limit = parseInt(show);
const skip = (parseInt(page) - 1) * limit;
const matchStage = {};
// Filter by date range
if (startDate && endDate) {
const start = new Date(startDate);
const end = new Date(endDate);
if (start.toDateString() === end.toDateString()) {
matchStage.createdAt = {
$gte: start,
$lt: new Date(start).setDate(start.getDate() + 1),
};
} else {
matchStage.createdAt = {
$gte: start,
$lte: new Date(end).setDate(end.getDate() + 1),
};
}
// matchStage.createdAt = {
// $gte: start,
// $lte: new Date(end.setDate(end.getDate() + 1)),
// };
} else if (startDate && endDate === "") {
matchStage.createdAt = {
$gte: new Date(startDate),
$lte: new Date(),
};
} else if (endDate && startDate === "") {
matchStage.createdAt = {
$lte: new Date(endDate),
};
}
// Filter by task status
if (status) {
matchStage.taskStatus = status;
}
// Aggregation pipeline
const tasks = await Task.aggregate([
{ $match: matchStage },
{
$lookup: {
from: "territorymanagers",
localField: "taskAssignedBy",
foreignField: "_id",
as: "taskAssignedBy",
},
},
{
$lookup: {
from: "salescoordinators",
localField: "taskAssignedTo",
foreignField: "_id",
as: "taskAssignedTo",
},
},
{
$match: {
...(TMname && {
"taskAssignedBy.name": { $regex: TMname, $options: "i" },
}),
...(SCname && {
"taskAssignedTo.name": { $regex: SCname, $options: "i" },
}),
},
},
{ $unwind: "$taskAssignedBy" },
{ $unwind: "$taskAssignedTo" },
{ $sort: { createdAt: -1 } },
{ $skip: skip },
{ $limit: limit },
{
$project: {
taskId: 1,
task: 1,
taskStatus: 1,
taskPriority: 1,
taskDueDate: 1,
note: 1,
createdAt: 1,
"taskAssignedBy.name": 1,
"taskAssignedTo.name": 1,
},
},
]);
// Total count
const totalTasks = await Task.countDocuments(matchStage);
res.status(200).json({
success: true,
data: tasks,
pagination: {
total: totalTasks,
page: parseInt(page),
show: limit,
pages: Math.ceil(totalTasks / limit),
},
});
} catch (error) {
console.error("Error fetching tasks:", error);
res.status(500).json({
success: false,
message: "Server error while fetching tasks",
error: error.message,
});
}
};

View File

@ -7,6 +7,7 @@ import {
getAllTasksByStatus, getAllTasksByStatus,
getTasksByDates, getTasksByDates,
getTodaysTasks, getTodaysTasks,
getTasks,
} from "./TaskController.js"; } from "./TaskController.js";
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js"; import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js"; import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
@ -38,4 +39,10 @@ router.get(
authorizeRoles("admin"), authorizeRoles("admin"),
getTodaysTasks getTodaysTasks
); );
router.get(
"/tasks",
isAuthenticatedUser,
authorizeRoles("admin"),
getTasks
);
export default router; export default router;

View File

@ -1149,3 +1149,132 @@ export const saveFCMTokenForUser = async (req, res) => {
res.status(500).send("Internal Server Error"); res.status(500).send("Internal Server Error");
} }
}; };
export const generatePrincipalDistributorReport = async (req, res) => {
try {
// Fetch users with role 'principal-distributor'
const distributors = await User.find({ role: "principal-Distributor" })
.select("uniqueId SBU name email phone")
.populate("mappedby", "name") // Territory Manager
.populate("mappedbySC", "name") // Sales Coordinator
.lean();
if (!distributors.length) {
return res
.status(404)
.json({ message: "No principal distributors found." });
}
// Prepare data for the sheet
const distributorData = [];
for (const distributor of distributors) {
// Fetch shipping addresses associated with the distributor (both default and non-default)
const addresses = await ShippingAddress.find({
user: distributor._id,
}).lean();
// Determine the address to use (first default or first address if none default)
let selectedAddress = null;
// Find the first default address, otherwise use the first address
const defaultAddress = addresses.find(
(address) => address.isDefault === true
);
if (defaultAddress) {
selectedAddress = defaultAddress;
} else {
selectedAddress = addresses[0]; // If no default, take the first address
}
// If we have a valid address, proceed with adding it to the report
if (selectedAddress) {
const addressDetails = {
"Unique ID": distributor.uniqueId,
SBU: distributor.SBU,
"Principal Distributor Name": distributor.name,
Email: distributor.email,
"Mobile Number": distributor.phone,
"Trade Name": selectedAddress.tradeName || "N/A",
"PAN Number": selectedAddress.panNumber || "N/A",
"GST Number": selectedAddress.gstNumber || "N/A",
State: selectedAddress.state || "N/A",
City: selectedAddress.city || "N/A",
Street: selectedAddress.street || "N/A",
Pincode: selectedAddress.postalCode || "N/A",
"Territory Manager": distributor.mappedby?.name || "N/A",
"Sales Coordinator": distributor.mappedbySC?.name || "N/A",
};
distributorData.push(addressDetails);
}
}
// Define headers for the worksheet
const headers = [
[
"Unique ID",
"SBU",
"Principal Distributor Name",
"Email",
"Mobile Number",
"Trade Name",
"PAN Number",
"GST Number",
"State",
"City",
"Street",
"Pincode",
"Territory Manager",
"Sales Coordinator",
],
];
// Create worksheet with headers
const worksheet = XLSX.utils.aoa_to_sheet(headers);
// Append distributor data below headers
XLSX.utils.sheet_add_json(worksheet, distributorData, {
skipHeader: true,
origin: "A2",
});
// Set column widths based on content length
const columnWidths = headers[0].map((header, index) => {
let maxLength = header.length;
for (const row of distributorData) {
const cellContent = row[header]?.toString() || "";
maxLength = Math.max(maxLength, cellContent.length);
}
return { wch: maxLength + 2 };
});
worksheet["!cols"] = columnWidths;
// Create workbook and append worksheet
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(
workbook,
worksheet,
"Principal_Distributor_Report"
);
// Write workbook to a buffer
const excelBuffer = XLSX.write(workbook, {
bookType: "xlsx",
type: "buffer",
});
// Send Excel file as response
res.setHeader(
"Content-Type",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
res.setHeader(
"Content-Disposition",
"attachment; filename=Principal_Distributor_Report.xlsx"
);
res.send(excelBuffer);
} catch (error) {
console.error("Error generating report:", error);
res.status(500).json({ message: "Failed to generate report" });
}
};

View File

@ -23,6 +23,7 @@ import {
getAllPrincipalDistributorbyscId, getAllPrincipalDistributorbyscId,
saveFCMTokenForUser, saveFCMTokenForUser,
getAllPD, getAllPD,
generatePrincipalDistributorReport,
} from "./userController.js"; } from "./userController.js";
import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
@ -46,6 +47,13 @@ router
authorizeRoles("admin"), authorizeRoles("admin"),
uploadPrincipaldistributors uploadPrincipaldistributors
); );
router
.route("/principaldistributor/download-report")
.get(
isAuthenticatedUser,
authorizeRoles("admin"),
generatePrincipalDistributorReport
);
//mapping start //mapping start
router router
.route("/admin/users") .route("/admin/users")