Added some api's : GWM
This commit is contained in:
parent
d96e82f150
commit
0915843ef4
52
app/controllers/config.controller.js
Normal file
52
app/controllers/config.controller.js
Normal file
@ -0,0 +1,52 @@
|
||||
const db = require("../models");
|
||||
const SubmissionDeadline = db.SubmissionDeadline;
|
||||
|
||||
|
||||
|
||||
// POST /api/submission-deadlines
|
||||
exports.updateDeadlineData = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
deadline_days_after_quarter_end,
|
||||
grace_periods_days_after_deadline,
|
||||
first_reminder_days_before_deadline,
|
||||
second_reminder_days_before_deadline,
|
||||
created_by,
|
||||
updated_by,
|
||||
} = req.body;
|
||||
|
||||
// Try to find existing record (id=1)
|
||||
let existing = await SubmissionDeadline.findByPk(1);
|
||||
|
||||
if (existing) {
|
||||
// Update
|
||||
await existing.update({
|
||||
deadline_days_after_quarter_end,
|
||||
grace_periods_days_after_deadline,
|
||||
first_reminder_days_before_deadline,
|
||||
second_reminder_days_before_deadline,
|
||||
updated_at: new Date(),
|
||||
updated_by,
|
||||
});
|
||||
|
||||
res.status(200).json({ status: "success", message: "Deadline updated successfully", data: existing });
|
||||
} else {
|
||||
// Create new (set id = 1 manually)
|
||||
const newRecord = await SubmissionDeadline.create({
|
||||
id: 1,
|
||||
deadline_days_after_quarter_end,
|
||||
grace_periods_days_after_deadline,
|
||||
first_reminder_days_before_deadline,
|
||||
second_reminder_days_before_deadline,
|
||||
created_at: new Date(),
|
||||
created_by,
|
||||
});
|
||||
|
||||
res.status(201).json({ status: "success", message: "Deadline created successfully", data: newRecord });
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ status: "failed", message: err.message });
|
||||
}
|
||||
};
|
||||
140
app/controllers/dashboard.controller.js
Normal file
140
app/controllers/dashboard.controller.js
Normal file
@ -0,0 +1,140 @@
|
||||
const db = require("../models");
|
||||
const { Op } = require("sequelize");
|
||||
|
||||
const Submission = db.Submission;
|
||||
const SubmissionDeadline = db.SubmissionDeadline;
|
||||
|
||||
function getQuarter(date) {
|
||||
const month = date.getMonth() + 1;
|
||||
if (month >= 4 && month <= 6) return "Q1";
|
||||
if (month >= 7 && month <= 9) return "Q2";
|
||||
if (month >= 10 && month <= 12) return "Q3";
|
||||
return "Q4"; // Jan-Mar
|
||||
}
|
||||
|
||||
function getQuarterDates(quarter, year) {
|
||||
switch (quarter) {
|
||||
case "Q1":
|
||||
return { start: new Date(year, 3, 1), end: new Date(year, 5, 30) };
|
||||
case "Q2":
|
||||
return { start: new Date(year, 6, 1), end: new Date(year, 8, 30) };
|
||||
case "Q3":
|
||||
return { start: new Date(year, 9, 1), end: new Date(year, 11, 31) };
|
||||
case "Q4":
|
||||
return { start: new Date(year, 0, 1), end: new Date(year, 2, 31) };
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function getPrevCurrNextQuarter(date) {
|
||||
const month = date.getMonth() + 1; // 1-12
|
||||
const year = date.getFullYear();
|
||||
const quarters = ["Q1", "Q2", "Q3", "Q4"];
|
||||
|
||||
// map month -> index: 0=Q1(Apr-Jun),1=Q2(Jul-Sep),2=Q3(Oct-Dec),3=Q4(Jan-Mar)
|
||||
const getQuarterIndex = (m) => {
|
||||
if (m >= 4 && m <= 6) return 0; // Apr-Jun -> Q1
|
||||
if (m >= 7 && m <= 9) return 1; // Jul-Sep -> Q2
|
||||
if (m >= 10 && m <= 12) return 2; // Oct-Dec -> Q3
|
||||
return 3; // Jan-Mar -> Q4
|
||||
};
|
||||
|
||||
const currentIndex = getQuarterIndex(month);
|
||||
const currentQuarter = quarters[currentIndex];
|
||||
|
||||
const previousIndex = (currentIndex - 1 + 4) % 4;
|
||||
const nextIndex = (currentIndex + 1) % 4;
|
||||
|
||||
const previousQuarter = quarters[previousIndex];
|
||||
const nextQuarter = quarters[nextIndex];
|
||||
|
||||
const previousQuarterYear = (currentIndex === 3) ? year - 1 : year;
|
||||
const nextQuarterYear = (currentIndex === 2) ? year + 1 : year;
|
||||
|
||||
return {
|
||||
previous_quarter: previousQuarter,
|
||||
previous_quarter_year: previousQuarterYear,
|
||||
current_quarter: currentQuarter,
|
||||
current_quarter_year: year,
|
||||
next_quarter: nextQuarter,
|
||||
next_quarter_year: nextQuarterYear,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
exports.getEstablishmentDashboard = async (req, res) => {
|
||||
try {
|
||||
const establishment_id = req.query.establishment_id;
|
||||
if (!establishment_id) {
|
||||
return res.status(400).json({ status: "failed", message: "establishment_id required" });
|
||||
}
|
||||
|
||||
const today = new Date();
|
||||
const quarters = getPrevCurrNextQuarter(today);
|
||||
|
||||
// Last 5 submissions
|
||||
const submission_history = await Submission.findAll({
|
||||
where: { establishment_id },
|
||||
order: [["created_at", "DESC"]],
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
// Submission status for current quarter
|
||||
const currentQuarterDates = getQuarterDates(quarters.current_quarter, quarters.current_quarter_year);
|
||||
|
||||
const currentSubmission = await Submission.findOne({
|
||||
where: {
|
||||
establishment_id,
|
||||
quarter: quarters.current_quarter,
|
||||
year: quarters.current_quarter_year,
|
||||
},
|
||||
order: [["created_at", "DESC"]],
|
||||
});
|
||||
|
||||
// Get submission deadline (assuming only one row)
|
||||
const deadline = await SubmissionDeadline.findByPk(1);
|
||||
|
||||
let nextDeadline = null;
|
||||
let submissionStatus = "Pending";
|
||||
|
||||
if (deadline) {
|
||||
const quarterEnd = currentQuarterDates.end;
|
||||
const deadlineDate = new Date(quarterEnd);
|
||||
deadlineDate.setDate(deadlineDate.getDate() + deadline.deadline_days_after_quarter_end);
|
||||
|
||||
nextDeadline = deadlineDate;
|
||||
|
||||
if (currentSubmission) {
|
||||
submissionStatus = "Submitted";
|
||||
}
|
||||
}
|
||||
|
||||
let lastSubmissionInfo = null;
|
||||
if (submission_history.length > 0) {
|
||||
const last = submission_history[0];
|
||||
lastSubmissionInfo = {
|
||||
quarter: last.quarter,
|
||||
year: last.year,
|
||||
submitted_on: last.created_at,
|
||||
};
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
status: "success",
|
||||
data: {
|
||||
...quarters,
|
||||
submission_status: submissionStatus,
|
||||
next_deadline: nextDeadline,
|
||||
last_submission: lastSubmissionInfo,
|
||||
submission_history,
|
||||
},
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ status: "failed", message: err.message });
|
||||
}
|
||||
};
|
||||
@ -6,13 +6,13 @@ const EstablishmentUser = db.establishment_user;
|
||||
// Create Establishment + linked user
|
||||
exports.createEstablishment = async (req, res) => {
|
||||
try {
|
||||
|
||||
const { establishment_code, factory_name, email, permanent_factory_code, industry_code, license_number, isic_code, emirate, total_employment, establishment_user, } = req.body;
|
||||
|
||||
const { establishment_code, factory_name, email, permanent_factory_code, industry_code, license_number, isic_code, emirate, emirati_male,emirati_female,non_emirati_male,non_emirati_female,total_emirati,total_employees, establishment_user, } = req.body;
|
||||
|
||||
if ( !establishment_code || !factory_name || !email || !establishment_user?.name || !establishment_user?.email || !establishment_user?.password )
|
||||
{
|
||||
res.status(400).send({'status':"failed",'message':"Missing required fields",'data': "" });
|
||||
}
|
||||
// if ( !establishment_code || !factory_name || !email || !establishment_user?.name || !establishment_user?.email || !establishment_user?.password )
|
||||
// {
|
||||
// res.status(400).send({'status':"failed",'message':"Missing required fields",'data': "" });
|
||||
// }
|
||||
|
||||
// Create Establishment
|
||||
const establishment = await Establishment.create({
|
||||
@ -24,22 +24,22 @@ exports.createEstablishment = async (req, res) => {
|
||||
license_number,
|
||||
isic_code,
|
||||
emirate,
|
||||
total_employment,
|
||||
emirati_male,emirati_female,non_emirati_male,non_emirati_female,total_emirati,total_employees,
|
||||
});
|
||||
|
||||
// Hash password for user
|
||||
const hashedPassword = await bcrypt.hash(establishment_user.password, 10);
|
||||
// const hashedPassword = await bcrypt.hash(establishment_user.password, 10);
|
||||
|
||||
// Create related Establishment User
|
||||
const user = await EstablishmentUser.create({
|
||||
establishment_id: establishment.id,
|
||||
name: establishment_user.name,
|
||||
email: establishment_user.email,
|
||||
password: hashedPassword,
|
||||
});
|
||||
// const user = await EstablishmentUser.create({
|
||||
// establishment_id: establishment.id,
|
||||
// name: establishment_user.name,
|
||||
// email: establishment_user.email,
|
||||
// password: hashedPassword,
|
||||
// });
|
||||
|
||||
|
||||
res.status(201).send({'status':"success",'message':"Establishment and linked user created successfully",'data': { establishment, user } });
|
||||
res.status(201).send({'status':"success",'message':"Establishment and linked user created successfully",'data': { establishment } });
|
||||
|
||||
} catch (err) {
|
||||
res.status(500).send({'status':"failed",'message':err.message });
|
||||
|
||||
@ -22,6 +22,7 @@ db.ZeroTargetReasonMaster = require("./zeroTargetReason.model")(sequelize, DataT
|
||||
db.Submission = require("./submission.model")(sequelize, DataTypes);
|
||||
db.SubmissionProduct = require("./submissionProduct.model")(sequelize, DataTypes);
|
||||
db.UnitMaster = require("./UnitMaster.model")(sequelize, DataTypes);
|
||||
db.SubmissionDeadline = require("./submissionDeadline.model")(sequelize, DataTypes);
|
||||
|
||||
|
||||
// Associations
|
||||
|
||||
@ -17,12 +17,6 @@ module.exports = (sequelize, DataTypes) => {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
emirati_male: DataTypes.INTEGER,
|
||||
emirati_female: DataTypes.INTEGER,
|
||||
non_emirati_male: DataTypes.INTEGER,
|
||||
non_emirati_female: DataTypes.INTEGER,
|
||||
total_emirati: DataTypes.INTEGER,
|
||||
total_employees: DataTypes.INTEGER,
|
||||
edit_request: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: false,
|
||||
|
||||
51
app/models/submissionDeadline.model.js
Normal file
51
app/models/submissionDeadline.model.js
Normal file
@ -0,0 +1,51 @@
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const SubmissionDeadline = sequelize.define(
|
||||
"submission_deadlines",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
deadline_days_after_quarter_end: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
grace_periods_days_after_deadline: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
first_reminder_days_before_deadline: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
second_reminder_days_before_deadline: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
created_at: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: DataTypes.NOW,
|
||||
},
|
||||
updated_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "submission_deadlines",
|
||||
timestamps: false,
|
||||
}
|
||||
);
|
||||
|
||||
return SubmissionDeadline;
|
||||
};
|
||||
|
||||
@ -13,6 +13,8 @@ const variationReasonMasterController = require("../controllers/variationReasonM
|
||||
const zeroTargetReasonMasterController = require("../controllers/zeroTargetReasonMaster.controller");
|
||||
const unitMasterController = require("../controllers/unitMasterController");
|
||||
const submissionController = require("../controllers/submission.controller");
|
||||
const ConfigController = require("../controllers/config.controller");
|
||||
const dashboardController = require("../controllers/dashboard.controller");
|
||||
|
||||
|
||||
|
||||
@ -41,6 +43,10 @@ const submissionController = require("../controllers/submission.controller");
|
||||
* description: Manage Unit Master entries
|
||||
* - name: Submissions
|
||||
* description: Manage establishment submissions
|
||||
* - name: Config
|
||||
* description: Sumbission config
|
||||
* - name: Dashboard
|
||||
* description:
|
||||
*/
|
||||
|
||||
|
||||
@ -1664,4 +1670,110 @@ router.put("/approveOrRejectSubmission/:id",[verifySignature, verifyToken], subm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/submission_deadlines:
|
||||
* post:
|
||||
* summary: Create or update submission deadline configuration (only one record allowed)
|
||||
* tags: [Config]
|
||||
* security:
|
||||
* - appSignature: []
|
||||
* - bearerAuth: []
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* deadline_days_after_quarter_end:
|
||||
* type: integer
|
||||
* example: 30
|
||||
* grace_periods_days_after_deadline:
|
||||
* type: integer
|
||||
* example: 7
|
||||
* first_reminder_days_before_deadline:
|
||||
* type: integer
|
||||
* example: 5
|
||||
* second_reminder_days_before_deadline:
|
||||
* type: integer
|
||||
* example: 2
|
||||
* created_by:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* updated_by:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Deadline data updated successfully
|
||||
* 201:
|
||||
* description: Deadline data created successfully
|
||||
* 500:
|
||||
* description: Server error
|
||||
*/
|
||||
router.post("/submission_deadlines",[verifySignature, verifyToken], ConfigController.updateDeadlineData);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/establishment_dashboard:
|
||||
* get:
|
||||
* summary: Get dashboard data for establishment user
|
||||
* tags: [Dashboard]
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: establishment_id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* description: ID of the establishment
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Dashboard data fetched successfully
|
||||
* 400:
|
||||
* description: Bad request
|
||||
* 403:
|
||||
* description: Invalid signature
|
||||
* 401:
|
||||
* description: Unauthorized
|
||||
* 500:
|
||||
* description: Server error
|
||||
*/
|
||||
router.get("/establishment_dashboard",dashboardController.getEstablishmentDashboard);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user