const boom = require("boom"); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const customJwtAuth = require("../customAuthJwt"); const { Deparments } = require("../models/Department"); const { Install, SensorStock, SensorQuotation, Order, Insensors, MasterSlaveData, ElectrictyWorkPictures, PlumbingWorkPictures, MaterialRecievedPictures } = require("../models/store"); const { Counter, User } = require("../models/User"); const { IotData, Tank } = require("../models/tanks"); const fastify = require("fastify")({ logger: true, //disableRequestLogging: true, genReqId(req) { // you get access to the req here if you need it - must be a synchronous function return uuidv4(); }, }); const generateTeamMemberId = async () => { var result = await Counter.findOneAndUpdate( { _id: 'teamMemberId_id' }, { $inc: { seq: 1 } }, { upsert: true, new: true } ); return result.seq; }; exports.createTeamMember = async (request, reply) => { try { const { departmentId, firstName, phone, password,email,alternativePhone ,status} = request.body; // Check if installation exists const installation = await Deparments.findOne({ departmentId }); if (!installation) { return reply.status(404).send({ simplydata: { error: true, message: "Installation not found", }, }); } // Check if phone number already exists in the team const existingMember = installation.team_member.team_member.find( (member) => member.phone === phone ); if (existingMember) { return reply.status(400).send({ simplydata: { error: true, message: "Phone number already exists in the team", }, }); } // Hash password const hashedPassword = await bcrypt.hash(password, 10); const c_id = await generateTeamMemberId(); const teamMemberId = `AWTM${c_id}`; // Create new team member const newTeamMember = { teamMemberId, firstName, phone, email, alternativePhone, installationTeamMemId: departmentId, password: hashedPassword, status, }; // Add to team members array installation.team_member.team_member.push(newTeamMember); await installation.save(); return reply.send({ simplydata: { error: false, message: "Team member created successfully", teamMemberId: newTeamMember.teamMemberId, }, }); } catch (err) { console.error("Error creating team member:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.getTeamMembers = async (request, reply) => { try { const { departmentId } = request.params; // ✅ Get departmentId from request params // ✅ Find the department using departmentId const department = await Deparments.findOne({ departmentId }); if (!department) { return reply.status(404).send({ simplydata: { error: true, message: "Department not found", }, }); } // ✅ Extract team members from department schema const teamMembers = department.team_member.team_member; return reply.send({ simplydata: { error: false, message: "Team members retrieved successfully", teamMembers, // ✅ Return the list of team members }, }); } catch (err) { console.error("Error fetching team members:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; // exports.assignTeamMemberToQuotation = async (request, reply) => { // try { // const { installationId } = request.params; // Get installationId from URL params // const { teamMemberId } = request.body; // Get teamMemberId from request body // if (!teamMemberId) { // return reply.status(400).send({ // simplydata: { // error: true, // message: "teamMemberId is required", // }, // }); // } // // Find installation by installationId // const installation = await Install.findOne({ installationId }); // if (!installation) { // return reply.status(404).send({ // simplydata: { // error: true, // message: "Installation not found", // }, // }); // } // // Extract team members list // const teamMembers = installation.team_member.team_member; // // Check if provided teamMemberId exists in the installation's team // const assignedTeamMember = teamMembers.find(member => member.teamMemberId === teamMemberId); // if (!assignedTeamMember) { // return reply.status(404).send({ // simplydata: { // error: true, // message: "Team member not found in this installation", // }, // }); // } // // Here, you would save the assigned team member to the quotation (modify as needed) // const quotation = { // installationId, // assignedTeamMember // }; // return reply.send({ // simplydata: { // error: false, // message: "Team member assigned to quotation successfully", // quotation // }, // }); // } catch (err) { // console.error("Error assigning team member to quotation:", err); // reply.status(500).send({ // simplydata: { // error: true, // message: "Internal server error", // }, // }); // } // }; exports.assignTeamMemberToQuotation = async (request, reply) => { try { const { installationId } = request.params; const { teamMemberId, quotationId } = request.body; if (!teamMemberId || !quotationId) { return reply.status(400).send({ simplydata: { error: true, message: "Both teamMemberId and quotationId are required", }, }); } // 🔹 Find installation by installationId const installation = await Install.findOne({ installationId }); if (!installation) { return reply.status(404).send({ simplydata: { error: true, message: "Installation not found", }, }); } // 🔹 Extract team members list const teamMembers = installation.team_member?.team_member || []; // 🔹 Check if the provided teamMemberId exists in the installation's team const assignedTeamMember = teamMembers.find( (member) => member.teamMemberId === teamMemberId ); if (!assignedTeamMember) { return reply.status(404).send({ simplydata: { error: true, message: "Team member not found in this installation", }, }); } // 🔹 Find or create the quotation for the given installationId let quotation = await Order.findOne({ installationId, quatationId: quotationId }); if (!quotation) { quotation = new Order({ installationId, quatationId: quotationId, assignedTeamMembers: [], // Ensure assignedTeamMembers array is initialized quatation_status: "Pending", // Default status when created }); } // 🔹 Assign the team member to the quotation if (!quotation.assignedTeamMembers) { quotation.assignedTeamMembers = []; } if (!quotation.assignedTeamMembers.includes(teamMemberId)) { quotation.assignedTeamMembers.push(teamMemberId); } // 🔹 Update order status when a team member is assigned quotation.quatation_status = "Assigned"; // Update status // 🔹 Save the updated quotation in the Order schema await quotation.save(); // 🔹 Update Installation schema with quotationId installation.quatationId = quotationId; await installation.save(); return reply.send({ simplydata: { error: false, message: "Team member assigned to quotation successfully", quotation, }, }); } catch (err) { console.error("Error assigning team member to quotation:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.getAllInstallers = async (request, reply) => { try { const { departmentName } = request.params; // Get installationId from request params // Check if installation exists const installationList = await Deparments.find({ departmentName }); if (!installationList) { return reply.status(404).send({ simplydata: { error: true, message: "Installation not found", }, }); } return reply.send({ simplydata: { error: false, installationList, // Return the list of team members }, }); } catch (err) { console.error("Error fetching team members:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.editTeamMember = async (request, reply) => { try { const { installationId, teamMemberId } = request.params; const updateData = request.body; // Find the installation const installation = await Install.findOne({ installationId }); if (!installation) { return reply.status(404).send({ simplydata: { error: true, message: "Installation not found", }, }); } // Find the team member let teamMember = installation.team_member.team_member.find( (member) => member.teamMemberId === teamMemberId ); if (!teamMember) { return reply.status(404).send({ simplydata: { error: true, message: "Team member not found", }, }); } // Update fields Object.assign(teamMember, updateData); // Save changes await installation.markModified("team_member.team_member"); await installation.save(); return reply.send({ simplydata: { error: false, message: "Team member updated successfully", }, }); } catch (err) { console.error("Error updating team member:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.deleteTeamMember = async (request, reply) => { try { const { installationId, teamMemberId } = request.params; // Find the installation const installation = await Install.findOne({ installationId }); if (!installation) { return reply.status(404).send({ simplydata: { error: true, message: "Installation not found", }, }); } // Find index of the team member const memberIndex = installation.team_member.team_member.findIndex( (member) => member.teamMemberId === teamMemberId ); if (memberIndex === -1) { return reply.status(404).send({ simplydata: { error: true, message: "Team member not found", }, }); } // Remove the team member from the array installation.team_member.team_member.splice(memberIndex, 1); // Save changes await installation.markModified("team_member.team_member"); await installation.save(); return reply.send({ simplydata: { error: false, message: "Team member deleted successfully", }, }); } catch (err) { console.error("Error deleting team member:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.getQuotationsByInstallationId = async (request, reply) => { try { const { installationId } = request.params; if (!installationId) { return reply.status(400).send({ simplydata: { error: true, message: "Installation ID is required", }, }); } // 🔹 Fetch quotations based on installationId const quotations = await Order.find({ installationId }); if (!quotations || quotations.length === 0) { return reply.status(404).send({ simplydata: { error: true, message: "No quotations found for this installation ID", }, }); } return reply.send({ simplydata: { error: false, message: "Quotations fetched successfully", quotations, }, }); } catch (err) { console.error("Error fetching quotations:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.getQuotationsByInstallationAndTeamMember = async (request, reply) => { try { const { installationId, teamMemberId } = request.params; if (!installationId || !teamMemberId) { return reply.status(400).send({ simplydata: { error: true, message: "Both installationId and teamMemberId are required", }, }); } // 🔹 Fetch quotations where installationId matches and teamMemberId is assigned const quotations = await Order.find({ installationId, assignedTeamMembers: teamMemberId, }); if (!quotations || quotations.length === 0) { return reply.status(404).send({ simplydata: { error: true, message: "No quotations found for this installation and team member", }, }); } return reply.send({ simplydata: { error: false, message: "Quotations fetched successfully", quotations, }, }); } catch (err) { console.error("Error fetching quotations:", err); reply.status(500).send({ simplydata: { error: true, message: "Internal server error", }, }); } }; exports.getDepartmentByFirstName = async (req, reply) => { try { let { firstName } = req.params; if (!firstName) { return reply.status(400).send({ simplydata: { error: true, message: "firstName is required" }, }); } // Trim and convert to lowercase firstName = firstName.trim().toLowerCase(); console.log("Searching for firstName:", firstName); // Debugging log // Search for the department with case-insensitive and space-tolerant regex const department = await Deparments.findOne({ firstName: { $regex: `^\\s*${firstName}\\s*$`, $options: "i" } }).lean(); console.log("Department found:", department); // Debugging log if (!department) { return reply.status(404).send({ simplydata: { error: true, message: "Department not found" }, }); } return reply.send({ simplydata: { error: false, message: "Department details fetched successfully", firstName: department.firstName, phone: department.phone, }, }); } catch (err) { console.error("Error fetching department details:", err); return reply.status(500).send({ simplydata: { error: true, message: "Internal server error" }, }); } }; exports.getByHardwareId = async (req, reply) => { try { const { hardwareId } = req.params; if (!hardwareId) { return reply.status(400).send({ error: "hardwareId is required" }); } console.log("Fetching details for hardwareId:", hardwareId); // Fetch only required fields to reduce response size // const data = await Collection.findOne({ hardwareId }) // .select("hardwareId mode tanks date time") // Select only needed fields // .lean(); const data = await IotData.find({ hardwareId }); if (!data) { return reply.send({ status_code: 404, message: "Data not found", data: null }); } return reply.send({ status_code: 200, message: "Success", data }); } catch (err) { console.error("Error:", err); return reply.status(500).send({ error: "Internal Server Error" }); } }; exports.getByHardwareAndTankId = async (req, reply) => { try { const { hardwareId, tankhardwareId } = req.params; if (!hardwareId || !tankhardwareId) { return reply.status(400).send({ error: "Both hardwareId and tankhardwareId are required" }); } console.log("Fetching details for:", { hardwareId, tankhardwareId }); // Correct query using $elemMatch const data = await IotData.findOne( { hardwareId, tanks: { $elemMatch: { tankhardwareId } } }, { "tanks.$": 1, hardwareId: 1, mode: 1, date: 1, time: 1 } // Projection to return only matched tank ); if (!data) { return reply.send({ status_code: 404, message: "Data not found", data: null }); } return reply.send({ status_code: 200, message: "Success", data }); } catch (err) { console.error("Error:", err); return reply.status(500).send({ error: "Internal Server Error" }); } }; exports.getAllocatedSensorsByTank = async (req, reply) => { try { let { customerId, tankName } = req.params; if (!customerId || !tankName) { return reply.status(400).send({ error: "customerId and tankName are required" }); } tankName = tankName.trim(); // Trim spaces console.log("Querying MongoDB with:", { customerId, tankName, status: "blocked" }); const allocatedSensors = await Insensors.find({ customerId, tankName: { $regex: `^${tankName}$`, $options: "i" }, // Case-insensitive search status: "blocked", }).lean(); if (!allocatedSensors.length) { return reply.send({ status_code: 200, message: "No allocated sensors found for this tank", allocatedSensors: [], }); } return reply.send({ status_code: 200, message: "Allocated sensors fetched successfully", allocatedSensors, }); } catch (err) { console.error("Error fetching allocated sensors:", err); return reply.status(500).send({ error: "Internal server error" }); } }; exports.createMasterSlaveData = async (req, reply) => { try { const { installationId } = req.params; const { type, customerId, hardwareId, batchno, masterId, tankName, tankLocation, materialRecived, electricityWork, plumbingWork, loraCheck } = req.body; if (!installationId || !hardwareId || !masterId) { return reply.status(400).send({ message: "installationId, hardwareId, and masterId are required." }); } // 🔹 Fetch stored electricity work pictures const electricityWorkData = await ElectrictyWorkPictures.findOne({ installationId, customerId }); const electricityWorkPictures = electricityWorkData ? electricityWorkData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() })) : []; // 🔹 Fetch stored plumbing work pictures const plumbingWorkData = await PlumbingWorkPictures.findOne({ installationId, customerId }); const plumbingWorkPictures = plumbingWorkData ? plumbingWorkData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() })) : []; const materialRecievedData = await MaterialRecievedPictures.findOne({ installationId, customerId }); const materialRecievedPictures = materialRecievedData ? materialRecievedData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() })) : []; // 🔹 Save all data to MasterSlaveData const newData = new MasterSlaveData({ installationId, type, customerId, hardwareId, batchno, masterId, tankName, tankLocation, materialRecived, electricityWork, plumbingWork, loraCheck, electricityWorkPictures, plumbingWorkPictures, materialRecievedPictures }); await newData.save(); reply.status(201).send({ message: "Master-Slave data created successfully", data: newData }); } catch (err) { reply.status(500).send({ message: err.message }); } }; exports.masterConnectedSlaveList = async (req, reply) => { try { const { connectedTo } = req.params; // Step 1: Find all slave tanks where connected_to matches const slaveTanks = await Insensors.find({ connected_to: connectedTo }); if (!slaveTanks || slaveTanks.length === 0) { return reply.status(404).send({ success: false, message: "No tanks found for the given connected_to value" }); } // Step 2: Fetch `tankLocation` and `typeOfWater` from the Tank schema const tankDetails = await Tank.findOne({ hardwareId: connectedTo }, { tankLocation: 1, typeOfWater: 1 }); if (!tankDetails) { return reply.status(404).send({ success: false, message: "Tank details not found for the given connectedTo" }); } // Step 3: Count the number of connected slaves const slaveCount = slaveTanks.length; return reply.send({ success: true, tankLocation: tankDetails.tankLocation, typeOfWater: tankDetails.typeOfWater, connectedSlaveCount: slaveCount, data: slaveTanks, }); } catch (error) { console.error("Error fetching master connected slave data:", error); return reply.status(500).send({ success: false, message: "Internal Server Error" }); } }; exports.mastrerList = async (req, reply) => { try { const { customerId, installationId } = req.params; // Step 1: Get User and extract buildingName const user = await User.findOne({ customerId , installationId }); if (!user) { return reply.status(404).send({ success: false, message: "User not found" }); } const { buildingName } = user; // Step 2: Get Tanks with matching customerId const tanks = await Tank.find({ customerId }); if (!tanks.length) { return reply.status(404).send({ success: false, message: "No tanks found for this customer" }); } // Step 3: Extract hardwareId from tanks const hardwareIds = tanks.map(tank => tank.hardwareId); // Step 4: Find master tanks in InSensors with both customerId and installationId const masterTanks = await Insensors.find({ customerId, connected_to: { $in: hardwareIds }, type: "master" }); if (!masterTanks.length) { return reply.status(404).send({ success: false, message: "No master tanks found" }); } return reply.send({ success: true, buildingName, data: masterTanks, user }); } catch (error) { console.error("Error fetching master tanks:", error); return reply.status(500).send({ success: false, message: "Internal Server Error" }); } };