GWM : Admin dashboard api
This commit is contained in:
parent
f0db22f2bd
commit
5c4bc028ba
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
const { Sequelize, Op } = require("sequelize");
|
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) {
|
function getQuarter(date) {
|
||||||
const month = date.getMonth() + 1;
|
const month = date.getMonth() + 1;
|
||||||
@ -154,38 +154,46 @@ exports.getEstablishmentDashboard = async (req, res) => {
|
|||||||
|
|
||||||
exports.adminDashboard = async (req, res) => {
|
exports.adminDashboard = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { quarter, year } = req.query; // e.g., Q1, 2025
|
let { quarter, year } = req.query;
|
||||||
|
|
||||||
// --- Summary Counts ---
|
// if quarter/year not passed → take latest open config
|
||||||
const [
|
if (!quarter || !year) {
|
||||||
totalEstablishments,
|
const lastConfig = await QuarterlyWindowsConfiguration.findOne({
|
||||||
submittedCount,
|
order: [
|
||||||
approvedCount,
|
['year', 'DESC'],
|
||||||
rejectedCount,
|
['quarter', 'DESC']
|
||||||
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
|
if (lastConfig) {
|
||||||
const startedEstIds = await Submission.findAll({
|
quarter = lastConfig.quarter;
|
||||||
attributes: [[Sequelize.fn("DISTINCT", Sequelize.col("establishment_id")), "id"]],
|
year = lastConfig.year;
|
||||||
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 = {};
|
const whereCond = {};
|
||||||
if (quarter) whereCond.quarter = quarter;
|
if (quarter) whereCond.quarter = quarter;
|
||||||
if (year) whereCond.year = year;
|
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({
|
const recentSubmissions = await Submission.findAll({
|
||||||
where: whereCond,
|
where: whereCond,
|
||||||
include: [
|
include: [
|
||||||
@ -197,11 +205,7 @@ exports.adminDashboard = async (req, res) => {
|
|||||||
{ model: Emirate, as: "establishment_emirate", attributes: ["name"] },
|
{ model: Emirate, as: "establishment_emirate", attributes: ["name"] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{ model: EstablishmentUser, as: "created_user", attributes: ["name"] },
|
||||||
model: EstablishmentUser,
|
|
||||||
as: "created_user",
|
|
||||||
attributes: ["name"],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
attributes: {
|
attributes: {
|
||||||
include: [
|
include: [
|
||||||
@ -219,9 +223,10 @@ exports.adminDashboard = async (req, res) => {
|
|||||||
limit: 10,
|
limit: 10,
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Send Response ---
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
status: "success",
|
status: "success",
|
||||||
|
selected_quarter: quarter,
|
||||||
|
selected_year: year,
|
||||||
summary: {
|
summary: {
|
||||||
total_establishments: totalEstablishments,
|
total_establishments: totalEstablishments,
|
||||||
submitted: submittedCount,
|
submitted: submittedCount,
|
||||||
@ -232,8 +237,97 @@ exports.adminDashboard = async (req, res) => {
|
|||||||
},
|
},
|
||||||
recent_submissions: recentSubmissions,
|
recent_submissions: recentSubmissions,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return res.status(500).json({ status: "failed", message: err.message });
|
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 });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
@ -24,6 +24,7 @@ exports.testEmail = async (req, res) => {
|
|||||||
}
|
}
|
||||||
await sendEmailService('gowthamceline46@gmail.com', 'establishment_user_creation_to_user', placeHolderData);
|
await sendEmailService('gowthamceline46@gmail.com', 'establishment_user_creation_to_user', placeHolderData);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.createEstablishment = async (req, res) => {
|
exports.createEstablishment = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
@ -634,16 +635,16 @@ exports.forgotPasswordVerifyOTP = async (req, res) => {
|
|||||||
|
|
||||||
const user = await EstablishmentUser.findOne({ where: { email: registered_email } });
|
const user = await EstablishmentUser.findOne({ where: { email: registered_email } });
|
||||||
if (!user || !user.reset_otp)
|
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
|
// Check OTP expiry
|
||||||
if (new Date() > new Date(user.reset_otp_expires_at))
|
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
|
// Compare OTP
|
||||||
const isOtpValid = await bcrypt.compare(otp, user.reset_otp);
|
const isOtpValid = await bcrypt.compare(otp, user.reset_otp);
|
||||||
if (!isOtpValid)
|
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
|
// Update password
|
||||||
const hashedPassword = await bcrypt.hash(password, 10);
|
const hashedPassword = await bcrypt.hash(password, 10);
|
||||||
|
|||||||
@ -2236,12 +2236,12 @@ router.get("/establishment_dashboard",[verifySignature, verifyToken],dashboardCo
|
|||||||
* parameters:
|
* parameters:
|
||||||
* - in: query
|
* - in: query
|
||||||
* name: quarter
|
* name: quarter
|
||||||
* required: true
|
* required: false
|
||||||
* schema:
|
* schema:
|
||||||
* type: string
|
* type: string
|
||||||
* - in: query
|
* - in: query
|
||||||
* name: year
|
* name: year
|
||||||
* required: true
|
* required: false
|
||||||
* schema:
|
* schema:
|
||||||
* type: integer
|
* type: integer
|
||||||
* responses:
|
* responses:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user