diff --git a/src/controllers/installationController.js b/src/controllers/installationController.js index 5549fe8d..56f210a9 100644 --- a/src/controllers/installationController.js +++ b/src/controllers/installationController.js @@ -2984,7 +2984,7 @@ exports.getIotDataByCustomerAndHardwareId = async (req, reply) => { // const slaveNames = disconnectedSlaves.map(s => s.slaveName); // // Check if disconnection is at least 15 minutes old -// if (diffInMinutes >= 15) { +// if (diffInMinutes >= 1) { // issuesToAdd.push({ // type: "GSM or LoRa Disconnected", // masterHardwareId: connected_to, @@ -3039,160 +3039,480 @@ exports.getIotDataByCustomerAndHardwareId = async (req, reply) => { +// exports.raiseATicket = async (req, reply) => { +// try { +// const { customerId, connected_to } = req.params; + +// if (!customerId || !connected_to) { +// return reply.code(400).send({ error: "customerId and connected_to are required" }); +// } + +// // Fetch all sensors and orders for the customer +// const sensors = await Insensors.find({ customerId }).lean(); +// const orders = await Order.find({ customerId }).lean(); + +// if (!sensors.length) { +// return reply.code(404).send({ message: "No sensors found for this customer." }); +// } + +// // Find master sensor matching connected_to +// const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"); +// if (!masterSensor) { +// return reply.code(404).send({ message: "Master hardwareId not found." }); +// } + +// // Map orders for quick lookup of masterName and location +// 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"); + +// // Helper to get the latest record from multiple IoT data docs +// 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); +// } + +// // Fetch all IoT data for the master (no date limit here, adjust if needed) +// 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 <= 1) masterConnectedStatus = "connected"; // within 1 minute considered connected +// } + +// // Find slaves connected to this master +// const connectedSlaves = sensors.filter( +// s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave" +// ); + +// const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId); + +// // Fetch all IoT data for slaves +// const allSlaveIotData = await IotData.find({ hardwareId: { $in: slaveHardwareIds } }).lean(); + +// const formattedSlaves = []; +// const disconnectedSlaves = []; + +// for (const slave of connectedSlaves) { +// const slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId); +// const latestSlaveRecord = getLatestDataRecord(slaveRecords); + +// let slaveStatus = "disconnected"; +// let lastSlaveDataTime = "No data"; +// let slaveDiff = null; + +// if (latestSlaveRecord?.date) { +// const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata"); +// slaveDiff = now.diff(slaveTime, "minutes"); +// lastSlaveDataTime = slaveTime.format("DD-MM-YYYY HH:mm:ss"); +// if (slaveDiff <= 1) slaveStatus = "connected"; +// } + +// if (slaveStatus === "disconnected") { +// disconnectedSlaves.push({ +// slaveHardwareId: slave.tankhardwareId, +// slaveName: slave.tankName || "Unknown Slave" +// }); +// } + +// formattedSlaves.push({ +// hardwareId: slave.hardwareId, +// slaveName: slave.tankName || null, +// location: slave.tankLocation || null, +// type: "slave", +// connected_status: slaveStatus, +// last_data_time: lastSlaveDataTime, +// diff_in_minutes: slaveDiff +// }); +// } + +// const issuesToAdd = []; + +// // Raise ticket only if master is disconnected and disconnection is at least 1 minute old +// if (masterConnectedStatus === "disconnected") { +// const existingMasterTicket = await Support.findOne({ +// "issues.hardwareId": connected_to, +// "issues.type": "GSM or LoRa Disconnected" +// }); + +// if (!existingMasterTicket && diffInMinutes >= 1) { +// const slaveHardwareIds = disconnectedSlaves.map(s => s.slaveHardwareId); +// const slaveNames = disconnectedSlaves.map(s => s.slaveName); + +// issuesToAdd.push({ +// type: "GSM or LoRa Disconnected", +// masterHardwareId: connected_to, +// hardwareId: connected_to, +// hardwareIds: slaveHardwareIds, +// slaveNames, +// message: `Master ${connected_to} is disconnected along with ${slaveHardwareIds.length} slave(s)`, +// disconnectedAt: lastDataTime // optional +// }); +// } +// } + +// if (issuesToAdd.length > 0) { +// const supportRecord = await Support.findOne({ supportId: "AWHYSU64" }); + +// if (supportRecord) { +// await Support.findOneAndUpdate( +// { supportId: "AWHYSU64" }, +// { +// $push: { issues: { $each: issuesToAdd } }, +// $set: { +// updatedAt: new Date(), +// lastTicketRaisedAt: moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss") +// } +// } +// ); +// } +// } + +// const masterDetails = { +// hardwareId: connected_to, +// masterName: masterSensor.masterName || orderMap[connected_to]?.masterName || null, +// location: masterSensor.location || orderMap[connected_to]?.location || null, +// type: "master", +// connected_status: masterConnectedStatus, +// last_data_time: lastDataTime, +// diff_in_minutes: diffInMinutes +// }; + +// return reply.send({ +// status_code: 200, +// message: "Checked connection and raised ticket if needed.", +// master: masterDetails, +// connected_slaves: formattedSlaves +// }); + +// } catch (error) { +// console.error("Error raising ticket:", error); +// return reply.code(500).send({ error: "Internal server error" }); +// } +// }; + + + +// exports.raiseATicket = async (req, reply) => { +// try { +// const { customerId, connected_to } = req.params; + +// if (!customerId || !connected_to) { +// return reply.code(400).send({ error: "customerId and connected_to are required" }); +// } + +// const sensors = await Insensors.find({ customerId }); + +// if (!sensors.length) { +// return reply.code(404).send({ message: "No sensors found for this customer." }); +// } + +// const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"); + +// if (!masterSensor) { +// return reply.code(404).send({ message: "Master hardwareId not found." }); +// } + +// const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean(); + +// if (!latestMasterRecord) { +// return reply.code(404).send({ message: "No IoT data found for this hardwareId." }); +// } + +// const now = moment.tz("Asia/Kolkata"); +// const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata"); +// const diffInMinutesMaster = now.diff(indiaTime, "minutes"); + +// const masterDisconnected = diffInMinutesMaster > 1 ? [{ +// hardwareId: connected_to, +// masterName: masterSensor.tankName || "Unknown Master", +// connected_status: "disconnected", +// last_seen_minutes_ago: diffInMinutesMaster +// }] : []; + +// const connectedSlaves = sensors.filter(sensor => +// sensor.connected_to?.trim() === connected_to.trim() && +// sensor.type === "slave" +// ); + +// const disconnectedSlaves = []; +// const slaveStatusList = []; + +// for (const slave of connectedSlaves) { +// const slaveId = slave.tankhardwareId?.trim(); +// const matchedTank = latestMasterRecord.tanks.find(tank => tank.tankhardwareId === slaveId); + +// let isDisconnected = true; +// let loraDiffInMinutes = null; + +// if (matchedTank && matchedTank.date) { +// const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata"); +// loraDiffInMinutes = now.diff(tankTime, "minutes"); + +// if (loraDiffInMinutes <= 1) { +// isDisconnected = false; +// } +// } + +// const slaveInfo = { +// hardwareId: connected_to, +// slaveHardwareId: slaveId, +// slaveName: slave.tankName || "Unknown Slave", +// connected_status: isDisconnected ? "disconnected" : "connected", +// last_seen_minutes_ago: loraDiffInMinutes +// }; + +// slaveStatusList.push(slaveInfo); + +// if (isDisconnected) { +// disconnectedSlaves.push(slaveInfo); +// } +// } + +// const issuesToAdd = []; + +// if (masterDisconnected.length > 0) { +// const existingGsmIssue = await Support.findOne({ +// "issues.hardwareId": connected_to, +// "issues.type": "GSM Disconnected" +// }); + +// if (!existingGsmIssue) { +// issuesToAdd.push({ +// type: "GSM Disconnected", +// hardwareId: connected_to, +// message: `Master GSM disconnected - ${connected_to}` +// }); +// } +// } + +// const newHardwareIds = []; +// const newSlaveNames = []; + +// for (const slave of disconnectedSlaves) { +// const existingSlaveIssue = await Support.findOne({ +// "issues.hardwareIds": slave.slaveHardwareId, +// "issues.masterHardwareId": connected_to, +// "issues.type": "LoRa Disconnected" +// }); + +// if (!existingSlaveIssue) { +// newHardwareIds.push(slave.slaveHardwareId); +// newSlaveNames.push(slave.slaveName); +// } +// } + +// if (newHardwareIds.length > 0) { +// issuesToAdd.push({ +// type: "LoRa Disconnected", +// masterHardwareId: connected_to, +// hardwareIds: newHardwareIds, +// slaveNames: newSlaveNames, +// message: `Slaves LoRa disconnected under master ${connected_to}` +// }); +// } + +// if (issuesToAdd.length > 0) { +// const supportRecord = await Support.findOne({ supportId: "AWHYSU64" }); + +// if (supportRecord) { +// await Support.findOneAndUpdate( +// { _id: supportRecord._id }, +// { +// $push: { +// issues: { $each: issuesToAdd } +// }, +// updatedAt: new Date() +// }, +// { new: true } +// ); +// } else { +// console.error("Support record not found for supportId AWHYSU64"); +// } +// } + +// return reply.send({ +// status_code: 200, +// message: "Checked connection and updated support if needed.", +// masterDisconnected, +// disconnectedSlaves, +// connectedSlaves: slaveStatusList +// }); + +// } catch (error) { +// console.error("Error raising ticket:", error); +// return reply.code(500).send({ error: "Internal server error" }); +// } +// }; + -exports.raiseATicket = async (req, reply) => { +const raiseATicketLikeLogic = async (customerId, connected_to) => { try { - const { customerId, connected_to } = req.params; + if (!customerId || !connected_to) return; - if (!customerId || !connected_to) { - return reply.code(400).send({ error: "customerId and connected_to are required" }); - } + const sensors = await Insensors.find({ customerId }).lean(); + const orders = await Order.find({ customerId }).lean(); - const sensors = await Insensors.find({ customerId }); + if (!sensors.length) return; - if (!sensors.length) { - return reply.code(404).send({ message: "No sensors found for this customer." }); - } + const masterSensor = sensors.find( + s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master" + ); + if (!masterSensor) return; - const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"); + const orderMap = {}; + orders.forEach(order => { + order.master_connections.forEach(conn => { + orderMap[conn.hardwareId] = { + masterName: conn.master_name || null, + location: conn.location || null + }; + }); + }); - if (!masterSensor) { - return reply.code(404).send({ message: "Master hardwareId not found." }); + 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); } - const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean(); + const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean(); + const latestMasterRecord = getLatestDataRecord(allMasterIotData); - if (!latestMasterRecord) { - return reply.code(404).send({ message: "No IoT data found for this hardwareId." }); - } + let masterConnectedStatus = "disconnected"; + let lastDataTime = "No data"; + let diffInMinutes = null; - const now = moment.tz("Asia/Kolkata"); - const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata"); - const diffInMinutesMaster = now.diff(indiaTime, "minutes"); + 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 <= 1) masterConnectedStatus = "connected"; + } - const masterDisconnected = diffInMinutesMaster > 1 ? [{ - hardwareId: connected_to, - masterName: masterSensor.tankName || "Unknown Master", - connected_status: "disconnected", - last_seen_minutes_ago: diffInMinutesMaster - }] : []; - - const connectedSlaves = sensors.filter(sensor => - sensor.connected_to?.trim() === connected_to.trim() && - sensor.type === "slave" + 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 disconnectedSlaves = []; - const slaveStatusList = []; for (const slave of connectedSlaves) { - const slaveId = slave.tankhardwareId?.trim(); - const matchedTank = latestMasterRecord.tanks.find(tank => tank.tankhardwareId === slaveId); + const slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId); + const latestSlaveRecord = getLatestDataRecord(slaveRecords); - let isDisconnected = true; - let loraDiffInMinutes = null; - - if (matchedTank && matchedTank.date) { - const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata"); - loraDiffInMinutes = now.diff(tankTime, "minutes"); + let slaveStatus = "disconnected"; + let slaveDiff = null; - if (loraDiffInMinutes <= 1) { - isDisconnected = false; - } + if (latestSlaveRecord?.date) { + const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata"); + slaveDiff = now.diff(slaveTime, "minutes"); + if (slaveDiff <= 1) slaveStatus = "connected"; } - const slaveInfo = { - hardwareId: connected_to, - slaveHardwareId: slaveId, - slaveName: slave.tankName || "Unknown Slave", - connected_status: isDisconnected ? "disconnected" : "connected", - last_seen_minutes_ago: loraDiffInMinutes - }; - - slaveStatusList.push(slaveInfo); - - if (isDisconnected) { - disconnectedSlaves.push(slaveInfo); + if (slaveStatus === "disconnected") { + disconnectedSlaves.push({ + slaveHardwareId: slave.tankhardwareId, + slaveName: slave.tankName || "Unknown Slave" + }); } } - const issuesToAdd = []; + const supportRecord = await Support.findOne({ supportId: "AWHYSU64" }); + if (!supportRecord) return; - if (masterDisconnected.length > 0) { - const existingGsmIssue = await Support.findOne({ - "issues.hardwareId": connected_to, - "issues.type": "GSM Disconnected" - }); + const existingIssues = supportRecord.issues || []; - if (!existingGsmIssue) { - issuesToAdd.push({ - type: "GSM Disconnected", - hardwareId: connected_to, - message: `Master GSM disconnected - ${connected_to}` - }); - } - } + const existingMasterIssue = existingIssues.find( + issue => + issue.hardwareId === connected_to && + issue.type === "GSM or LoRa Disconnected" + ); + + const alreadyReportedSlaves = new Set( + existingMasterIssue?.hardwareIds || [] + ); - const newHardwareIds = []; + const newSlaveHardwareIds = []; const newSlaveNames = []; for (const slave of disconnectedSlaves) { - const existingSlaveIssue = await Support.findOne({ - "issues.hardwareIds": slave.slaveHardwareId, - "issues.masterHardwareId": connected_to, - "issues.type": "LoRa Disconnected" - }); - - if (!existingSlaveIssue) { - newHardwareIds.push(slave.slaveHardwareId); + if (!alreadyReportedSlaves.has(slave.slaveHardwareId)) { + newSlaveHardwareIds.push(slave.slaveHardwareId); newSlaveNames.push(slave.slaveName); } } - if (newHardwareIds.length > 0) { - issuesToAdd.push({ - type: "LoRa Disconnected", + if (masterConnectedStatus === "disconnected" && diffInMinutes >= 1 && (newSlaveHardwareIds.length > 0 || !existingMasterIssue)) { + const newIssue = { + type: "GSM or LoRa Disconnected", masterHardwareId: connected_to, - hardwareIds: newHardwareIds, + hardwareId: connected_to, + hardwareIds: newSlaveHardwareIds, slaveNames: newSlaveNames, - message: `Slaves LoRa disconnected under master ${connected_to}` - }); - } - - if (issuesToAdd.length > 0) { - const supportRecord = await Support.findOne({ supportId: "AWHYSU64" }); + message: `Master ${connected_to} is disconnected along with ${newSlaveHardwareIds.length} new slave(s)`, + disconnectedAt: lastDataTime + }; - if (supportRecord) { - await Support.findOneAndUpdate( - { _id: supportRecord._id }, - { - $push: { - issues: { $each: issuesToAdd } - }, - updatedAt: new Date() + await Support.findOneAndUpdate( + { supportId: "AWHYSU64" }, + { + $push: existingMasterIssue ? { + "issues.$[elem].hardwareIds": { $each: newSlaveHardwareIds }, + "issues.$[elem].slaveNames": { $each: newSlaveNames } + } : { + issues: newIssue }, - { new: true } - ); - } else { - console.error("Support record not found for supportId AWHYSU64"); - } + $set: { + updatedAt: new Date(), + lastTicketRaisedAt: now.format("YYYY-MM-DD HH:mm:ss") + } + }, + existingMasterIssue + ? { arrayFilters: [{ "elem.hardwareId": connected_to, "elem.type": "GSM or LoRa Disconnected" }] } + : {} + ); } - return reply.send({ - status_code: 200, - message: "Checked connection and updated support if needed.", - masterDisconnected, - disconnectedSlaves, - connectedSlaves: slaveStatusList - }); - } catch (error) { - console.error("Error raising ticket:", error); - return reply.code(500).send({ error: "Internal server error" }); + console.error("Error in raiseATicketLikeLogic:", error); } }; +const cron = require("node-cron"); + +cron.schedule("* * * * *", async () => { + console.log("Running auto ticket check..."); + const allMasters = await Insensors.find({ type: "master" }).lean(); + for (const master of allMasters) { + await raiseATicketLikeLogic(master.customerId, master.hardwareId); + } +}); exports.raiseATicketBuildingDetails = async (req, reply) => { try { @@ -4477,84 +4797,126 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { return reply.code(400).send({ error: "supportId is required" }); } - // 1. Get the support record by supportId + // 1. Fetch support record const supportRecord = await Support.findOne({ supportId }).lean(); if (!supportRecord) { return reply.code(404).send({ message: "No support record found for this supportId" }); } - // 2. Extract all hardwareIds from issues - const hardwareIds = []; + // 2. Collect all hardwareIds (hardwareId + hardwareIds[]) + const allHardwareIds = new Set(); for (const issue of supportRecord.issues) { - if (issue.hardwareId) hardwareIds.push(issue.hardwareId); - if (Array.isArray(issue.hardwareIds)) hardwareIds.push(...issue.hardwareIds); + if (issue.hardwareId) allHardwareIds.add(issue.hardwareId.trim().toLowerCase()); + if (Array.isArray(issue.hardwareIds)) { + issue.hardwareIds.forEach(id => { + if (typeof id === "string") allHardwareIds.add(id.trim().toLowerCase()); + }); + } } - if (hardwareIds.length === 0) { + if (allHardwareIds.size === 0) { return reply.code(404).send({ message: "No hardware IDs found in issues" }); } - // 3. Find disconnected Insensors + const hardwareIdsArray = Array.from(allHardwareIds); + + // 3. Find disconnected insensors using connected_to match (normalize connected_to) const disconnectedSensors = await Insensors.find({ - $or: [ - // { hardwareId: { $in: hardwareIds } }, - { connected_to: { $in: hardwareIds } } - ], - // connected_status: "disconnected" + connected_to: { $in: hardwareIdsArray } }).lean(); - if (disconnectedSensors.length === 0) { + if (!disconnectedSensors.length) { return reply.code(404).send({ message: "No disconnected issues found" }); } - // 4. Get all unique customerIds + // 4. Get unique customerIds from disconnected sensors const customerIds = [...new Set(disconnectedSensors.map(s => s.customerId))]; const customers = await User.find({ customerId: { $in: customerIds } }).lean(); - // 5. Map unique customers - const uniqueCustomerMap = {}; - for (const user of customers) { - if (!uniqueCustomerMap[user.customerId]) { - uniqueCustomerMap[user.customerId] = { - customer: { - customerId: user.customerId, - username: user.username || "", - firstName: user.profile?.firstName || "", - lastName: user.profile?.lastName || "", - phone: user.phone || user.profile?.contactNumber || "", - email: user.emails?.[0]?.email || "", - phoneVerified: user.phoneVerified || false, - address1: user.profile?.address1 || "", - address2: user.profile?.address2 || "", - city: user.profile?.city || "", - state: user.profile?.state || "", - country: user.profile?.country || "", - zip: user.profile?.zip || "", - notes: user.profile?.notes || "", - latitude: user.latitude, - longitude: user.longitude, - fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")), - installationId: user.installationId || "", - notificationPreferences: { - allowNotifications: user.allowNotifications || false, - automaticStartAndStopNotify: user.automaticStartAndStopNotify || false, - manualStartAndStopNotify: user.manualStartAndStopNotify || false, - criticalLowWaterAlert: user.criticalLowWaterAlert || false, - lowWaterAlert: user.lowWaterAlert || false, - notificationPreference: user.notificationPreference || "never" - }, - surveyStatus: user.survey_status || "pending", - buildingName: user.buildingName, - stripePaymentStatus: user.stripePaymentStatus || false, - stripeSubscriptionStatus: user.stripeSubscriptionStatus || false, - createdAt: user.createdAt, - updatedAt: user.updatedAt + // 5. For each customer, calculate total unique hardwareIds involved in their disconnected sensors + const customerHardwareMap = {}; + + for (const sensor of disconnectedSensors) { + const custId = sensor.customerId; + if (!customerHardwareMap[custId]) { + customerHardwareMap[custId] = new Set(); + } + + // Normalize sensor hardwareId and connected_to for safe comparisons + const sensorHw = sensor.tankhardwareId?.trim().toLowerCase(); + const sensorConnected = sensor.connected_to?.trim().toLowerCase(); + console.log("sensorHw",sensorHw) + console.log("sensorConnected",sensorConnected) + + for (const issue of supportRecord.issues) { + const issueHw = issue.hardwareId?.trim().toLowerCase(); + + if ( + issueHw && + (sensorHw === issueHw || sensorConnected === issueHw) + ) { + console.log(`Adding hardwareId ${issue.hardwareId} for customer ${custId}`); + 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) { + console.log(`Adding hardwareId ${id} for customer ${custId}`); + customerHardwareMap[custId].add(id); + } } - }; + } } } - const response = Object.values(uniqueCustomerMap); + // 6. Build final response + const response = []; + + for (const user of customers) { + const custId = user.customerId; + const hardwareIdSet = customerHardwareMap[custId] || new Set(); + + response.push({ + customer: { + customerId: custId, + username: user.username || "", + firstName: user.profile?.firstName || "", + lastName: user.profile?.lastName || "", + phone: user.phone || user.profile?.contactNumber || "", + email: user.emails?.[0]?.email || "", + phoneVerified: user.phoneVerified || false, + address1: user.profile?.address1 || "", + address2: user.profile?.address2 || "", + city: user.profile?.city || "", + state: user.profile?.state || "", + country: user.profile?.country || "", + zip: user.profile?.zip || "", + notes: user.profile?.notes || "", + latitude: user.latitude, + longitude: user.longitude, + fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")), + installationId: user.installationId || "", + notificationPreferences: { + allowNotifications: user.allowNotifications || false, + automaticStartAndStopNotify: user.automaticStartAndStopNotify || false, + manualStartAndStopNotify: user.manualStartAndStopNotify || false, + criticalLowWaterAlert: user.criticalLowWaterAlert || false, + lowWaterAlert: user.lowWaterAlert || false, + notificationPreference: user.notificationPreference || "never" + }, + surveyStatus: user.survey_status || "pending", + buildingName: user.buildingName, + stripePaymentStatus: user.stripePaymentStatus || false, + stripeSubscriptionStatus: user.stripeSubscriptionStatus || false, + createdAt: user.createdAt, + updatedAt: user.updatedAt, + lastTicketRaisedAt: supportRecord.lastTicketRaisedAt || null, + totalHardwareIdsCount: hardwareIdSet.size + } + }); + } return reply.send({ status_code: 200, @@ -4567,6 +4929,10 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { } }; + + + + exports.getDisconnectedCustomerDetailsByTeamMemberId = async (req, reply) => { try { const { support_teamMemberId } = req.params; diff --git a/src/routes/installationRoute.js b/src/routes/installationRoute.js index 96b5f046..0b5191e3 100644 --- a/src/routes/installationRoute.js +++ b/src/routes/installationRoute.js @@ -489,23 +489,23 @@ module.exports = function (fastify, opts, next) { handler: installationController.getIotDataByCustomerAndHardwareId, }); - fastify.get("/api/getraiseAticket/:customerId/:connected_to", { - schema: { - description: "Raise A Ticket for Support", - tags: ["Support"], - summary: "Raise A Ticket for Support", - params: { - type: "object", - properties: { - customerId: { type: "string" }, - connected_to: { type: "string" }, + // fastify.get("/api/getraiseAticket/:customerId/:connected_to", { + // schema: { + // description: "Raise A Ticket for Support", + // tags: ["Support"], + // summary: "Raise A Ticket for Support", + // params: { + // type: "object", + // properties: { + // customerId: { type: "string" }, + // connected_to: { type: "string" }, - }, - required: [ "customerId"], - }, - }, - handler: installationController.raiseATicket, - }); + // }, + // required: [ "customerId"], + // }, + // }, + // handler: installationController.raiseATicket, + // }); fastify.get("/api/getraiseAticketBuildingDetails/:customerId/:connected_to/:installationId", { schema: {