High-severity issues fixed

This commit is contained in:
unknown 2025-12-15 18:59:01 +05:30
parent e635c9787a
commit 3a6c3c6c8f
10 changed files with 433 additions and 197 deletions

View File

@ -2,6 +2,7 @@ const db = require("../models");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
require("dotenv").config();
const sanitize = require("sanitize-html");
const User = db.user;
const EstablishmentUser = db.EstablishmentUser;
@ -115,10 +116,18 @@ exports.logout = (req, res) => {
});
};
const sanitizeStringValue = (value) =>
typeof value === "string"
? sanitize(value, { allowedTags: [], allowedAttributes: {} })
: value;
// Register new user
exports.register = async (req, res) => {
try {
const { name, email, password } = req.body;
const name = sanitizeStringValue(req.body.name);
const email = sanitizeStringValue(req.body.email);
const password = req.body.password;
if (!name || !email || !password)
return res.status(400).send({
status: "error",
@ -141,8 +150,7 @@ exports.register = async (req, res) => {
return res.status(201).send({
status: "ok",
code: "REGISTERED",
message: "User registered successfully",
data: newUser
message: "User registered successfully"
});
} catch (err) {

View File

@ -19,6 +19,12 @@ const path = require("path");
const { version } = require("os");
const sequelize = db.sequelize;
const { sanitizeForLog } = require("../utils/sanitize");
const sanitize = require("sanitize-html");
const sanitizeStringValue = (value) =>
typeof value === "string"
? sanitize(value, { allowedTags: [], allowedAttributes: {} })
: value;
exports.testEmail = async (req, res) => {
placeHolderData = {
@ -137,39 +143,39 @@ exports.createEstablishment = async (req, res) => {
// Create establishment record
const establishment = await Establishment.create({
establishment_code,
factory_name,
permanent_factory_code: permanent_factory_code || null,
industry_code: industry_code || null,
industry_code_production: industry_code_production || null,
industry_code_mismatch_remarks,
license_number,
isic_code,
description,
establishment_address,
establishment_code: sanitizeStringValue(establishment_code),
factory_name: sanitizeStringValue(factory_name),
permanent_factory_code: sanitizeStringValue(permanent_factory_code),
industry_code: sanitizeStringValue(industry_code),
industry_code_production: sanitizeStringValue(industry_code_production),
industry_code_mismatch_remarks: sanitizeStringValue(industry_code_mismatch_remarks),
license_number: sanitizeStringValue(license_number),
isic_code: sanitizeStringValue(isic_code),
description: sanitizeStringValue(description),
establishment_address: sanitizeStringValue(establishment_address),
establishment_city_town_id,
establishment_emirate_id,
establishment_postal_code,
establishment_po_box,
establishment_makani_number,
establishment_contact_person_name,
establishment_contact_person_designation,
establishment_mobile_number,
establishment_contact_email,
establishment_website,
establishment_postal_code: sanitizeStringValue(establishment_postal_code),
establishment_po_box: sanitizeStringValue(establishment_po_box),
establishment_makani_number: sanitizeStringValue(establishment_makani_number),
establishment_contact_person_name: sanitizeStringValue(establishment_contact_person_name),
establishment_contact_person_designation: sanitizeStringValue(establishment_contact_person_designation),
establishment_mobile_number: sanitizeStringValue(establishment_mobile_number),
establishment_contact_email: sanitizeStringValue(establishment_contact_email),
establishment_website: sanitizeStringValue(establishment_website),
corporate_same_as_establishment,
corporate_name,
corporate_address,
corporate_name: sanitizeStringValue(corporate_name),
corporate_address: sanitizeStringValue(corporate_address),
corporate_city_town_id,
corporate_emirate_id,
corporate_postal_code,
corporate_po_box,
corporate_makani_number,
corporate_contact_person_name,
corporate_contact_person_designation,
corporate_mobile_number,
corporate_email,
corporate_website,
corporate_postal_code: sanitizeStringValue(corporate_postal_code),
corporate_po_box: sanitizeStringValue(corporate_po_box),
corporate_makani_number: sanitizeStringValue(corporate_makani_number),
corporate_contact_person_name: sanitizeStringValue(corporate_contact_person_name),
corporate_contact_person_designation: sanitizeStringValue(corporate_contact_person_designation),
corporate_mobile_number: sanitizeStringValue(corporate_mobile_number),
corporate_email: sanitizeStringValue(corporate_email),
corporate_website: sanitizeStringValue(corporate_website),
emirati_male,
emirati_female,
non_emirati_male,
@ -179,7 +185,6 @@ exports.createEstablishment = async (req, res) => {
created_by: req.body.created_by || req.user.id,
created_at: new Date(),
});
// Hash password
const hashedPassword = await bcrypt.hash(establishment_user.password, 10);
@ -194,46 +199,15 @@ exports.createEstablishment = async (req, res) => {
//send email to user
placeHolderData = {
contact_name : sanitizeForLog(establishment_user.name),
contact_name : sanitizeStringValue(establishment_user.name),
portal_url : process.env.FE_BASE_URL,
username : sanitizeForLog(establishment_user.email),
username : sanitizeStringValue(establishment_user.email),
password : establishment_user.password,
support_email : process.env.SUPPORT_EMAIL,
support_phone : process.env.SUPPORT_PHONE,
}
await sendEmailService(sanitizeForLog(establishment_user.email), 'establishment_user_creation_to_user', placeHolderData);
// insert establishment_products
// if (Array.isArray(establishment_products) && establishment_products.length > 0) {
// // remove duplicates from request itself
// let uniqueProducts = [...new Set(establishment_products.map(x => x.product_id))];
// // now check which already exist for this establishment
// const existing = await EstablishmentProduct.findAll({
// where: {
// establishment_id: establishment.id,
// product_id: uniqueProducts
// },
// attributes: ['product_id']
// });
// const existingIds = existing.map(x => x.product_id);
// // filter only new ones (not existing)
// const newProducts = uniqueProducts
// .filter(pid => !existingIds.includes(pid))
// .map(pid => ({
// establishment_id: establishment.id,
// product_id: pid,
// created_at: new Date(),
// }));
// // only insert if have new ones
// if (newProducts.length) {
// await EstablishmentProduct.bulkCreate(newProducts);
// }
// }
await sendEmailService(sanitizeStringValue(establishment_user.email), 'establishment_user_creation_to_user', placeHolderData);
// insert establishment_products
if (Array.isArray(establishment_products) && establishment_products.length > 0)
@ -273,14 +247,15 @@ exports.createEstablishment = async (req, res) => {
await EstablishmentProduct.bulkCreate(insertData);
}
}
//Return success response
return res.status(201).send({
status: "success",
message: "Establishment and linked user created successfully",
data: {
establishment,
data: {
establishment:{
id:establishment.id,
establishment_code: establishment.establishment_code,
},
user: {
id: user.id,
name: user.name,
@ -290,18 +265,14 @@ exports.createEstablishment = async (req, res) => {
});
} catch (err) {
if (err.name === "SequelizeUniqueConstraintError") {
// extract exact field
const field = err.errors[0].path; // <-- this gives the column name
const field = err.errors[0].path;
return res.status(400).json({
status: "failed",
message: `${field} already exists`
});
}
return res.status(500).send({status: "failed",message: err.message || "Internal server error",});
return res.status(500).send({status: "failed",message: err.message,});
}
};
@ -807,7 +778,29 @@ exports.getAllEmirates = async (req, res) => {
exports.getAllCityTowns = async (req, res) => {
try {
const { emirate_id } = req.query;
let { emirate_id } = req.query;
if (emirate_id) {
emirate_id = Number(emirate_id);
if (isNaN(emirate_id)) {
return res.status(400).send({
status: "failed",
message: "Invalid emirate_id"
});
}
const emirateExists = await Emirate.findOne({
where: { id: emirate_id }
});
if (!emirateExists) {
return res.status(404).send({
status: "failed",
message: "Emirate not found"
});
}
}
const whereClause = {};
if (emirate_id) {
@ -819,8 +812,13 @@ exports.getAllCityTowns = async (req, res) => {
attributes: ["id", "name", "emirate_id"],
order: [["name", "ASC"]],
});
const sanitizedCities = cities.map(city => ({
id: city.id,
name: sanitizeStringValue(city.name),
emirate_id: city.emirate_id,
}));
return res.status(200).send({status: "success", message: "City/Town fetched successfully", data: cities, });
return res.status(200).send({status: "success", message: "City/Town fetched successfully", data: sanitizedCities, });
} catch (err) {
return res.status(500).send({ status: "failed", message: err.message || "Internal server error", });

View File

@ -8,16 +8,69 @@ const UnitMaster = db.UnitMaster;
exports.createEstablishmentProduct = async (req, res) => {
try {
const { establishment_id , product_id, action_done_by , created_by } = req.body;
let { establishment_id , product_id, action_done_by , created_by } = req.body;
if (establishment_id === undefined) {
return res.status(400).json({
status: "failed",
message: "establishment_id is required"
});
}
establishment_id = Number(establishment_id);
if (!Number.isInteger(establishment_id) || establishment_id <= 0) {
return res.status(400).json({
status: "failed",
message: "Invalid establishment_id"
});
}
if (product_id === undefined) {
return res.status(400).json({
status: "failed",
message: "product_id is required"
});
}
product_id = Number(product_id);
if (!Number.isInteger(product_id) || (product_id <= 0 && product_id > 10)) {
return res.status(400).json({
status: "failed",
message: "Invalid product_id"
});
}
if (action_done_by === undefined) {
return res.status(400).json({
status: "failed",
message: "action_done_by is required"
});
}
if (typeof action_done_by !== "string" || action_done_by.trim().length === 0) {
return res.status(400).json({
status: "failed",
message: "Invalid action_done_by"
});
}
action_done_by = action_done_by.trim();
const existingMapping = await EstablishmentProduct.findOne({
where: {
establishment_id,
product_id
}
});
if (existingMapping) {
return res.status(409).json({
status: "failed",
message: "This product is already mapped to the establishment"
});
}
const data = await EstablishmentProduct.create({
establishment_id,
product_id,
action_done_by,
created_by: created_by || req.user?.id || null,
});
res.status(201).send({'status':"success",'message':"Creation successful",'data': data });
res.status(201).send({'status':"success",'message':"Establishment Product Created successfully."});
} catch (err) {
res.status(500).send({'status':"failed",'message':err.message });
@ -28,8 +81,16 @@ exports.getAllEstablishmentProducts = async (req, res) => {
try {
const whereClause = {};
if (req.query.establishment_id) {
whereClause.establishment_id = req.query.establishment_id;
if (typeof req.query.establishment_id !== "undefined") {
const establishmentId = parseInt(req.query.establishment_id, 10);
if (!Number.isInteger(establishmentId) || establishmentId <= 0) {
return res.status(400).json({
status: "failed",
message: "Invalid establishment_id"
});
}
whereClause.establishment_id = establishmentId;
}
const data = await EstablishmentProduct.findAll({

View File

@ -1,6 +1,7 @@
const db = require("../models");
const bcrypt = require("bcryptjs");
const EstablishmentUser = db.EstablishmentUser;
const Establishment = db.Establishment;
const { sendEmailService } = require("../services/email.service");
const { sanitizeForLog } = require("../utils/sanitize");
@ -8,64 +9,110 @@ const { sanitizeForLog } = require("../utils/sanitize");
// Create User
exports.createUser = async (req, res) => {
try {
const { establishment_id, name, email, password , gender} = req.body;
const hashed = await bcrypt.hash(password, 10);
email = sanitizeForLog(email || "");
name = sanitizeForLog(name || "");
gender = sanitizeForLog(gender || "");
if (!establishment_id || !email) {
return res.status(400).send({
let { establishment_id, name, email, password, gender } = req.body;
establishment_id = Number(establishment_id);
if (!Number.isInteger(establishment_id) || establishment_id <= 0) {
return res.status(400).json({
status: "error",
code: "MISSING_FIELDS",
message: "establishment_id and email are required"
message: "Invalid establishment_id"
});
}
const existing = await EstablishmentUser.findOne({ where: { email, is_active: true } });
if (existing) {
return res.status(400).send({
const establishment = await Establishment.findByPk(establishment_id);
if (!establishment) {
return res.status(404).json({
status: "error",
message: "Establishment not found"
});
}
if (typeof email !== "string" || email.trim().length === 0) {
return res.status(400).json({
status: "error",
message: "Email is required"
});
}
email = email.trim().toLowerCase();
if (typeof password !== "string" || password.length < 6) {
return res.status(400).json({
status: "error",
message: "Password must be at least 6 characters long"
});
}
name = typeof name === "string" ? name.trim() : null;
if (gender) {
gender = gender.toString().toLowerCase();
if (!["male", "female", "other"].includes(gender)) {
return res.status(400).json({
status: "error",
message: "Invalid gender"
});
}
gender = gender.charAt(0).toUpperCase() + gender.slice(1);
}
const existingUser = await EstablishmentUser.findOne({
where: { email, is_active: true }
});
if (existingUser) {
return res.status(409).json({
status: "error",
code: "EMAIL_EXISTS",
message: "Email already exists"
});
}
const hashedPassword = await bcrypt.hash(password, 10);
const user = await EstablishmentUser.create({
establishment_id,
name,
email,
password: hashed,
password: hashedPassword,
gender,
created_by: req.user.id,
created_by: req.user.id
});
//send email to user
placeHolderData = {
contact_name : name,
portal_url : process.env.FE_BASE_URL,
username : email,
password : password,
support_email : process.env.SUPPORT_EMAIL,
support_phone : process.env.SUPPORT_PHONE,
}
await sendEmailService(email, 'establishment_user_creation_to_user', placeHolderData);
await sendEmailService(email, "establishment_user_creation_to_user", {
contact_name: name,
portal_url: process.env.FE_BASE_URL,
username: email,
password,
support_email: process.env.SUPPORT_EMAIL,
support_phone: process.env.SUPPORT_PHONE
});
return res.status(201).send({'status':"ok", 'message':"Creation successful",'data': user });
} catch (err) {
return res.status(500).send({'status':"error",'message':err.message });
return res.status(201).json({
status: "success",
message: "Establishment User created successfully",
data: {
name: user.name,
email: user.email,
}
});
} catch (error) {
return res.status(500).json({
status: "error",
message: error.message
});
}
};
// Get all users
exports.getAllUsers = async (req, res) => {
try {
try {
let users;
if (typeof req.query.establishment_id !== 'undefined') {
const establishmentId = parseInt(req.query.establishment_id, 10);
if (Number.isNaN(establishmentId)) {
return res.status(400).json({
status: "failed",
message: "Invalid establishment_id"
});
}
users = await EstablishmentUser.findAll({ where:{ establishment_id : establishmentId} });
}else{
users = await EstablishmentUser.findAll();
}
const users = await EstablishmentUser.findAll({ where:{ establishment_id : req.query.establishment_id} });
return res.status(200).send({'status':"success",'message':"Fetched successfully",'data': users });
} catch (err) {

View File

@ -1,12 +1,19 @@
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const db = require("../models");
const sanitize = require("sanitize-html");
const EstablishmentUser = db.EstablishmentUser;
const sanitizeStringValue = (value) =>
typeof value === "string"
? sanitize(value, { allowedTags: [], allowedAttributes: {} })
: value;
// User Login
exports.login = async (req, res) => {
try {
const { email, password } = req.body;
const email = sanitizeStringValue(req.body.email);
const password = req.body.password;
if (!email || !password)
return res.status(400).send({'status':"failed",'message':"Email and password required",'data': ""});
@ -16,11 +23,17 @@ exports.login = async (req, res) => {
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword)
return res.status(401).json({ message: "Invalid password" });
// Create JWT token
const token = jwt.sign({ id: user.id, email: user.email , name: user.name, establishment_id: user.establishment_id }, process.env.JWT_SECRET, {
expiresIn: "6h",
});
const token = jwt.sign(
{
id: user.id,
email: sanitizeStringValue(user.email),
name: sanitizeStringValue(user.name),
establishment_id: user.establishment_id
},
process.env.JWT_SECRET,
{ expiresIn: "6h" }
);
res.status(200).send({'status':"success",'message':"Login successful",'data': token });

View File

@ -5,12 +5,20 @@ const db = require("../models");
const { Sequelize } = require("sequelize");
const Product = db.Product;
const UnitMaster = db.UnitMaster;
const sanitize = require("sanitize-html");
const cleanString = (value) =>
typeof value === "string"
? sanitize(value, { allowedTags: [], allowedAttributes: {} })
: value;
exports.createProduct = async (req, res) => {
try {
const { product_name, hs_code, hs_description } = req.body;
const product_name = cleanString(req.body.product_name);
const hs_description = cleanString(req.body.hs_description);
const hs_code = req.body.hs_code;
const unit_id = req.body.unit_id;
if (hs_description && hs_description.length > 1000) {
return res.status(400).json({
status: "failed",
@ -51,9 +59,16 @@ exports.createProduct = async (req, res) => {
message: `HS Code '${hs_code}' already exists.`
});
}
req.body.created_by = req.user.id;
const data = await Product.create(req.body);
res.status(201).send({'status':"success",'message':"created successfully",'data': data });
await Product.create({
product_name,
hs_code,
hs_description,
unit_id,
created_by: req.user.id
});
res.status(201).send({'status':"success",'message':"created successfully." });
} catch (error) {
res.status(500).send({'status':"failed",'message':error.message });
}

View File

@ -5,6 +5,7 @@ const QuarterlyWindowsConfiguration = db.QuarterlyWindowsConfiguration;
const Establishment = db.Establishment;
const EstablishmentUser = db.EstablishmentUser;
const { sendEmailService } = require("../services/email.service");
const sanitize = require("sanitize-html");
// Create new configuration
@ -23,13 +24,31 @@ exports.createConfig = async (req, res) => {
// get active establishment count
const assignedCount = await Establishment.count({
where: { is_active: true }
});
// set auto values before inserting
req.body.assigned = assignedCount;
req.body.responded = 0;
req.body.not_responded = assignedCount;
req.body.created_by = req.body.created_by || req.user.id;
});
function sanitizeValue(value) {
if (typeof value === "string") {
return sanitize(value, {
allowedTags: [],
allowedAttributes: {},
});
}
if (Array.isArray(value)) {
return value.map(sanitizeValue);
}}
const payload = {
survey_name: sanitizeValue(req.body.survey_name),
quarter: sanitizeValue(req.body.quarter),
year: req.body.year,
start_date: req.body.start_date,
end_date: req.body.end_date,
grace_periods_days: req.body.grace_periods_days,
assigned: assignedCount,
responded: 0,
not_responded: assignedCount,
created_by: req.user.id,
};
const placeholder = {
survey_name: survey_name,
@ -42,11 +61,10 @@ exports.createConfig = async (req, res) => {
support_phone: process.env.SUPPORT_PHONE
};
const data = await QuarterlyWindowsConfiguration.create(req.body);
const data = await QuarterlyWindowsConfiguration.create(payload);
res.status(201).send({
status: "success",
message: "Quarterly window configuration created successfully",
data,
message: "Quarterly window configuration created successfully"
});
sendEmailsToEstablishments(placeholder);
} catch (err) {

View File

@ -5,11 +5,26 @@ const { UnitMaster } = require("../models");
const fs = require("fs");
const csv = require("csv-parser");
const path = require("path");
const sanitize = require("sanitize-html");
const sanitizeStringValue = (value) =>
typeof value === "string"
? sanitize(value, { allowedTags: [], allowedAttributes: {} }).trim()
: value;
// Create new Unit
exports.createUnit = async (req, res) => {
try {
const { uom } = req.body;
let {
uom,
description,
is_base_unit,
base_unit_id,
factor
} = req.body;
uom = sanitizeStringValue(uom);
description = sanitizeStringValue(description);
factor = sanitizeStringValue(factor);
if (!uom || typeof uom !== "string" || !uom.trim()) {
return res.status(400).json({
@ -17,27 +32,47 @@ exports.createUnit = async (req, res) => {
message: "UOM (Unit Name) is required and must be a non-empty string.",
});
}
const cleaned = uom.replace(/[^a-zA-Z]/g, "").toUpperCase();
if (!description) {
return res.status(400).json({
status: "error",
message: "Description is required and must be a non-empty string.",
});
}
const cleaned = uom.replace(/[^A-Za-z]/g, "").toUpperCase();
if (!cleaned) {
return res.status(400).json({
status: "error",
message: "UOM must contain at least one letter (A-Z).",
message: "UOM must contain at least one alphabetic character.",
});
}
is_base_unit = Boolean(is_base_unit);
if (base_unit_id !== null && base_unit_id !== undefined) {
base_unit_id = Number(base_unit_id);
if (Number.isNaN(base_unit_id)) {
return res.status(400).json({
status: "error",
message: "base_unit_id must be a valid number."
});
}
}
// SAFE: no Sequelize.where, no SQL functions
const existingUOM = await UnitMaster.findOne({
where: Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("uom")),
uom.toLowerCase()
),
where: {
uom: cleaned
}
});
if (existingUOM)
if (existingUOM) {
return res.status(400).json({
status: "error",
message: `Unit '${uom}' already exists with short key '${existingUOM.uom_short_name}'.`,
message: `Unit '${cleaned}' already exists with short key '${existingUOM.uom_short_name}'.`,
});
}
//Generate short name (same rule as CSV)
// Abbreviation map
const abbreviationMap = {
METER: "MT",
METRE: "MT",
@ -58,44 +93,51 @@ exports.createUnit = async (req, res) => {
UNIT: "UNT",
};
let uomShort;
let uomShort =
cleaned.length <= 5
? cleaned
: (abbreviationMap[cleaned] || cleaned.substring(0, 3)) +
Math.random().toString(36).substring(2, 4).toUpperCase();
if (cleaned.length <= 5) {
uomShort = cleaned;
} else {
// If >5 letters, use abbreviation or auto-generate
const baseShort = abbreviationMap[cleaned] || cleaned.substring(0, 3);
const randomLetters = () =>
Array.from({ length: 2 }, () =>
String.fromCharCode(65 + Math.floor(Math.random() * 26))
).join("");
uomShort = `${baseShort}${randomLetters()}`.substring(0, 5);
}
uomShort = uomShort.substring(0, 5);
let exists = await UnitMaster.findOne({
where: Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("uom_short_name")),
uomShort.toLowerCase()
),
where: {
uom_short_name: uomShort
}
});
while (exists) {
const randomSuffix = Math.random().toString(36).substring(2, 3).toUpperCase();
uomShort = (uomShort.substring(0, 4) + randomSuffix).substring(0, 5);
const suffix = Math.random().toString(36).substring(2, 3).toUpperCase();
uomShort = (uomShort.substring(0, 4) + suffix).substring(0, 5);
exists = await UnitMaster.findOne({
where: Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("uom_short_name")),
uomShort.toLowerCase()
),
where: {
uom_short_name: uomShort
}
});
}
req.body.uom_short_name = uomShort;
req.body.created_by = req.body.created_by || req.user.id;
const unit = await UnitMaster.create(req.body);
res.status(201).json({ status: "success", data: unit });
const unit = await UnitMaster.create({
uom: cleaned,
uom_short_name: uomShort,
description,
is_base_unit,
base_unit_id,
factor: factor || null,
created_by: req.body.created_by || req.user.id
});
return res.status(201).json({
status: "success",
message: "Unit created successfully."
});
} catch (err) {
res.status(400).json({ status: "error", message: err.message });
return res.status(400).json({
status: "error",
message: err.message
});
}
};
@ -385,19 +427,16 @@ exports.uploadUnitMasterFromCSV = async (req, res) => {
let uomShort = row._generatedShort;
const description = row._description;
const normalizedUom = sanitizeStringValue(uom).toUpperCase();
const normalizedShort = uomShort.toUpperCase();
const existing = await UnitMaster.findOne({
where: {
[Op.or]: [
Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("uom")),
uom.toLowerCase()
),
Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("uom_short_name")),
uomShort.toLowerCase()
),
],
},
{ uom: normalizedUom },
{ uom_short_name: normalizedShort }
]
}
});
if (existing) {

View File

@ -5,15 +5,43 @@ const VariationReasonMaster = db.VariationReasonMaster;
// Create
exports.createReason = async (req, res) => {
try {
const { reason, high_or_low } = req.body;
let { reason, high_or_low } = req.body;
if (typeof reason !== "string" || reason.trim().length === 0) {
return res.status(400).json({
status: "failed",
message: "Reason is required"
});
}
reason = reason.trim();
if (!reason)
return res.status(400).send({ status: "failed", message: "Reason is required" });
if (high_or_low) {
high_or_low = high_or_low.toString().toLowerCase();
if (!["low", "high"].includes(high_or_low)) {
return res.status(400).json({
status: "failed",
message: "Invalid high_or_low value"
});
}
high_or_low = high_or_low === "low" ? "Low" : "High";
}
const newReason = await VariationReasonMaster.create({
reason,
high_or_low,
created_by: req.body.created_by || req.user.id
});
return res.status(201).json({
status: "success",
message: "Reason created successfully"
});
const newReason = await VariationReasonMaster.create({ reason, high_or_low, created_by: req.body.created_by || req.user.id });
res.status(201).send({ status: "success", message: "Reason created successfully", data: newReason });
} catch (err) {
res.status(500).send({ status: "failed", message: err.message });
return res.status(500).json({
status: "failed",
message: "Internal server error"
});
}
};

View File

@ -4,11 +4,20 @@ const ZeroTargetReasonMaster = db.ZeroTargetReasonMaster;
// Create
exports.create = async (req, res) => {
try {
const { reason, is_active } = req.body;
if (!reason) return res.status(400).send({ status: "failed", message: "Reason is required" });
let { reason, is_active } = req.body;
if (typeof reason !== "string" || reason.trim().length === 0) {
return res.status(400).json({
status: "failed",
message: "Reason is required"
});
}
reason = reason.trim();
if (typeof is_active !== "boolean") {
is_active = true;
}
const data = await ZeroTargetReasonMaster.create({ reason, is_active, created_by: req.user.id });
res.status(201).send({ status: "success", data });
res.status(201).send({ status: "success", message: "Record created successfully",});
} catch (err) {
res.status(500).send({ status: "failed", message: err.message });
}