|
|
|
@ -635,7 +635,7 @@ exports.assignTeamMemberToQuotation = async (request, reply) => {
|
|
|
|
|
// 🔁 Raise ticket if applicable
|
|
|
|
|
const sensor = await Insensors.findOne({ hardwareId }).lean();
|
|
|
|
|
if (sensor?.customerId) {
|
|
|
|
|
await raiseATicketLikeLogic(sensor.customerId, hardwareId);
|
|
|
|
|
// await raiseATicketLikeLogic(sensor.customerId, hardwareId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return reply.send({
|
|
|
|
@ -3681,6 +3681,197 @@ exports.getIotDataByCustomerAndHardwareId = async (req, reply) => {
|
|
|
|
|
|
|
|
|
|
const cron = require("node-cron");
|
|
|
|
|
|
|
|
|
|
// const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
|
// try {
|
|
|
|
|
// if (!customerId || !connected_to) return;
|
|
|
|
|
|
|
|
|
|
// const sensors = await Insensors.find({ customerId }).lean();
|
|
|
|
|
// const orders = await Order.find({ customerId }).lean();
|
|
|
|
|
// if (!sensors.length) return;
|
|
|
|
|
|
|
|
|
|
// const masterSensor = sensors.find(
|
|
|
|
|
// s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"
|
|
|
|
|
// );
|
|
|
|
|
// if (!masterSensor) return;
|
|
|
|
|
|
|
|
|
|
// const orderMap = {};
|
|
|
|
|
// orders.forEach(order => {
|
|
|
|
|
// order.master_connections.forEach(conn => {
|
|
|
|
|
// orderMap[conn.hardwareId] = {
|
|
|
|
|
// masterName: conn.master_name || null,
|
|
|
|
|
// location: conn.location || null
|
|
|
|
|
// };
|
|
|
|
|
// });
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// const now = moment.tz("Asia/Kolkata");
|
|
|
|
|
|
|
|
|
|
// function getLatestDataRecord(records) {
|
|
|
|
|
// if (!records || records.length === 0) return null;
|
|
|
|
|
// return records.reduce((latest, record) => {
|
|
|
|
|
// if (!latest) return record;
|
|
|
|
|
// return new Date(record.date) > new Date(latest.date) ? record : latest;
|
|
|
|
|
// }, null);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 🔸 Master status check
|
|
|
|
|
// const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
|
|
|
|
|
// const latestMasterRecord = getLatestDataRecord(allMasterIotData);
|
|
|
|
|
|
|
|
|
|
// let masterConnectedStatus = "disconnected";
|
|
|
|
|
// let lastDataTime = "No data";
|
|
|
|
|
// let diffInMinutes = null;
|
|
|
|
|
|
|
|
|
|
// if (latestMasterRecord?.date) {
|
|
|
|
|
// const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
|
|
|
|
|
// diffInMinutes = now.diff(indiaTime, "minutes");
|
|
|
|
|
// lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
|
|
|
|
|
// if (diffInMinutes <= 2) masterConnectedStatus = "connected";
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 🔸 Slave status check
|
|
|
|
|
// const connectedSlaves = sensors.filter(
|
|
|
|
|
// s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
|
|
|
|
|
// );
|
|
|
|
|
// console.log("connectedSlaves",connectedSlaves)
|
|
|
|
|
// const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);
|
|
|
|
|
// // const allSlaveIotData = await IotData.find({ "tanks.tankhardwareId": { $in: slaveHardwareIds } }).lean();
|
|
|
|
|
// const allSlaveIotData = await IotData.aggregate([
|
|
|
|
|
// { $match: { "tanks.tankhardwareId": { $in: slaveHardwareIds } } },
|
|
|
|
|
// { $project: {
|
|
|
|
|
// hardwareId: 1,
|
|
|
|
|
// date: 1,
|
|
|
|
|
// "tanks": {
|
|
|
|
|
// $filter: {
|
|
|
|
|
// input: "$tanks",
|
|
|
|
|
// as: "tank",
|
|
|
|
|
// cond: { $in: ["$$tank.tankhardwareId", slaveHardwareIds] }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// ]);
|
|
|
|
|
// console.log("allSlaveIotData",allSlaveIotData)
|
|
|
|
|
// // 🔹 Create map of latest tank data
|
|
|
|
|
// const latestTankDataMap = {};
|
|
|
|
|
// for (const record of allSlaveIotData) {
|
|
|
|
|
// const baseDate = record.date;
|
|
|
|
|
// for (const tank of record.tanks || []) {
|
|
|
|
|
// const tankId = tank.tankhardwareId;
|
|
|
|
|
// const tankDate = tank.date || baseDate;
|
|
|
|
|
|
|
|
|
|
// if (!tankId || !tankDate) continue;
|
|
|
|
|
|
|
|
|
|
// if (
|
|
|
|
|
// !latestTankDataMap[tankId] ||
|
|
|
|
|
// new Date(tankDate) > new Date(latestTankDataMap[tankId].date)
|
|
|
|
|
// ) {
|
|
|
|
|
// latestTankDataMap[tankId] = {
|
|
|
|
|
// date: tankDate,
|
|
|
|
|
// time: tank.time,
|
|
|
|
|
// hardwareId: tankId
|
|
|
|
|
// };
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const disconnectedSlaves = [];
|
|
|
|
|
// for (const slave of connectedSlaves) {
|
|
|
|
|
// const latestSlaveRecord = latestTankDataMap[slave.tankhardwareId];
|
|
|
|
|
|
|
|
|
|
// let slaveStatus = "disconnected";
|
|
|
|
|
// if (latestSlaveRecord?.date) {
|
|
|
|
|
// const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
|
|
|
|
|
// const slaveDiff = now.diff(slaveTime, "minutes");
|
|
|
|
|
// if (slaveDiff <= 2) slaveStatus = "connected";
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (slaveStatus === "disconnected") {
|
|
|
|
|
// disconnectedSlaves.push({
|
|
|
|
|
// slaveHardwareId: slave.tankhardwareId,
|
|
|
|
|
// slaveName: slave.tankName || "Unknown Slave"
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// console.log(",disconnectedSlaves",disconnectedSlaves)
|
|
|
|
|
|
|
|
|
|
// if (disconnectedSlaves.length === 0 && masterConnectedStatus === "connected") {
|
|
|
|
|
// return; // ✅ No ticket needed
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
|
|
|
|
|
// if (!supportRecord) return;
|
|
|
|
|
|
|
|
|
|
// const existingIssues = supportRecord.issues || [];
|
|
|
|
|
// const existingMasterIssue = existingIssues.find(
|
|
|
|
|
// issue =>
|
|
|
|
|
// issue.hardwareId === connected_to &&
|
|
|
|
|
// issue.type === "GSM or LoRa Disconnected" &&
|
|
|
|
|
// issue.resolved !== true
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
// const alreadyReportedSlaves = new Set(existingMasterIssue?.hardwareIds || []);
|
|
|
|
|
// const newSlaveHardwareIds = [];
|
|
|
|
|
// const newSlaveNames = [];
|
|
|
|
|
|
|
|
|
|
// for (const slave of disconnectedSlaves) {
|
|
|
|
|
// if (!alreadyReportedSlaves.has(slave.slaveHardwareId)) {
|
|
|
|
|
// newSlaveHardwareIds.push(slave.slaveHardwareId);
|
|
|
|
|
// newSlaveNames.push(slave.slaveName);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
// // 🔸 Raise new issue
|
|
|
|
|
// if (!existingMasterIssue && (masterConnectedStatus === "disconnected" || disconnectedSlaves.length > 0)) {
|
|
|
|
|
// const newIssue = {
|
|
|
|
|
// type: "GSM or LoRa Disconnected",
|
|
|
|
|
// masterHardwareId: connected_to,
|
|
|
|
|
// hardwareId: connected_to,
|
|
|
|
|
// hardwareIds: newSlaveHardwareIds,
|
|
|
|
|
// slaveNames: newSlaveNames,
|
|
|
|
|
// message: `Master ${connected_to} is ${masterConnectedStatus} with ${disconnectedSlaves.length} disconnected slave(s)`,
|
|
|
|
|
// disconnectedAt: lastDataTime,
|
|
|
|
|
// lastTicketRaisedAt: formattedNow,
|
|
|
|
|
// resolved: false
|
|
|
|
|
// };
|
|
|
|
|
// await Support.findOneAndUpdate(
|
|
|
|
|
// { supportId: "AWHYSU64" },
|
|
|
|
|
// { $push: { issues: newIssue }, $set: { updatedAt: new Date() } }
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 🔸 Update existing issue with new disconnected slaves
|
|
|
|
|
// if (existingMasterIssue && newSlaveHardwareIds.length > 0) {
|
|
|
|
|
// await Support.findOneAndUpdate(
|
|
|
|
|
// { supportId: "AWHYSU64" },
|
|
|
|
|
// {
|
|
|
|
|
// $push: {
|
|
|
|
|
// "issues.$[elem].hardwareIds": { $each: newSlaveHardwareIds },
|
|
|
|
|
// "issues.$[elem].slaveNames": { $each: newSlaveNames }
|
|
|
|
|
// },
|
|
|
|
|
// $set: {
|
|
|
|
|
// "issues.$[elem].lastTicketRaisedAt": formattedNow,
|
|
|
|
|
// updatedAt: new Date()
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// arrayFilters: [
|
|
|
|
|
// {
|
|
|
|
|
// "elem.hardwareId": connected_to,
|
|
|
|
|
// "elem.type": "GSM or LoRa Disconnected",
|
|
|
|
|
// "elem.resolved": false
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
// console.error("Error in raiseATicketLikeLogic:", error);
|
|
|
|
|
// }
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
|
try {
|
|
|
|
|
if (!customerId || !connected_to) return;
|
|
|
|
@ -3706,94 +3897,23 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
|
|
|
|
|
|
const now = moment.tz("Asia/Kolkata");
|
|
|
|
|
|
|
|
|
|
function getLatestDataRecord(records) {
|
|
|
|
|
if (!records || records.length === 0) return null;
|
|
|
|
|
return records.reduce((latest, record) => {
|
|
|
|
|
if (!latest) return record;
|
|
|
|
|
return new Date(record.date) > new Date(latest.date) ? record : latest;
|
|
|
|
|
}, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 🔸 Master status check
|
|
|
|
|
const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
|
|
|
|
|
const latestMasterRecord = getLatestDataRecord(allMasterIotData);
|
|
|
|
|
|
|
|
|
|
let masterConnectedStatus = "disconnected";
|
|
|
|
|
let lastDataTime = "No data";
|
|
|
|
|
let diffInMinutes = null;
|
|
|
|
|
|
|
|
|
|
if (latestMasterRecord?.date) {
|
|
|
|
|
const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
|
|
|
|
|
diffInMinutes = now.diff(indiaTime, "minutes");
|
|
|
|
|
lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
|
|
|
|
|
if (diffInMinutes <= 2) masterConnectedStatus = "connected";
|
|
|
|
|
}
|
|
|
|
|
// Get status from Insensors.connected_status directly
|
|
|
|
|
let masterConnectedStatus = masterSensor.connected_status || "disconnected";
|
|
|
|
|
const lastDataTime = masterSensor.connected_gsm_date && masterSensor.connected_gsm_time
|
|
|
|
|
? `${masterSensor.connected_gsm_date} ${masterSensor.connected_gsm_time}`
|
|
|
|
|
: "No data";
|
|
|
|
|
|
|
|
|
|
// 🔸 Slave status check
|
|
|
|
|
// Get all slaves connected to this master
|
|
|
|
|
const connectedSlaves = sensors.filter(
|
|
|
|
|
s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
|
|
|
|
|
);
|
|
|
|
|
console.log("connectedSlaves",connectedSlaves)
|
|
|
|
|
const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);
|
|
|
|
|
// const allSlaveIotData = await IotData.find({ "tanks.tankhardwareId": { $in: slaveHardwareIds } }).lean();
|
|
|
|
|
const allSlaveIotData = await IotData.aggregate([
|
|
|
|
|
{ $match: { "tanks.tankhardwareId": { $in: slaveHardwareIds } } },
|
|
|
|
|
{ $project: {
|
|
|
|
|
hardwareId: 1,
|
|
|
|
|
date: 1,
|
|
|
|
|
"tanks": {
|
|
|
|
|
$filter: {
|
|
|
|
|
input: "$tanks",
|
|
|
|
|
as: "tank",
|
|
|
|
|
cond: { $in: ["$$tank.tankhardwareId", slaveHardwareIds] }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]);
|
|
|
|
|
console.log("allSlaveIotData",allSlaveIotData)
|
|
|
|
|
// 🔹 Create map of latest tank data
|
|
|
|
|
const latestTankDataMap = {};
|
|
|
|
|
for (const record of allSlaveIotData) {
|
|
|
|
|
const baseDate = record.date;
|
|
|
|
|
for (const tank of record.tanks || []) {
|
|
|
|
|
const tankId = tank.tankhardwareId;
|
|
|
|
|
const tankDate = tank.date || baseDate;
|
|
|
|
|
|
|
|
|
|
if (!tankId || !tankDate) continue;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
!latestTankDataMap[tankId] ||
|
|
|
|
|
new Date(tankDate) > new Date(latestTankDataMap[tankId].date)
|
|
|
|
|
) {
|
|
|
|
|
latestTankDataMap[tankId] = {
|
|
|
|
|
date: tankDate,
|
|
|
|
|
time: tank.time,
|
|
|
|
|
hardwareId: tankId
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const disconnectedSlaves = [];
|
|
|
|
|
for (const slave of connectedSlaves) {
|
|
|
|
|
const latestSlaveRecord = latestTankDataMap[slave.tankhardwareId];
|
|
|
|
|
|
|
|
|
|
let slaveStatus = "disconnected";
|
|
|
|
|
if (latestSlaveRecord?.date) {
|
|
|
|
|
const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
|
|
|
|
|
const slaveDiff = now.diff(slaveTime, "minutes");
|
|
|
|
|
if (slaveDiff <= 2) slaveStatus = "connected";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (slaveStatus === "disconnected") {
|
|
|
|
|
disconnectedSlaves.push({
|
|
|
|
|
slaveHardwareId: slave.tankhardwareId,
|
|
|
|
|
slaveName: slave.tankName || "Unknown Slave"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
console.log(",disconnectedSlaves",disconnectedSlaves)
|
|
|
|
|
const disconnectedSlaves = connectedSlaves.filter(
|
|
|
|
|
s => s.connected_status === "disconnected"
|
|
|
|
|
).map(s => ({
|
|
|
|
|
slaveHardwareId: s.tankhardwareId,
|
|
|
|
|
slaveName: s.tankName || "Unknown Slave"
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
if (disconnectedSlaves.length === 0 && masterConnectedStatus === "connected") {
|
|
|
|
|
return; // ✅ No ticket needed
|
|
|
|
@ -3823,7 +3943,7 @@ console.log("connectedSlaves",connectedSlaves)
|
|
|
|
|
|
|
|
|
|
const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
// 🔸 Raise new issue
|
|
|
|
|
// Raise new issue
|
|
|
|
|
if (!existingMasterIssue && (masterConnectedStatus === "disconnected" || disconnectedSlaves.length > 0)) {
|
|
|
|
|
const newIssue = {
|
|
|
|
|
type: "GSM or LoRa Disconnected",
|
|
|
|
@ -3842,7 +3962,7 @@ console.log("connectedSlaves",connectedSlaves)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 🔸 Update existing issue with new disconnected slaves
|
|
|
|
|
// Update existing issue
|
|
|
|
|
if (existingMasterIssue && newSlaveHardwareIds.length > 0) {
|
|
|
|
|
await Support.findOneAndUpdate(
|
|
|
|
|
{ supportId: "AWHYSU64" },
|
|
|
|
@ -3874,15 +3994,42 @@ console.log("connectedSlaves",connectedSlaves)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cron.schedule("* * * * *", async () => {
|
|
|
|
|
// console.log("Running auto ticket check...");
|
|
|
|
|
// const allMasters = await Insensors.find({ }).lean();
|
|
|
|
|
// for (const master of allMasters) {
|
|
|
|
|
// await raiseATicketLikeLogic(master.customerId, master.hardwareId);
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// cron.schedule("* * * * *", async () => {
|
|
|
|
|
// try {
|
|
|
|
|
// console.log("🔁 Running auto-disconnect ticket check...");
|
|
|
|
|
// const allMasters = await Insensors.find({ type: "master" }).lean();
|
|
|
|
|
|
|
|
|
|
cron.schedule("* * * * *", async () => {
|
|
|
|
|
console.log("Running auto ticket check...");
|
|
|
|
|
const allMasters = await Insensors.find({ }).lean();
|
|
|
|
|
for (const master of allMasters) {
|
|
|
|
|
await raiseATicketLikeLogic(master.customerId, master.hardwareId);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// for (const master of allMasters) {
|
|
|
|
|
// const customerId = master.customerId;
|
|
|
|
|
// const hardwareId = master.hardwareId;
|
|
|
|
|
|
|
|
|
|
// const connectedSlaves = await Insensors.find({
|
|
|
|
|
// connected_to: hardwareId,
|
|
|
|
|
// type: "slave"
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
// const disconnectedSlaves = connectedSlaves.filter(
|
|
|
|
|
// s => s.connected_status === "disconnected"
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
// const masterIsDisconnected = master.connected_status === "disconnected";
|
|
|
|
|
|
|
|
|
|
// if (masterIsDisconnected || disconnectedSlaves.length > 0) {
|
|
|
|
|
// await raiseATicketLikeLogic(customerId, hardwareId);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
// console.error("Cron error:", err);
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
exports.raiseATicketBuildingDetails = async (req, reply) => {
|
|
|
|
|
try {
|
|
|
|
|