fcsc_ipi_backend/app/routes/routes.js

3575 lines
103 KiB
JavaScript

const express = require("express");
const router = express.Router();
const verifyToken = require("../middleware/auth.middleware");
const verifySignature = require("../middleware/app.middleware");
const adminUserController = require("../controllers/user.controller");
const authController = require("../controllers/auth.controller");
const establishmentController = require("../controllers/establishment.controller");
const establishmentUserController = require("../controllers/establishment_user.controller");
const establishmentUserAuthController = require("../controllers/establishment_users_auth.controller");
const productController = require("../controllers/products.controller");
const establishmentProductController = require("../controllers/establishment_products.controller");
const variationReasonMasterController = require("../controllers/variationReasonMaster.controller");
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");
const notificationTemplateController = require("../controllers/notificationTemplate.controller");
const quarterlyWindowsController = require("../controllers/quarterlyWindowsConfiguration.controller");
const calculationController = require("../controllers/calculation.controller");
const ManufacturingIpiController = require("../controllers/manufacturingIPI.controller")
const testController = require("../controllers/test.controller");
const exportController = require("../controllers/export.controller");
const fs = require("fs");
const path = require("path");
const multer = require("multer");
const { UPLOAD_DIR } = require("../config/upload.config");
const upload = multer({ dest: UPLOAD_DIR });
const { handleCsvUpload } = require("../middleware/csvUpload.middleware");
/**
* @swagger
* /api/calculate_base_year:
* post:
* summary: Base year calculation 2022
* tags: [IIP Calculation]
* security:
* - appSignature: []
* - CSRF: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - baseYear
* - forceRecalculate
* properties:
* baseYear:
* type: integer
* example: 2022
* forceRecalculate:
* type: string
* example: false
* responses:
* 200:
* description: Base year production calculated successfully
*/
router.post("/calculate_base_year",[] , calculationController.calculate_base_year);
/**
* @swagger
* /api/survey_auto_submit:
* post:
* summary: Auto survey submission for Quarter
* tags: [IIP Calculation]
* security:
* - appSignature: []
* - CSRF: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - year
* - quarter
* properties:
* year:
* type: integer
* example: 2025
* quarter:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* example: Q2
* responses:
* 200:
* description: Auto survey completed successfully
*/
router.post("/survey_auto_submit",[] , calculationController.survey_auto_submit);
/**
* @swagger
* /api/calculate_quarter:
* post:
* summary: Calculate IPI for a selected year and quarter (Quarter → Month mapping)
* tags: [IIP Calculation]
* security:
* - appSignature: []
* - CSRF: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - year
* - quarter
* properties:
* year:
* type: integer
* example: 2025
* quarter:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* example: Q2
* description: |
* Quarter to month mapping:
* - Q1 → Jan to Mar (1 - 3)
* - Q2 → Apr to Jun (4 - 6)
* - Q3 → Jul to Sep (7 - 9)
* - Q4 → Oct to Dec (10 - 12)
* responses:
* 200:
* description: Quarterly IPI calculation completed successfully
*/
router.post("/calculate_quarter",[] , calculationController.calculate_quarter);
/**
* @swagger
* /api/survey_auto_submit_and_calculate:
* post:
* summary: Auto submit missing surveys, then calculate IPI for the quarter
* description: |
* Runs in sequence:
* 1. survey_auto_submit — auto-fill missing submissions and verify completeness
* 2. calculate_quarter — run IPI calculation for the same year and quarter
* tags: [IIP Calculation]
* security:
* - appSignature: []
* - CSRF: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - year
* - quarter
* properties:
* year:
* type: integer
* example: 2025
* quarter:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* example: Q2
* responses:
* 200:
* description: Auto submit and quarterly calculation completed successfully
* 400:
* description: Invalid year or quarter
* 500:
* description: Server error
*/
router.post(
"/survey_auto_submit_and_calculate",
[],
calculationController.survey_auto_submit_and_calculate
);
router.get("/calculate_month",[] , calculationController.calculate_month);
/**
* @swagger
* tags:
* - name: Admin And Establishments User Auth
* description: Authentication
* - name: Admin Users
* description: User management APIs
* - name: Establishments
* description: CRUD APIs for managing Establishments
* - name: Establishment Users
* description: CRUD APIs for managing Establishment Users
* - name: Products
* description: CRUD APIs for managing Products
* - name: Establishment Products
* description: CRUD APIs for linking establishments and products
* - name: Variation Reason Master
* description: Manage variation reason master data
* - name: Zero Target Reasons
* description: API for managing zero target reasons
* - name: Unit Master
* description: Manage Unit Master entries
* - name: Submissions
* description: Manage establishment submissions
* - name: Config
* description: Sumbission config
* - name: Dashboard
* description:
* - name: Notification Templates
* description: Manage notification templates
* - name: Quarterly Windows Configuration
* description: Manage quarterly windows configuration master data
* - name: Establishment Pwd Reset Requests
* description: Manage Establishment Pwd Reset Requests
* - name: Master
* description:
*/
/**
* @swagger
* components:
* securitySchemes:
* bearerAuth:
* type: http
* scheme: bearer
* bearerFormat: JWT
* description: "key to identify authorized user"
* appSignature:
* type: apiKey
* in: header
* name: APP_SIGNATURE
* description: "Signature key to identify authorized application"
* CSRF:
* type: apiKey
* in: header
* name: X-CSRF-Token
* description: "Signature key to identify authorized application"
*/
/**
* @swagger
* /api/auth/admin_register:
* post:
* summary: Register new Admin-user (For testing purpose only)
* tags: [Admin And Establishments User Auth]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - name
* - email
* - password
* properties:
* name:
* type: string
* example: John Doe
* email:
* type: string
* example: john@example.com
* password:
* type: string
* example: "<password>"
* responses:
* 201:
* description: User registered successfully
* 400:
* description: Missing fields or duplicate email
* 500:
* description: Server error
*/
router.post("/auth/admin_register",[verifySignature], authController.register);
/**
* @swagger
* /api/auth/login:
* post:
* summary: Login Admin-user / Establishments-user and get JWT token
* tags: [Admin And Establishments User Auth]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* properties:
* email:
* type: string
* example: john@example.com
* password:
* type: string
* example: "<password>"
* responses:
* 201:
* description: User verifyed successfully
* 404:
* description: Missing email
* 500:
* description: Server error
*/
router.post("/auth/login",[verifySignature], authController.login);
/**
* @swagger
* /api/auth/logout:
* get:
* summary: Logout Admin-user / Establishments-user
* tags: [Admin And Establishments User Auth]
* security:
* - appSignature: []
*/
router.get("/auth/logout",[verifySignature], authController.logout);
/**
* @swagger
* /api/admin_users:
* get:
* summary: Get all users (Protected)
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 201:
* description: Fetched successfully
* 404:
* description: Missing Data
* 500:
* description: Server error
*/
router.get("/admin_users", [verifySignature , verifyToken], adminUserController.getAllUsers);
/**
* @swagger
* /api/admin_users/{id}:
* get:
* summary: Get user by ID (Protected)
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: User ID
* responses:
* 201:
* description: Fetched successfully
* 404:
* description: Missing Data
* 500:
* description: Server error
*/
router.get("/admin_users/:id", [verifySignature, verifyToken], adminUserController.getUserById);
/**
* @swagger
* /api/admin_users:
* post:
* summary: Create a user
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name: { type: string }
* email: { type: string }
* password:
* type: string
* example: "<password>"
* responses:
* 201:
* description: created successfully
* 404:
* description: Missing Data
* 500:
* description: Server error
*/
router.post("/admin_users",[verifySignature, verifyToken], adminUserController.createUser);
/**
* @swagger
* /api/admin_users/{id}:
* put:
* summary: Update user
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: User ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name: { type: string }
* email: { type: string }
* is_active: { type: boolean }
* responses:
* 201:
* description: updated successfully
* 404:
* description: Missing Data
* 500:
* description: Server error
*/
router.put("/admin_users/:id",[verifySignature, verifyToken], adminUserController.updateUser);
/**
* @swagger
* /api/admin_users/{id}:
* delete:
* summary: Delete user
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: User ID
* responses:
* 201:
* description: deleted successfully
* 404:
* description: Missing Data
* 500:
* description: Server error
*/
router.delete("/admin_users/:id",[verifySignature, verifyToken], adminUserController.deleteUser);
/**
* @swagger
* /api/admin_users/{id}/change-password:
* put:
* summary: Change Admin User Password
* description: Allows an Admin user to change their password after verifying the old password.
* tags: [Admin Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* description: ID of the admin user
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - old_password
* - new_password
* - confirm_password
* properties:
* old_password:
* type: string
* example: "OldPassword@123"
* new_password:
* type: string
* example: "ExamplePassword123!"
* confirm_password:
* type: string
* example: "ExamplePassword123!"
* responses:
* 200:
* description: Password updated successfully
* 400:
* description: Validation or password mismatch error
* 404:
* description: User not found
* 500:
* description: Internal server error
*/
router.put("/admin_users/:id/change-password",[verifySignature, verifyToken], adminUserController.changeAdminUserPassword);
router.get("/testEmail", establishmentController.testEmail);
/**
* @swagger
* /api/test/submissions-with-products:
* post:
* summary: Create test submission and submission-products for multiple quarters
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* required:
* - year
* - establishment_id
* - product_id
* - data
* properties:
* year:
* type: integer
* example: 2022
* establishment_id:
* type: integer
* example: 2
* product_id:
* type: integer
* example: 3
* data:
* type: array
* items:
* type: object
* required:
* - quarter
* - qty
* - cost
* properties:
* quarter:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* example: Q1
* qty:
* type: number
* example: 456573559
* cost:
* type: number
* example: 40566560717
* example:
* - year: 2022
* establishment_id: 2
* product_id: 3
* data:
* - quarter: Q1
* qty: 456573559
* cost: 40566560717
* - quarter: Q2
* qty: 8755776
* cost: 7654656
* - quarter: Q3
* qty: 7465465
* cost: 865454
* - quarter: Q4
* qty: 656465465
* cost: 98776
* - year: 2022
* establishment_id: 2
* product_id: 3
* data:
* - quarter: Q1
* qty: 456573559
* cost: 40566560717
* - quarter: Q2
* qty: 8755776
* cost: 7654656
* - quarter: Q3
* qty: 7465465
* cost: 865454
* - quarter: Q4
* qty: 656465465
* cost: 98776
* responses:
* 201:
* description: Submission and products processed successfully
* 400:
* description: Validation error
* 500:
* description: Server error
*/
router.post("/test/submissions-with-products",[verifySignature], testController.createSubmissionWithProducts);
/**
* @swagger
* /api/establishments:
* post:
* summary: Create a new Establishment with linked user
* tags: [Establishments]
* security:
* - appSignature: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_code
* - factory_name
* - email
* - establishment_user
* properties:
* establishment_code: { type: string }
* factory_name: { type: string }
* permanent_factory_code: { type: string }
* industry_code: { type: string }
* industry_code_mismatch_remarks: { type: string }
* license_number: { type: string }
* isic_code: { type: string }
* description: { type: string }
* establishment_address: { type: string }
* establishment_city_town_id: { type: integer, description: "FK from city_towns" }
* establishment_emirate_id: { type: integer, description: "FK from emirates" }
* establishment_postal_code: { type: string }
* establishment_po_box: { type: string }
* establishment_makani_number: { type: string }
* establishment_contact_person_name: { type: string }
* establishment_contact_person_designation: { type: string }
* establishment_mobile_number: { type: string }
* establishment_contact_email: { type: string }
* establishment_website: { type: string }
* corporate_same_as_establishment: { type: boolean }
* corporate_name: { type: string }
* corporate_address: { type: string }
* corporate_city_town_id: { type: integer, description: "FK from city_towns" }
* corporate_emirate_id: { type: integer, description: "FK from emirates" }
* corporate_postal_code: { type: string }
* corporate_po_box: { type: string }
* corporate_makani_number: { type: string }
* corporate_contact_person_name: { type: string }
* corporate_contact_person_designation: { type: string }
* corporate_mobile_number: { type: string }
* corporate_email: { type: string }
* corporate_website: { type: string }
* emirati_male: { type: integer }
* emirati_female: { type: integer }
* non_emirati_male: { type: integer }
* non_emirati_female: { type: integer }
* total_emirati: { type: integer }
* total_employees: { type: integer }
* ERN: { type: string }
* zone: { type: string, description: "Establishment zone (optional)" }
* created_by: { type: integer }
* establishment_user:
* type: object
* required:
* - name
* - email
* - password
* properties:
* name: { type: string }
* email: { type: string }
* password:
* type: string
* example: "<password>"
* establishment_products:
* type: array
* items:
* type: object
* required:
* - product_id
* properties:
* product_id: { type: integer }
* created_by: { type: integer }
* updated_by: { type: integer }
* action_done_by: { type: string }
* responses:
* 201:
* description: Establishment and linked user created successfully
* 400:
* description: Missing required fields
* 500:
* description: Server error
*/
router.post("/establishments",[verifySignature, verifyToken], establishmentController.createEstablishment);
/**
* @swagger
* /api/establishments:
* get:
* summary: Get all Establishments with pagination, filters, and sorting
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: page
* schema: { type: integer, default: 1 }
* description: Current page number
* - in: query
* name: limit
* schema: { type: integer, default: 10 }
* description: Number of records per page
* - in: query
* name: search
* schema: { type: string }
* description: Search by Establishment name, email, or code
* - in: query
* name: emirate_id
* schema: { type: integer }
* description: Filter by Emirate ID
* - in: query
* name: isic_code
* schema: { type: string }
* description: Filter by ISIC code
* - in: query
* name: status
* schema: { type: string, enum: [active, inactive] }
* description: Filter by active/inactive status
* - in: query
* name: sort_by
* schema: { type: string, default: created_at }
* description: Column to sort by (e.g. name, created_at)
* - in: query
* name: sort_order
* schema: { type: string, enum: [ASC, DESC], default: DESC }
* description: Sorting order
* - in: query
* name: export
* schema: { type: string, enum: [excel] }
* description: Set "excel" to download as Excel file
* responses:
* 200:
* description: Fetched establishments successfully
* 500:
* description: Internal server error
*/
router.get("/establishments",[verifySignature, verifyToken], establishmentController.getAllEstablishments);
/**
* @swagger
* /api/establishments/{id}:
* get:
* summary: Get an Establishment by ID
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment ID
* responses:
* 200:
* description: Establishment details
* 404:
* description: Establishment not found
*/
router.get("/establishments/:id",[verifySignature, verifyToken], establishmentController.getEstablishmentById);
/**
* @swagger
* /api/establishments/{id}:
* put:
* summary: Update an Establishment by ID
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* establishment_code: { type: string }
* factory_name: { type: string }
* permanent_factory_code: { type: string }
* industry_code: { type: string }
* industry_code_mismatch_remarks: { type: string }
* license_number: { type: string }
* isic_code: { type: string }
* description: { type: string }
* establishment_address: { type: string }
* establishment_city_town_id: { type: integer, description: "FK from city_towns" }
* establishment_emirate_id: { type: integer, description: "FK from emirates" }
* establishment_postal_code: { type: string }
* establishment_po_box: { type: string }
* establishment_makani_number: { type: string }
* establishment_contact_person_name: { type: string }
* establishment_contact_person_designation: { type: string }
* establishment_mobile_number: { type: string }
* establishment_contact_email: { type: string }
* establishment_website: { type: string }
* corporate_same_as_establishment: { type: boolean }
* corporate_name: { type: string }
* corporate_address: { type: string }
* corporate_city_town_id: { type: integer, description: "FK from city_towns" }
* corporate_emirate_id: { type: integer, description: "FK from emirates" }
* corporate_postal_code: { type: string }
* corporate_po_box: { type: string }
* corporate_makani_number: { type: string }
* corporate_contact_person_name: { type: string }
* corporate_contact_person_designation: { type: string }
* corporate_mobile_number: { type: string }
* corporate_email: { type: string }
* corporate_website: { type: string }
* emirati_male: { type: integer }
* emirati_female: { type: integer }
* non_emirati_male: { type: integer }
* non_emirati_female: { type: integer }
* total_emirati: { type: integer }
* total_employees: { type: integer }
* ERN: { type: string }
* zone: { type: string, description: "Establishment zone (optional)" }
* updated_by: { type: integer }
* establishment_products:
* type: array
* items:
* type: object
* required:
* - product_id
* properties:
* product_id: { type: integer }
* created_by: { type: integer }
* updated_by: { type: integer }
* action_done_by: { type: string }
* responses:
* 200:
* description: Establishment updated successfully
* 400:
* description: Invalid data
* 404:
* description: Establishment not found
*/
router.put("/establishments/:id",[verifySignature, verifyToken], establishmentController.updateEstablishment);
/**
* @swagger
* /api/establishments/{id}:
* delete:
* summary: Delete an Establishment by ID
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment ID
* responses:
* 200:
* description: Establishment deleted successfully
* 404:
* description: Establishment not found
*/
router.delete("/establishments/:id",[verifySignature, verifyToken], establishmentController.deleteEstablishment);
/**
* @swagger
* /api/establishments/uploadCSV:
* post:
* summary: Upload Establishment data in bulk using CSV file
* description: This API accepts CSV file and inserts multiple Establishment in bulk. CSV header columns must match Establishment table columns.
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* file:
* type: string
* format: binary
* description: CSV file to upload
* responses:
* 200:
* description: Customer Profiles inserted successfully.
* 400:
* description: No file uploaded
* 500:
* description: Server error
*/
router.post("/establishments/uploadCSV",[verifySignature, verifyToken, upload.single("file")], establishmentController.establishmentBulkUpload);
/**
* @swagger
* /api/searchIsicMaster:
* get:
* summary: Get all Isic Master data
* tags: [Establishments]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: code
* schema: { type: string }
* - in: query
* name: description
* schema: { type: string }
* responses:
* 200:
* description: Fetched successfully
* 500:
* description: Internal server error
*/
router.get("/searchIsicMaster",[verifySignature, verifyToken], establishmentController.searchIsicMaster);
/**
* @swagger
* /api/establishment-users:
* post:
* summary: Create a new Establishment User
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_id
* - name
* - email
* - password
* properties:
* establishment_id:
* type: integer
* example: 1
* name:
* type: string
* example: Gem Watson
* email:
* type: string
* example: gem@alpha.com
* password:
* type: string
* example: "<password>"
* gender:
* type: string
* example: male
* is_active:
* type: boolean
* example: true
* responses:
* 201:
* description: Establishment User created successfully
* 400:
* description: Missing or invalid fields
* 500:
* description: Server error
*/
router.post("/establishment-users",[verifySignature, verifyToken], establishmentUserController.createUser);
/**
* @swagger
* /api/establishment-users:
* get:
* summary: Get all Establishment Users
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* schema:
* type: integer
* required: false
* description: Filter products by establishment ID
* example: 1
* responses:
* 200:
* description: List of establishment users
*/
router.get("/establishment-users",[verifySignature, verifyToken], establishmentUserController.getAllUsers);
/**
* @swagger
* /api/establishment-users/{id}:
* get:
* summary: Get an Establishment User by ID
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment User ID
* responses:
* 200:
* description: Establishment User details
* 404:
* description: User not found
*/
router.get("/establishment-users/:id",[verifySignature, verifyToken], establishmentUserController.getUserById);
/**
* @swagger
* /api/establishment-users/{id}:
* put:
* summary: Update an Establishment User
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment User ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* example: Gem Watson Updated
* email:
* type: string
* example: gem.updated@alpha.com
* password:
* type: string
* example: "<password>"
* gender:
* type: string
* example: male
* is_active:
* type: boolean
* example: true
* responses:
* 200:
* description: Establishment User updated successfully
* 400:
* description: Invalid data
* 404:
* description: User not found
*/
router.put("/establishment-users/:id",[verifySignature, verifyToken], establishmentUserController.updateUser);
/**
* @swagger
* /api/establishment-users/{id}/change-password:
* put:
* summary: Change Establishment User Password
* description: Allows an establishment user to change their password after verifying the old password.
* tags: [Establishment Users]
* security:
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* description: ID of the establishment user
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - old_password
* - new_password
* - confirm_password
* properties:
* old_password:
* type: string
* example: "OldPassword@123"
* new_password:
* type: string
* example: "ExamplePassword123!"
* confirm_password:
* type: string
* example: "ExamplePassword123!"
* responses:
* 200:
* description: Password updated successfully
* 400:
* description: Validation or password mismatch error
* 404:
* description: User not found
* 500:
* description: Internal server error
*/
router.put("/establishment-users/:id/change-password",[verifySignature, verifyToken], establishmentUserController.changeUserPassword);
/**
* @swagger
* /api/establishment-users/{id}:
* delete:
* summary: Delete an Establishment User
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: Establishment User ID
* responses:
* 200:
* description: Establishment User deleted successfully
* 404:
* description: User not found
*/
router.delete("/establishment-users/:id",[verifySignature, verifyToken], establishmentUserController.deleteUser);
/**
* @swagger
* /api/trigger-establishment-users-welcome-email:
* post:
* summary: Sending Establishment User Welcome Email
* tags: [Establishment Users]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_id
* properties:
* establishment_id:
* type: integer
* example: 1
* responses:
* 200:
* description: Email send success
* 400:
* description: Missing or invalid fields
* 500:
* description: Server error
*/
router.post("/trigger-establishment-users-welcome-email",[verifySignature, verifyToken], establishmentUserController.triggerEstablishmentUsersWelcomeEmail);
/**
* @swagger
* /api/products:
* post:
* summary: Create a new Product
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [product_name]
* properties:
* product_name:
* type: string
* example: "Laptop"
* hs_code:
* type: string
* example: "8471.30"
* hs_description:
* type: string
* example: "Portable automatic data processing machines"
* unit_id:
* type: integer
* example: "select data from unit master"
* weight_in_ib:
* type: number
* description: Optional weight used in IPI weighting (decimal, DECIMAL(18,10) in DB).
* example: 100.655214
* is_active:
* type: boolean
* example: true
* responses:
* 201:
* description: Product created successfully
*/
router.post("/products",[verifySignature, verifyToken], productController.createProduct);
/**
* @swagger
* /api/products:
* get:
* summary: Get all Products
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: List of products
*/
router.get("/products",[verifySignature, verifyToken], productController.getAllProducts);
/**
* @swagger
* /api/products/{id}:
* get:
* summary: Get Product by ID
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Product found
* 404:
* description: Product not found
*/
router.get("/products/:id", [verifySignature, verifyToken],productController.getProductById);
/**
* @swagger
* /api/products/{id}:
* put:
* summary: Update a Product
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* content:
* application/json:
* schema:
* type: object
* properties:
* product_name:
* type: string
* example: "Laptop"
* hs_code:
* type: string
* example: "8471.30"
* hs_description:
* type: string
* example: "Portable automatic data processing machines"
* unit_id:
* type: integer
* example: "select data from unit master"
* weight_in_ib:
* type: number
* description: Optional weight used in IPI weighting (decimal). Omit to leave unchanged; send null to clear.
* example: 100.655214
* is_active:
* type: boolean
* example: true
* responses:
* 200:
* description: Product updated successfully
* 404:
* description: Product not found
*/
router.put("/products/:id",[verifySignature, verifyToken], productController.updateProduct);
/**
* @swagger
* /api/products/{id}:
* delete:
* summary: Delete a Product
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Product deleted successfully
* 404:
* description: Product not found
*/
router.delete("/products/:id",[verifySignature, verifyToken], productController.deleteProduct);
/**
* @swagger
* /api/products/uploadCSV:
* post:
* summary: Upload products in bulk using CSV file
* description: This API accepts CSV file and inserts multiple products in bulk. CSV header columns must match Product table columns.
* tags: [Products]
* security:
* - bearerAuth: []
* appSignature: []
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* required:
* - file
* properties:
* file:
* type: string
* format: binary
* description: CSV file — form field name must be "file"
* responses:
* 201:
* description: Products uploaded successfully
* 400:
* description: Missing file, wrong form field, or validation error
* 403:
* description: Missing or invalid APP_SIGNATURE or auth token
* 500:
* description: Server error
*/
router.post(
"/products/uploadCSV",
[verifySignature, verifyToken, handleCsvUpload],
productController.uploadProductsFromCSV
);
/**
* @swagger
* /api/download-sample-product-upload-file:
* get:
* summary: Download sample CSV template for bulk product upload
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Sample CSV file downloaded successfully
* content:
* text/csv:
* schema:
* type: string
* format: binary
* 404:
* description: File not found
* 500:
* description: Server error
*/
router.get("/download-sample-product-upload-file",[verifySignature, verifyToken], productController.downloadProductSample);
/**
* @swagger
* /api/establishment-products:
* post:
* summary: Create a new EstablishmentProduct (link establishment with product)
* tags: [Establishment Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_id
* - product_id
* properties:
* establishment_id:
* type: integer
* example: 1
* product_id:
* type: integer
* example: 10
* action_done_by:
* type: string
* example: admin_users
* created_by:
* type: integer
* example: 1
* responses:
* 201:
* description: EstablishmentProduct created successfully
* 400:
* description: Missing or invalid fields
* 500:
* description: Server error
*/
router.post("/establishment-products",[verifySignature, verifyToken], establishmentProductController.createEstablishmentProduct);
/**
* @swagger
* /api/establishment-products:
* get:
* summary: Get all EstablishmentProducts
* tags: [Establishment Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* schema:
* type: integer
* required: false
* description: Filter products by establishment ID
* example: 1
* responses:
* 200:
* description: List of establishment-product links
* 500:
* description: Server error
*/
router.get("/establishment-products",[verifySignature, verifyToken], establishmentProductController.getAllEstablishmentProducts);
/**
* @swagger
* /api/establishment-products/{id}:
* get:
* summary: Get an EstablishmentProduct by ID
* tags: [Establishment Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: EstablishmentProduct ID
* responses:
* 200:
* description: EstablishmentProduct details
* 404:
* description: Record not found
* 500:
* description: Server error
*/
router.get("/establishment-products/:id",[verifySignature, verifyToken], establishmentProductController.getEstablishmentProductById);
/**
* @swagger
* /api/establishment-products/{id}:
* put:
* summary: Update an EstablishmentProduct by ID
* tags: [Establishment Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: EstablishmentProduct ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* establishment_id:
* type: integer
* example: 1
* product_id:
* type: integer
* example: 10
* action_done_by:
* type: string
* example: admin_users
* updated_by:
* type: integer
* example: 1
* responses:
* 200:
* description: Record updated successfully
* 400:
* description: Invalid data
* 404:
* description: Record not found
* 500:
* description: Server error
*/
router.put("/establishment-products/:id",[verifySignature, verifyToken], establishmentProductController.updateEstablishmentProduct);
/**
* @swagger
* /api/establishment-products/{id}:
* delete:
* summary: Delete an EstablishmentProduct by ID
* tags: [Establishment Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: EstablishmentProduct ID
* responses:
* 200:
* description: Record deleted successfully
* 404:
* description: Record not found
* 500:
* description: Server error
*/
router.delete("/establishment-products/:id",[verifySignature, verifyToken], establishmentProductController.deleteEstablishmentProduct);
/**
* @swagger
* /api/variation_reasons:
* post:
* summary: Create a new variation reason
* tags: [Variation Reason Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [reason]
* properties:
* reason:
* type: string
* example: "Unexpected delay"
* high_or_low:
* type: string
* example: "High"
* responses:
* 201:
* description: Reason created successfully
*/
router.post("/variation_reasons",[verifySignature, verifyToken], variationReasonMasterController.createReason);
/**
* @swagger
* /api/variation_reasons:
* get:
* summary: Get all variation reasons
* tags: [Variation Reason Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: List of reasons
*/
router.get("/variation_reasons",[verifySignature, verifyToken], variationReasonMasterController.getAllReasons);
/**
* @swagger
* /api/variation_reasons/{id}:
* get:
* summary: Get a reason by ID
* tags: [Variation Reason Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Reason ID
* responses:
* 200:
* description: Reason fetched successfully
* 404:
* description: Reason not found
*/
router.get("/variation_reasons/:id",[verifySignature, verifyToken], variationReasonMasterController.getReasonById);
/**
* @swagger
* /api/variation_reasons/{id}:
* put:
* summary: Update a variation reason
* tags: [Variation Reason Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Reason ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* reason:
* type: string
* example: "Price fluctuation"
* high_or_low:
* type: string
* example: "Low"
* is_active:
* type: boolean
* example: true
* responses:
* 200:
* description: Updated successfully
* 404:
* description: Reason not found
*/
router.put("/variation_reasons/:id",[verifySignature, verifyToken], variationReasonMasterController.updateReason);
/**
* @swagger
* /api/variation_reasons/{id}:
* delete:
* summary: Delete a variation reason
* tags: [Variation Reason Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Reason ID
* responses:
* 200:
* description: Deleted successfully
* 404:
* description: Reason not found
*/
router.delete("/variation_reasons/:id",[verifySignature, verifyToken], variationReasonMasterController.deleteReason);
/**
* @swagger
* /api/zero_target_reason:
* get:
* summary: Get all zero target reasons
* tags: [Zero Target Reasons]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: List of reasons
*/
router.get("/zero_target_reason/",[verifySignature, verifyToken], zeroTargetReasonMasterController.getAll);
/**
* @swagger
* /api/zero_target_reason/{id}:
* get:
* summary: Get zero target reason by ID
* tags: [Zero Target Reasons]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Reason found
*/
router.get("/zero_target_reason/:id",[verifySignature, verifyToken], zeroTargetReasonMasterController.getById);
/**
* @swagger
* /api/zero_target_reason:
* post:
* summary: Create a new zero target reason
* tags: [Zero Target Reasons]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* reason:
* type: string
* is_active:
* type: boolean
* responses:
* 201:
* description: Created successfully
*/
router.post("/zero_target_reason/",[verifySignature, verifyToken], zeroTargetReasonMasterController.create);
/**
* @swagger
* /api/zero_target_reason/{id}:
* put:
* summary: Update zero target reason
* tags: [Zero Target Reasons]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* reason:
* type: string
* is_active:
* type: boolean
* responses:
* 200:
* description: Updated successfully
*/
router.put("/zero_target_reason/:id",[verifySignature, verifyToken], zeroTargetReasonMasterController.update);
/**
* @swagger
* /api/zero_target_reason/{id}:
* delete:
* summary: Delete zero target reason
* tags: [Zero Target Reasons]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* responses:
* 200:
* description: Deleted successfully
*/
router.delete("/zero_target_reason/:id",[verifySignature, verifyToken], zeroTargetReasonMasterController.delete);
/**
* @swagger
* /api/unit_master:
* get:
* summary: Get all units
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: List of units
*/
router.get("/unit_master",[verifySignature, verifyToken], unitMasterController.getAllUnits);
/**
* @swagger
* /api/unit_master/{id}:
* get:
* summary: Get unit by ID
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Unit details
*/
router.get("/unit_master/:id",[verifySignature, verifyToken], unitMasterController.getUnitById);
/**
* @swagger
* /api/unit_master:
* post:
* summary: Create a new unit
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* uom: { type: string }
* is_base_unit: { type : boolean }
* base_unit_id: { type : integer }
* factor: { type : string }
* description: { type : string }
* responses:
* 201:
* description: Unit created successfully
*/
router.post("/unit_master",[verifySignature, verifyToken], unitMasterController.createUnit);
/**
* @swagger
* /api/unit_master/{id}:
* put:
* summary: Update a unit
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* uom: { type: string }
* uom_short_name: { type: string }
* is_base_unit: { type : boolean }
* base_unit_id: { type : integer }
* factor: { type : string }
* description: { type : string }
* is_active: { type : boolean }
* responses:
* 200:
* description: Unit updated successfully
*/
router.put("/unit_master/:id",[verifySignature, verifyToken], unitMasterController.updateUnit);
/**
* @swagger
* /api/unit_master/{id}:
* delete:
* summary: Delete a unit
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* responses:
* 200:
* description: Unit deleted successfully
*/
router.delete("/unit_master/:id",[verifySignature, verifyToken], unitMasterController.deleteUnit);
/**
* @swagger
* /api/unit_master/uploadCSV:
* post:
* summary: Upload products in bulk using CSV file
* description: This API accepts CSV file and inserts multiple products in bulk. CSV header columns must match Product table columns.
* tags: [Unit Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* file:
* type: string
* format: binary
* description: CSV file to upload
* responses:
* 201:
* description: Unit Master file uploaded successfully
* 400:
* description: No file uploaded
* 500:
* description: Server error
*/
router.post("/unit_master/uploadCSV",[ verifySignature, verifyToken, upload.single("file")], unitMasterController.uploadUnitMasterFromCSV);
/**
* @swagger
* /api/submissions:
* post:
* summary: Create submission with up to 10 products
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* establishment_id: { type: integer }
* quarter: { type: string, enum: [Q1, Q2, Q3, Q4] }
* year: { type: integer }
* emirati_male: { type: integer }
* emirati_female: { type: integer }
* non_emirati_male: { type: integer }
* non_emirati_female: { type: integer }
* total_emirati: { type: integer }
* total_employees: { type: integer }
* created_by: { type: integer }
* products:
* type: array
* items:
* type: object
* properties:
* product_id: { type: integer }
* unit_id: { type: integer }
* annual_installed_capacity: { type: string }
* previous_quantity_period_one: { type: string }
* previous_quantity_period_two: { type: string }
* previous_quantity_period_three: { type: string }
* previous_cost_period_one: { type: string }
* previous_cost_period_two: { type: string }
* previous_cost_period_three: { type: string }
* current_quantity_period_one: { type: string }
* current_quantity_period_two: { type: string }
* current_quantity_period_three: { type: string }
* current_cost_period_one: { type: string }
* current_cost_period_two: { type: string }
* current_cost_period_three: { type: string }
* forecast_quantity_period_one: { type: string }
* forecast_quantity_period_two: { type: string }
* forecast_quantity_period_three: { type: string }
* forecast_cost_period_one: { type: string }
* forecast_cost_period_two: { type: string }
* forecast_cost_period_three: { type: string }
* previous_quantity: { type: string }
* previous_cost: { type: string }
* current_quantity: { type: string }
* current_cost: { type: string }
* forecast_quantity: { type: string }
* forecast_cost: { type: string }
* variation_reason_master_id: { type: string }
* other_variation_reason: { type: string }
* zero_target_reason_master_id: { type: string }
* other_zero_target_reason: { type: string }
* remarks: { type: string }
* responses:
* 201:
* description: Submission created
*/
router.post("/submissions",[verifySignature, verifyToken], submissionController.createSubmission);
/**
* @swagger
* /api/submissions/{id}:
* put:
* summary: Update submission with products
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* establishment_id: { type: integer }
* quarter: { type: string, enum: [Q1, Q2, Q3, Q4] }
* year: { type: integer }
* emirati_male: { type: integer }
* emirati_female: { type: integer }
* non_emirati_male: { type: integer }
* non_emirati_female: { type: integer }
* total_emirati: { type: integer }
* total_employees: { type: integer }
* updated_by: { type: integer }
* products:
* type: array
* items:
* type: object
* properties:
* id: { type: integer }
* product_id: { type: integer }
* unit_id: { type: integer }
* annual_installed_capacity: { type: string }
* previous_quantity_period_one: { type: string }
* previous_quantity_period_two: { type: string }
* previous_quantity_period_three: { type: string }
* previous_cost_period_one: { type: string }
* previous_cost_period_two: { type: string }
* previous_cost_period_three: { type: string }
* current_quantity_period_one: { type: string }
* current_quantity_period_two: { type: string }
* current_quantity_period_three: { type: string }
* current_cost_period_one: { type: string }
* current_cost_period_two: { type: string }
* current_cost_period_three: { type: string }
* forecast_quantity_period_one: { type: string }
* forecast_quantity_period_two: { type: string }
* forecast_quantity_period_three: { type: string }
* forecast_cost_period_one: { type: string }
* forecast_cost_period_two: { type: string }
* forecast_cost_period_three: { type: string }
* previous_quantity: { type: string }
* previous_cost: { type: string }
* current_quantity: { type: string }
* current_cost: { type: string }
* forecast_quantity: { type: string }
* forecast_cost: { type: string }
* variation_reason_master_id: { type: string }
* other_variation_reason: { type: string }
* zero_target_reason_master_id: { type: string }
* other_zero_target_reason: { type: string }
* remarks: { type: string }
* responses:
* 200:
* description: Updated successfully
*/
router.put("/submissions/:id",[verifySignature, verifyToken], submissionController.updateSubmission);
/**
* @swagger
* /api/submissions/history/{establishment_id}:
* get:
* summary: Get submission history for establishment
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: establishment_id
* in: path
* required: true
* responses:
* 200:
* description: History list
*/
router.get("/submissions/history/:establishment_id",[verifySignature, verifyToken], submissionController.submissionHistory);
/**
* @swagger
* /api/submissions:
* get:
* summary: Get submissions list with pagination, filters, search, and export
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: page
* schema: { type: integer, default: 1 }
* description: Page number
* - in: query
* name: limit
* schema: { type: integer, default: 10 }
* description: Items per page
* - in: query
* name: search
* schema: { type: string }
* description: Search by establishment name or code
* - in: query
* name: quarter
* schema: { type: string }
* - in: query
* name: year
* schema: { type: integer }
* - in: query
* name: status
* schema: { type: string }
* - in: query
* name: emirate_id
* schema: { type: integer }
* - in: query
* name: export_excel
* schema: { type: boolean }
* description: If true, exports data to Excel file
* responses:
* 200:
* description: Submission list retrieved successfully
* 500:
* description: Server error
*/
router.get("/submissions",[verifySignature, verifyToken], submissionController.submissionList);
/**
* @swagger
* /api/exports/annex-ii:
* get:
* summary: Export Annex II establishment quarterly data (quantity and value)
* tags: [Exports]
* security:
* - appSignature: []
* - bearerAuth: []
* parameters:
* - in: query
* name: years
* schema: { type: string, example: "2022,2025,2026" }
* description: Comma-separated years to include (defaults to all years with data)
* - in: query
* name: status
* schema: { type: string, example: "Approved" }
* description: Comma-separated submission statuses (default Approved,Submitted,Resubmitted)
* - in: query
* name: emirate_id
* schema: { type: integer }
* - in: query
* name: establishment_id
* schema: { type: integer }
* responses:
* 200:
* description: Excel file download
* 404:
* description: No data found
*/
router.get(
"/exports/annex-ii",
[verifySignature, verifyToken],
exportController.exportAnnexII
);
/**
* @swagger
* /api/exports/annex-iii-quantity:
* get:
* summary: Export Annex III item-level quantity data
* tags: [Exports]
* security:
* - appSignature: []
* - bearerAuth: []
* parameters:
* - in: query
* name: years
* schema: { type: string, example: "2022,2025" }
* - in: query
* name: status
* schema: { type: string, example: "Approved" }
* - in: query
* name: emirate_id
* schema: { type: integer }
* - in: query
* name: establishment_id
* schema: { type: integer }
* responses:
* 200:
* description: Excel file download
*/
router.get(
"/exports/annex-iii-quantity",
[verifySignature, verifyToken],
exportController.exportAnnexIIIQuantity
);
/**
* @swagger
* /api/exports/annex-iii-values:
* get:
* summary: Export Annex III item-level value (cost) data
* tags: [Exports]
* security:
* - appSignature: []
* - bearerAuth: []
* parameters:
* - in: query
* name: years
* schema: { type: string, example: "2022,2025" }
* - in: query
* name: status
* schema: { type: string, example: "Approved" }
* - in: query
* name: emirate_id
* schema: { type: integer }
* - in: query
* name: establishment_id
* schema: { type: integer }
* responses:
* 200:
* description: Excel file download
*/
router.get(
"/exports/annex-iii-values",
[verifySignature, verifyToken],
exportController.exportAnnexIIIValues
);
/**
* @swagger
* /api/submissions/view/{id}:
* get:
* summary: Get submission details by ID or by (establishment_id, year, quarter)
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: false
* description: Submission ID (optional if using query combination)
* schema:
* type: integer
* - name: establishment_id
* in: query
* required: false
* schema:
* type: integer
* - name: year
* in: query
* required: false
* schema:
* type: integer
* - name: quarter
* in: query
* required: false
* schema:
* type: string
* responses:
* 200:
* description: Submission details retrieved successfully
* 404:
* description: Submission not found
* 500:
* description: Server error
*/
router.get("/submissions/view/:id",[verifySignature, verifyToken], submissionController.viewSubmissionDetails);
/**
* @swagger
* /api/submissionEditRequest/{id}:
* put:
* summary: Update request for submission products
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* edit_request: { type: integer }
* responses:
* 200:
* description: Updated successfully
*/
router.put("/submissionEditRequest/:id",[verifySignature, verifyToken], submissionController.submissionEditRequest);
/**
* @swagger
* /api/enableOrDisableSubmissionEditAccess/{id}:
* put:
* summary: Allow or deny the edit request of submission products
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* edit_access:
* type: integer
* description: 1 for Enable, 0 for Disable
* responses:
* 200:
* description: Updated successfully
*/
router.put("/enableOrDisableSubmissionEditAccess/:id",[verifySignature, verifyToken], submissionController.enableOrDisableSubmissionEditAccess);
/**
* @swagger
* /api/approveOrRejectSubmission/{id}:
* put:
* summary: Approve or Reject the submission
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* approve_reject_status:
* type: integer
* description: 1 for Approve, 2 for Reject
* reject_reason:
* type: string
* description: rejection reason
* approve_or_reject_by:
* type: integer
* description: logged admin user primary id
* responses:
* 200:
* description: Updated successfully
*/
router.put("/approveOrRejectSubmission/:id",[verifySignature, verifyToken], submissionController.approveOrRejectSubmission);
/**
* @swagger
* /api/getQuarterPeriods:
* post:
* summary: get Quarter Periods based on current quarter and year
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* current_year: { type: integer }
* current_quarter: { type: string }
* responses:
* 200:
* description: Updated successfully
*/
router.post("/getQuarterPeriods",[verifySignature, verifyToken], submissionController.getQuarterPeriods);
/**
* @swagger
* /api/submissions/getPreviousForecastData:
* get:
* summary: Get Previous and Forecast Data based on Establishment + Quarter + Year + Product
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* required: true
* schema: { type: integer }
* - in: query
* name: quarter
* required: true
* schema: { type: string, enum: [Q1, Q2, Q3, Q4] }
* - in: query
* name: year
* required: true
* schema: { type: integer }
* - in: query
* name: product_id
* required: true
* schema: { type: integer }
* responses:
* 200:
* description: Previous forecast data fetched successfully
* 404:
* description: Not found
* 500:
* description: Server error
*/
router.get("/submissions/getPreviousForecastData",[verifySignature, verifyToken], submissionController.getPreviousForecastData);
/**
* @swagger
* /api/submissions/getBeforePreviousData:
* get:
* summary: compute the quarter two steps before (before-previous) based on Establishment + current_quarter + current_year + Product
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* required: true
* schema: { type: integer }
* - in: query
* name: current_quarter
* required: true
* schema: { type: string, enum: [Q1, Q2, Q3, Q4] }
* - in: query
* name: current_year
* required: true
* schema: { type: integer }
* - in: query
* name: product_id
* required: true
* schema: { type: integer }
* responses:
* 200:
* description: Previous forecast data fetched successfully
* 404:
* description: Not found
* 500:
* description: Server error
*/
router.get("/submissions/getBeforePreviousData",[verifySignature, verifyToken], submissionController.getBeforePreviousData);
/**
* @swagger
* /api/submissions/getProductSubmissionHistory:
* get:
* summary: Get Product submission history data based on Establishment + Product
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* required: true
* schema: { type: integer }
* - in: query
* name: product_id
* required: true
* schema: { type: integer }
* responses:
* 200:
* description: Product submission history data fetched successfully
* 404:
* description: Not found
* 500:
* description: Server error
*/
router.get("/submissions/getProductSubmissionHistory",[verifySignature, verifyToken], submissionController.getProductSubmissionHistory);
/**
* @swagger
* /api/submission-audit-history:
* get:
* summary: Get submission product update history (merged view)
* description: Returns submission history with submission + product level change history merged. If no filters passed → returns entire history list.
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: establishment_id
* schema:
* type: integer
* required: true
* description: Filter by establishment_id
* - in: query
* name: year
* schema:
* type: integer
* required: false
* description: Filter by year
* - in: query
* name: quarter
* schema:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* required: false
* description: Filter by quarter
* - in: query
* name: product_id
* schema:
* type: integer
* required: false
* description: Filter by product_id
* responses:
* 200:
* description: Merged submission history list retrieved successfully
* 500:
* description: Server error
*/
router.get("/submission-audit-history",[verifySignature, verifyToken], submissionController.getSubmissionHistory);
/**
* @swagger
* /api/submissions/deleteDraftSubmissionData:
* get:
* summary: Delete submission (hard delete)
* tags: [Submissions]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: id
* required: true
* schema: { type: integer }
* responses:
* 200:
* description: successfully Deleted
* 404:
* description: Not found
* 500:
* description: Server error
*/
router.get("/submissions/deleteDraftSubmissionData",[verifySignature, verifyToken], submissionController.deleteDraftSubmissionData);
/**
* @swagger
* /api/submission_deadlines:
* post:
* summary: Create or update submission deadline configuration (only one record allowed)
* tags: [Config]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* 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]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* 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",[verifySignature, verifyToken],dashboardController.getEstablishmentDashboard);
/**
* @swagger
* /api/admin_dashboard:
* get:
* summary: Get dashboard data for admin user
* tags: [Dashboard]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: quarter
* required: false
* schema:
* type: string
* - in: query
* name: year
* required: false
* schema:
* type: integer
* responses:
* 200:
* description: Dashboard data fetched successfully
* 400:
* description: Bad request
* 403:
* description: Invalid signature
* 401:
* description: Unauthorized
* 500:
* description: Server error
*/
router.get("/admin_dashboard",[verifySignature, verifyToken], dashboardController.adminDashboard);
/**
* @swagger
* /api/notification_templates:
* get:
* summary: Get all notification templates
* tags: [Notification Templates]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Fetched successfully
*/
router.get("/notification_templates",[verifySignature, verifyToken], notificationTemplateController.getAllTemplates);
/**
* @swagger
* /api/notification_templates/{id}:
* get:
* summary: Get a single notification template
* tags: [Notification Templates]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* responses:
* 200:
* description: Fetched successfully
*/
router.get("/notification_templates/:id",[verifySignature, verifyToken], notificationTemplateController.getTemplateById);
/**
* @swagger
* /api/notification_templates/{id}:
* put:
* summary: Update a notification template
* tags: [Notification Templates]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* 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",[verifySignature, verifyToken], notificationTemplateController.updateTemplate);
/**
* @swagger
* /api/quarterly_windows:
* post:
* summary: Create new quarterly configuration
* tags: [Quarterly Windows Configuration]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* survey_name: { type: string, example: "Test"}
* year: { type: integer }
* quarter: { type: string, example: "Q1" }
* start_date: { type: string, format: date }
* end_date: { type: string, format: date }
* grace_periods_days: { type: integer }
* is_active: { type: boolean }
* responses:
* 201:
* description: Created successfully
*/
router.post("/quarterly_windows",[verifySignature, verifyToken], quarterlyWindowsController.createConfig);
/**
* @swagger
* /api/quarterly_windows:
* get:
* summary: Get all quarterly configurations
* tags: [Quarterly Windows Configuration]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Fetched successfully
*/
router.get("/quarterly_windows",[verifySignature, verifyToken], quarterlyWindowsController.getAllConfigs);
/**
* @swagger
* /api/quarterly_windows/{id}:
* get:
* summary: Get configuration by ID
* tags: [Quarterly Windows Configuration]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* responses:
* 200:
* description: Fetched successfully
*/
router.get("/quarterly_windows/:id",[verifySignature, verifyToken], quarterlyWindowsController.getConfigById);
/**
* @swagger
* /api/quarterly_windows/{id}:
* put:
* summary: Update configuration by ID
* tags: [Quarterly Windows Configuration]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - name: id
* in: path
* required: true
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* survey_name: { type: string, example: "Test"}
* year: { type: integer }
* quarter: { type: string, example: "Q1" }
* start_date: { type: string, format: date }
* end_date: { type: string, format: date }
* grace_periods_days: { type: integer }
* is_active: { type: boolean }
* responses:
* 200:
* description: Updated successfully
*/
router.put("/quarterly_windows/:id",[verifySignature, verifyToken], quarterlyWindowsController.updateConfig);
/**
* @swagger
* /api/password-reset-requests:
* get:
* summary: Get all establishment password reset requests
* tags: [Establishment Reset Requests]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: []
* responses:
* 200:
* description: List of all reset requests
* 500:
* description: Internal server error
*/
router.get("/password-reset-requests", establishmentController.getAllRequests);
/**
* @swagger
* /api/password-reset-requests:
* post:
* summary: Create a new establishment reset request
* tags: [Establishment Reset Requests]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_name
* - establishment_code
* - registered_email
* properties:
* establishment_name:
* type: string
* example: "ABC Industries"
* establishment_code:
* type: string
* example: "EST1234"
* registered_email:
* type: string
* example: "contact@abcindustries.com"
* contact_person_name:
* type: string
* example: "John Doe"
* contact_phone:
* type: string
* example: "+971501234567"
* additional_notes:
* type: string
* example: "Forgot credentials and need account reset."
* responses:
* 201:
* description: Reset request created successfully
* 400:
* description: Validation failed or mismatch between establishment and email
* 404:
* description: Establishment or user not found
* 500:
* description: Internal server error
*/
router.post("/password-reset-requests", establishmentController.createRequest);
/**
* @swagger
* /api/forgot-password/request-otp:
* post:
* summary: Request OTP for establishment user pwd reset
* tags: [Establishment Pwd Reset Requests]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - establishment_name
* - establishment_code
* - registered_email
* properties:
* establishment_name: { type: string, example: "ABC Industries" }
* establishment_code: { type: string, example: "EST1234" }
* registered_email: { type: string, example: "contact@abcindustries.com" }
* user_type: {type: string, example: "establishment_user"}
* responses:
* 200:
* description: OTP sent successfully
* 400:
* description: Missing or invalid data
* 404:
* description: Establishment or user not found
* 500:
* description: Server error
*/
router.post("/forgot-password/request-otp",[verifySignature], establishmentController.forgotPasswordRequestOTP);
/**
* @swagger
* /api/forgot-password/verify-otp:
* post:
* summary: Verify OTP and reset establishment user Pwd
* tags: [Establishment Pwd Reset Requests]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - registered_email
* - otp
* - password
* - confirm_password
* properties:
* registered_email: { type: string, example: "contact@abcindustries.com" }
* otp: { type: string, example: "123456" }
* password: { type: string, example: "<pwd>" }
* confirm_password: { type: string, example: "<pwd>" }
* responses:
* 200:
* description: Password reset successfully
* 400:
* description: Invalid OTP or password mismatch
* 404:
* description: User or OTP not found
* 500:
* description: Server error
*/
router.post("/forgot-password/verify-otp",[verifySignature], establishmentController.forgotPasswordVerifyOTP);
/**
* @swagger
* /api/emirates:
* get:
* summary: Get all Emirates
* tags: [Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Emirates fetched successfully
* 500:
* description: Server error
*/
router.get("/emirates", [verifySignature, verifyToken], establishmentController.getAllEmirates);
/**
* @swagger
* /api/city-towns:
* get:
* summary: Get all City/Town (optional filter by emirate_id)
* tags: [Master]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: emirate_id
* schema:
* type: integer
* description: Filter cities by emirate_id
* responses:
* 200:
* description: City/Town fetched successfully
* 500:
* description: Server error
*/
router.get("/city-towns", [verifySignature, verifyToken], establishmentController.getAllCityTowns);
/**
* @swagger
* /api/establishment/download-sample-file:
* get:
* summary: Download sample CSV template for bulk company profile upload
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Sample CSV file downloaded successfully
* content:
* text/csv:
* schema:
* type: string
* format: binary
* 404:
* description: File not found
* 500:
* description: Server error
*/
router.get("/establishment/download-sample-file",[verifySignature, verifyToken], establishmentController.downloadCompanyProfileSample);
/**
* @swagger
* /api/unit_master_download_sample_file:
* get:
* summary: Download sample CSV template for bulk Unit Master upload
* tags: [Products]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* responses:
* 200:
* description: Sample CSV file downloaded successfully
* content:
* text/csv:
* schema:
* type: string
* format: binary
* 404:
* description: File not found
* 500:
* description: Server error
*/
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);
/**
* @swagger
* /api/manufacturing/getManufacturingMonthlyOverview:
* get:
* summary: Get Manufacturing IPI Overview by year and quarter
* tags: [ManufacturingIPI]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
* parameters:
* - in: query
* name: year
* required: true
* schema:
* type: integer
* description: Year (e.g., 2025)
* - in: query
* name: quarter
* required: true
* schema:
* type: string
* enum: [Q1, Q2, Q3, Q4]
* description: Quarter (Q1-Q4)
* responses:
* 200:
* description: Manufacturing IPI Overview fetched successfully
* 400:
* description: Invalid parameters
* 404:
* description: Data not found
* 500:
* description: Server error
*/
router.get("/manufacturing/getManufacturingMonthlyOverview", [verifySignature, verifyToken], ManufacturingIpiController.getManufacturingMonthlyOverviewByYearMonth);
/**
* @swagger
* /api/auth/request-otp:
* post:
* summary: Request OTP for login Admin or Establishment User
* tags: [Admin And Establishments User Auth]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - registered_email
* properties:
* registered_email: { type: string, example: "contact@abcindustries.com" }
* responses:
* 200:
* description: OTP sent successfully
* 400:
* description: Missing or invalid data
* 404:
* description: Establishment or user not found
* 500:
* description: Server error
*/
router.post("/auth/request-otp",[verifySignature], establishmentController.requestOTPForLogin);
/**
* @swagger
* /api/auth/verify-otp:
* post:
* summary: Verify OTP to signin
* tags: [Admin And Establishments User Auth]
* security:
* - appSignature: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - registered_email
* - otp
* properties:
* registered_email: { type: string, example: "contact@abcindustries.com" }
* otp: { type: string, example: "123456" }
* responses:
* 200:
* description: Otp verified successfully
* 400:
* description: Invalid OTP
* 404:
* description: User or OTP not found
* 500:
* description: Server error
*/
router.post("/auth/verify-otp",[verifySignature], establishmentController.verifyOTPForLogin);
/**
* @swagger
* /api/calculation-log/getCalculationLogs:
* get:
* summary: Get calculation logs by reference year and month
* tags: [CalculationLog]
* security:
* - appSignature: []
* - CSRF: []
* cookieAuth: []
* parameters:
* - in: query
* name: year
* required: true
* schema:
* type: integer
* example: 2025
* description: Reference year
* - in: query
* name: month
* required: true
* schema:
* type: integer
* example: 4
* description: Reference month (1-12)
* responses:
* 200:
* description: Calculation log details fetched successfully
* 400:
* description: Year and month are required
* 404:
* description: No records found
* 500:
* description: Server error
*/
router.get( "/calculation-log/getCalculationLogs", [verifySignature, verifyToken], calculationController.getCalculationLogsByYearMonth);
module.exports = router;