|  |  |  | @ -3714,6 +3714,7 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  |       }, null); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 🔸 Master status check
 | 
			
		
	
		
			
				
					|  |  |  |  |     const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean(); | 
			
		
	
		
			
				
					|  |  |  |  |     const latestMasterRecord = getLatestDataRecord(allMasterIotData); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -3728,17 +3729,40 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  |       if (diffInMinutes <= 2) masterConnectedStatus = "connected"; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 🔸 Slave status check
 | 
			
		
	
		
			
				
					|  |  |  |  |     const connectedSlaves = sensors.filter( | 
			
		
	
		
			
				
					|  |  |  |  |       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave" | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId); | 
			
		
	
		
			
				
					|  |  |  |  |     const allSlaveIotData = await IotData.find({ hardwareId: { $in: slaveHardwareIds } }).lean(); | 
			
		
	
		
			
				
					|  |  |  |  |     const allSlaveIotData = await IotData.find({ "tanks.tankhardwareId": { $in: slaveHardwareIds } }).lean(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 🔹 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 slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId); | 
			
		
	
		
			
				
					|  |  |  |  |       const latestSlaveRecord = getLatestDataRecord(slaveRecords); | 
			
		
	
		
			
				
					|  |  |  |  |       const latestSlaveRecord = latestTankDataMap[slave.tankhardwareId]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       let slaveStatus = "disconnected"; | 
			
		
	
		
			
				
					|  |  |  |  |       if (latestSlaveRecord?.date) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -3754,6 +3778,11 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     console.log(",disconnectedSlaves",disconnectedSlaves) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (disconnectedSlaves.length === 0 && masterConnectedStatus === "connected") { | 
			
		
	
		
			
				
					|  |  |  |  |       return; // ✅ No ticket needed
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     const supportRecord = await Support.findOne({ supportId: "AWHYSU64" }); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!supportRecord) return; | 
			
		
	
	
		
			
				
					|  |  |  | @ -3779,20 +3808,15 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     const formattedNow = now.format("YYYY-MM-DD HH:mm:ss"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // Only raise ticket if master is disconnected
 | 
			
		
	
		
			
				
					|  |  |  |  |     if ( | 
			
		
	
		
			
				
					|  |  |  |  |       masterConnectedStatus === "disconnected" && | 
			
		
	
		
			
				
					|  |  |  |  |       diffInMinutes >= 2 && | 
			
		
	
		
			
				
					|  |  |  |  |       (newSlaveHardwareIds.length > 0 || !existingMasterIssue) | 
			
		
	
		
			
				
					|  |  |  |  |     ) { | 
			
		
	
		
			
				
					|  |  |  |  |       if (!existingMasterIssue) { | 
			
		
	
		
			
				
					|  |  |  |  |     // 🔸 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 disconnected along with ${newSlaveHardwareIds.length} new slave(s)`, | 
			
		
	
		
			
				
					|  |  |  |  |         message: `Master ${connected_to} is ${masterConnectedStatus} with ${disconnectedSlaves.length} disconnected slave(s)`, | 
			
		
	
		
			
				
					|  |  |  |  |         disconnectedAt: lastDataTime, | 
			
		
	
		
			
				
					|  |  |  |  |         lastTicketRaisedAt: formattedNow, | 
			
		
	
		
			
				
					|  |  |  |  |         resolved: false | 
			
		
	
	
		
			
				
					|  |  |  | @ -3801,7 +3825,10 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  |         { supportId: "AWHYSU64" }, | 
			
		
	
		
			
				
					|  |  |  |  |         { $push: { issues: newIssue }, $set: { updatedAt: new Date() } } | 
			
		
	
		
			
				
					|  |  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |  |       } else { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 🔸 Update existing issue with new disconnected slaves
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (existingMasterIssue && newSlaveHardwareIds.length > 0) { | 
			
		
	
		
			
				
					|  |  |  |  |       await Support.findOneAndUpdate( | 
			
		
	
		
			
				
					|  |  |  |  |         { supportId: "AWHYSU64" }, | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
	
		
			
				
					|  |  |  | @ -3825,16 +3852,17 @@ const raiseATicketLikeLogic = async (customerId, connected_to) => { | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |       ); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |   } catch (error) { | 
			
		
	
		
			
				
					|  |  |  |  |     console.error("Error in raiseATicketLikeLogic:", error); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | cron.schedule("* * * * *", async () => { | 
			
		
	
		
			
				
					|  |  |  |  |   console.log("Running auto ticket check..."); | 
			
		
	
		
			
				
					|  |  |  |  |   const allMasters = await Insensors.find({ type: "master" }).lean(); | 
			
		
	
		
			
				
					|  |  |  |  |   const allMasters = await Insensors.find({  }).lean(); | 
			
		
	
		
			
				
					|  |  |  |  |   for (const master of allMasters) { | 
			
		
	
		
			
				
					|  |  |  |  |     await raiseATicketLikeLogic(master.customerId, master.hardwareId); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
	
		
			
				
					|  |  |  | @ -5294,7 +5322,7 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { | 
			
		
	
		
			
				
					|  |  |  |  |     // 2. Filter only unresolved issues
 | 
			
		
	
		
			
				
					|  |  |  |  |     const unresolvedIssues = (supportRecord.issues || []).filter(issue => issue.resolved === false); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 3. Collect all hardwareIds (hardwareId + hardwareIds[] from unresolved issues)
 | 
			
		
	
		
			
				
					|  |  |  |  |     // 3. Collect all unique hardwareIds (from hardwareId and hardwareIds arrays) from unresolved issues
 | 
			
		
	
		
			
				
					|  |  |  |  |     const allHardwareIds = new Set(); | 
			
		
	
		
			
				
					|  |  |  |  |     for (const issue of unresolvedIssues) { | 
			
		
	
		
			
				
					|  |  |  |  |       if (issue.hardwareId) allHardwareIds.add(issue.hardwareId.trim().toLowerCase()); | 
			
		
	
	
		
			
				
					|  |  |  | @ -5337,23 +5365,17 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { | 
			
		
	
		
			
				
					|  |  |  |  |       const sensorConnected = sensor.connected_to?.trim().toLowerCase(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       for (const issue of unresolvedIssues) { | 
			
		
	
		
			
				
					|  |  |  |  |         const issueHw = issue.hardwareId?.trim().toLowerCase(); | 
			
		
	
		
			
				
					|  |  |  |  |         const allIssueHardwareIds = [ | 
			
		
	
		
			
				
					|  |  |  |  |           ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []), | 
			
		
	
		
			
				
					|  |  |  |  |           issue.hardwareId?.trim().toLowerCase() | 
			
		
	
		
			
				
					|  |  |  |  |         ]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         if ( | 
			
		
	
		
			
				
					|  |  |  |  |           issueHw && | 
			
		
	
		
			
				
					|  |  |  |  |           (sensorHw === issueHw || sensorConnected === issueHw) | 
			
		
	
		
			
				
					|  |  |  |  |           allIssueHardwareIds.includes(sensorHw) || | 
			
		
	
		
			
				
					|  |  |  |  |           allIssueHardwareIds.includes(sensorConnected) | 
			
		
	
		
			
				
					|  |  |  |  |         ) { | 
			
		
	
		
			
				
					|  |  |  |  |           customerHardwareMap[custId].add(issue.hardwareId); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (Array.isArray(issue.hardwareIds)) { | 
			
		
	
		
			
				
					|  |  |  |  |           for (const id of issue.hardwareIds) { | 
			
		
	
		
			
				
					|  |  |  |  |             const idNorm = id?.trim().toLowerCase(); | 
			
		
	
		
			
				
					|  |  |  |  |             if (sensorHw === idNorm || sensorConnected === idNorm) { | 
			
		
	
		
			
				
					|  |  |  |  |               customerHardwareMap[custId].add(id); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |           } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |