// 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 ) ;
}
} ;
exports . getallsuppliers = async ( req , reply ) => {
try {
// Find the specific tank
const suppliers = await Supplier . find ( {
} ) ;
if ( ! suppliers ) {
return reply . send ( { status _code : 404 , error : "suppliers not found" } ) ;
}
// Send the found tank within a list
reply . send ( { status _code : 200 , data : [ suppliers ] } ) ;
} catch ( err ) {
throw boom . boomify ( err ) ;
}
} ;