|
|
@ -3859,130 +3859,181 @@ const cron = require("node-cron");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
// const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
try {
|
|
|
|
// try {
|
|
|
|
if (!customerId || !connected_to) return;
|
|
|
|
// if (!customerId || !connected_to) return;
|
|
|
|
|
|
|
|
|
|
|
|
const normalizedConnectedTo = connected_to.trim().toLowerCase();
|
|
|
|
// const normalizedConnectedTo = connected_to.trim().toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
const sensors = await Insensors.find({ customerId }).lean();
|
|
|
|
// const sensors = await Insensors.find({ customerId }).lean();
|
|
|
|
if (!sensors.length) return;
|
|
|
|
// if (!sensors.length) return;
|
|
|
|
|
|
|
|
|
|
|
|
const masterSensor = sensors.find(
|
|
|
|
// const masterSensor = sensors.find(
|
|
|
|
(s) => s.hardwareId?.trim().toLowerCase() === normalizedConnectedTo && s.type === "master"
|
|
|
|
// (s) => s.hardwareId?.trim().toLowerCase() === normalizedConnectedTo && s.type === "master"
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
if (!masterSensor) return;
|
|
|
|
// if (!masterSensor) return;
|
|
|
|
|
|
|
|
|
|
|
|
const orders = await Order.find({ customerId }).lean();
|
|
|
|
// const orders = await Order.find({ customerId }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
const connectedSlaves = sensors.filter(
|
|
|
|
// const connectedSlaves = sensors.filter(
|
|
|
|
(s) => s.connected_to?.trim().toLowerCase() === normalizedConnectedTo && s.type === "slave"
|
|
|
|
// (s) => s.connected_to?.trim().toLowerCase() === normalizedConnectedTo && s.type === "slave"
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
const disconnectedSlaves = connectedSlaves
|
|
|
|
// const disconnectedSlaves = connectedSlaves
|
|
|
|
.filter((s) => s.connected_status === "disconnected")
|
|
|
|
// .filter((s) => s.connected_status === "disconnected")
|
|
|
|
.map((s) => ({
|
|
|
|
// .map((s) => ({
|
|
|
|
slaveHardwareId: s.tankhardwareId?.trim().toLowerCase(),
|
|
|
|
// slaveHardwareId: s.tankhardwareId?.trim().toLowerCase(),
|
|
|
|
slaveName: s.tankName || "Unknown Slave",
|
|
|
|
// slaveName: s.tankName || "Unknown Slave",
|
|
|
|
}));
|
|
|
|
// }));
|
|
|
|
|
|
|
|
|
|
|
|
const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
|
|
|
|
// const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
|
|
|
|
if (!supportRecord) return;
|
|
|
|
// if (!supportRecord) return;
|
|
|
|
|
|
|
|
|
|
|
|
const now = moment.tz("Asia/Kolkata");
|
|
|
|
// const now = moment.tz("Asia/Kolkata");
|
|
|
|
const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");
|
|
|
|
// const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
|
|
const existingMasterIssue = supportRecord.issues.find(
|
|
|
|
// const existingMasterIssue = supportRecord.issues.find(
|
|
|
|
(issue) =>
|
|
|
|
// (issue) =>
|
|
|
|
issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
|
|
|
|
// issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
|
|
|
|
issue.type === "GSM or LoRa Disconnected" &&
|
|
|
|
// issue.type === "GSM or LoRa Disconnected" &&
|
|
|
|
!issue.resolved &&
|
|
|
|
// !issue.resolved &&
|
|
|
|
!issue.movedToCategory
|
|
|
|
// !issue.movedToCategory
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
if (existingMasterIssue) {
|
|
|
|
// if (existingMasterIssue) {
|
|
|
|
if (masterSensor.connected_status === "connected") {
|
|
|
|
// if (masterSensor.connected_status === "connected") {
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
const existingSlaveHardwareIds = new Set();
|
|
|
|
// const existingSlaveHardwareIds = new Set();
|
|
|
|
supportRecord.issues
|
|
|
|
// supportRecord.issues
|
|
|
|
.filter(
|
|
|
|
// .filter(
|
|
|
|
(issue) =>
|
|
|
|
// (issue) =>
|
|
|
|
issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
|
|
|
|
// issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
|
|
|
|
!issue.movedToCategory
|
|
|
|
// !issue.movedToCategory
|
|
|
|
)
|
|
|
|
// )
|
|
|
|
.forEach((issue) => {
|
|
|
|
// .forEach((issue) => {
|
|
|
|
(issue.hardwareIds || []).forEach((id) => {
|
|
|
|
// (issue.hardwareIds || []).forEach((id) => {
|
|
|
|
if (typeof id === "string") {
|
|
|
|
// if (typeof id === "string") {
|
|
|
|
existingSlaveHardwareIds.add(id.trim().toLowerCase());
|
|
|
|
// existingSlaveHardwareIds.add(id.trim().toLowerCase());
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
});
|
|
|
|
// });
|
|
|
|
});
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
const newSlaveHardwareIds = [];
|
|
|
|
// const newSlaveHardwareIds = [];
|
|
|
|
const newSlaveNames = [];
|
|
|
|
// const newSlaveNames = [];
|
|
|
|
|
|
|
|
|
|
|
|
for (const slave of disconnectedSlaves) {
|
|
|
|
// for (const slave of disconnectedSlaves) {
|
|
|
|
const sensorCurrent = sensors.find(
|
|
|
|
// const sensorCurrent = sensors.find(
|
|
|
|
(s) => s.tankhardwareId?.trim().toLowerCase() === slave.slaveHardwareId
|
|
|
|
// (s) => s.tankhardwareId?.trim().toLowerCase() === slave.slaveHardwareId
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
console.log("sensorCurrent",sensorCurrent)
|
|
|
|
// console.log("sensorCurrent",sensorCurrent)
|
|
|
|
if (
|
|
|
|
// if (
|
|
|
|
sensorCurrent &&
|
|
|
|
// sensorCurrent &&
|
|
|
|
sensorCurrent.connected_status === "disconnected" &&
|
|
|
|
// sensorCurrent.connected_status === "disconnected" &&
|
|
|
|
!existingSlaveHardwareIds.has(slave.slaveHardwareId)
|
|
|
|
// !existingSlaveHardwareIds.has(slave.slaveHardwareId)
|
|
|
|
) {
|
|
|
|
// ) {
|
|
|
|
newSlaveHardwareIds.push(slave.slaveHardwareId);
|
|
|
|
// newSlaveHardwareIds.push(slave.slaveHardwareId);
|
|
|
|
newSlaveNames.push(slave.slaveName);
|
|
|
|
// newSlaveNames.push(slave.slaveName);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// 👇 Even if no new slaves found, if master is disconnected, still raise a ticket
|
|
|
|
// // 👇 Even if no new slaves found, if master is disconnected, still raise a ticket
|
|
|
|
const masterDisconnected = masterSensor.connected_status !== "connected";
|
|
|
|
// const masterDisconnected = masterSensor.connected_status !== "connected";
|
|
|
|
|
|
|
|
|
|
|
|
if (!masterDisconnected && newSlaveHardwareIds.length === 0) {
|
|
|
|
// if (!masterDisconnected && newSlaveHardwareIds.length === 0) {
|
|
|
|
return;
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
const lastDataTime =
|
|
|
|
// const lastDataTime =
|
|
|
|
masterSensor.connected_gsm_date && masterSensor.connected_gsm_time
|
|
|
|
// masterSensor.connected_gsm_date && masterSensor.connected_gsm_time
|
|
|
|
? `${masterSensor.connected_gsm_date} ${masterSensor.connected_gsm_time}`
|
|
|
|
// ? `${masterSensor.connected_gsm_date} ${masterSensor.connected_gsm_time}`
|
|
|
|
: "No data";
|
|
|
|
// : "No data";
|
|
|
|
|
|
|
|
|
|
|
|
const message = `Master ${connected_to} is ${masterSensor.connected_status || "disconnected"}${newSlaveHardwareIds.length > 0
|
|
|
|
|
|
|
|
? ` with ${newSlaveHardwareIds.length} disconnected slave(s)`
|
|
|
|
|
|
|
|
: ""}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const newIssue = {
|
|
|
|
|
|
|
|
type: "GSM or LoRa Disconnected",
|
|
|
|
|
|
|
|
masterHardwareId: normalizedConnectedTo,
|
|
|
|
|
|
|
|
hardwareId: normalizedConnectedTo,
|
|
|
|
|
|
|
|
hardwareIds: newSlaveHardwareIds,
|
|
|
|
|
|
|
|
slaveNames: newSlaveNames,
|
|
|
|
|
|
|
|
message,
|
|
|
|
|
|
|
|
disconnectedAt: lastDataTime,
|
|
|
|
|
|
|
|
lastTicketRaisedAt: formattedNow,
|
|
|
|
|
|
|
|
resolved: false,
|
|
|
|
|
|
|
|
movedToCategory: false,
|
|
|
|
|
|
|
|
createdAt: formattedNow,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Support.findOneAndUpdate(
|
|
|
|
// const message = `Master ${connected_to} is ${masterSensor.connected_status || "disconnected"}${newSlaveHardwareIds.length > 0
|
|
|
|
{ supportId: "AWHYSU64" },
|
|
|
|
// ? ` with ${newSlaveHardwareIds.length} disconnected slave(s)`
|
|
|
|
{
|
|
|
|
// : ""}`;
|
|
|
|
$push: { issues: newIssue },
|
|
|
|
|
|
|
|
$set: { updatedAt: new Date() },
|
|
|
|
// const newIssue = {
|
|
|
|
}
|
|
|
|
// type: "GSM or LoRa Disconnected",
|
|
|
|
);
|
|
|
|
// masterHardwareId: normalizedConnectedTo,
|
|
|
|
} catch (error) {
|
|
|
|
// hardwareId: normalizedConnectedTo,
|
|
|
|
console.error("Error in raiseATicketLikeLogic:", error);
|
|
|
|
// hardwareIds: newSlaveHardwareIds,
|
|
|
|
|
|
|
|
// slaveNames: newSlaveNames,
|
|
|
|
|
|
|
|
// message,
|
|
|
|
|
|
|
|
// disconnectedAt: lastDataTime,
|
|
|
|
|
|
|
|
// lastTicketRaisedAt: formattedNow,
|
|
|
|
|
|
|
|
// resolved: false,
|
|
|
|
|
|
|
|
// movedToCategory: false,
|
|
|
|
|
|
|
|
// createdAt: formattedNow,
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// await Support.findOneAndUpdate(
|
|
|
|
|
|
|
|
// { supportId: "AWHYSU64" },
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// $push: { issues: newIssue },
|
|
|
|
|
|
|
|
// $set: { updatedAt: new Date() },
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
|
|
// console.error("Error in raiseATicketLikeLogic:", error);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
|
|
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
|
|
const formattedNow = new Date(now.getTime() + 19800000) // +05:30 offset in ms
|
|
|
|
|
|
|
|
.toISOString()
|
|
|
|
|
|
|
|
.replace("T", " ")
|
|
|
|
|
|
|
|
.substring(0, 19);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if already categorized
|
|
|
|
|
|
|
|
const alreadyCategorized = supportRecord.categorizedIssues.some(
|
|
|
|
|
|
|
|
(catIssue) => catIssue.hardwareId === masterHardwareId
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if already raised and unresolved & not categorized
|
|
|
|
|
|
|
|
const alreadyRaisedUnresolved = supportRecord.issues.some(
|
|
|
|
|
|
|
|
(issue) =>
|
|
|
|
|
|
|
|
issue.hardwareId === masterHardwareId &&
|
|
|
|
|
|
|
|
issue.resolved === false &&
|
|
|
|
|
|
|
|
issue.movedToCategory === false
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alreadyCategorized) {
|
|
|
|
|
|
|
|
console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alreadyRaisedUnresolved) {
|
|
|
|
|
|
|
|
console.log(`⛔ Unresolved ticket already exists for ${masterHardwareId}. Skipping.`);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const slaveHardwareIds = slaveData.map((slave) => slave.hardwareId);
|
|
|
|
|
|
|
|
const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const newIssue = {
|
|
|
|
|
|
|
|
type: "GSM or LoRa Disconnected",
|
|
|
|
|
|
|
|
masterHardwareId,
|
|
|
|
|
|
|
|
hardwareId: masterHardwareId,
|
|
|
|
|
|
|
|
hardwareIds: slaveHardwareIds,
|
|
|
|
|
|
|
|
slaveNames: slaveNames,
|
|
|
|
|
|
|
|
resolved: false,
|
|
|
|
|
|
|
|
movedToCategory: false,
|
|
|
|
|
|
|
|
lastTicketRaisedAt: formattedNow,
|
|
|
|
|
|
|
|
createdAt: formattedNow,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
supportRecord.issues.push(newIssue);
|
|
|
|
|
|
|
|
supportRecord.lastTicketRaisedAt = formattedNow;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await supportRecord.save();
|
|
|
|
|
|
|
|
console.log(`✅ New ticket raised for ${masterHardwareId}`);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4160,47 +4211,91 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => {
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cron.schedule("*/1 * * * *", async () => {
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
|
|
|
// console.log("🔁 Running auto-disconnect ticket check...");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Find all master sensors
|
|
|
|
|
|
|
|
// const allMasters = await Insensors.find({ type: "master" }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for (const master of allMasters) {
|
|
|
|
|
|
|
|
// const customerId = master.customerId;
|
|
|
|
|
|
|
|
// const hardwareId = master.hardwareId;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!customerId || !hardwareId) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Find slaves connected to this master
|
|
|
|
|
|
|
|
// const connectedSlaves = await Insensors.find({
|
|
|
|
|
|
|
|
// connected_to: hardwareId,
|
|
|
|
|
|
|
|
// type: "slave"
|
|
|
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Filter disconnected slaves
|
|
|
|
|
|
|
|
// const disconnectedSlaves = connectedSlaves.filter(
|
|
|
|
|
|
|
|
// (s) => s.connected_status === "disconnected"
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const masterIsDisconnected = master.connected_status === "disconnected";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Only raise ticket if master is disconnected or has disconnected slaves
|
|
|
|
|
|
|
|
// if (masterIsDisconnected || disconnectedSlaves.length > 0) {
|
|
|
|
|
|
|
|
// await raiseATicketLikeLogic(customerId, hardwareId);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// console.log("✅ Auto ticket check completed.");
|
|
|
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
|
|
|
// console.error("Cron error:", err);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
cron.schedule("*/1 * * * *", async () => {
|
|
|
|
cron.schedule("*/1 * * * *", async () => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
console.log("🔁 Running auto-disconnect ticket check...");
|
|
|
|
console.log("🔁 Running auto-disconnect ticket check...");
|
|
|
|
|
|
|
|
|
|
|
|
// Find all master sensors
|
|
|
|
// Step 1: Get all support profiles
|
|
|
|
const allMasters = await Insensors.find({ type: "master" }).lean();
|
|
|
|
const allSupportProfiles = await Support.find({}).lean();
|
|
|
|
|
|
|
|
|
|
|
|
for (const master of allMasters) {
|
|
|
|
for (const supportRecord of allSupportProfiles) {
|
|
|
|
const customerId = master.customerId;
|
|
|
|
const supportId = supportRecord.supportId;
|
|
|
|
const hardwareId = master.hardwareId;
|
|
|
|
if (!supportId) continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (!customerId || !hardwareId) continue;
|
|
|
|
// Step 2: Find all master sensors (you can filter by zone, supportId etc. if required)
|
|
|
|
|
|
|
|
const allMasters = await Insensors.find({ type: "master" }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
// Find slaves connected to this master
|
|
|
|
for (const master of allMasters) {
|
|
|
|
const connectedSlaves = await Insensors.find({
|
|
|
|
const customerId = master.customerId;
|
|
|
|
connected_to: hardwareId,
|
|
|
|
const hardwareId = master.hardwareId;
|
|
|
|
type: "slave"
|
|
|
|
|
|
|
|
}).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Filter disconnected slaves
|
|
|
|
if (!customerId || !hardwareId) continue;
|
|
|
|
const disconnectedSlaves = connectedSlaves.filter(
|
|
|
|
|
|
|
|
(s) => s.connected_status === "disconnected"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const masterIsDisconnected = master.connected_status === "disconnected";
|
|
|
|
// Step 3: Find connected slaves for this master
|
|
|
|
|
|
|
|
const connectedSlaves = await Insensors.find({
|
|
|
|
|
|
|
|
connected_to: hardwareId,
|
|
|
|
|
|
|
|
type: "slave"
|
|
|
|
|
|
|
|
}).lean();
|
|
|
|
|
|
|
|
|
|
|
|
// Only raise ticket if master is disconnected or has disconnected slaves
|
|
|
|
// Step 4: Check if master or any slave is disconnected
|
|
|
|
if (masterIsDisconnected || disconnectedSlaves.length > 0) {
|
|
|
|
const disconnectedSlaves = connectedSlaves.filter(
|
|
|
|
await raiseATicketLikeLogic(customerId, hardwareId);
|
|
|
|
(s) => s.connected_status === "disconnected"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const masterIsDisconnected = master.connected_status === "disconnected";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step 5: Raise a ticket if needed
|
|
|
|
|
|
|
|
if (masterIsDisconnected || disconnectedSlaves.length > 0) {
|
|
|
|
|
|
|
|
await raiseATicketLikeLogic(supportRecord, hardwareId, disconnectedSlaves);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log("✅ Auto ticket check completed.");
|
|
|
|
console.log("✅ Auto ticket check completed.");
|
|
|
|
} catch (err) {
|
|
|
|
} catch (err) {
|
|
|
|
console.error("Cron error:", err);
|
|
|
|
console.error("❌ Cron error:", err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.raiseATicketBuildingDetails = async (req, reply) => {
|
|
|
|
exports.raiseATicketBuildingDetails = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const { customerId, connected_to, installationId } = req.params;
|
|
|
|
const { customerId, connected_to, installationId } = req.params;
|
|
|
|