// const fastify = require("fastify")({ // logger: true, // }); //const axios = require('axios'); const bcrypt = require("bcrypt"); const saltRounds = 10; const libphonenumberjs = require("libphonenumber-js"); // External Dependancies // offers http-friendly error objects. const boom = require("boom"); const { Tankerbooking} = require("../models/tankers") // Get Data Models const { RequestedBooking,Supplier, generateSupplierId, FriendRequest,DeliveryBoy} = require("../models/supplier") const { User,Counter, generateBookingId,resetCounter,generateCustomerId,ProfilePicture, AddTeamMembers,Cart} = require('../models/User') //const User = require("../models/User"); const customJwtAuth = require("../customAuthJwt"); const fastify = require("fastify")({ logger: true, }); //function to encrypt password. //used bcrypt module. async function bcryptPassword(password) { encryptedPwd = bcrypt.hash(password, saltRounds); return encryptedPwd; } //function to decrypt password return user object . //used bcrypt module. async function bcryptComparePassword(pwd, encpassword) { isSame = bcrypt.compare(pwd, encpassword); return isSame; } // Get current users exports.getCurrentUser = async (req, reply) => { try { const users = await User.findOne({ customerId: req.body.customerId }); return users; } catch (err) { throw boom.boomify(err); } }; // Get all users exports.getUsers = async (req, reply) => { const limit = parseInt(req.query.limit) || 100; const page = parseInt(req.query.page) || 1; const startindex = (page - 1) * limit; try { await User.find() .limit(limit) .skip(startindex) .exec() .then((docs) => { reply.send({ status_code: 200, data: docs, count: docs.length }); }) .catch((err) => { console.log(err); reply.send({ error: err }); }); } catch (err) { throw boom.boomify(err); } }; // Get single user by ID exports.getSingleUser = async (req, reply) => { try { const customerId = req.params.customerId; const user = await User.findOne({ customerId: customerId }); return user; } catch (err) { throw boom.boomify(err); } }; // Edit user info by userId exports.editUserInfo = async (req, body) => { try { const { userId } = req.params; console.log(customerId) const userInfo = await User.findById(userId); const updateData = req.body; console.log(updateData.firstName); if (updateData.firstName) userInfo.profile.firstName = updateData.firstName; if (updateData.lastName) userInfo.profile.lastName = updateData.lastName; if (updateData.phone) userInfo.profile.contactNumber = updateData.phone; if (updateData.address1) userInfo.profile.address1 = updateData.address1; if (updateData.address2) userInfo.profile.address2 = updateData.address2; if (updateData.city) userInfo.profile.city = updateData.city; if (updateData.state) userInfo.profile.state = updateData.state; if (updateData.country) userInfo.profile.country = updateData.country; if (updateData.zip) userInfo.profile.zip = updateData.zip; if (updateData.phone) userInfo.phone = updateData.phone; if (updateData.email) userInfo.emails[0].email = updateData.email; if (updateData.role) userInfo.profile.role = updateData.role; const user = await userInfo.save(); return user; } catch (err) { throw boom.boomify(err); } }; exports.editCuurentUserInfo = async (req, reply) => { try { const { customerId } = req.params; const userInfo = await User.findOne({ customerId: customerId.toString() }); const updateData = req.body; if (updateData.buildingName) userInfo.buildingName = updateData.buildingName if (updateData.firstName) userInfo.profile.firstName = updateData.firstName; if (updateData.lastName) userInfo.profile.lastName = updateData.lastName; if (updateData.username) userInfo.username = updateData.username; if (updateData.phone) userInfo.profile.contactNumber = updateData.phone; if (updateData.address1) userInfo.profile.address1 = updateData.address1; if (updateData.address2) userInfo.profile.address2 = updateData.address2; if (updateData.city) userInfo.profile.city = updateData.city; if (updateData.state) userInfo.profile.state = updateData.state; if (updateData.country) userInfo.profile.country = updateData.country; if (updateData.zip) userInfo.profile.zip = updateData.zip; if (updateData.phone) userInfo.phone = updateData.phone; if (updateData.emails) userInfo.emails = updateData.emails; console.log(userInfo.emails[0].email) if (updateData.role) userInfo.profile.role = updateData.role; if (updateData.phone) { const phoneNumber = updateData.phone //libphonenumberjs.parsePhoneNumber(updateData.phone); if (phoneNumber) { // access returned collection if (!phoneNumber) { //if (!phoneNumber.isValid()) { error = { armintatankdata: { error: true, code: 10002, message: "10002 - Phone # " + updateData.phone + " is not a valid phone number", }, }; req.body.regError = error; reply.status(406).send(error); } } } if (userInfo.phone == updateData.phone) { console.log("IF++++++++++++++="); userInfo.phone = updateData.phone; userInfo.phoneVerified = true; } else { console.log("Ilse++++++++++++++="); userInfo.phone = updateData.phone; userInfo.phoneVerified = false; } const user = await userInfo.save(); return user; } catch (err) { throw boom.boomify(err); } }; // Add a new user // Function accepts username, password , encrypts password and saves it in the database. exports.addUser = async (req, reply) => { try { // await resetCounter();//to set customer id back to 0 var c_id = await generateCustomerId() var building= ((req.body.buildingName).slice(0, 3)).toUpperCase(); var customer_id = `AWSU${building}${c_id}` // console.log("This is the reply in the handler after the validations", reply); userData = { installationId:req.params.installationId, customerId: customer_id, username: req.body.username, emails: req.body.emails, password: req.body.password, phone: req.body.phone, buildingName: req.body.buildingName, inchargeName: req.body.inchargeName, profile: { firstName: req.body.firstName, lastName: req.body.lastName, contactNumber: req.body.phone, country: req.body.country, state: req.body.state, city: req.body.city, address1: req.body.address1, address2: req.body.address2, zip: req.body.zip, notes: req.body.notes, }, longitude: req.body.longitude, latitude:req.body.latitude, fcmId: req.body.fcmId, deviceId: req.body.deviceId }; var user = new User(userData); //password is not at the top level in the collection. userpass = req.body.password; // If fields are sent via form encoding , capture the fields and assign them to the user Object. checkFormEncoding = isUserFormUrlEncoded(req); if (checkFormEncoding.isUserFormUrlEncoded) { usertobeInserted = checkFormEncoding.user; console.log("thsi true url string"); user.installationId = usertobeInserted.installationId; user.username = usertobeInserted.username; user.firstName = usertobeInserted.firstName; user.lastName = usertobeInserted.lastName; user.phone = usertobeInserted.phone; user.emails = usertobeInserted.emails; user.passsword = usertobeInserted.password; user.buildingName = usertobeInserted.buildingName; user.inchargeName = usertobeInserted.inchargeName; user.customerId = usertobeInserted.customer_id; user.latitude = usertobeInserted.latitude; user.longitude = usertobeInserted.longitude user.fcmId = usertobeInserted.fcmId user.deviceId = usertobeInserted.deviceId } console.log("---------checkurl ecnoded string-----------------------"); // Store hash in your password DB. hash = await bcryptPassword(userpass); if (hash) { user.services.password.bcrypt = hash; if (req.body.role) { user.profile.role = req.body.role; console.log("******************************************************"); console.log(user); } else { // override and make the user role as "user" by default role = ["user"]; user.profile.role = role; } insertedUser = await user.save(); console.log(insertedUser); if (insertedUser) { // Prepare user object and wrap it inside the armintatankdata var retUser = { armintatankdata: { username: insertedUser.username, phone: insertedUser.phone, customerId: insertedUser.customerId, inchargeName: insertedUser.inchargeName, buildingName: insertedUser.buildingName, emails: [ { email: insertedUser.emails[0].email, }, ], profile: insertedUser.profile, longitude: insertedUser.longitude, latitude:insertedUser.latitude, fcmId: insertedUser.fcmId, deviceId: insertedUser.deviceId }, status_code: 200, }; return retUser; } } } catch (err) { throw boom.boomify(err); } }; // Login a user // Accepts a user , password , and checks in the system to see if user exists , and password is valid // returns a user object so that jwt token can be created and sent back to the client exports.loginUser = async (req, fcmIds, deviceId) => { try { const { phone, password } = req.body; let user = await User.findOne({ phone }); let isStaff = false; let staffMember = null; // If not a main user, check staff inside all users if (!user) { const users = await User.find({ "staff.staff.phone": phone }); for (const u of users) { const foundStaff = u.staff.staff.find((s) => s.phone === phone); if (foundStaff) { user = u; // Assign user as the main user under which the staff exists staffMember = foundStaff; isStaff = true; break; } } } // If no user or staff found, return invalid credentials if (!user) return { same: false }; // Validate password let isSame = false; if (isStaff) { isSame = password === staffMember.password; // Plain text comparison for staff } else { isSame = await bcrypt.compare(password, user.services.password.bcrypt); // Bcrypt for main users } if (!isSame) return { same: false }; // Update deviceId user.deviceId = deviceId; await user.save(); return { same: true, user, isStaff, staffMember }; } catch (err) { throw boom.boomify(err); } }; exports.loginUserWithOTP = async (req) => { try { const phone = req.body.phone; const phoneVerificationCode = req.body.phoneVerificationCode; const userDetails = await User.findOne({ phone: phone }); const supplier = await Supplier.findOne({phone: phone}) const deliveryBoy = await DeliveryBoy.findOne( { phone : phone}) const installation = await Install.findOne( { phone : phone}) let user; if(userDetails){ user = await User.findOne({ phone: phone, 'phoneVerificationCode': phoneVerificationCode }); } if(supplier){ user = await Supplier.findOne({ phone: phone, 'phoneVerificationCode': phoneVerificationCode }); } if(deliveryBoy){ user = await DeliveryBoy.findOne({ phone: phone, 'phoneVerificationCode': phoneVerificationCode }); } if(installation){ user = await Install.findOne({ phone: phone, 'phoneVerificationCode': phoneVerificationCode }); } if (user) { return { same: true, user: user }; } else { return { same: false }; } } catch (err) { throw boom.boomify(err); } }; // Update an existing user exports.updateUser = async (req, reply) => { try { const id = req.params.id; const user = req.body; const { ...updateData } = user; const update = await User.findByIdAndUpdate(id, updateData, { new: true }); return update; } catch (err) { throw boom.boomify(err); } }; // Delete a user exports.deleteUser = async (req, reply) => { try { const id = req.params.id; const user = await User.findByIdAndRemove(id); return user; } catch (err) { throw boom.boomify(err); } }; //Added the getphone user and delphone user apis for testing purposes exports.getPhoneUser = async (req, reply) => { try { console.log(" requesting the api getPhoneUser , and passing the phone "); const phone = req.body.phone; const user = await User.findOne({ phone: phone }); return user; } catch (err) { throw boom.boomify(err); } }; exports.delPhoneUser = async (req, reply) => { try { const phone = req.body.phone; console.log("deleting users wiht the phone ....", phone); const user = await User.deleteOne({ phone: phone }); return user; } catch (err) { throw boom.boomify(err); } }; // exports.uploadProfilePicture = async (req, reply) => { // try { // const customerId = req.params.customerId; // const picture = req.body.picture; // let profilePicture = await ProfilePicture.findOne({ customerId }); // if (!profilePicture) { // profilePicture = new ProfilePicture({ // customerId, // picture, // }); // } else { // profilePicture. picture = picture; // } // await profilePicture.save(); // reply.send({ message: 'Profile picture uploaded successfully' }); // } catch (error) { // reply.status(500).send({ error: error.message }); // } // }; const multer = require('multer'); const fs = require('fs'); const storage = multer.diskStorage({ destination: function (req, file, cb) { if (!fs.existsSync(__dirname + '/temp')) { fs.mkdirSync(__dirname + '/temp'); } cb(null, './temp'); }, filename: function (req, file, cb) { cb(null, file.originalname + '-' + Date.now() + '.' + file.mimetype.split('/')[1]); } }); const upload = multer({ storage: storage }).single('picture'); // Specify the field name used for the file upload exports.uploadProfilePicture = async (req, reply) => { try { upload(req, reply, async (err) => { if (err) { reply.status(400).send({ error: 'Failed to upload profile picture' }); return; } const customerId = req.params.customerId; const picturePath = req.file.path; let profilePicture = await ProfilePicture.findOne({ customerId }); if (!profilePicture) { profilePicture = new ProfilePicture({ customerId, picture: fs.readFileSync(picturePath), }); } else { profilePicture.picture = fs.readFileSync(picturePath); } await profilePicture.save(); // Delete the temporary uploaded file fs.unlinkSync(picturePath); reply.send({ message: 'Profile picture uploaded successfully' }); }); } catch (error) { reply.status(500).send({ error: error.message }); } }; exports.logout = async (request, reply) => { const invalidatedTokens = {}; const accessToken = request.headers.authorization && request.body.access_token; invalidatedTokens[accessToken] = true; reply.send({ message: 'Logout successful' }) } // controller.js const http = require('https'); const { Install } = require("../models/store"); exports.sendSms = async (request, reply) => { const code = Math.floor(100000 + Math.random() * 900000); const username = 'Arminta'; const apiKey = '2068323bea61494d315b'; const senderId = 'ARMNTA'; const mobile = request.body.mobileNumbers//'8341426949'; const message = `Welcome to Arminta !!! your OTP is ${code} please use it for login.`//`Welcome to Arminta !!! your OTP is ${code} please use it for login.`; const user = await User.findOne({phone: mobile}) const supplier = await Supplier.findOne({phone: mobile}) const deliveryBoy = await DeliveryBoy.findOne( { phone : mobile}) const installation = await Install.findOne( { phone : mobile}) if(user){ await User.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } if(supplier){ await Supplier.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } if(deliveryBoy){ await DeliveryBoy.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } if(installation){ await Install.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } const apiUrl = `https://smslogin.co/v3/api.php?username=${username}&apikey=${apiKey}&senderid=${senderId}&mobile=${mobile}&message=${encodeURIComponent(message)}`; const options = { method: 'GET', headers: { 'Content-Type': 'application/json' } }; const req = http.request(apiUrl, options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { reply.send(data); }); }); req.on('error', (error) => { console.error(error); reply.send({ error: 'Failed to send SMS' }); }); req.end(); } exports.forgotPassword = async (req, reply) => { try { // Create a new User object from the request body var user = new User(req.body); // Check if the request body is URL encoded checkFormEncoding = isUserFormUrlEncoded(req); if (checkFormEncoding.isUserFormUrlEncoded) { // Extract user information from the request body usertobeInserted = checkFormEncoding.user; user.username = usertobeInserted.username; user.firstName = usertobeInserted.firstName; user.lastName = usertobeInserted.lastName; user.phone = usertobeInserted.phone; user.emails = usertobeInserted.emails; } // Find a user with the given phone number in the database userExists = await User.findOne({ phone: user.phone, }); if (userExists) { // Generate a random password reset code const code = Math.floor(100000 + Math.random() * 900000); // Convert the code to a string and hash it using bcrypt codestr = ""; codestr = code.toString(); hash = await bcryptPassword(codestr); // Update the user's password reset code and password hash in the database const filter = { phone: userExists.phone, }; const update = { $set: { passwordResetCode: code, "services.password.bcrypt": hash, oneTimePasswordSetFlag: true, }, }; const doc = await User.updateOne(filter, update); // Find the updated user in the database updatedUser = await User.findOne({ phone: userExists.phone }); if (updatedUser.oneTimePasswordSetFlag) { // Send an SMS with the password reset code const request = { body: { mobileNumbers: userExists.phone, }, }; const response = { send: (data) => { console.log(data); // Optional: Log the response from the SMS provider // Send a success response with the password reset code req.body.passwordResetCode = code; reply.send('{"armintatankdata":{"error":false,"forgotPassword": true}}'); }, }; await exports.sendSms(request, response); } else { // Send an error response if the password reset code was not set error = { armintatankdata: { error: true, code: 10007, message: "10007 - Unable to reset password", }, }; req.body.regError = error; reply.send(error); } } else { // Send an error response if no user was found with the given phone number error = { armintatankdata: { error: true, code: 10006, message: "10006 - Please check the phone number you entered..", }, }; req.body.regError = error; reply.send(error); } } catch (err) { // Handle any errors that occur during the API request throw boom.boomify(err); } }; exports.changePassword = async (req, reply) => { try { const {phone, oldPassword, newPassword } = req.body; if (!oldPassword || !newPassword) { return reply.send({ armintatankdata: { error: true, code: 10008, message: "10008 - Old password and new password are required", }, }); } // Find user by phone const user = await User.findOne({ phone }); if (!user) { return reply.send({ armintatankdata: { error: true, code: 10006, message: "10006 - User not found. Please check the phone number.", }, }); } // Verify old password const isMatch = await bcrypt.compare(oldPassword, user.services.password.bcrypt); if (!isMatch) { return reply.send({ armintatankdata: { error: true, code: 10009, message: "10009 - Incorrect old password", }, }); } // Hash new password const hashedPassword = await bcrypt.hash(newPassword, 10); // Update password await User.updateOne( { phone }, { $set: { "services.password.bcrypt": hashedPassword, oneTimePasswordSetFlag: false, // Reset OTP flag after password change }, } ); reply.send({ armintatankdata: { error: false, message: "Password changed successfully", }, }); } catch (err) { throw boom.boomify(err); } }; exports.addingfavoratesupplier = async (req, reply) => { try { const { customerId } = req.params; const { supplierId } = req.query; if (!supplierId) { return reply.code(400).send({ status_code: 400, message: "supplierId is required" }); } // Find user const user = await User.findOne({ customerId }); if (!user) { return reply.code(404).send({ status_code: 404, message: "User not found" }); } // Add supplierId to favorate_suppliers if not already there if (!user.favorate_suppliers.includes(supplierId)) { user.favorate_suppliers.push(supplierId); await user.save(); } // Fetch FriendRequest status const friendRequest = await FriendRequest.findOne({ customerId, supplierId }); const status = friendRequest ? friendRequest.status : "not_requested"; reply.send({ status_code: 200, message: "Supplier added to favorites successfully", data: { customerId, supplierId, favorate_suppliers: user.favorate_suppliers, status, }, }); } catch (err) { console.error(err); reply.status(500).send({ status_code: 500, message: err.message }); } }; exports.forgotPasswordSupplier = async (req, reply) => { try { // Create a new Supplier object from the request body var supplier = new Supplier(req.body); // Check if the request body is URL encoded checkFormEncoding = isSupplierFormUrlEncoded(req); if (checkFormEncoding.isSupplierFormUrlEncoded) { // Extract supplier information from the request body suppliertobeInserted = checkFormEncoding.supplier; supplier.username = suppliertobeInserted.username; supplier.firstName = suppliertobeInserted.firstName; supplier.lastName = suppliertobeInserted.lastName; supplier.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; } // Find a supplier with the given phone number in the database supplierExists = await Supplier.findOne({ phone: supplier.phone, }); if (supplierExists) { // Generate a random password reset code const code = Math.floor(100000 + Math.random() * 900000); // Convert the code to a string and hash it using bcrypt codestr = ""; codestr = code.toString(); hash = await bcryptPassword(codestr); // Update the supplier's password reset code and password hash in the database const filter = { phone: supplierExists.phone, }; const update = { $set: { passwordResetCode: code, "services.password.bcrypt": hash, oneTimePasswordSetFlag: true, }, }; const doc = await Supplier.updateOne(filter, update); // Find the updated supplier in the database updatedSupplier = await Supplier.findOne({ phone: supplierExists.phone }); if (updatedSupplier.oneTimePasswordSetFlag) { // Send an SMS with the password reset code const request = { body: { mobileNumbers: supplierExists.phone, }, }; const response = { send: (data) => { console.log(data); // Optional: Log the response from the SMS provider // Send a success response with the password reset code req.body.passwordResetCode = code; reply.send('{"armintatankdata":{"error":false,"forgotPassword": true}}'); }, }; await exports.sendSms(request, response); } else { // Send an error response if the password reset code was not set error = { armintatankdata: { error: true, code: 10007, message: "10007 - Unable to reset password", }, }; req.body.regError = error; reply.send(error); } } else { // Send an error response if no supplier was found with the given phone number error = { armintatankdata: { error: true, code: 10006, message: "10006 - Please check the phone number you entered..", }, }; req.body.regError = error; reply.send(error); } } catch (err) { // Handle any errors that occur during the API request throw boom.boomify(err); } }; exports.addTeamMembers = async (req, reply) => { try { const customerId = req.params.customerId console.log(req.params); deliveryData = { customerId: customerId, teamAdminName: req.body.teamAdminName, name: req.body.Name, phone: req.body.phone, }; var agent_mobile = req.body.phone var i_agent = await AddTeamMembers.findOne({ phone: agent_mobile}) if(i_agent){ throw new Error('phone already exists'); } else { var agent = new AddTeamMembers(deliveryData); checkFormEncoding = isUserFormUrlEncoded(req); if (checkFormEncoding.isUserFormUrlEncoded) { usertobeInserted = checkFormEncoding.agent; console.log("thsi true url string"); agent.customerId = usertobeInserted.customerId agent.teamAdminName = usertobeInserted.teamAdminName agent.name = usertobeInserted.name; agent.phone = usertobeInserted.phone; } } const insertedagent = await agent.save(); console.log("inster...", insertedagent) return insertedagent; } catch (err) { throw boom.boomify(err); } }; exports.deleteTeamMember = async (req, reply) => { try { var customerId = req.params.customerId; var phone = req.query.phone; const delivery = await AddTeamMembers.findOneAndDelete({ phone: phone, customerId: customerId, }); reply.send({ status_code: 200, data: delivery }); } catch (err) { throw boom.boomify(err); } }; exports.editFavoriteSupplier = async (req, reply) => { try { const { customerId } = req.params; const { oldSupplierId, newSupplierId } = req.query; const user = await User.findOne({ customerId }); if (!user) return reply.code(404).send({ status_code: 404, message: "User not found" }); const index = user.favorate_suppliers.indexOf(oldSupplierId); if (index === -1) return reply.code(400).send({ status_code: 400, message: "Old supplier not found in favorites" }); user.favorate_suppliers[index] = newSupplierId; await user.save(); reply.send({ status_code: 200, message: "Favorite supplier updated", data: user.favorate_suppliers, }); } catch (err) { throw boom.boomify(err); } }; exports.deleteFavoriteSupplier = async (req, reply) => { try { const { customerId } = req.params; const { supplierId } = req.query; const user = await User.findOne({ customerId }); if (!user) return reply.code(404).send({ status_code: 404, message: "User not found" }); const initialLength = user.favorate_suppliers.length; user.favorate_suppliers = user.favorate_suppliers.filter(id => id !== supplierId); if (user.favorate_suppliers.length === initialLength) return reply.code(400).send({ status_code: 400, message: "Supplier not found in favorites" }); await user.save(); reply.send({ status_code: 200, message: "Favorite supplier removed", data: user.favorate_suppliers, }); } catch (err) { throw boom.boomify(err); } }; exports.updateTeamMember = async (req, reply) => { try { var customerId = req.params.customerId; var phone = req.query.phone; const delivery = req.body; const { ...updateData } = delivery; const update = await AddTeamMembers.findOneAndUpdate( { phone: phone, customerId: customerId }, updateData, { new: true } ); console.log(update); //return update; reply.send({ status_code: 200, data: update }); } catch (err) { throw boom.boomify(err); } }; exports.createstaff = async (request, reply) => { try { const { customerId } = request.params; const { staff } = request.body; if (!staff || !Array.isArray(staff)) { return reply.status(400).send({ error: 'Invalid staff data provided' }); } // Find user by customerId const user = await User.findOne({ customerId }); if (!user) { return reply.status(404).send({ error: 'Customer not found' }); } // Check for duplicate phone numbers const existingPhones = new Set(user.staff.staff.map((member) => member.phone)); const newStaff = []; const duplicatePhones = []; staff.forEach((member) => { if (member.phone && existingPhones.has(member.phone)) { duplicatePhones.push(member.phone); } else { if (member.phone) { existingPhones.add(member.phone); } newStaff.push({ name: member.name || null, phone: member.phone || null, password: member.password || null, all_motor_access:member.all_motor_access, status: "active", // Default status }); } }); if (duplicatePhones.length > 0) { return reply.status(400).send({ error: 'Duplicate phone numbers found', duplicatePhones }); } // Update the user document with the new staff members user.staff.staff.push(...newStaff); // Save the updated user document await user.save(); reply.send({ message: 'Staff members added successfully', staff: user.staff.staff }); } catch (error) { console.error('Error creating staff:', error); reply.status(500).send({ error: 'An error occurred while adding staff' }); } }; exports.editStaff = async (request, reply) => { try { const { customerId, phone } = request.params; const { name, password,all_motor_access } = request.body; const user = await User.findOne({ customerId, "staff.staff.phone": phone }); if (!user) { return reply.status(404).send({ error: 'Staff member not found' }); } const staffMember = user.staff.staff.find(member => member.phone === phone); staffMember.name = name || staffMember.name; staffMember.password = password || staffMember.password; staffMember.all_motor_access = all_motor_access || staffMember.all_motor_access; await user.save(); reply.send({ message: 'Staff member updated successfully', staff: staffMember }); } catch (error) { console.error('Error updating staff member:', error); reply.status(500).send({ error: 'An error occurred while updating staff' }); } }; exports.deleteStaff = async (request, reply) => { try { const { customerId, phone } = request.params; const user = await User.findOne({ customerId }); if (!user) { return reply.status(404).send({ error: 'Customer not found' }); } const initialLength = user.staff.staff.length; user.staff.staff = user.staff.staff.filter(member => member.phone !== phone); if (initialLength === user.staff.staff.length) { return reply.status(404).send({ error: 'Staff member not found' }); } await user.save(); reply.send({ message: 'Staff member deleted successfully' }); } catch (error) { console.error('Error deleting staff member:', error); reply.status(500).send({ error: 'An error occurred while deleting staff' }); } }; exports.blockStaff = async (request, reply) => { try { const { customerId, phone } = request.params; const user = await User.findOne({ customerId, "staff.staff.phone": phone }); if (!user) { return reply.status(404).send({ error: 'Staff member not found' }); } const staffMember = user.staff.staff.find(member => member.phone === phone); staffMember.status = 'blocked'; await user.save(); reply.send({ message: 'Staff member blocked successfully', staff: staffMember }); } catch (error) { console.error('Error blocking staff member:', error); reply.status(500).send({ error: 'An error occurred while blocking staff' }); } }; exports.getFavoriteSuppliers = async (req, reply) => { const { customerId } = req.params; try { // Find the user by customerId const user = await User.findOne({ customerId }); if (!user) { return reply.status(404).send({ status_code: 404, message: "User not found" }); } const supplierIds = user.favorate_suppliers || []; // Get full supplier details for those supplierIds const suppliers = await Supplier.find({ supplierId: { $in: supplierIds } }).exec(); reply.send({ status_code: 200, data: suppliers, count: suppliers.length }); } catch (err) { console.error("Error fetching favorite suppliers:", err); reply.status(500).send({ status_code: 500, message: "Internal server error" }); } }; exports.getCartByUserId = async (req, reply) => { try { const { customerId } = req.params; const cart = await Cart.findOne({ customerId }) || { customerId, items: [] }; reply.send({ status_code: 200, message: "Cart fetched successfully", data: cart, }); } catch (err) { console.error("Error fetching cart:", err); reply.status(500).send({ error: "Internal server error" }); } }; exports.addItemToCart = async (req, reply) => { try { const { customerId } = req.params; const { productId, name, quantity, price } = req.body; let cart = await Cart.findOne({ customerId }); if (!cart) { cart = new Cart({ customerId, items: [] }); } const existingItem = cart.items.find(item => item.productId === productId); if (existingItem) { existingItem.quantity += quantity; } else { cart.items.push({ productId, name, quantity, price }); } await cart.save(); reply.send({ status_code: 200, message: "Item added to cart", data: cart, }); } catch (err) { console.error("Error adding item:", err); reply.status(500).send({ error: "Internal server error" }); } }; exports.removeItemFromCart = async (req, reply) => { try { const { customerId } = req.params; const { productId } = req.body; const cart = await Cart.findOne({ customerId }); if (!cart) { return reply.status(404).send({ error: "Cart not found" }); } cart.items = cart.items.filter(item => item.productId !== productId); await cart.save(); reply.send({ status_code: 200, message: "Item removed from cart", data: cart, }); } catch (err) { console.error("Error removing item:", err); reply.status(500).send({ error: "Internal server error" }); } }; exports.clearCart = async (req, reply) => { try { const { customerId } = req.params; const cart = await Cart.findOneAndUpdate( { customerId }, { items: [] }, { new: true } ); reply.send({ status_code: 200, message: "Cart cleared", data: cart, }); } catch (err) { console.error("Error clearing cart:", err); reply.status(500).send({ error: "Internal server error" }); } }; exports.getuserOrders = async (req, reply) => { try { const { customerId } = req.params; const orders = await Tankerbooking.find({ customerId }).sort({ createdAt: -1 }).lean(); return reply.send({ status_code: 200, message: `Orders for customer ${customerId} fetched successfully`, data: orders }); } catch (err) { throw boom.boomify(err); } }; exports.getuserRequestbookings = async (req, reply) => { try { const { customerId } = req.params; // 1. Get all bookings const bookings = await RequestedBooking.find({ customerId }).sort({ createdAt: -1 }).lean(); // 2. Collect all supplierIds used const allSupplierIds = new Set(); bookings.forEach(booking => { booking.requested_suppliers?.forEach(s => { if (s.supplierId) allSupplierIds.add(s.supplierId); }); }); // 3. Query all supplier details at once const supplierList = await Supplier.find({ supplierId: { $in: [...allSupplierIds] } }).lean(); const supplierMap = {}; supplierList.forEach(s => { supplierMap[s.supplierId] = { supplierId: s.supplierId, supplierName: s.suppliername, phone: s.phone, longitude: s.longitude, latitude: s.latitude, address: s.profile?.office_address, status: s.status }; }); // 4. Attach supplier_details inside each requested_suppliers[] object const enrichedBookings = bookings.map(booking => { booking.requested_suppliers = booking.requested_suppliers.map(supplier => ({ ...supplier, supplier_details: supplierMap[supplier.supplierId] || null })); return booking; }); // 5. Send final response return reply.send({ status_code: 200, message: `Orders for customer ${customerId} fetched successfully`, data: enrichedBookings }); } catch (err) { console.error(err); throw boom.boomify(err); } }; const mongoose = require('mongoose'); exports.acceptRequestedBooking = async (req, reply) => { const { supplierId } = req.params; const { action, _id } = req.body; if (!["accept", "reject"].includes(action)) { return reply.code(400).send({ message: "Invalid action. Must be 'accept' or 'reject'." }); } try { const requestedBooking = await RequestedBooking.findOne({ _id: new mongoose.Types.ObjectId(_id), 'requested_suppliers.supplierId': supplierId }); if (!requestedBooking) { return reply.code(404).send({ message: "No matching request for given ID and supplier" }); } const matchedSupplier = requestedBooking.requested_suppliers.find(s => s.supplierId === supplierId); if (!matchedSupplier) { return reply.code(404).send({ message: "Supplier not found in requested_suppliers array" }); } if (action === "reject") { matchedSupplier.status = "rejected_by_user"; await requestedBooking.save(); return reply.code(200).send({ status_code: 200, message: "Supplier request rejected by user", data: requestedBooking }); } // Accept path requestedBooking.status = 'accepted'; await requestedBooking.save(); const customer = await User.findOne({ customerId: requestedBooking.customerId }).lean(); if (!customer) return reply.code(404).send({ message: "Customer not found" }); const supplier = await Supplier.findOne({ supplierId }).lean(); if (!supplier) return reply.code(404).send({ message: "Supplier not found" }); if (!matchedSupplier.quoted_amount) { return reply.code(400).send({ message: "Quoted amount missing for this supplier" }); } requestedBooking.requested_suppliers = requestedBooking.requested_suppliers.filter( s => s.supplierId !== supplierId ); // ✅ Optional: Mark booking as fully processed if no more suppliers remain if (requestedBooking.requested_suppliers.length === 0) { requestedBooking.status = 'processed'; } await requestedBooking.save(); // Format: ARM + YYYYMMDD + random digit (0–9) const today = new Date(); const datePart = today.toISOString().slice(0, 10).replace(/-/g, ''); // YYYYMMDD const randomDigit = Math.floor(Math.random() * 10); // 0–9 const bookingId = `ARM${datePart}${randomDigit}`; const newBooking = new Tankerbooking({ bookingid: bookingId, customerId: customer.customerId, customerName: customer.profile.firstName, customerPhone: customer.phone, address: customer.address1, latitude: customer.latitude, longitude: customer.longitude, supplierId: supplier.supplierId, supplierName: supplier.suppliername, supplierPhone: supplier.phone, supplierAddress: customer.address, type_of_water: requestedBooking.type_of_water, capacity: requestedBooking.capacity, quantity: requestedBooking.quantity, total_required_capacity: requestedBooking.total_required_capacity, expectedDateOfDelivery: requestedBooking.date, time: requestedBooking.time, price: matchedSupplier.quoted_amount, status: 'pending' }); await newBooking.save(); reply.code(200).send({ status_code: 200, message: "Booking accepted and moved to tanker bookings", data: newBooking }); } catch (err) { console.error(err); throw boom.internal("Failed to handle booking action", err); } }; exports.getordersofcustomer = async (req, reply) => { try { const customerId = req.params.customerId; // Find the specific tank const mainTank = await Tankerbooking.find({ customerId: customerId, }); if (!mainTank) { return reply.send({ status_code: 404, error: "Main tank not found" }); } // Send the found tank within a list reply.send({ status_code: 200, data: [mainTank] }); } catch (err) { throw boom.boomify(err); } };