|
|
@ -7537,6 +7537,185 @@ exports.getRemoveConnectedMastersWithSlaves = async (req, reply) => {
|
|
|
|
// };
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
|
|
|
// const { supportId } = req.params;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!supportId) {
|
|
|
|
|
|
|
|
// return reply.code(400).send({ error: "supportId is required" });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const supportRecord = await Support.findOne({ supportId }).lean();
|
|
|
|
|
|
|
|
// if (!supportRecord) {
|
|
|
|
|
|
|
|
// return reply.code(404).send({ message: "No support record found for this supportId" });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const unresolvedIssues = supportRecord.issues?.filter(
|
|
|
|
|
|
|
|
// (issue) => issue.resolved === false && issue.movedToCategory === false
|
|
|
|
|
|
|
|
// ) || [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const existingCategorizedHardwareIds = new Set();
|
|
|
|
|
|
|
|
// (supportRecord.categorizedIssues || []).forEach(issue => {
|
|
|
|
|
|
|
|
// if (issue.hardwareId) existingCategorizedHardwareIds.add(issue.hardwareId.trim().toLowerCase());
|
|
|
|
|
|
|
|
// if (Array.isArray(issue.hardwareIds)) {
|
|
|
|
|
|
|
|
// issue.hardwareIds.forEach(id => {
|
|
|
|
|
|
|
|
// if (typeof id === "string") existingCategorizedHardwareIds.add(id.trim().toLowerCase());
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const hardwareIdsArray = new Set();
|
|
|
|
|
|
|
|
// unresolvedIssues.forEach((issue) => {
|
|
|
|
|
|
|
|
// if (issue.hardwareId) hardwareIdsArray.add(issue.hardwareId.trim());
|
|
|
|
|
|
|
|
// if (Array.isArray(issue.hardwareIds)) {
|
|
|
|
|
|
|
|
// issue.hardwareIds.forEach((id) => {
|
|
|
|
|
|
|
|
// if (typeof id === "string") hardwareIdsArray.add(id.trim());
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const allHardwareIds = [...hardwareIdsArray];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // const disconnectedSensorsRaw = await Insensors.find({
|
|
|
|
|
|
|
|
// // connected_status: "disconnected",
|
|
|
|
|
|
|
|
// // $or: [
|
|
|
|
|
|
|
|
// // { connected_to: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// // { hardwareId: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// // { tankhardwareId: { $in: allHardwareIds } }
|
|
|
|
|
|
|
|
// // ]
|
|
|
|
|
|
|
|
// // }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedSensorsRaw = await Insensors.find({
|
|
|
|
|
|
|
|
// connected_status: "disconnected",
|
|
|
|
|
|
|
|
// $or: [
|
|
|
|
|
|
|
|
// { connected_to: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// { hardwareId: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// { tankhardwareId: { $in: allHardwareIds } }
|
|
|
|
|
|
|
|
// ]
|
|
|
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedSensors = disconnectedSensorsRaw.filter(sensor => {
|
|
|
|
|
|
|
|
// const ids = [
|
|
|
|
|
|
|
|
// sensor.hardwareId?.trim().toLowerCase(),
|
|
|
|
|
|
|
|
// sensor.connected_to?.trim().toLowerCase(),
|
|
|
|
|
|
|
|
// sensor.tankhardwareId?.trim().toLowerCase()
|
|
|
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
// return !ids.some(id => existingCategorizedHardwareIds.has(id));
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const customerHardwareMap = {};
|
|
|
|
|
|
|
|
// for (const sensor of disconnectedSensors) {
|
|
|
|
|
|
|
|
// const custId = sensor.customerId;
|
|
|
|
|
|
|
|
// if (!customerHardwareMap[custId]) {
|
|
|
|
|
|
|
|
// customerHardwareMap[custId] = new Set();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const sensorHw = sensor.tankhardwareId?.trim().toLowerCase();
|
|
|
|
|
|
|
|
// const sensorConnected = sensor.connected_to?.trim().toLowerCase();
|
|
|
|
|
|
|
|
// const sensorHardwareId = sensor.hardwareId?.trim().toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for (const issue of unresolvedIssues) {
|
|
|
|
|
|
|
|
// const allIssueHardwareIds = [
|
|
|
|
|
|
|
|
// ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []),
|
|
|
|
|
|
|
|
// issue.hardwareId?.trim().toLowerCase()
|
|
|
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const isCategorizedMatch = [sensorHw, sensorConnected, sensorHardwareId].some(id =>
|
|
|
|
|
|
|
|
// id && existingCategorizedHardwareIds.has(id)
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// if (isCategorizedMatch) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (
|
|
|
|
|
|
|
|
// (sensorHw && allIssueHardwareIds.includes(sensorHw)) ||
|
|
|
|
|
|
|
|
// (sensorConnected && allIssueHardwareIds.includes(sensorConnected)) ||
|
|
|
|
|
|
|
|
// (sensorHardwareId && allIssueHardwareIds.includes(sensorHardwareId))
|
|
|
|
|
|
|
|
// ) {
|
|
|
|
|
|
|
|
// for (const hw of allIssueHardwareIds) {
|
|
|
|
|
|
|
|
// if (hw && !existingCategorizedHardwareIds.has(hw)) {
|
|
|
|
|
|
|
|
// customerHardwareMap[custId].add(hw);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const customerDetails = await User.find({
|
|
|
|
|
|
|
|
// customerId: { $in: Object.keys(customerHardwareMap) }
|
|
|
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const customerResults = customerDetails.map((customer) => {
|
|
|
|
|
|
|
|
// const customerId = customer.customerId;
|
|
|
|
|
|
|
|
// const affectedHardwareSet = customerHardwareMap[customerId] || new Set();
|
|
|
|
|
|
|
|
// const affectedLowerSet = new Set([...affectedHardwareSet].map(id => id.toLowerCase().trim()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedSensorsForCustomer = disconnectedSensors.filter(
|
|
|
|
|
|
|
|
// s => s.customerId === customerId && s.connected_status === "disconnected"
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedSlaves = disconnectedSensorsForCustomer.filter(s => s.type === 'slave');
|
|
|
|
|
|
|
|
// const disconnectedMasters = disconnectedSensorsForCustomer.filter(s => s.type === 'master');
|
|
|
|
|
|
|
|
// console.log("disconnectedMasters",disconnectedMasters)
|
|
|
|
|
|
|
|
// const uniqueDisconnectedHardwareIds = new Set([
|
|
|
|
|
|
|
|
// ...disconnectedMasters.map(s => s.hardwareId?.trim()),
|
|
|
|
|
|
|
|
// ...disconnectedSlaves.map(s => s.tankhardwareId?.trim() || s.hardwareId?.trim())
|
|
|
|
|
|
|
|
// ].filter(Boolean));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedCount = disconnectedMasters.length + disconnectedSlaves.length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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));
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 || 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: uniqueDisconnectedHardwareIds.size,
|
|
|
|
|
|
|
|
// hardwareIds: [...uniqueDisconnectedHardwareIds],
|
|
|
|
|
|
|
|
// lastTicketRaisedAt: lastTicketRaisedAt || null,
|
|
|
|
|
|
|
|
// disconnectedCount
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return reply.code(200).send({
|
|
|
|
|
|
|
|
// success: true,
|
|
|
|
|
|
|
|
// totalCustomers: customerResults.length,
|
|
|
|
|
|
|
|
// customers: customerResults
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
|
|
// console.error("Error in getDisconnectedCustomerDetails:", error);
|
|
|
|
|
|
|
|
// return reply.code(500).send({
|
|
|
|
|
|
|
|
// success: false,
|
|
|
|
|
|
|
|
// message: "Internal Server Error"
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const { supportId } = req.params;
|
|
|
|
const { supportId } = req.params;
|
|
|
@ -7576,25 +7755,17 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
|
|
|
|
|
|
|
|
const allHardwareIds = [...hardwareIdsArray];
|
|
|
|
const allHardwareIds = [...hardwareIdsArray];
|
|
|
|
|
|
|
|
|
|
|
|
// const disconnectedSensorsRaw = await Insensors.find({
|
|
|
|
// ✅ Fetch all relevant sensors (connected or disconnected)
|
|
|
|
// connected_status: "disconnected",
|
|
|
|
const relevantSensorsRaw = await Insensors.find({
|
|
|
|
// $or: [
|
|
|
|
|
|
|
|
// { connected_to: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// { hardwareId: { $in: allHardwareIds } },
|
|
|
|
|
|
|
|
// { tankhardwareId: { $in: allHardwareIds } }
|
|
|
|
|
|
|
|
// ]
|
|
|
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const disconnectedSensorsRaw = await Insensors.find({
|
|
|
|
|
|
|
|
connected_status: "disconnected",
|
|
|
|
|
|
|
|
$or: [
|
|
|
|
$or: [
|
|
|
|
{ connected_to: { $in: allHardwareIds } },
|
|
|
|
{ connected_to: { $in: allHardwareIds } },
|
|
|
|
{ hardwareId: { $in: allHardwareIds } },
|
|
|
|
{ hardwareId: { $in: allHardwareIds } },
|
|
|
|
{ tankhardwareId: { $in: allHardwareIds } }
|
|
|
|
{ tankhardwareId: { $in: allHardwareIds } }
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}).lean();
|
|
|
|
}).lean();
|
|
|
|
|
|
|
|
|
|
|
|
const disconnectedSensors = disconnectedSensorsRaw.filter(sensor => {
|
|
|
|
// ✅ Filter out already categorized ones
|
|
|
|
|
|
|
|
const sensors = relevantSensorsRaw.filter(sensor => {
|
|
|
|
const ids = [
|
|
|
|
const ids = [
|
|
|
|
sensor.hardwareId?.trim().toLowerCase(),
|
|
|
|
sensor.hardwareId?.trim().toLowerCase(),
|
|
|
|
sensor.connected_to?.trim().toLowerCase(),
|
|
|
|
sensor.connected_to?.trim().toLowerCase(),
|
|
|
@ -7604,7 +7775,7 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const customerHardwareMap = {};
|
|
|
|
const customerHardwareMap = {};
|
|
|
|
for (const sensor of disconnectedSensors) {
|
|
|
|
for (const sensor of sensors) {
|
|
|
|
const custId = sensor.customerId;
|
|
|
|
const custId = sensor.customerId;
|
|
|
|
if (!customerHardwareMap[custId]) {
|
|
|
|
if (!customerHardwareMap[custId]) {
|
|
|
|
customerHardwareMap[custId] = new Set();
|
|
|
|
customerHardwareMap[custId] = new Set();
|
|
|
@ -7648,13 +7819,11 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
const affectedHardwareSet = customerHardwareMap[customerId] || new Set();
|
|
|
|
const affectedHardwareSet = customerHardwareMap[customerId] || new Set();
|
|
|
|
const affectedLowerSet = new Set([...affectedHardwareSet].map(id => id.toLowerCase().trim()));
|
|
|
|
const affectedLowerSet = new Set([...affectedHardwareSet].map(id => id.toLowerCase().trim()));
|
|
|
|
|
|
|
|
|
|
|
|
const disconnectedSensorsForCustomer = disconnectedSensors.filter(
|
|
|
|
const sensorsForCustomer = sensors.filter(s => s.customerId === customerId);
|
|
|
|
s => s.customerId === customerId && s.connected_status === "disconnected"
|
|
|
|
|
|
|
|
);
|
|
|
|
const disconnectedSlaves = sensorsForCustomer.filter(s => s.type === 'slave' && s.connected_status === "disconnected");
|
|
|
|
|
|
|
|
const disconnectedMasters = sensorsForCustomer.filter(s => s.type === 'master' && s.connected_status === "disconnected");
|
|
|
|
|
|
|
|
|
|
|
|
const disconnectedSlaves = disconnectedSensorsForCustomer.filter(s => s.type === 'slave');
|
|
|
|
|
|
|
|
const disconnectedMasters = disconnectedSensorsForCustomer.filter(s => s.type === 'master');
|
|
|
|
|
|
|
|
console.log("disconnectedMasters",disconnectedMasters)
|
|
|
|
|
|
|
|
const uniqueDisconnectedHardwareIds = new Set([
|
|
|
|
const uniqueDisconnectedHardwareIds = new Set([
|
|
|
|
...disconnectedMasters.map(s => s.hardwareId?.trim()),
|
|
|
|
...disconnectedMasters.map(s => s.hardwareId?.trim()),
|
|
|
|
...disconnectedSlaves.map(s => s.tankhardwareId?.trim() || s.hardwareId?.trim())
|
|
|
|
...disconnectedSlaves.map(s => s.tankhardwareId?.trim() || s.hardwareId?.trim())
|
|
|
@ -7717,7 +7886,6 @@ exports.getDisconnectedCustomerDetails = async (req, reply) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.getDisconnectedCustomerDetailsByTeamMemberId = async (req, reply) => {
|
|
|
|
exports.getDisconnectedCustomerDetailsByTeamMemberId = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const { support_teamMemberId } = req.params;
|
|
|
|
const { support_teamMemberId } = req.params;
|
|
|
|