From 59975c709a954b9cf800a2ae51499e1bc1e9365e Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Thu, 23 Oct 2025 13:47:55 +0530 Subject: [PATCH] merge --- app/controllers/dashboard.controller.js | 28 ++++- .../notificationTemplate.controller.js | 89 ++++++++++++++ app/models/index.js | 1 + app/models/notificationTemplate.model.js | 52 ++++++++ app/routes/routes.js | 116 +++++++++++++++++- 5 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 app/controllers/notificationTemplate.controller.js create mode 100644 app/models/notificationTemplate.model.js diff --git a/app/controllers/dashboard.controller.js b/app/controllers/dashboard.controller.js index 1c0e230..9b74721 100644 --- a/app/controllers/dashboard.controller.js +++ b/app/controllers/dashboard.controller.js @@ -1,7 +1,8 @@ const db = require("../models"); const { Op } = require("sequelize"); - +const { Sequelize } = require("sequelize"); const Submission = db.Submission; +const SubmissionProduct = db.SubmissionProduct; const SubmissionDeadline = db.SubmissionDeadline; function getQuarter(date) { @@ -76,11 +77,36 @@ exports.getEstablishmentDashboard = async (req, res) => { const quarters = getPrevCurrNextQuarter(today); // Last 5 submissions + // const submission_history = await Submission.findAll({ + // where: { establishment_id }, + // order: [["created_at", "DESC"]], + // limit: 5, + // }); + const submission_history = await Submission.findAll({ where: { establishment_id }, order: [["created_at", "DESC"]], limit: 5, + attributes: { + include: [ + [ + Sequelize.literal(`( + SELECT COUNT(*) + FROM submission_products AS sp + WHERE sp.submission_id = submission.id + )`), + "product_count", + ], + ], + }, + // include: [ + // { + // model: SubmissionProduct, + // as: "products", // ✅ use your actual alias here + // }, + // ], }); + // Submission status for current quarter const currentQuarterDates = getQuarterDates(quarters.current_quarter, quarters.current_quarter_year); diff --git a/app/controllers/notificationTemplate.controller.js b/app/controllers/notificationTemplate.controller.js new file mode 100644 index 0000000..3a7ce1a --- /dev/null +++ b/app/controllers/notificationTemplate.controller.js @@ -0,0 +1,89 @@ +const db = require("../models"); +const NotificationTemplate = db.NotificationTemplate; + +// Create template +exports.createTemplate = async (req, res) => { + try { + const template = await NotificationTemplate.create(req.body); + res.status(201).send({ + status: "success", + message: "Template created successfully", + data: template, + }); + } catch (err) { + res.status(500).send({ status: "failed", message: err.message }); + } +}; + +// Get all templates +exports.getAllTemplates = async (req, res) => { + try { + const templates = await NotificationTemplate.findAll(); + res.status(200).send({ + status: "success", + message: "Fetched successfully", + data: templates, + }); + } catch (err) { + res.status(500).send({ status: "failed", message: err.message }); + } +}; + +// Get single template +exports.getTemplateById = async (req, res) => { + try { + const template = await NotificationTemplate.findByPk(req.params.id); + if (!template) + return res + .status(404) + .send({ status: "failed", message: "Template not found" }); + + res.status(200).send({ + status: "success", + message: "Fetched successfully", + data: template, + }); + } catch (err) { + res.status(500).send({ status: "failed", message: err.message }); + } +}; + +// Update template +exports.updateTemplate = async (req, res) => { + try { + const [updated] = await NotificationTemplate.update(req.body, { + where: { id: req.params.id }, + }); + + if (!updated) + return res + .status(404) + .send({ status: "failed", message: "Template not found" }); + + res + .status(200) + .send({ status: "success", message: "Updated successfully" }); + } catch (err) { + res.status(500).send({ status: "failed", message: err.message }); + } +}; + +// Delete template +exports.deleteTemplate = async (req, res) => { + try { + const deleted = await NotificationTemplate.destroy({ + where: { id: req.params.id }, + }); + + if (!deleted) + return res + .status(404) + .send({ status: "failed", message: "Template not found" }); + + res + .status(200) + .send({ status: "success", message: "Deleted successfully" }); + } catch (err) { + res.status(500).send({ status: "failed", message: err.message }); + } +}; diff --git a/app/models/index.js b/app/models/index.js index a6857f1..96d3805 100644 --- a/app/models/index.js +++ b/app/models/index.js @@ -23,6 +23,7 @@ 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); +db.NotificationTemplate = require("./notificationTemplate.model")(sequelize, DataTypes); // Associations diff --git a/app/models/notificationTemplate.model.js b/app/models/notificationTemplate.model.js new file mode 100644 index 0000000..3597a38 --- /dev/null +++ b/app/models/notificationTemplate.model.js @@ -0,0 +1,52 @@ +module.exports = (sequelize, DataTypes) => { + const NotificationTemplate = sequelize.define( + "notification_templates", + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + title: { + type: DataTypes.STRING, + allowNull: false, + }, + template_code: { + type: DataTypes.STRING, + allowNull: false, + unique: true, + }, + subject: { + type: DataTypes.STRING, + allowNull: true, + }, + body_html: { + type: DataTypes.TEXT, + allowNull: false, + }, + placeholders: { + type: DataTypes.JSON, + allowNull: true, + }, + is_active: { + type: DataTypes.BOOLEAN, + defaultValue: true, + }, + created_at: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updated_at: { + type: DataTypes.DATE, + allowNull: true, + }, + }, + { + tableName: "notification_templates", + timestamps: false, + } + ); + + return NotificationTemplate; + }; + \ No newline at end of file diff --git a/app/routes/routes.js b/app/routes/routes.js index 693d9ff..9184c75 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -15,6 +15,7 @@ const unitMasterController = require("../controllers/unitMasterController"); const submissionController = require("../controllers/submission.controller"); const ConfigController = require("../controllers/config.controller"); const dashboardController = require("../controllers/dashboard.controller"); +const notificationTemplateController = require("../controllers/notificationTemplate.controller"); @@ -44,7 +45,9 @@ const dashboardController = require("../controllers/dashboard.controller"); * - name: Config * description: Sumbission config * - name: Dashboard - * description: + * description: + * - name: Notification Templates + * description: Manage notification templates */ @@ -1818,4 +1821,115 @@ router.get("/establishment_dashboard",[verifySignature, verifyToken],dashboardCo + + + + + +/** + * @swagger + * /api/notification_templates: + * get: + * summary: Get all notification templates + * tags: [Notification Templates] + * responses: + * 200: + * description: Fetched successfully + */ +router.get("/notification_templates", notificationTemplateController.getAllTemplates); + +/** + * @swagger + * /api/notification_templates/{id}: + * get: + * summary: Get a single notification template + * tags: [Notification Templates] + * parameters: + * - name: id + * in: path + * required: true + * responses: + * 200: + * description: Fetched successfully + */ +router.get("/notification_templates/:id", notificationTemplateController.getTemplateById); + +// /** +// * @swagger +// * /api/notification_templates: +// * post: +// * summary: Create a new notification template +// * tags: [Notification Templates] +// * requestBody: +// * required: true +// * content: +// * application/json: +// * schema: +// * type: object +// * properties: +// * title: { type: string } +// * template_code: { type: string } +// * subject: { type: string } +// * body_html: { type: string } +// * placeholders: { type: array, items: { type: string } } +// * responses: +// * 201: +// * description: Created successfully +// */ +// router.post("/notification_templates", notificationTemplateController.createTemplate); + +/** + * @swagger + * /api/notification_templates/{id}: + * put: + * summary: Update a notification template + * tags: [Notification Templates] + * parameters: + * - name: id + * in: path + * required: true + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * title: { type: string } + * subject: { type: string } + * body_html: { type: string } + * placeholders: { type: array, items: { type: string } } + * responses: + * 200: + * description: Updated successfully + */ +router.put("/notification_templates/:id", notificationTemplateController.updateTemplate); + +// /** +// * @swagger +// * /api/notification_templates/{id}: +// * delete: +// * summary: Delete a notification template +// * tags: [Notification Templates] +// * parameters: +// * - name: id +// * in: path +// * required: true +// * responses: +// * 200: +// * description: Deleted successfully +// */ +// router.delete("/notification_templates/:id", notificationTemplateController.deleteTemplate); + + + + + + + + + + + + module.exports = router;