From 2ef1dc8be4e65565c75f14455a542a503086d778 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Dec 2025 12:55:37 +0530 Subject: [PATCH 01/12] Added getAllManufacturingIndex API --- .../manufacturingIPI.controller.js | 43 ++++++++++++ app/models/manufacturingIPI.model.js | 67 +++++++++++++++++++ app/routes/routes.js | 21 ++++++ 3 files changed, 131 insertions(+) create mode 100644 app/controllers/manufacturingIPI.controller.js create mode 100644 app/models/manufacturingIPI.model.js diff --git a/app/controllers/manufacturingIPI.controller.js b/app/controllers/manufacturingIPI.controller.js new file mode 100644 index 0000000..8d80711 --- /dev/null +++ b/app/controllers/manufacturingIPI.controller.js @@ -0,0 +1,43 @@ +const db = require("../models"); +const ManufacturingIpi = db.ManufacturingIpi; +const logger = require("../services/logger"); + +const formatDecimal = (value) => { + if (value === null || value === undefined || value === '' || value === 0) { + return "0.00"; + } + return parseFloat(value).toFixed(2); +}; + +exports.getAllManufacturingIndexDetails = async (req, res) => { + try { + const rawData = await ManufacturingIpi.findAll({ + order: [["created_at", "DESC"]], + }); + + // Format decimal fields + const data = rawData.map(item => { + const plainItem = item.get({ plain: true }); + return { + ...plainItem, + total_weight: formatDecimal(plainItem.total_weight), + weighted_index_sum: formatDecimal(plainItem.weighted_index_sum), + manufacturing_index: formatDecimal(plainItem.manufacturing_index), + mom_change: formatDecimal(plainItem.mom_change), + yoy_change: formatDecimal(plainItem.yoy_change), + }; + }); + + logger.info(`getAllManufacturingIndexDetails API: Fetched ${data.length} manufacturing index records successfully`); + + res.status(200).send({ + status: "success", + message: "Fetched successfully", + data: data + }); + + } catch (error) { + logger.error(`getAllManufacturingIndexDetails API: ${error.message}`); + res.status(500).send({ status: "failed", message: "Internal server error" }); + } +}; \ No newline at end of file diff --git a/app/models/manufacturingIPI.model.js b/app/models/manufacturingIPI.model.js new file mode 100644 index 0000000..a16a8ef --- /dev/null +++ b/app/models/manufacturingIPI.model.js @@ -0,0 +1,67 @@ +module.exports = (sequelize, DataTypes) => { + const ManufacturingIpi = sequelize.define("manufacturing_ipi", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + year: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month_name: { + type: DataTypes.STRING, + allowNull: false, + }, + reference_date: { + type: DataTypes.DATEONLY, + allowNull: false, + }, + total_weight: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + weighted_index_sum: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + manufacturing_index: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + mom_change: { + type: DataTypes.DECIMAL(12, 2), + allowNull: true, + }, + yoy_change: { + type: DataTypes.DECIMAL(12, 2), + allowNull: true, + }, + status: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: 'Completed', + }, + generated_on: { + type: DataTypes.DATE, + allowNull: false, + }, + created_at: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, { + tableName: "manufacturing_ipi", + timestamps: false, + }); + + return ManufacturingIpi; +}; \ No newline at end of file diff --git a/app/routes/routes.js b/app/routes/routes.js index 335299b..5b984bf 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -17,6 +17,7 @@ const ConfigController = require("../controllers/config.controller"); const dashboardController = require("../controllers/dashboard.controller"); const notificationTemplateController = require("../controllers/notificationTemplate.controller"); const quarterlyWindowsController = require("../controllers/quarterlyWindowsConfiguration.controller"); +const ManufacturingIpiController = require("../controllers/manufacturingIPI.controller") const fs = require("fs"); const path = require("path"); const multer = require("multer"); @@ -2992,6 +2993,26 @@ router.get("/establishment/download-sample-file",[verifySignature, verifyToken], */ router.get("/unit_master_download_sample_file",[verifySignature, verifyToken], unitMasterController.downloadUnitMasterFile); +/** + * @swagger + * /api/manufacturing/getManufacturingIndex: + * get: + * summary: Get all Manufacturing IPI Index list + * tags: [ManufacturingIpi] + * security: + * - appSignature: [] + * - CSRF: [] + * cookieAuth: [] # or bearerAuth: [] if you use Authorization header + * responses: + * 200: + * description: ManufacturingIpi Index details fetched successfully + * 404: + * description: Not found + * 500: + * description: Server error + */ +router.get("/manufacturing/getManufacturingIndex",[verifySignature, verifyToken], ManufacturingIpiController.getAllManufacturingIndexDetails); + From b0c6d95a6974c3edd5215936a4221010cd7c3a4b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Dec 2025 13:07:12 +0530 Subject: [PATCH 02/12] csrf token checking --- app/routes/routes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/routes/routes.js b/app/routes/routes.js index 5b984bf..3f0bcd1 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -2998,10 +2998,9 @@ router.get("/unit_master_download_sample_file",[verifySignature, verifyToken], u * /api/manufacturing/getManufacturingIndex: * get: * summary: Get all Manufacturing IPI Index list - * tags: [ManufacturingIpi] + * tags: [ManufacturingIPI] * security: * - appSignature: [] - * - CSRF: [] * cookieAuth: [] # or bearerAuth: [] if you use Authorization header * responses: * 200: From 454f97e84cb26636b1b6a3692b3d57673f66746b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Dec 2025 15:19:28 +0530 Subject: [PATCH 03/12] bug fixed --- app/models/index.js | 1 + app/routes/routes.js | 1 + 2 files changed, 2 insertions(+) diff --git a/app/models/index.js b/app/models/index.js index 2062210..0acb42c 100644 --- a/app/models/index.js +++ b/app/models/index.js @@ -29,6 +29,7 @@ db.EstablishmentPasswordResetRequest = require("./establishmentPasswordResetRequ db.Emirate = require("./emirate.model")(sequelize, DataTypes); db.CityTown = require("./cityTown.model")(sequelize, DataTypes); db.SubmissionHistory = require("./submissionHistory.model")(sequelize, DataTypes); +db.ManufacturingIpi = require("./manufacturingIPI.model.js")(sequelize, DataTypes); // Associations db.Establishment.hasMany(db.EstablishmentUser, { diff --git a/app/routes/routes.js b/app/routes/routes.js index 3f0bcd1..e017150 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -3001,6 +3001,7 @@ router.get("/unit_master_download_sample_file",[verifySignature, verifyToken], u * tags: [ManufacturingIPI] * security: * - appSignature: [] + * - CSRF: [] * cookieAuth: [] # or bearerAuth: [] if you use Authorization header * responses: * 200: From 8ce1d8b8e4ccfd8ac1e545fc4366118400dd3c3e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Dec 2025 16:46:10 +0530 Subject: [PATCH 04/12] Added API: getManufacturingMonthlyOverview --- .../manufacturingIPI.controller.js | 150 ++++++++++++++++++ app/controllers/products.controller.js | 8 +- app/models/index.js | 4 +- app/models/isic2DigitIndices.model.js | 59 +++++++ app/models/isic3DigitIndices.model.js | 59 +++++++ app/models/isic4DigitIndices.model.js | 59 +++++++ app/routes/routes.js | 35 ++++ 7 files changed, 369 insertions(+), 5 deletions(-) create mode 100644 app/models/isic2DigitIndices.model.js create mode 100644 app/models/isic3DigitIndices.model.js create mode 100644 app/models/isic4DigitIndices.model.js diff --git a/app/controllers/manufacturingIPI.controller.js b/app/controllers/manufacturingIPI.controller.js index 8d80711..1a0937d 100644 --- a/app/controllers/manufacturingIPI.controller.js +++ b/app/controllers/manufacturingIPI.controller.js @@ -1,5 +1,8 @@ const db = require("../models"); const ManufacturingIpi = db.ManufacturingIpi; +const Isic2DigitIndices = db.Isic2DigitIndices; +const Isic3DigitIndices = db.Isic3DigitIndices; +const Isic4DigitIndices = db.Isic4DigitIndices; const logger = require("../services/logger"); const formatDecimal = (value) => { @@ -38,6 +41,153 @@ exports.getAllManufacturingIndexDetails = async (req, res) => { } catch (error) { logger.error(`getAllManufacturingIndexDetails API: ${error.message}`); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } +}; + +exports.getManufacturingMonthlyOverviewByYearMonth = async (req, res) => { + try { + const { year, month } = req.query; + + // Validate parameters exist + if (!year || !month) { + logger.warn('getManufacturingMonthlyOverview API: Missing required parameters'); + return res.status(400).send({ + status: "failed", + message: "Year and month are required" + }); + } + + // Sanitize and validate input - prevent SQL injection + const yearInt = parseInt(year, 10); + const monthInt = parseInt(month, 10); + + // Validate that parsing was successful + if (isNaN(yearInt) || isNaN(monthInt)) { + logger.warn(`getManufacturingMonthlyOverview API: Invalid input - year: ${year}, month: ${month}`); + return res.status(400).send({ + status: "failed", + message: "Year and month must be valid numbers" + }); + } + + // Validate year range (reasonable bounds) + if (yearInt < 2000 || yearInt > 2100) { + return res.status(400).send({ + status: "failed", + message: "Year must be between 2000 and 2100" + }); + } + + // Validate month range + if (monthInt < 1 || monthInt > 12) { + return res.status(400).send({ + status: "failed", + message: "Month must be between 1 and 12" + }); + } + + // Common where clause + const whereClause = { + year: yearInt, + month: monthInt + }; + + // Fetch data from all tables in parallel + const [manufacturingData, isic2DigitData, isic3DigitData, isic4DigitData] = await Promise.all([ + ManufacturingIpi.findOne({ + attributes: ['manufacturing_index', 'mom_change', 'yoy_change'], + where: whereClause + }), + Isic2DigitIndices.findAll({ + attributes: ['isic_2digit_code', 'isic_description', 'total_weight', 'weighted_index_sum', 'isic_2digit_index'], + where: whereClause, + order: [['isic_2digit_code', 'ASC']] + }), + Isic3DigitIndices.findAll({ + attributes: ['isic_3digit_code', 'isic_description', 'total_weight', 'weighted_index_sum', 'isic_3digit_index'], + where: whereClause, + order: [['isic_3digit_code', 'ASC']] + }), + Isic4DigitIndices.findAll({ + attributes: ['isic_4digit_code', 'isic_description', 'total_weight', 'weighted_index_sum', 'isic_4digit_index'], + where: whereClause, + order: [['isic_4digit_code', 'ASC']] + }) + ]); + + // Check if manufacturing data exists (main data) + if (!manufacturingData) { + logger.info(`getManufacturingMonthlyOverview API: No data found for year ${yearInt}, month ${monthInt}`); + return res.status(404).send({ + status: "failed", + message: "No data found for the specified period" + }); + } + + // Format Manufacturing IPI data + const plainManufacturing = manufacturingData.get({ plain: true }); + const formattedManufacturing = { + manufacturing_index: formatDecimal(plainManufacturing.manufacturing_index), + mom_change: formatDecimal(plainManufacturing.mom_change), + yoy_change: formatDecimal(plainManufacturing.yoy_change), + }; + + // Format ISIC 2-digit data + const formattedIsic2Digit = isic2DigitData.map(item => { + const plainItem = item.get({ plain: true }); + return { + isic_2digit_code: plainItem.isic_2digit_code, + isic_description: plainItem.isic_description, + total_weight: formatDecimal(plainItem.total_weight), + weighted_index_sum: formatDecimal(plainItem.weighted_index_sum), + isic_2digit_index: formatDecimal(plainItem.isic_2digit_index), + }; + }); + + // Format ISIC 3-digit data + const formattedIsic3Digit = isic3DigitData.map(item => { + const plainItem = item.get({ plain: true }); + return { + isic_3digit_code: plainItem.isic_3digit_code, + isic_description: plainItem.isic_description, + total_weight: formatDecimal(plainItem.total_weight), + weighted_index_sum: formatDecimal(plainItem.weighted_index_sum), + isic_3digit_index: formatDecimal(plainItem.isic_3digit_index), + }; + }); + + // Format ISIC 4-digit data + const formattedIsic4Digit = isic4DigitData.map(item => { + const plainItem = item.get({ plain: true }); + return { + isic_4digit_code: plainItem.isic_4digit_code, + isic_description: plainItem.isic_description, + total_weight: formatDecimal(plainItem.total_weight), + weighted_index_sum: formatDecimal(plainItem.weighted_index_sum), + isic_4digit_index: formatDecimal(plainItem.isic_4digit_index), + }; + }); + + logger.info(`getManufacturingMonthlyOverview API: Successfully fetched data for year ${yearInt}, month ${monthInt}`); + + res.status(200).send({ + status: "success", + message: "Fetched successfully", + manufacturing_total: formattedManufacturing, + isic_2digit: formattedIsic2Digit, + isic_3digit: formattedIsic3Digit, + isic_4digit: formattedIsic4Digit + + }); + + } catch (error) { + logger.error(`getManufacturingMonthlyOverview API Error: ${error.message}`); + logger.error(`Stack trace: ${error.stack}`); + res.status(500).send({ + status: "failed", + message: "Internal server error" + }); + } }; \ No newline at end of file diff --git a/app/controllers/products.controller.js b/app/controllers/products.controller.js index a1be7d8..7e59582 100644 --- a/app/controllers/products.controller.js +++ b/app/controllers/products.controller.js @@ -118,7 +118,7 @@ exports.getAllProducts = async (req, res) => { }); } catch (error) { - logger.error(err.message); + logger.error(error.message); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -133,7 +133,7 @@ exports.getProductById = async (req, res) => { res.status(200).send({'status':"success",'message':"Fetched successfully",'data': data }); } catch (error) { - logger.error(err.message); + logger.error(error.message); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -170,7 +170,7 @@ exports.deleteProduct = async (req, res) => { res.status(200).send({'status':"success",'message':"Deleted successfully",'data': "" }); } catch (error) { - logger.error(err.message); + logger.error(error.message); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -181,7 +181,7 @@ exports.downloadProductSample = async (req, res) => { const filePath = path.join(__dirname, "../downloads_csv/products_upload_sample.csv"); return res.download(filePath, "products_upload_sample.csv"); } catch (error) { - logger.error(err.message); + logger.error(error.message); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; diff --git a/app/models/index.js b/app/models/index.js index 0acb42c..1868525 100644 --- a/app/models/index.js +++ b/app/models/index.js @@ -30,7 +30,9 @@ db.Emirate = require("./emirate.model")(sequelize, DataTypes); db.CityTown = require("./cityTown.model")(sequelize, DataTypes); db.SubmissionHistory = require("./submissionHistory.model")(sequelize, DataTypes); db.ManufacturingIpi = require("./manufacturingIPI.model.js")(sequelize, DataTypes); - +db.Isic2DigitIndices = require("./isic2DigitIndices.model.js")(sequelize, DataTypes); +db.Isic3DigitIndices = require("./isic3DigitIndices.model.js")(sequelize, DataTypes); +db.Isic4DigitIndices = require("./isic4DigitIndices.model.js")(sequelize, DataTypes); // Associations db.Establishment.hasMany(db.EstablishmentUser, { foreignKey: "establishment_id", diff --git a/app/models/isic2DigitIndices.model.js b/app/models/isic2DigitIndices.model.js new file mode 100644 index 0000000..76d9a00 --- /dev/null +++ b/app/models/isic2DigitIndices.model.js @@ -0,0 +1,59 @@ +module.exports = (sequelize, DataTypes) => { + const Isic2DigitIndices = sequelize.define("isic_2digit_indices", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + isic_2digit_code: { + type: DataTypes.STRING, + allowNull: false, + }, + isic_description: { + type: DataTypes.STRING, + allowNull: true, + validate: { + len: { + args: [0, 1000], + msg: "Description is too long. Maximum allowed length is 1000 characters." + }} + }, + year: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month_name: { + type: DataTypes.STRING, + allowNull: false, + }, + total_weight: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + weighted_index_sum: { + type: DataTypes.DECIMAL(10, 4), + allowNull: false, + }, + isic_2digit_index: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + created_at: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, { + tableName: "isic_2digit_indices", + timestamps: false, + }); + + return Isic2DigitIndices; +}; \ No newline at end of file diff --git a/app/models/isic3DigitIndices.model.js b/app/models/isic3DigitIndices.model.js new file mode 100644 index 0000000..da70f28 --- /dev/null +++ b/app/models/isic3DigitIndices.model.js @@ -0,0 +1,59 @@ +module.exports = (sequelize, DataTypes) => { + const Isic3DigitIndices = sequelize.define("isic_3digit_indices", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + isic_3digit_code: { + type: DataTypes.STRING, + allowNull: false, + }, + isic_description: { + type: DataTypes.STRING, + allowNull: true, + validate: { + len: { + args: [0, 1000], + msg: "Description is too long. Maximum allowed length is 1000 characters." + }} + }, + year: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month_name: { + type: DataTypes.STRING, + allowNull: false, + }, + total_weight: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + weighted_index_sum: { + type: DataTypes.DECIMAL(10, 4), + allowNull: false, + }, + isic_3digit_index: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + created_at: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, { + tableName: "isic_3digit_indices", + timestamps: false, + }); + + return Isic3DigitIndices; +}; \ No newline at end of file diff --git a/app/models/isic4DigitIndices.model.js b/app/models/isic4DigitIndices.model.js new file mode 100644 index 0000000..daa65af --- /dev/null +++ b/app/models/isic4DigitIndices.model.js @@ -0,0 +1,59 @@ +module.exports = (sequelize, DataTypes) => { + const Isic4DigitIndices = sequelize.define("isic_4digit_indices", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + isic_4digit_code: { + type: DataTypes.STRING, + allowNull: false, + }, + isic_description: { + type: DataTypes.STRING, + allowNull: true, + validate: { + len: { + args: [0, 1000], + msg: "Description is too long. Maximum allowed length is 1000 characters." + }} + }, + year: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month: { + type: DataTypes.INTEGER, + allowNull: false, + }, + month_name: { + type: DataTypes.STRING, + allowNull: false, + }, + total_weight: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + weighted_index_sum: { + type: DataTypes.DECIMAL(10, 4), + allowNull: false, + }, + isic_4digit_index: { + type: DataTypes.DECIMAL(10, 2), + allowNull: false, + }, + created_at: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, { + tableName: "isic_4digit_indices", + timestamps: false, + }); + + return Isic4DigitIndices; +}; \ No newline at end of file diff --git a/app/routes/routes.js b/app/routes/routes.js index e017150..ba7831e 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -3013,6 +3013,41 @@ router.get("/unit_master_download_sample_file",[verifySignature, verifyToken], u */ router.get("/manufacturing/getManufacturingIndex",[verifySignature, verifyToken], ManufacturingIpiController.getAllManufacturingIndexDetails); +/** + * @swagger + * /api/manufacturing/getManufacturingMonthlyOverview + * get: + * summary: Get Manufacturing IPI Monthly Overview by year and month + * tags: [ManufacturingIPI] + * security: + * - appSignature: [] + * - CSRF: [] + * cookieAuth: [] + * parameters: + * - name: year + * in: query + * required: true + * schema: + * type: integer + * description: Year (e.g., 2025) + * - name: month + * in: query + * required: true + * schema: + * type: integer + * description: Month (1-12) + * responses: + * 200: + * description: Manufacturing IPI Monthly Overview fetched successfully + * 400: + * description: Invalid parameters + * 404: + * description: Data not found + * 500: + * description: Server error + */ +router.get("/manufacturing/getManufacturingMonthlyOverview", [verifySignature, verifyToken], ManufacturingIpiController.getManufacturingMonthlyOverviewByYearMonth); + From f4ac302680eb3737706e9ee4314da7864736c225 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Dec 2025 16:58:49 +0530 Subject: [PATCH 05/12] Routes file modified --- app/routes/routes.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/routes/routes.js b/app/routes/routes.js index ba7831e..3047589 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -3015,23 +3015,23 @@ router.get("/manufacturing/getManufacturingIndex",[verifySignature, verifyToken] /** * @swagger - * /api/manufacturing/getManufacturingMonthlyOverview + * /api/manufacturing/getManufacturingMonthlyOverview: * get: * summary: Get Manufacturing IPI Monthly Overview by year and month * tags: [ManufacturingIPI] * security: * - appSignature: [] * - CSRF: [] - * cookieAuth: [] + * cookieAuth: [] # or bearerAuth: [] if you use Authorization header * parameters: - * - name: year - * in: query + * - in: query + * name: year * required: true * schema: * type: integer * description: Year (e.g., 2025) - * - name: month - * in: query + * - in: query + * name: month * required: true * schema: * type: integer From e18346a474c74009ae478333d2a7964eaebc2c4c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Dec 2025 12:44:50 +0530 Subject: [PATCH 06/12] ERROR log capture --- app/controllers/auth.controller.js | 5 +++- app/controllers/config.controller.js | 1 + app/controllers/dashboard.controller.js | 2 ++ app/controllers/deployment.controller.js | 2 ++ app/controllers/establishment.controller.js | 30 +++++++++++++------ .../establishment_products.controller.js | 5 ++++ .../establishment_user.controller.js | 11 +++++-- .../establishment_users_auth.controller.js | 2 ++ .../notificationTemplate.controller.js | 5 ++++ app/controllers/products.controller.js | 13 ++++++-- ...uarterlyWindowsConfiguration.controller.js | 10 ++++++- app/controllers/submission.controller.js | 13 ++++++++ app/controllers/unitMasterController.js | 11 ++++++- app/controllers/user.controller.js | 6 ++++ .../variationReasonMaster.controller.js | 5 ++++ .../zeroTargetReasonMaster.controller.js | 5 ++++ 16 files changed, 110 insertions(+), 16 deletions(-) diff --git a/app/controllers/auth.controller.js b/app/controllers/auth.controller.js index ef70e58..e14e914 100644 --- a/app/controllers/auth.controller.js +++ b/app/controllers/auth.controller.js @@ -97,6 +97,7 @@ exports.login = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error", @@ -173,7 +174,9 @@ exports.register = async (req, res) => { const ERROR_STATUS = "error"; const ERROR_CODE = "SERVER_ERROR"; const ERROR_MESSAGE = "An unexpected error occurred"; - + logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); + return res.status(500).send({ status: ERROR_STATUS, code: ERROR_CODE, diff --git a/app/controllers/config.controller.js b/app/controllers/config.controller.js index b96eede..bea9434 100644 --- a/app/controllers/config.controller.js +++ b/app/controllers/config.controller.js @@ -48,6 +48,7 @@ exports.updateDeadlineData = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/dashboard.controller.js b/app/controllers/dashboard.controller.js index 2fed341..e144b88 100644 --- a/app/controllers/dashboard.controller.js +++ b/app/controllers/dashboard.controller.js @@ -181,6 +181,7 @@ exports.getEstablishmentDashboard = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -282,6 +283,7 @@ exports.adminDashboard = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/deployment.controller.js b/app/controllers/deployment.controller.js index 57c7088..a2e844a 100644 --- a/app/controllers/deployment.controller.js +++ b/app/controllers/deployment.controller.js @@ -121,6 +121,8 @@ exports.deployment = async (req, res) => { } catch (err) { + logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; \ No newline at end of file diff --git a/app/controllers/establishment.controller.js b/app/controllers/establishment.controller.js index 6dc3952..0972b6e 100644 --- a/app/controllers/establishment.controller.js +++ b/app/controllers/establishment.controller.js @@ -277,7 +277,8 @@ exports.createEstablishment = async (req, res) => { message: `${field} already exists` }); } - logger.error('Error creating establishment', { error: err.message }); + logger.error(`Error creating establishment: ${err.message }`); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({status: "failed",message: "Internal server error" }); } }; @@ -439,7 +440,8 @@ exports.getAllEstablishments = async (req, res) => { }); } catch (err) { - logger.error('Error on get all establishment', { error: err.message }); + logger.error(`Error on get all establishment: ${err.message }`); + logger.error(`Stack trace: ${err.stack}`); res.setHeader('X-Frame-Options', 'DENY'); res.setHeader('X-Content-Type-Options', 'nosniff'); @@ -527,7 +529,8 @@ exports.getEstablishmentById = async (req, res) => { return res.status(200).send({'status':"success",'message':"Fetched successfully",'data': data }); } catch (err) { - logger.error('Error on get establishment by Id', { error: err.message }); + logger.error(`Error on get establishment by Id: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -698,7 +701,8 @@ exports.updateEstablishment = async (req, res) => { const field = err.errors[0].path; return res.status(400).json({ status:"failed", message:`${field} already exists` }); } - logger.error('Error updating establishment', { error: err.message }); + logger.error(`Error updating establishment: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status:"failed", message: "Internal server error" }); } }; @@ -714,7 +718,7 @@ exports.deleteEstablishment = async (req, res) => { return res.status(200).send({'status':"success",'message':"Deleted successfully",'data': "" }); } catch (err) { - logger.error('Error deleting establishment', { error: err.message }); + logger.error(`Error deleting establishment: ${ err.message }`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -729,7 +733,8 @@ exports.getAllEmirates = async (req, res) => { return res.status(200).send({status: "success", message: "Emirates fetched successfully", data: emirates,}); } catch (err) { - logger.error('Error on get all emirates', { error: err.message }); + logger.error(`Error on get all emirates: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({status: "failed",message: "Internal server error", }); } }; @@ -779,7 +784,8 @@ exports.getAllCityTowns = async (req, res) => { return res.status(200).send({status: "success", message: "City/Town fetched successfully", data: sanitizedCities, }); } catch (err) { - logger.error('Error getting all city towns', { error: err.message }); + logger.error(`Error getting all city towns: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -795,7 +801,8 @@ exports.getAllRequests = async (req, res) => { data: requests, }); } catch (err) { - logger.error('Error on getall request', { error: err.message }); + logger.error(`Error on getall request: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -874,7 +881,8 @@ exports.createRequest = async (req, res) => { }); } catch (err) { console.error(err); - logger.error('Error on create request', { error: err.message }); + logger.error(`Error on create request: ${ err.message }`); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error"}); } }; @@ -959,6 +967,7 @@ exports.forgotPasswordRequestOTP = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -1035,6 +1044,7 @@ exports.forgotPasswordVerifyOTP = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -1086,6 +1096,7 @@ function deleteFileSecure(filePath) { } catch (err) { if (logger && logger.error) { logger.error('File deletion error: ' + err.message); + logger.error(`Stack trace: ${err.stack}`); } } } @@ -1637,6 +1648,7 @@ exports.downloadCompanyProfileSample = async (req, res) => { return res.download(safeFilePath, "company_profile_upload_sample.csv"); } catch (error) { logger.error('Error on downloading company profile sample file' + error.message ); + logger.error(`Stack trace: ${error.stack}`); return res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/establishment_products.controller.js b/app/controllers/establishment_products.controller.js index 1c72785..f982170 100644 --- a/app/controllers/establishment_products.controller.js +++ b/app/controllers/establishment_products.controller.js @@ -75,6 +75,7 @@ exports.createEstablishmentProduct = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -118,6 +119,7 @@ exports.getAllEstablishmentProducts = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -133,6 +135,7 @@ exports.getEstablishmentProductById = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -158,6 +161,7 @@ exports.updateEstablishmentProduct = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -173,6 +177,7 @@ exports.deleteEstablishmentProduct = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; diff --git a/app/controllers/establishment_user.controller.js b/app/controllers/establishment_user.controller.js index eb14202..45c6afc 100644 --- a/app/controllers/establishment_user.controller.js +++ b/app/controllers/establishment_user.controller.js @@ -107,7 +107,8 @@ exports.createUser = async (req, res) => { message: "Establishment User created successfully.", }); } catch (error) { - logger.error(err.message); + logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); return res.status(500).json({ status: "error", message: "Internal server error" }); } }; @@ -133,6 +134,7 @@ exports.getAllUsers = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -149,6 +151,7 @@ exports.getUserById = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -178,6 +181,7 @@ exports.updateUser = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -235,6 +239,7 @@ exports.changeUserPassword = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({ status: "failed", message: "An unexpected error occurred" @@ -255,6 +260,7 @@ exports.deleteUser = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -335,7 +341,8 @@ exports.triggerEstablishmentUsersWelcomeEmail = async (req, res) => { } catch (error) { console.error(error); - logger.error(err.message); + logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); return res.status(500).json({ status: "error", message: "Internal server error" }); } }; diff --git a/app/controllers/establishment_users_auth.controller.js b/app/controllers/establishment_users_auth.controller.js index efc8fd2..2ab8f05 100644 --- a/app/controllers/establishment_users_auth.controller.js +++ b/app/controllers/establishment_users_auth.controller.js @@ -40,6 +40,7 @@ exports.login = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -53,6 +54,7 @@ exports.logout = async (req, res) => { res.status(200).json({ message: "Logout successful (client should discard token)" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; diff --git a/app/controllers/notificationTemplate.controller.js b/app/controllers/notificationTemplate.controller.js index 2dedca9..ae338d2 100644 --- a/app/controllers/notificationTemplate.controller.js +++ b/app/controllers/notificationTemplate.controller.js @@ -40,6 +40,7 @@ exports.createTemplate = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -81,6 +82,7 @@ exports.updateTemplate = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error" @@ -99,6 +101,7 @@ exports.getAllTemplates = async (req, res) => { }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -119,6 +122,7 @@ exports.getTemplateById = async (req, res) => { }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -140,6 +144,7 @@ exports.deleteTemplate = async (req, res) => { .send({ status: "success", message: "Deleted successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/products.controller.js b/app/controllers/products.controller.js index 7e59582..50f609d 100644 --- a/app/controllers/products.controller.js +++ b/app/controllers/products.controller.js @@ -72,7 +72,8 @@ exports.createProduct = async (req, res) => { res.status(201).send({'status':"success",'message':"created successfully." }); } catch (error) { - logger.error(err.message); + logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -119,6 +120,7 @@ exports.getAllProducts = async (req, res) => { } catch (error) { logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -134,6 +136,7 @@ exports.getProductById = async (req, res) => { } catch (error) { logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -154,7 +157,8 @@ exports.updateProduct = async (req, res) => { res.status(200).send({'status':"success",'message':"Updated successfully",'data': "" }); } catch (error) { - logger.error(err.message); + logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -171,6 +175,7 @@ exports.deleteProduct = async (req, res) => { } catch (error) { logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -182,6 +187,7 @@ exports.downloadProductSample = async (req, res) => { return res.download(filePath, "products_upload_sample.csv"); } catch (error) { logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -228,6 +234,7 @@ function deleteFileSecure(filePath) { } catch (err) { if (logger && logger.error) { logger.error('File deletion error: ' + err.message); + logger.error(`Stack trace: ${err.stack}`); } } } @@ -592,6 +599,7 @@ exports.uploadProductsFromCSV = async (req, res) => { deleteFileSecure(sanitizedPath); if (logger && logger.error) { logger.error("CSV processing error: " + processingError.message); + logger.error(`Stack trace: ${processingError.stack}`); } return res.status(500).send({ status: "failed", @@ -614,6 +622,7 @@ exports.uploadProductsFromCSV = async (req, res) => { deleteFileSecure(sanitizedPath); if (logger && logger.error) { logger.error("Upload error: " + error.message); + logger.error(`Stack trace: ${error.stack}`); } return res.status(500).send({ status: "failed", diff --git a/app/controllers/quarterlyWindowsConfiguration.controller.js b/app/controllers/quarterlyWindowsConfiguration.controller.js index ec25a3f..49853c0 100644 --- a/app/controllers/quarterlyWindowsConfiguration.controller.js +++ b/app/controllers/quarterlyWindowsConfiguration.controller.js @@ -70,6 +70,7 @@ exports.createConfig = async (req, res) => { sendEmailsToEstablishments(placeholder); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -86,12 +87,15 @@ async function sendEmailsToEstablishments(placeholder) { await new Promise(resolve => setTimeout(resolve, 1000)); } catch (emailErr) { - console.error("Email failed:", user.email, emailErr.message); + logger.error(emailErr.message); + logger.error(`Stack trace: ${emailErr.stack}`); + console.error("Email failed:", emailErr.message); } } } catch (err) { console.error("Email background job failed:", err.message); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } } @@ -118,6 +122,7 @@ exports.getAllConfigs = async (req, res) => { .send({ status: "success", message: "Fetched successfully", quarter_count: data.length, data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -136,6 +141,7 @@ exports.getConfigById = async (req, res) => { .send({ status: "success", message: "Fetched successfully", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -158,6 +164,7 @@ exports.updateConfig = async (req, res) => { .send({ status: "success", message: "Updated successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -178,6 +185,7 @@ exports.deleteConfig = async (req, res) => { .send({ status: "success", message: "Deleted successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index 2634ced..5c7d2d5 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -196,6 +196,7 @@ exports.createSubmission = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -295,6 +296,7 @@ exports.updateSubmission = async (req, res) => { }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).json({ status: "failed", message: "Internal server error" }); } }; @@ -329,6 +331,7 @@ exports.submissionHistory = async (req, res) => { res.status(200).json({ status: "success", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -481,6 +484,7 @@ exports.submissionList = async (req, res) => { } catch (err) { console.error(err); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -556,6 +560,7 @@ exports.viewSubmissionDetails = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -656,6 +661,7 @@ exports.getSubmissionHistory = async (req, res) => { } catch (err) { console.log(err); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } } @@ -683,6 +689,7 @@ exports.submissionEditRequest = async (req, res) => { } catch (err) { console.error(err); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -710,6 +717,7 @@ exports.enableOrDisableSubmissionEditAccess = async (req, res) => { } catch (err) { console.error(err); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -783,6 +791,7 @@ exports.approveOrRejectSubmission = async (req, res) => { } catch (err) { console.error(err); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } @@ -804,6 +813,7 @@ exports.getQuarterPeriods = async (req, res) => { return res.status(200).json({ status: "success", data: quarter_periods }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -854,6 +864,7 @@ exports.getPreviousForecastData = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -937,6 +948,7 @@ exports.getBeforePreviousData = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -1009,6 +1021,7 @@ exports.getProductSubmissionHistory = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/unitMasterController.js b/app/controllers/unitMasterController.js index 59fe9c8..549f963 100644 --- a/app/controllers/unitMasterController.js +++ b/app/controllers/unitMasterController.js @@ -135,6 +135,7 @@ exports.createUnit = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -170,6 +171,7 @@ exports.getAllUnits = async (req, res) => { res.status(200).json({ status: "success",unit_count : units.length, data: units }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -183,6 +185,7 @@ exports.getUnitById = async (req, res) => { res.status(200).json({ status: "success", data: unit }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -200,6 +203,7 @@ exports.updateUnit = async (req, res) => { res.status(200).json({ status: "success" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -214,6 +218,7 @@ exports.deleteUnit = async (req, res) => { res.status(200).json({ status: "success", message: "Unit deleted successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -269,6 +274,8 @@ function deleteFileSecure(filePath) { } return false; } catch (err) { + logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); console.error("File delete error:", err.message); return false; } @@ -589,6 +596,7 @@ exports.uploadUnitMasterFromCSV = async (req, res) => { } catch (err) { deleteFileSecure(sanitizedPath); logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -608,7 +616,8 @@ exports.downloadUnitMasterFile = async (req, res) => { return res.download(safeFilePath, "unit_master_sample.csv"); } catch (error) { - logger.error(err.message); + logger.error(error.message); + logger.error(`Stack trace: ${error.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/user.controller.js b/app/controllers/user.controller.js index daf61bd..c66098c 100644 --- a/app/controllers/user.controller.js +++ b/app/controllers/user.controller.js @@ -21,6 +21,7 @@ exports.createUser = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -35,6 +36,7 @@ exports.getAllUsers = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -51,6 +53,7 @@ exports.getUserById = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': "Internal server error" }); } }; @@ -77,6 +80,7 @@ exports.updateUser = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message':"Internal server error" }); } }; @@ -95,6 +99,7 @@ exports.deleteUser = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({'status':"failed",'message': 'Internal server error' }); } }; @@ -137,6 +142,7 @@ exports.changeAdminUserPassword = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).send({ status: "failed", message: "Internal server error" }); } }; diff --git a/app/controllers/variationReasonMaster.controller.js b/app/controllers/variationReasonMaster.controller.js index 1f80128..0c8b8d1 100644 --- a/app/controllers/variationReasonMaster.controller.js +++ b/app/controllers/variationReasonMaster.controller.js @@ -40,6 +40,7 @@ exports.createReason = async (req, res) => { } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ status: "failed", message: "Internal server error" @@ -54,6 +55,7 @@ exports.getAllReasons = async (req, res) => { res.status(200).send({ status: "success", message: "Fetched successfully", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error"}); } }; @@ -66,6 +68,7 @@ exports.getReasonById = async (req, res) => { res.status(200).send({ status: "success", message: "Fetched successfully", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -83,6 +86,7 @@ exports.updateReason = async (req, res) => { res.status(200).send({ status: "success", message: "Updated successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -95,6 +99,7 @@ exports.deleteReason = async (req, res) => { res.status(200).send({ status: "success", message: "Deleted successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message:"Internal server error" }); } }; diff --git a/app/controllers/zeroTargetReasonMaster.controller.js b/app/controllers/zeroTargetReasonMaster.controller.js index 3c6a212..3a22af0 100644 --- a/app/controllers/zeroTargetReasonMaster.controller.js +++ b/app/controllers/zeroTargetReasonMaster.controller.js @@ -21,6 +21,7 @@ exports.create = async (req, res) => { res.status(201).send({ status: "success", message: "Record created successfully",}); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -32,6 +33,7 @@ exports.getAll = async (req, res) => { res.status(200).send({ status: "success", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -45,6 +47,7 @@ exports.getById = async (req, res) => { res.status(200).send({ status: "success", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; @@ -61,6 +64,7 @@ exports.update = async (req, res) => { res.status(200).send({ status: "success", data }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error"}); } }; @@ -74,6 +78,7 @@ exports.delete = async (req, res) => { res.status(200).send({ status: "success", message: "Deleted successfully" }); } catch (err) { logger.error(err.message); + logger.error(`Stack trace: ${err.stack}`); res.status(500).send({ status: "failed", message: "Internal server error" }); } }; From d7d91fac7767ece2c9399e54af450627ed6719e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Dec 2025 17:55:37 +0530 Subject: [PATCH 07/12] test --- app/controllers/submission.controller.js | 51 +++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index 5c7d2d5..907170a 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -808,9 +808,58 @@ exports.getQuarterPeriods = async (req, res) => { .json({ status: "failed", message: "current_year and current_quarter are required" }); } - const quarter_periods = getQuarterPeriods(Number(current_year), current_quarter); + const query = ` + SELECT id, survey_name, year, quarter, start_date, end_date, + grace_periods_days, is_active, created_at, created_by, + updated_at, updated_by, assigned, responded + FROM quarterly_windows_configuration_master + WHERE year = ? AND quarter = ? + LIMIT 1 + `; + + const [quarterConfigs] = await db.query(query, [current_year, current_quarter]); + + // Check if quarter configuration exists + if (!quarterConfigs || quarterConfigs.length === 0) { + return res.status(404).json({ + status: "failed", + message: `No configuration found for Quarter ${current_quarter} ${current_year}` + }); + } + + const config = quarterConfigs[0]; + + // Check if quarter is active + if (config.is_active === 0) { + return res.status(403).json({ + status: "failed", + message: `Quarter ${current_quarter} ${current_year} is not active. Cannot create surveys.` + }); + } + + // Calculate the final deadline (end_date + grace_periods_days) + const endDate = new Date(config.end_date); + const gracePeriodDays = config.grace_periods_days || 0; + const finalDeadline = new Date(endDate); + finalDeadline.setDate(finalDeadline.getDate() + gracePeriodDays); + + const currentDateTime = new Date(); + + // Check if the quarter is closed + if (currentDateTime > finalDeadline) { + const formattedDeadline = finalDeadline.toISOString().split('T')[0]; + return res.status(403).json({ + status: "failed", + message: `Quarter ${current_quarter} ${current_year} is closed. The grace period ended on ${formattedDeadline}. Cannot create surveys for this quarter.`, + quarter_closed: true, + deadline: finalDeadline.toISOString(), + current_time: currentDateTime.toISOString() + }); + }else{ + const quarter_periods = getQuarterPeriods(Number(current_year), current_quarter); return res.status(200).json({ status: "success", data: quarter_periods }); + } } catch (err) { logger.error(err.message); logger.error(`Stack trace: ${err.stack}`); From 53eb76f6b364580283f89d3a1655e24e420c220f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Dec 2025 17:58:18 +0530 Subject: [PATCH 08/12] test --- app/controllers/submission.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index 907170a..df167bc 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -863,7 +863,7 @@ exports.getQuarterPeriods = async (req, res) => { } catch (err) { logger.error(err.message); logger.error(`Stack trace: ${err.stack}`); - res.status(500).send({ status: "failed", message: "Internal server error" }); + res.status(500).send({ status: "failed", message: err.message, stack:err.stack }); } }; From 0640d64e5dd6943d4f927df2915c07dcbbda3f0f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Dec 2025 18:05:30 +0530 Subject: [PATCH 09/12] test --- app/controllers/submission.controller.js | 78 +++++++++++------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index df167bc..b0abb8a 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -808,58 +808,50 @@ exports.getQuarterPeriods = async (req, res) => { .json({ status: "failed", message: "current_year and current_quarter are required" }); } - const query = ` - SELECT id, survey_name, year, quarter, start_date, end_date, - grace_periods_days, is_active, created_at, created_by, - updated_at, updated_by, assigned, responded - FROM quarterly_windows_configuration_master - WHERE year = ? AND quarter = ? - LIMIT 1 - `; - - const [quarterConfigs] = await db.query(query, [current_year, current_quarter]); - - // Check if quarter configuration exists - if (!quarterConfigs || quarterConfigs.length === 0) { - return res.status(404).json({ - status: "failed", - message: `No configuration found for Quarter ${current_quarter} ${current_year}` + const config = await QuarterlyWindowConfig.findOne({ + where: { + year: current_year, + quarter: current_quarter + } + }); + + if (!config) { + return res.status(404).json({ + status: "failed", + message: `No configuration found for Quarter ${current_quarter} ${current_year}` }); } - - const config = quarterConfigs[0]; - - // Check if quarter is active + if (config.is_active === 0) { - return res.status(403).json({ - status: "failed", - message: `Quarter ${current_quarter} ${current_year} is not active. Cannot create surveys.` + return res.status(403).json({ + status: "failed", + message: `Quarter ${current_quarter} ${current_year} is not active` + }); + } + + + const endDate = new Date(config.end_date); + const graceDays = Number(config.grace_periods_days || 0); + + const finalDeadline = new Date(endDate); + finalDeadline.setDate(finalDeadline.getDate() + graceDays); + + const now = new Date(); + + if (now > finalDeadline) { + return res.status(403).json({ + status: "failed", + quarter_closed: true, + message: `Quarter ${current_quarter} ${current_year} is closed`, + deadline: finalDeadline.toISOString(), + current_time: now.toISOString() }); } - // Calculate the final deadline (end_date + grace_periods_days) - const endDate = new Date(config.end_date); - const gracePeriodDays = config.grace_periods_days || 0; - const finalDeadline = new Date(endDate); - finalDeadline.setDate(finalDeadline.getDate() + gracePeriodDays); - - const currentDateTime = new Date(); - - // Check if the quarter is closed - if (currentDateTime > finalDeadline) { - const formattedDeadline = finalDeadline.toISOString().split('T')[0]; - return res.status(403).json({ - status: "failed", - message: `Quarter ${current_quarter} ${current_year} is closed. The grace period ended on ${formattedDeadline}. Cannot create surveys for this quarter.`, - quarter_closed: true, - deadline: finalDeadline.toISOString(), - current_time: currentDateTime.toISOString() - }); - }else{ const quarter_periods = getQuarterPeriods(Number(current_year), current_quarter); return res.status(200).json({ status: "success", data: quarter_periods }); - } + } catch (err) { logger.error(err.message); logger.error(`Stack trace: ${err.stack}`); From 9170139392f759a06b28598cf6bbcf88a27f0dab Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Dec 2025 18:07:30 +0530 Subject: [PATCH 10/12] test --- app/controllers/submission.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index b0abb8a..a419707 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -808,7 +808,7 @@ exports.getQuarterPeriods = async (req, res) => { .json({ status: "failed", message: "current_year and current_quarter are required" }); } - const config = await QuarterlyWindowConfig.findOne({ + const config = await QuarterlyWindowsConfiguration.findOne({ where: { year: current_year, quarter: current_quarter From 34a9fbf4fc6bea9d2cf8ce2869742741cac8094c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Dec 2025 10:09:48 +0530 Subject: [PATCH 11/12] Error message modified getQuarterPeriods API --- app/controllers/submission.controller.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index a419707..8102b7e 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -842,12 +842,11 @@ exports.getQuarterPeriods = async (req, res) => { return res.status(403).json({ status: "failed", quarter_closed: true, - message: `Quarter ${current_quarter} ${current_year} is closed`, + message: `Quarter ${current_quarter} ${current_year} is closed. The grace period ended on ${finalDeadline}. Cannot create surveys for this quarter.`, deadline: finalDeadline.toISOString(), current_time: now.toISOString() }); - } - + } const quarter_periods = getQuarterPeriods(Number(current_year), current_quarter); return res.status(200).json({ status: "success", data: quarter_periods }); From 856f221399138591b979ea86ab049a40a1ad13fa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Dec 2025 11:56:39 +0530 Subject: [PATCH 12/12] Closed Quarter restricted --- app/controllers/dashboard.controller.js | 10 ++++++++ app/controllers/submission.controller.js | 31 +++--------------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/app/controllers/dashboard.controller.js b/app/controllers/dashboard.controller.js index e144b88..d92a124 100644 --- a/app/controllers/dashboard.controller.js +++ b/app/controllers/dashboard.controller.js @@ -143,6 +143,16 @@ exports.getEstablishmentDashboard = async (req, res) => { if (activeQuarters?.length > 0) { for (const q of activeQuarters) { + const endDate = new Date(q.end_date); + const graceDays = Number(q.grace_periods_days || 0); + const finalDeadline = new Date(endDate); + finalDeadline.setDate(finalDeadline.getDate() + graceDays); + const now = new Date(); + + // Skip this quarter if it's closed (deadline has passed) + if (now > finalDeadline) { + continue; + } const submissionMatch = await Submission.findOne({ where: { diff --git a/app/controllers/submission.controller.js b/app/controllers/submission.controller.js index 8102b7e..11f3020 100644 --- a/app/controllers/submission.controller.js +++ b/app/controllers/submission.controller.js @@ -811,7 +811,8 @@ exports.getQuarterPeriods = async (req, res) => { const config = await QuarterlyWindowsConfiguration.findOne({ where: { year: current_year, - quarter: current_quarter + quarter: current_quarter, + is_active: true } }); @@ -820,33 +821,7 @@ exports.getQuarterPeriods = async (req, res) => { status: "failed", message: `No configuration found for Quarter ${current_quarter} ${current_year}` }); - } - - if (config.is_active === 0) { - return res.status(403).json({ - status: "failed", - message: `Quarter ${current_quarter} ${current_year} is not active` - }); - } - - - const endDate = new Date(config.end_date); - const graceDays = Number(config.grace_periods_days || 0); - - const finalDeadline = new Date(endDate); - finalDeadline.setDate(finalDeadline.getDate() + graceDays); - - const now = new Date(); - - if (now > finalDeadline) { - return res.status(403).json({ - status: "failed", - quarter_closed: true, - message: `Quarter ${current_quarter} ${current_year} is closed. The grace period ended on ${finalDeadline}. Cannot create surveys for this quarter.`, - deadline: finalDeadline.toISOString(), - current_time: now.toISOString() - }); - } + } const quarter_periods = getQuarterPeriods(Number(current_year), current_quarter); return res.status(200).json({ status: "success", data: quarter_periods });