GWM : Admin dashboard api

This commit is contained in:
Gowtham M 2025-11-06 11:30:17 +05:30
parent f0db22f2bd
commit 5c4bc028ba
3 changed files with 133 additions and 38 deletions

View File

@ -1,6 +1,6 @@
const { Sequelize, Op } = require("sequelize");
const { Establishment, Submission, Emirate, EstablishmentUser, SubmissionProduct, SubmissionDeadline } = require("../models");
const { Establishment, Submission, Emirate, EstablishmentUser, SubmissionProduct, SubmissionDeadline, QuarterlyWindowsConfiguration } = require("../models");
function getQuarter(date) {
const month = date.getMonth() + 1;
@ -154,38 +154,46 @@ exports.getEstablishmentDashboard = async (req, res) => {
exports.adminDashboard = async (req, res) => {
try {
const { quarter, year } = req.query; // e.g., Q1, 2025
let { quarter, year } = req.query;
// --- Summary Counts ---
const [
totalEstablishments,
submittedCount,
approvedCount,
rejectedCount,
pendingCount
] = await Promise.all([
Establishment.count(),
Submission.count(),
Submission.count({ where: { status: "Approved" } }),
Submission.count({ where: { status: "Rejected" } }),
Submission.count({ where: { status: "Pending" } }),
]);
// if quarter/year not passed → take latest open config
if (!quarter || !year) {
const lastConfig = await QuarterlyWindowsConfiguration.findOne({
order: [
['year', 'DESC'],
['quarter', 'DESC']
]
});
// Not Started = total establishments - those that have any submission
const startedEstIds = await Submission.findAll({
attributes: [[Sequelize.fn("DISTINCT", Sequelize.col("establishment_id")), "id"]],
raw: true,
});
const startedIds = startedEstIds.map(e => e.id);
const notStartedCount = await Establishment.count({
where: { id: { [Op.notIn]: startedIds } },
});
if (lastConfig) {
quarter = lastConfig.quarter;
year = lastConfig.year;
}
}
// --- Recent 10 submissions for given quarter & year ---
const whereCond = {};
if (quarter) whereCond.quarter = quarter;
if (year) whereCond.year = year;
const totalEstablishments = await Establishment.count();
const submittedCount = await Submission.count({ where: whereCond });
const approvedCount = await Submission.count({ where: { ...whereCond, status: "Approved" } });
const rejectedCount = await Submission.count({ where: { ...whereCond, status: "Rejected" } });
const pendingCount = await Submission.count({ where: { ...whereCond, status: "Pending" } });
// only when query param not used → not started count
let notStartedCount = 0;
if (!req.query.quarter && !req.query.year) {
const startedEstIds = await Submission.findAll({
attributes: [[Sequelize.fn("DISTINCT", Sequelize.col("establishment_id")), "id"]],
raw: true,
});
const startedIds = startedEstIds.map(e => e.id);
notStartedCount = await Establishment.count({
where: { id: { [Op.notIn]: startedIds } },
});
}
const recentSubmissions = await Submission.findAll({
where: whereCond,
include: [
@ -197,11 +205,7 @@ exports.adminDashboard = async (req, res) => {
{ model: Emirate, as: "establishment_emirate", attributes: ["name"] },
],
},
{
model: EstablishmentUser,
as: "created_user",
attributes: ["name"],
},
{ model: EstablishmentUser, as: "created_user", attributes: ["name"] },
],
attributes: {
include: [
@ -219,9 +223,10 @@ exports.adminDashboard = async (req, res) => {
limit: 10,
});
// --- Send Response ---
return res.status(200).json({
status: "success",
selected_quarter: quarter,
selected_year: year,
summary: {
total_establishments: totalEstablishments,
submitted: submittedCount,
@ -232,8 +237,97 @@ exports.adminDashboard = async (req, res) => {
},
recent_submissions: recentSubmissions,
});
} catch (err) {
console.error(err);
return res.status(500).json({ status: "failed", message: err.message });
}
};
};
// exports.adminDashboard = async (req, res) => {
// try {
// const { quarter, year } = req.query; // e.g., Q1, 2025
// // --- Summary Counts ---
// const [
// totalEstablishments,
// submittedCount,
// approvedCount,
// rejectedCount,
// pendingCount
// ] = await Promise.all([
// Establishment.count(),
// Submission.count(),
// Submission.count({ where: { status: "Approved" } }),
// Submission.count({ where: { status: "Rejected" } }),
// Submission.count({ where: { status: "Pending" } }),
// ]);
// // Not Started = total establishments - those that have any submission
// const startedEstIds = await Submission.findAll({
// attributes: [[Sequelize.fn("DISTINCT", Sequelize.col("establishment_id")), "id"]],
// raw: true,
// });
// const startedIds = startedEstIds.map(e => e.id);
// const notStartedCount = await Establishment.count({
// where: { id: { [Op.notIn]: startedIds } },
// });
// // --- Recent 10 submissions for given quarter & year ---
// const whereCond = {};
// if (quarter) whereCond.quarter = quarter;
// if (year) whereCond.year = year;
// const recentSubmissions = await Submission.findAll({
// where: whereCond,
// include: [
// {
// model: Establishment,
// as: "establishment",
// attributes: ["factory_name"],
// include: [
// { model: Emirate, as: "establishment_emirate", attributes: ["name"] },
// ],
// },
// {
// model: EstablishmentUser,
// as: "created_user",
// attributes: ["name"],
// },
// ],
// attributes: {
// include: [
// [
// Sequelize.literal(`(
// SELECT COUNT(*)
// FROM submission_products AS sp
// WHERE sp.submission_id = submission.id
// )`),
// "product_count",
// ],
// ],
// },
// order: [["created_at", "DESC"]],
// limit: 10,
// });
// // --- Send Response ---
// return res.status(200).json({
// status: "success",
// summary: {
// total_establishments: totalEstablishments,
// submitted: submittedCount,
// approved: approvedCount,
// rejected: rejectedCount,
// pending: pendingCount,
// not_started: notStartedCount,
// },
// recent_submissions: recentSubmissions,
// });
// } catch (err) {
// console.error(err);
// return res.status(500).json({ status: "failed", message: err.message });
// }
// };

View File

@ -24,6 +24,7 @@ exports.testEmail = async (req, res) => {
}
await sendEmailService('gowthamceline46@gmail.com', 'establishment_user_creation_to_user', placeHolderData);
};
exports.createEstablishment = async (req, res) => {
try {
const {
@ -634,16 +635,16 @@ exports.forgotPasswordVerifyOTP = async (req, res) => {
const user = await EstablishmentUser.findOne({ where: { email: registered_email } });
if (!user || !user.reset_otp)
return res.status(404).json({ status: "failed", message: "OTP not found or invalid user" });
return res.status(404).json({ status: "failed", message: "verification code not found or invalid user" });
// Check OTP expiry
if (new Date() > new Date(user.reset_otp_expires_at))
return res.status(400).json({ status: "failed", message: "OTP expired" });
return res.status(400).json({ status: "failed", message: "Verification code has expired. Please request a new one" });
// Compare OTP
const isOtpValid = await bcrypt.compare(otp, user.reset_otp);
if (!isOtpValid)
return res.status(400).json({ status: "failed", message: "Invalid OTP" });
return res.status(400).json({ status: "failed", message: "Invalid verification code" });
// Update password
const hashedPassword = await bcrypt.hash(password, 10);

View File

@ -2236,12 +2236,12 @@ router.get("/establishment_dashboard",[verifySignature, verifyToken],dashboardCo
* parameters:
* - in: query
* name: quarter
* required: true
* required: false
* schema:
* type: string
* - in: query
* name: year
* required: true
* required: false
* schema:
* type: integer
* responses: