diff --git a/src/controllers/installationController.js b/src/controllers/installationController.js index 2e2da0f4..52261ea7 100644 --- a/src/controllers/installationController.js +++ b/src/controllers/installationController.js @@ -5685,6 +5685,186 @@ exports.raiseATicketSlave = async (req, reply) => { // } // }; +// exports.getDisconnectedIssuesBySupportId = async (req, reply) => { +// try { +// const { supportId, customerId } = req.params; + +// if (!supportId || !customerId) { +// return reply.code(400).send({ error: "supportId and customerId are required" }); +// } + +// const supportRecord = await Support.findOne({ supportId }).lean(); +// if (!supportRecord) { +// return reply.code(404).send({ message: "No support record found for this supportId and customerId" }); +// } + +// const allIssues = supportRecord.issues || []; +// const hardwareSet = new Set(); + +// for (const issue of allIssues) { +// if (issue.hardwareId) hardwareSet.add(issue.hardwareId); +// if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId); +// } + +// const hardwareIds = [...hardwareSet]; + +// const sensors = await Insensors.find({ +// customerId, +// $or: [ +// { hardwareId: { $in: hardwareIds } }, +// { tankhardwareId: { $in: hardwareIds } } +// ] +// }).lean(); + +// const sensorMap = {}; +// for (const sensor of sensors) { +// if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor; +// if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor; +// } + +// const orders = await Order.find({ customerId }).lean(); + +// const orderMap = {}; +// for (const order of orders) { +// (order.master_connections || []).forEach(conn => { +// if (conn.hardwareId) { +// orderMap[conn.hardwareId] = { +// masterName: conn.master_name || null, +// location: conn.location || null +// }; +// } +// }); +// } + +// const slaveOrderMap = {}; +// for (const order of orders) { +// (order.tank_connections || []).forEach(conn => { +// if (conn.hardwareId) { +// slaveOrderMap[conn.hardwareId] = { +// location: conn.location || null, +// typeOfWater: conn.typeOfWater || null +// }; +// } +// }); +// } + +// const masterMap = {}; +// const now = moment.tz("Asia/Kolkata"); + +// for (const issue of allIssues) { +// const masterId = issue.masterHardwareId || issue.hardwareId; +// const masterSensor = sensorMap[masterId]; +// if (!masterSensor || masterSensor.type !== "master") continue; + +// const latestMasterData = await IotData.findOne({ hardwareId: masterSensor.hardwareId }).sort({ date: -1 }).lean(); + +// let gsmConnected = false; +// if (latestMasterData?.date) { +// const gsmTime = moment.tz(latestMasterData.date, "Asia/Kolkata"); +// gsmConnected = now.diff(gsmTime, "minutes") <= 1; +// } + +// if (!masterMap[masterSensor.hardwareId]) { +// const enriched = orderMap[masterSensor.hardwareId] || {}; +// masterMap[masterSensor.hardwareId] = { +// hardwareId: masterSensor.hardwareId, +// masterName: enriched.masterName || masterSensor.masterName || "", +// location: enriched.location || masterSensor.location || "", +// type: "master", +// connected_status: gsmConnected ? "connected" : "disconnected", +// gsm_last_check_time: masterSensor.gsm_last_check_time, +// gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time, +// connected_gsm_date: masterSensor.connected_gsm_date, +// connected_gsm_time: masterSensor.connected_gsm_time, +// connected_lora_date: masterSensor.connected_lora_date, +// connected_lora_time: masterSensor.connected_lora_time, +// support_gsm_last_check_time: masterSensor.support_gsm_last_check_time, +// support_lora_last_check_time: masterSensor.support_lora_last_check_time, +// 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: [] +// }; +// } + +// const master = masterMap[masterSensor.hardwareId]; +// const connectedSlaves = await Insensors.find({ +// connected_to: masterSensor.hardwareId, +// type: "slave", +// customerId +// }).lean(); + +// const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId)); + +// for (const slave of connectedSlaves) { +// const slaveHardwareId = slave.tankhardwareId || slave.hardwareId; +// if (slaveSet.has(slaveHardwareId)) continue; +// slaveSet.add(slaveHardwareId); + +// const tankInfo = await Tank.findOne({ +// $or: [ +// { hardwareId: slaveHardwareId }, +// { tankhardwareId: slaveHardwareId } +// ] +// }).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; +// } + +// const slaveEnriched = { +// hardwareId: slaveHardwareId, +// tankName: slave.tankName || tankInfo?.tankName || "", +// location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "", +// connected_status: loraConnected ? "connected" : "disconnected", +// connected_lora_time: slave.connected_lora_time, +// connected_lora_date: slave.connected_lora_date, +// lora_last_check_time: slave.lora_last_check_time, +// lora_last_disconnect_time: slave.lora_last_disconnect_time, +// connected_to: slave.connected_to, +// masterName: master.masterName, +// type: "slave", +// 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 +// }; + +// master.connected_slaves.push(slaveEnriched); +// master.connected_slave_count++; +// } +// } + +// // 🔍 Filter comments by customerId +// const comments = (supportRecord.comments || []) +// .filter(c => c.customerId === customerId) +// .map(c => ({ +// text: c.text, +// commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm") +// })); + +// for (const master of Object.values(masterMap)) { +// master.comments = comments; +// } + +// return reply.send({ +// status_code: 200, +// supportId, +// customerId, +// totalMasters: Object.keys(masterMap).length, +// disconnectedIssues: Object.values(masterMap) +// }); +// } catch (error) { +// console.error("Error fetching disconnected issues:", error); +// return reply.code(500).send({ error: "Internal server error" }); +// } +// }; + exports.getDisconnectedIssuesBySupportId = async (req, reply) => { try { const { supportId, customerId } = req.params; @@ -5764,6 +5944,19 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { gsmConnected = now.diff(gsmTime, "minutes") <= 1; } + // Get latest lastTicketRaisedAt for this master + const relatedIssues = allIssues.filter( + i => + i.hardwareId === masterSensor.hardwareId || + i.masterHardwareId === masterSensor.hardwareId + ); + + const lastTicketRaisedAt = relatedIssues.reduce((latest, issue) => { + if (!issue.lastTicketRaisedAt) return latest; + const current = new Date(issue.lastTicketRaisedAt); + return !latest || current > new Date(latest) ? issue.lastTicketRaisedAt : latest; + }, null); + if (!masterMap[masterSensor.hardwareId]) { const enriched = orderMap[masterSensor.hardwareId] || {}; masterMap[masterSensor.hardwareId] = { @@ -5783,7 +5976,8 @@ 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: [] + connected_slaves: [], + lastTicketRaisedAt: lastTicketRaisedAt }; } @@ -5817,6 +6011,17 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { loraConnected = now.diff(loraTime, "minutes") <= 1; } + // Get latest lastTicketRaisedAt for this slave + const slaveRelatedIssues = allIssues.filter( + i => i.hardwareId === slaveHardwareId + ); + + const slaveLastTicketRaisedAt = slaveRelatedIssues.reduce((latest, issue) => { + if (!issue.lastTicketRaisedAt) return latest; + const current = new Date(issue.lastTicketRaisedAt); + return !latest || current > new Date(latest) ? issue.lastTicketRaisedAt : latest; + }, null); + const slaveEnriched = { hardwareId: slaveHardwareId, tankName: slave.tankName || tankInfo?.tankName || "", @@ -5832,7 +6037,8 @@ 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 + team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time, + lastTicketRaisedAt: slaveLastTicketRaisedAt }; master.connected_slaves.push(slaveEnriched); @@ -5840,7 +6046,7 @@ exports.getDisconnectedIssuesBySupportId = async (req, reply) => { } } - // 🔍 Filter comments by customerId + // Filter comments by customerId const comments = (supportRecord.comments || []) .filter(c => c.customerId === customerId) .map(c => ({ @@ -6562,28 +6768,72 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => { customerId: { $in: Object.keys(customerHardwareMap) } }).lean(); + // const customerResults = customerDetails.map((customer) => { + // const affectedHardwareSet = customerHardwareMap[customer.customerId] || new Set(); + // return { + // customerId: customer.customerId, + // buildingName: customer.buildingName || "", + // location: customer.location || "", + // username: customer.username || "", + // firstName: customer.profile?.firstName || "", + // lastName: customer.profile?.lastName || "", + // phone: customer.phone || user.profile?.contactNumber || "", + // email: customer.emails?.[0]?.email || "", + // phoneVerified: customer.phoneVerified || false, + // address1: customer.profile?.address1 || "", + // address2: customer.profile?.address2 || "", + // city: customer.profile?.city || "", + // latitude: customer.latitude, + // longitude: customer.longitude, + // totalHardwareIdsCount: affectedHardwareSet.size, + // hardwareIds: [...affectedHardwareSet] + // }; + // }); + const customerResults = customerDetails.map((customer) => { const affectedHardwareSet = customerHardwareMap[customer.customerId] || new Set(); + const affectedLowerSet = new Set([...affectedHardwareSet].map(id => id.toLowerCase().trim())); + + // Get all unresolved issues related to this customer's affected hardwareIds + const customerIssues = unresolvedIssues.filter(issue => { + const allIssueHardwareIds = [ + ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []), + issue.hardwareId?.trim().toLowerCase() + ].filter(Boolean); + return allIssueHardwareIds.some(hw => affectedLowerSet.has(hw)); + }); + + // Get the latest lastTicketRaisedAt from the issues + const lastTicketRaisedAt = customerIssues.reduce((latest, issue) => { + const issueTime = new Date(issue.lastTicketRaisedAt); + if (!isNaN(issueTime)) { + return (!latest || issueTime > new Date(latest)) ? issue.lastTicketRaisedAt : latest; + } + return latest; + }, null); + return { customerId: customer.customerId, buildingName: customer.buildingName || "", location: customer.location || "", username: customer.username || "", - firstName: customer.profile?.firstName || "", - lastName: customer.profile?.lastName || "", - phone: customer.phone || user.profile?.contactNumber || "", - email: customer.emails?.[0]?.email || "", - phoneVerified: customer.phoneVerified || false, - address1: customer.profile?.address1 || "", - address2: customer.profile?.address2 || "", - city: customer.profile?.city || "", - latitude: customer.latitude, - longitude: customer.longitude, + firstName: customer.profile?.firstName || "", + lastName: customer.profile?.lastName || "", + phone: customer.phone || customer.profile?.contactNumber || "", + email: customer.emails?.[0]?.email || "", + phoneVerified: customer.phoneVerified || false, + address1: customer.profile?.address1 || "", + address2: customer.profile?.address2 || "", + city: customer.profile?.city || "", + latitude: customer.latitude, + longitude: customer.longitude, totalHardwareIdsCount: affectedHardwareSet.size, - hardwareIds: [...affectedHardwareSet] + hardwareIds: [...affectedHardwareSet], + lastTicketRaisedAt: lastTicketRaisedAt || null }; }); - + + return reply.code(200).send({ success: true, totalCustomers: customerResults.length,