diff --git a/src/controllers/installationController.js b/src/controllers/installationController.js index 8f82f274..c8a0cd35 100644 --- a/src/controllers/installationController.js +++ b/src/controllers/installationController.js @@ -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({ @@ -716,7 +716,7 @@ exports.getByHardwareIdSupport = async (req, 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({ @@ -3870,16 +3870,13 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { const normalizedConnectedTo = connected_to.trim().toLowerCase(); const masterSensor = sensors.find( - s => - s.hardwareId?.trim().toLowerCase() === normalizedConnectedTo && - s.type === "master" && - s.support_issue_status !== "active" // 🔴 Don't raise if already active + s => s.hardwareId?.trim().toLowerCase() === normalizedConnectedTo && s.type === "master" ); if (!masterSensor) return; const orderMap = {}; orders.forEach(order => { - order.master_connections?.forEach(conn => { + order.master_connections.forEach(conn => { orderMap[conn.hardwareId] = { masterName: conn.master_name || null, location: conn.location || null @@ -3888,24 +3885,20 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { }); const now = moment.tz("Asia/Kolkata"); + const 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"; + // Get all slaves connected to this master 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 - .filter( - s => - s.connected_status === "disconnected" && - s.support_issue_status !== "active" // 🔴 Don't re-raise for already active - ) + .filter(s => s.connected_status === "disconnected") .map(s => ({ slaveHardwareId: s.tankhardwareId?.trim().toLowerCase(), slaveName: s.tankName || "Unknown Slave" @@ -3924,8 +3917,10 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { issue.type === "GSM or LoRa Disconnected" && issue.resolved === false ); + if (unresolvedMasterIssue) return; + // Check both unresolved and resolved issues for previously reported slaves const allSlaveHardwareIdsAlreadyReported = new Set(); existingIssues .filter(issue => issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo) @@ -3947,6 +3942,7 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { } } + // Still raise the issue if master is disconnected, even if no new slaves if (newSlaveHardwareIds.length === 0 && masterConnectedStatus === "connected") return; const formattedNow = now.format("YYYY-MM-DD HH:mm:ss"); @@ -3971,16 +3967,6 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { } ); - // ✅ Mark all involved sensors as "active" - await Insensors.updateMany( - { - $or: [ - { hardwareId: normalizedConnectedTo }, - { tankhardwareId: { $in: newSlaveHardwareIds } } - ] - }, - { $set: { support_issue_status: "active" } } - ); } catch (error) { console.error("Error in raiseATicketLikeLogic:", error); } @@ -4001,46 +3987,25 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { cron.schedule("* * * * *", async () => { try { console.log("🔁 Running auto-disconnect ticket check..."); - - // Get all master sensors const allMasters = await Insensors.find({ type: "master" }).lean(); for (const master of allMasters) { const customerId = master.customerId; const hardwareId = master.hardwareId; - // Get all slaves connected to this master const connectedSlaves = await Insensors.find({ connected_to: hardwareId, type: "slave" }).lean(); - // Filter disconnected slaves (regardless of support_issue_status) const disconnectedSlaves = connectedSlaves.filter( s => s.connected_status === "disconnected" ); - // Check master disconnected and active status const masterIsDisconnected = master.connected_status === "disconnected"; - const masterAlreadyActive = master.support_issue_status === "active"; - - // Check if any disconnected slave is already marked active - const anySlaveAlreadyActive = disconnectedSlaves.some( - slave => slave.support_issue_status === "active" - ); - // Decide if ticket should be raised: - // Raise if master is disconnected and not already active - // OR there are disconnected slaves and none of them are active - const shouldRaiseTicket = - (masterIsDisconnected && !masterAlreadyActive) || - (disconnectedSlaves.length > 0 && !anySlaveAlreadyActive); - - if (shouldRaiseTicket) { - console.log(`⚠️ Raising ticket for master: ${hardwareId}`); + if (masterIsDisconnected || disconnectedSlaves.length > 0) { await raiseATicketLikeLogic(customerId, hardwareId); - } else { - console.log(`✅ Skipping ticket for ${hardwareId} — already active.`); } } } catch (err) { @@ -5138,6 +5103,7 @@ exports.raiseATicketSlave = async (req, reply) => { // } // }; + exports.getDisconnectedIssuesBySupportId = async (req, reply) => { try { const { supportId, customerId } = req.params; @@ -5202,14 +5168,12 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { } const masterMap = {}; + for (const issue of allIssues) { const masterId = issue.masterHardwareId || issue.hardwareId; const masterSensor = sensorMap[masterId]; if (!masterSensor || masterSensor.type !== "master") continue; - // Proceed even if support_issue_status is not "active" - const masterIssueStatus = masterSensor.support_issue_status || "inactive"; - const latestMasterData = await IotData.findOne({ hardwareId: masterSensor.hardwareId }).sort({ date: -1 }).lean(); const now = moment.tz("Asia/Kolkata"); let gsmConnected = false; @@ -5238,13 +5202,11 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time, team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time, connected_slave_count: 0, - connected_slaves: [], - support_issue_status: masterIssueStatus + connected_slaves: [] }; } const master = masterMap[masterSensor.hardwareId]; - const connectedSlaves = await Insensors.find({ connected_to: masterSensor.hardwareId, type: "slave", @@ -5254,7 +5216,6 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId)); for (const slave of connectedSlaves) { - const slaveIssueStatus = slave.support_issue_status || "inactive"; const slaveHardwareId = slave.tankhardwareId || slave.hardwareId; if (slaveSet.has(slaveHardwareId)) continue; slaveSet.add(slaveHardwareId); @@ -5267,9 +5228,9 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { }).lean(); const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {}; + const matchedTank = latestMasterData?.tanks?.find(t => t.tankhardwareId === slaveHardwareId); let loraConnected = false; - if (matchedTank?.date && matchedTank.tankHeight !== "0") { const loraTime = moment.tz(matchedTank.date, "Asia/Kolkata"); loraConnected = now.diff(loraTime, "minutes") <= 1; @@ -5290,8 +5251,7 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "", tankHeight: slave.tankHeight, support_lora_last_check_time: slave.support_lora_last_check_time, - team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time, - support_issue_status: slaveIssueStatus + team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time }; master.connected_slaves.push(slaveEnriched); @@ -5299,13 +5259,9 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { } } - const comments = (supportRecord.comments || []).map(c => ({ - text: c.text, - commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm") - })); - + const commentTexts = (supportRecord.comments || []).map(c => c.text); for (const master of Object.values(masterMap)) { - master.comments = comments; + master.comments = commentTexts; } return reply.send({ @@ -5546,17 +5502,10 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { const hardwareIdsArray = Array.from(allHardwareIds); console.log("hardwareIdsArray",hardwareIdsArray) // 4. Find disconnected insensors using connected_to match - // const disconnectedSensors = await Insensors.find({ - // connected_to: { $in: hardwareIdsArray }, - // connected_status: "disconnected" - // }).lean(); const disconnectedSensors = await Insensors.find({ connected_to: { $in: hardwareIdsArray }, - connected_status: "disconnected", - support_issue_status: "inactive" + connected_status: "disconnected" }).lean(); - - console.log("disconnectedSensors",disconnectedSensors) if (!disconnectedSensors.length) { return reply.code(404).send({ message: "No disconnected issues found" }); @@ -6181,8 +6130,11 @@ exports.moveIssueToCategory = async (req, reply) => { support.categorizedIssues = []; } + // Find the issue where hardwareId matches either hardwareId or inside hardwareIds array const index = support.issues.findIndex((issue) => { + // Master hardwareId match if (issue.hardwareId === hardwareId) return true; + // Slave hardwareIds array match if (Array.isArray(issue.hardwareIds) && issue.hardwareIds.includes(hardwareId)) return true; return false; }); @@ -6193,28 +6145,18 @@ exports.moveIssueToCategory = async (req, reply) => { const issue = support.issues[index]; + // If the hardwareId matches master hardwareId, move entire issue as is if (issue.hardwareId === hardwareId) { - // Master issue moved - issue.resolved = true; - support.categorizedIssues.push({ ...issue, masterHardwareId: issue.masterHardwareId || issue.hardwareId, category, movedAt: nowTime, }); - support.issues.splice(index, 1); - - // ✅ Mark master as inactive - await Insensors.updateOne( - { hardwareId }, - { $set: { support_issue_status: "inactive" } } - ); - issueMoved = true; } else { - // Slave hardware match + // hardwareId matches inside hardwareIds array — move that slave issue individually const slaveIndex = issue.hardwareIds.indexOf(hardwareId); if (slaveIndex !== -1) { const slaveName = issue.slaveNames?.[slaveIndex] || "Unknown"; @@ -6228,18 +6170,12 @@ exports.moveIssueToCategory = async (req, reply) => { movedAt: nowTime, }); + // Remove slave from issue issue.hardwareIds.splice(slaveIndex, 1); issue.slaveNames.splice(slaveIndex, 1); - // ✅ Mark slave as inactive - await Insensors.updateOne( - { tankhardwareId: hardwareId }, - { $set: { support_issue_status: "inactive" } } - ); - - // If no more slaves, remove the whole issue + // If no more slaves left, remove the issue completely if (issue.hardwareIds.length === 0) { - issue.resolved = true; support.issues.splice(index, 1); }