conflict
This commit is contained in:
commit
7fa2ca890d
@ -5,6 +5,7 @@ require("dotenv").config();
|
|||||||
|
|
||||||
const User = db.user;
|
const User = db.user;
|
||||||
const EstablishmentUser = db.EstablishmentUser;
|
const EstablishmentUser = db.EstablishmentUser;
|
||||||
|
const Establishment = db.Establishment;
|
||||||
|
|
||||||
// Register new user
|
// Register new user
|
||||||
exports.register = async (req, res) => {
|
exports.register = async (req, res) => {
|
||||||
@ -45,9 +46,12 @@ exports.login = async (req, res) => {
|
|||||||
|
|
||||||
if(userRole == 'Admin')
|
if(userRole == 'Admin')
|
||||||
{
|
{
|
||||||
tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole }
|
tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole , last_login : userData.last_login }
|
||||||
|
await User.update({ last_login : Date() }, { where: { id: userData.id } });
|
||||||
}else{
|
}else{
|
||||||
tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole , establishment_id: userData.establishment_id }
|
const establishment_data = await Establishment.findByPk(userData.establishment_id);
|
||||||
|
tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole , establishment_id: userData.establishment_id , establishment_data , last_login : userData.last_login }
|
||||||
|
await EstablishmentUser.update({ last_login : Date() }, { where: { id: userData.id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = jwt.sign(tokenData, process.env.JWT_SECRET, {
|
const token = jwt.sign(tokenData, process.env.JWT_SECRET, {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const db = require("../models");
|
const db = require("../models");
|
||||||
const Submission = db.Submission;
|
const Submission = db.Submission;
|
||||||
const SubmissionProduct = db.SubmissionProduct;
|
const SubmissionProduct = db.SubmissionProduct;
|
||||||
|
const SubmissionHistory = db.SubmissionHistory;
|
||||||
const Establishment = db.Establishment;
|
const Establishment = db.Establishment;
|
||||||
const EstablishmentUser = db.EstablishmentUser;
|
const EstablishmentUser = db.EstablishmentUser;
|
||||||
const UnitMaster = db.UnitMaster;
|
const UnitMaster = db.UnitMaster;
|
||||||
@ -425,6 +426,90 @@ exports.viewSubmissionDetails = async (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// GET Submission History
|
||||||
|
exports.getSubmissionHistory = async (req, res) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const { establishment_id, year, quarter, product_id } = req.query;
|
||||||
|
|
||||||
|
let whereSubmission = {};
|
||||||
|
let whereProduct = {};
|
||||||
|
|
||||||
|
// dynamic filter user can pass 0, null, empty -> no filter
|
||||||
|
if (establishment_id) whereSubmission.establishment_id = establishment_id;
|
||||||
|
if (year) whereSubmission.year = year;
|
||||||
|
if (quarter) whereSubmission.quarter = quarter;
|
||||||
|
if (product_id) whereProduct.product_id = product_id;
|
||||||
|
|
||||||
|
// 1) Get all filtered submissions (or all)
|
||||||
|
const submissions = await Submission.findAll({
|
||||||
|
where: whereSubmission
|
||||||
|
});
|
||||||
|
|
||||||
|
if (submissions.length === 0) {
|
||||||
|
return res.status(200).json({ status:"success", data: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
const submissionIds = submissions.map(x => x.id);
|
||||||
|
|
||||||
|
// 2) Get submission products
|
||||||
|
const products = await SubmissionProduct.findAll({
|
||||||
|
where: {
|
||||||
|
submission_id: submissionIds,
|
||||||
|
...whereProduct
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{ model: Product, as: "product", attributes: ["product_name","hs_code"] }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (products.length === 0) {
|
||||||
|
return res.status(200).json({ status:"success", data: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
const productPKs = products.map(x => x.id);
|
||||||
|
|
||||||
|
// 3) history table
|
||||||
|
const history = await SubmissionHistory.findAll({
|
||||||
|
where: { primary_key: productPKs, table_name: "submission_products" },
|
||||||
|
order:[["created_at","DESC"]]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4) merge here
|
||||||
|
let finalData = products.map(prod => {
|
||||||
|
const sub = submissions.find(s => s.id === prod.submission_id);
|
||||||
|
const productHistory = history.filter(h => h.primary_key === prod.id);
|
||||||
|
|
||||||
|
return {
|
||||||
|
submission_date: sub.created_at,
|
||||||
|
establishment_id: sub.establishment_id,
|
||||||
|
year: sub.year,
|
||||||
|
quarter: sub.quarter,
|
||||||
|
hs_code: prod.product.hs_code,
|
||||||
|
product_name: prod.product.product_name,
|
||||||
|
status: sub.status,
|
||||||
|
actor: "Establishment",
|
||||||
|
details: productHistory.map(h => ({
|
||||||
|
column: h.column_name,
|
||||||
|
old: h.old_value,
|
||||||
|
new: h.new_value,
|
||||||
|
date: h.created_at
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// remove empty details rows
|
||||||
|
finalData = finalData.filter(item => item.details.length > 0);
|
||||||
|
|
||||||
|
return res.status(200).json({ status:"success", data: finalData });
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return res.status(500).json({ status:"failed", message: err.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exports.submissionEditRequest = async (req, res) => {
|
exports.submissionEditRequest = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,10 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
},
|
},
|
||||||
|
last_login: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
reset_otp: {
|
reset_otp: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ db.QuarterlyWindowsConfiguration = require("./quarterlyWindowsConfiguration.mode
|
|||||||
db.EstablishmentPasswordResetRequest = require("./establishmentPasswordResetRequest.model")(sequelize, DataTypes);
|
db.EstablishmentPasswordResetRequest = require("./establishmentPasswordResetRequest.model")(sequelize, DataTypes);
|
||||||
db.Emirate = require("./emirate.model")(sequelize, DataTypes);
|
db.Emirate = require("./emirate.model")(sequelize, DataTypes);
|
||||||
db.CityTown = require("./cityTown.model")(sequelize, DataTypes);
|
db.CityTown = require("./cityTown.model")(sequelize, DataTypes);
|
||||||
|
db.SubmissionHistory = require("./submissionHistory.model")(sequelize, DataTypes);
|
||||||
|
|
||||||
// Associations
|
// Associations
|
||||||
db.Establishment.hasMany(db.EstablishmentUser, {
|
db.Establishment.hasMany(db.EstablishmentUser, {
|
||||||
|
|||||||
48
app/models/submissionHistory.model.js
Normal file
48
app/models/submissionHistory.model.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// models/SubmissionHistory.js
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const SubmissionHistory = sequelize.define(
|
||||||
|
"SubmissionHistory",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
primary_key: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false, // submission_products.id
|
||||||
|
},
|
||||||
|
table_name: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
column_name: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
old_value: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
new_value: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
updated_by: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tableName: "submission_history",
|
||||||
|
timestamps: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return SubmissionHistory;
|
||||||
|
};
|
||||||
|
|
||||||
@ -18,6 +18,18 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
},
|
},
|
||||||
|
last_login: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
reset_otp: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
reset_otp_expires_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return User;
|
return User;
|
||||||
|
|||||||
@ -2073,7 +2073,49 @@ router.post("/getQuarterPeriods",[verifySignature, verifyToken], submissionContr
|
|||||||
* 500:
|
* 500:
|
||||||
* description: Server error
|
* description: Server error
|
||||||
*/
|
*/
|
||||||
router.get("/submissions/getPreviousForecastData", submissionController.getPreviousForecastData);
|
router.get("/submissions/getPreviousForecastData",[verifySignature, verifyToken], submissionController.getPreviousForecastData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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]
|
||||||
|
* 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", submissionController.getSubmissionHistory);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user