|
|
// 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")
|
|
|
const {EstimationOrder} = require("../models/store");
|
|
|
|
|
|
// Get Data Models
|
|
|
const { RecurringRequestedBooking,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.loginUser = async (req, fcmIds, deviceId) => {
|
|
|
try {
|
|
|
const { phone, password } = req.body;
|
|
|
let user = await User.findOne({ phone });
|
|
|
let isStaff = false;
|
|
|
let staffMember = null;
|
|
|
|
|
|
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;
|
|
|
staffMember = foundStaff;
|
|
|
isStaff = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!user) return { same: false };
|
|
|
|
|
|
let isSame = false;
|
|
|
|
|
|
if (isStaff) {
|
|
|
isSame = password === staffMember.password;
|
|
|
} else {
|
|
|
const otpMatch =
|
|
|
//user.oneTimePasswordSetFlag &&
|
|
|
user.passwordResetCode &&
|
|
|
password === user.passwordResetCode.toString();
|
|
|
|
|
|
if (otpMatch) {
|
|
|
isSame = true;
|
|
|
user.oneTimePasswordSetFlag = false;
|
|
|
user.passwordResetCode = null;
|
|
|
} else {
|
|
|
isSame = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!isSame) return { same: false };
|
|
|
|
|
|
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.forgotPassword = async (req, reply) => {
|
|
|
try {
|
|
|
var user = new User(req.body);
|
|
|
|
|
|
checkFormEncoding = isUserFormUrlEncoded(req);
|
|
|
if (checkFormEncoding.isUserFormUrlEncoded) {
|
|
|
usertobeInserted = checkFormEncoding.user;
|
|
|
user.username = usertobeInserted.username;
|
|
|
user.firstName = usertobeInserted.firstName;
|
|
|
user.lastName = usertobeInserted.lastName;
|
|
|
user.phone = usertobeInserted.phone;
|
|
|
user.emails = usertobeInserted.emails;
|
|
|
}
|
|
|
|
|
|
const userExists = await User.findOne({ phone: user.phone });
|
|
|
|
|
|
if (!userExists) {
|
|
|
return reply.send({
|
|
|
armintatankdata: {
|
|
|
error: true,
|
|
|
code: 10006,
|
|
|
message: "10006 - Please check the phone number you entered.",
|
|
|
},
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// Generate a random 6-digit code
|
|
|
const code = Math.floor(100000 + Math.random() * 900000);
|
|
|
|
|
|
// Store OTP only (not password hash)
|
|
|
const update = {
|
|
|
$set: {
|
|
|
passwordResetCode: code,
|
|
|
oneTimePasswordSetFlag: true,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
await User.updateOne({ phone: userExists.phone }, update);
|
|
|
|
|
|
const updatedUser = await User.findOne({ phone: userExists.phone });
|
|
|
|
|
|
if (updatedUser.oneTimePasswordSetFlag) {
|
|
|
const request = {
|
|
|
body: {
|
|
|
mobileNumbers: userExists.phone,
|
|
|
},
|
|
|
};
|
|
|
const response = {
|
|
|
send: (data) => {
|
|
|
console.log(data);
|
|
|
req.body.passwordResetCode = code;
|
|
|
reply.send({
|
|
|
armintatankdata: {
|
|
|
error: false,
|
|
|
forgotPassword: true,
|
|
|
},
|
|
|
});
|
|
|
},
|
|
|
};
|
|
|
await exports.sendSms(request, response);
|
|
|
} else {
|
|
|
return reply.send({
|
|
|
armintatankdata: {
|
|
|
error: true,
|
|
|
code: 10007,
|
|
|
message: "Unable to reset password",
|
|
|
},
|
|
|
});
|
|
|
}
|
|
|
} catch (err) {
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// exports.forgotPassword = async (req, reply) => {
|
|
|
// try {
|
|
|
// const user = await User.findOne({ phone: req.body.phone });
|
|
|
|
|
|
// if (!user) {
|
|
|
// return reply.send({
|
|
|
// armintatankdata: {
|
|
|
// error: true,
|
|
|
// code: 10006,
|
|
|
// message: "10006 - Please check the phone number you entered..",
|
|
|
// },
|
|
|
// });
|
|
|
// }
|
|
|
|
|
|
// const code = Math.floor(100000 + Math.random() * 900000).toString();
|
|
|
// const hashedOTP = await bcrypt.hash(code, 10);
|
|
|
|
|
|
// await User.updateOne(
|
|
|
// { phone: user.phone },
|
|
|
// {
|
|
|
// $set: {
|
|
|
// "services.password.bcrypt": hashedOTP,
|
|
|
// temporaryPasswordCode: code,
|
|
|
// oneTimePasswordSetFlag: true,
|
|
|
// },
|
|
|
// }
|
|
|
// );
|
|
|
|
|
|
// // Simulated SMS logic
|
|
|
// console.log("OTP sent:", code);
|
|
|
|
|
|
// reply.send({
|
|
|
// armintatankdata: {
|
|
|
// error: false,
|
|
|
// forgotPassword: true,
|
|
|
// },
|
|
|
// });
|
|
|
// } catch (err) {
|
|
|
// 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);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// controllers/user.controller.js (or wherever your controllers live)
|
|
|
|
|
|
// const Supplier = require("../models/supplier.model"); // not needed here
|
|
|
|
|
|
/**
|
|
|
* GET /api/getuserRequestbookingsforsupplier/:supplierId
|
|
|
* Returns bookings where this supplier was requested, showing only this supplier's sub-entry.
|
|
|
*/
|
|
|
exports.getuserRequestbookingsForSupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { supplierId } = req.params;
|
|
|
|
|
|
if (!supplierId) {
|
|
|
return reply.code(400).send({
|
|
|
status_code: 400,
|
|
|
message: "supplierId is required",
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 1) Find all bookings that include this supplier
|
|
|
const bookings = await RequestedBooking.find({
|
|
|
"requested_suppliers.supplierId": supplierId,
|
|
|
})
|
|
|
.sort({ createdAt: -1 })
|
|
|
.lean();
|
|
|
|
|
|
if (!bookings.length) {
|
|
|
return reply.send({
|
|
|
status_code: 200,
|
|
|
message: `No orders found for supplier ${supplierId}`,
|
|
|
data: [],
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 2) Collect all unique customerIds
|
|
|
const customerIds = [...new Set(bookings.map((b) => b.customerId))];
|
|
|
|
|
|
// 3) Fetch user details for those customers
|
|
|
const users = await User.find({ customerId: { $in: customerIds } }).lean();
|
|
|
|
|
|
// 4) Build map for quick lookup
|
|
|
const userMap = users.reduce((acc, u) => {
|
|
|
acc[u.customerId] = u;
|
|
|
return acc;
|
|
|
}, {});
|
|
|
|
|
|
// 5) Format data with user info
|
|
|
const data = bookings.map((b) => {
|
|
|
const mySupplierEntry =
|
|
|
(b.requested_suppliers || []).find(
|
|
|
(s) => s.supplierId === supplierId
|
|
|
) || null;
|
|
|
|
|
|
return {
|
|
|
_id: b._id,
|
|
|
customerId: b.customerId,
|
|
|
type_of_water: b.type_of_water,
|
|
|
capacity: b.capacity,
|
|
|
quantity: b.quantity,
|
|
|
total_required_capacity: b.total_required_capacity,
|
|
|
date: b.date,
|
|
|
time: b.time,
|
|
|
booking_status: b.status,
|
|
|
createdAt: b.createdAt,
|
|
|
updatedAt: b.updatedAt,
|
|
|
|
|
|
// supplier-specific entry
|
|
|
my_supplier_entry: mySupplierEntry,
|
|
|
|
|
|
// attach full user details here
|
|
|
customer_details: userMap[b.customerId] || null,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
return reply.send({
|
|
|
status_code: 200,
|
|
|
message: `Orders for supplier ${supplierId} fetched successfully`,
|
|
|
data,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error(err);
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
exports.getuserRequestbookingsforplansforsupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { supplierId } = req.params;
|
|
|
|
|
|
if (!supplierId) {
|
|
|
return reply.code(400).send({
|
|
|
status_code: 400,
|
|
|
message: "supplierId is required",
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 1) Find all bookings that include this supplier
|
|
|
const bookings = await RecurringRequestedBooking.find({
|
|
|
"requested_suppliers.supplierId": supplierId,
|
|
|
})
|
|
|
.sort({ createdAt: -1 })
|
|
|
.lean();
|
|
|
|
|
|
// 2) For each booking, expose only this supplier's subdocument
|
|
|
const data = bookings.map((b) => {
|
|
|
const mySupplierEntry = (b.requested_suppliers || []).find(
|
|
|
(s) => s.supplierId === supplierId
|
|
|
) || null;
|
|
|
|
|
|
return {
|
|
|
_id: b._id,
|
|
|
customerId: b.customerId,
|
|
|
type_of_water: b.type_of_water,
|
|
|
capacity: b.capacity,
|
|
|
quantity: b.quantity,
|
|
|
frequency:b.frequency,
|
|
|
weekly_count:b.weekly_count,
|
|
|
total_required_capacity: b.total_required_capacity,
|
|
|
date: b.date,
|
|
|
time: b.time,
|
|
|
// booking-wide status (e.g., pending/confirmed/cancelled)
|
|
|
booking_status: b.status,
|
|
|
createdAt: b.createdAt,
|
|
|
updatedAt: b.updatedAt,
|
|
|
|
|
|
// only the supplier's own requested_suppliers entry
|
|
|
my_supplier_entry: mySupplierEntry, // { supplierId, quoted_amount, time, status }
|
|
|
};
|
|
|
});
|
|
|
|
|
|
return reply.send({
|
|
|
status_code: 200,
|
|
|
message: `Orders for supplier ${supplierId} fetched successfully`,
|
|
|
data,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error(err);
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
// Assuming you have these models imported somewhere above:
|
|
|
// const RecurringRequestedBooking = require("...");
|
|
|
// const Supplier = require("...");
|
|
|
|
|
|
exports.getuserRequestbookingsforplansforcustomer = async (req, reply) => {
|
|
|
try {
|
|
|
const { customerId } = req.params;
|
|
|
|
|
|
if (!customerId) {
|
|
|
return reply.code(400).send({
|
|
|
status_code: 400,
|
|
|
message: "customerId is required",
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 1) Get bookings
|
|
|
const bookings = await RecurringRequestedBooking.find({ customerId })
|
|
|
.sort({ createdAt: -1 })
|
|
|
.lean();
|
|
|
|
|
|
if (!bookings.length) {
|
|
|
return reply.send({
|
|
|
status_code: 200,
|
|
|
message: `Orders for customer ${customerId} fetched successfully`,
|
|
|
data: [],
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 2) Collect unique supplierIds from requested_suppliers
|
|
|
const supplierIdSet = new Set();
|
|
|
for (const b of bookings) {
|
|
|
const rs = Array.isArray(b.requested_suppliers) ? b.requested_suppliers : [];
|
|
|
for (const s of rs) {
|
|
|
if (s && typeof s.supplierId === "string" && s.supplierId.trim() && s.supplierId !== "string") {
|
|
|
supplierIdSet.add(s.supplierId.trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
const supplierIds = Array.from(supplierIdSet);
|
|
|
|
|
|
// 3) Fetch suppliers and index by supplierId
|
|
|
const suppliers = supplierIds.length
|
|
|
? await Supplier.find({ supplierId: { $in: supplierIds } })
|
|
|
.select("-__v") // tweak projection as you like
|
|
|
.lean()
|
|
|
: [];
|
|
|
|
|
|
const supplierById = new Map();
|
|
|
for (const s of suppliers) {
|
|
|
// Key is Supplier.supplierId (string), not _id
|
|
|
supplierById.set(s.supplierId, s);
|
|
|
}
|
|
|
|
|
|
// 4) Attach supplier details into each requested_suppliers entry
|
|
|
const data = bookings.map((b) => {
|
|
|
const rs = Array.isArray(b.requested_suppliers) ? b.requested_suppliers : [];
|
|
|
const enriched = rs.map((item) => ({
|
|
|
...item,
|
|
|
supplier: supplierById.get(item?.supplierId) || null, // attach or null if not found
|
|
|
}));
|
|
|
return {
|
|
|
...b,
|
|
|
requested_suppliers: enriched,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
return reply.send({
|
|
|
status_code: 200,
|
|
|
message: `Orders for customer ${customerId} fetched successfully`,
|
|
|
data,
|
|
|
});
|
|
|
} 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 amount_due = matchedSupplier.quoted_amount-matchedSupplier.advance_paid
|
|
|
|
|
|
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,
|
|
|
amount_paid: String(matchedSupplier.advance_paid),
|
|
|
amount_due: String(amount_due),
|
|
|
advance_reference_number: matchedSupplier.advance_ref_number,
|
|
|
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);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
exports.estimationsget = async (req, reply) => {
|
|
|
try {
|
|
|
// Find the specific tank
|
|
|
const estimations = await EstimationOrder.find({customerId:req.params.customerId
|
|
|
});
|
|
|
if (!estimations) {
|
|
|
return reply.send({ status_code: 404, error: "estimations not found" });
|
|
|
}
|
|
|
// Send the found tank within a list
|
|
|
reply.send({ status_code: 200, data: [estimations] });
|
|
|
} catch (err) {
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
exports.updatePaymentForBooking = async (req, reply) => {
|
|
|
try {
|
|
|
const { bookingid } = req.params;
|
|
|
const { payment_mode, payment_reference_number } = req.body;
|
|
|
|
|
|
if (!bookingid) {
|
|
|
return reply.code(400).send({
|
|
|
status_code: 400,
|
|
|
message: 'bookingid (param) is required',
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (typeof payment_mode === 'undefined' && typeof payment_reference_number === 'undefined') {
|
|
|
return reply.code(400).send({
|
|
|
status_code: 400,
|
|
|
message: 'At least one of payment_mode or payment_reference_number must be provided in body',
|
|
|
});
|
|
|
}
|
|
|
|
|
|
const update = {};
|
|
|
if (typeof payment_mode !== 'undefined') update.payment_mode = payment_mode;
|
|
|
if (typeof payment_reference_number !== 'undefined') update.payment_reference_number = payment_reference_number;
|
|
|
|
|
|
const updated = await Tankerbooking.findOneAndUpdate(
|
|
|
{ bookingid },
|
|
|
{ $set: update },
|
|
|
{ new: true, runValidators: true }
|
|
|
).lean();
|
|
|
|
|
|
if (!updated) {
|
|
|
return reply.code(404).send({
|
|
|
status_code: 404,
|
|
|
message: `No booking found with bookingid ${bookingid}`,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return reply.code(200).send({
|
|
|
status_code: 200,
|
|
|
message: 'Payment info updated successfully',
|
|
|
data: updated,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error('updatePaymentForBooking error:', err);
|
|
|
// keep using boom as you used earlier
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
// controllers/recurringRequestedBookingController.js
|
|
|
|
|
|
exports.updateQuotedAmountForSupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { _id } = req.params;
|
|
|
const { supplierId, amount } = req.body;
|
|
|
|
|
|
if (!_id) {
|
|
|
return reply.code(400).send({ status_code: 400, message: '_id (param) is required' });
|
|
|
}
|
|
|
if (!supplierId) {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'supplierId (body) is required' });
|
|
|
}
|
|
|
if (typeof amount === 'undefined' || amount === null || amount === '') {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'amount (body) is required' });
|
|
|
}
|
|
|
|
|
|
// convert amount to number if possible
|
|
|
const numericAmount = Number(amount);
|
|
|
if (Number.isNaN(numericAmount)) {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'amount must be a valid number' });
|
|
|
}
|
|
|
|
|
|
// Atomic update using positional $ operator
|
|
|
const filter = { _id, 'requested_suppliers.supplierId': supplierId };
|
|
|
const update = { $set: { 'requested_suppliers.$.quoted_amount': numericAmount } };
|
|
|
|
|
|
const updated = await RequestedBooking.findOneAndUpdate(filter, update, {
|
|
|
new: true,
|
|
|
runValidators: true,
|
|
|
}).lean();
|
|
|
|
|
|
if (!updated) {
|
|
|
// either booking _id not found OR supplierId not found inside requested_suppliers
|
|
|
// let's check which one
|
|
|
const bookingExists = await RequestedBooking.findById(_id).lean();
|
|
|
if (!bookingExists) {
|
|
|
return reply.code(404).send({ status_code: 404, message: `Booking with _id ${_id} not found` });
|
|
|
}
|
|
|
|
|
|
// booking exists but supplier entry missing
|
|
|
return reply.code(404).send({
|
|
|
status_code: 404,
|
|
|
message: `Supplier ${supplierId} not found in requested_suppliers for booking ${_id}`,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return reply.code(200).send({
|
|
|
status_code: 200,
|
|
|
message: `quoted_amount updated for supplier ${supplierId}`,
|
|
|
data: updated,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error('updateQuotedAmountForSupplier error:', err);
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
exports.updatestatusForSupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { _id } = req.params;
|
|
|
const { supplierId, status } = req.body;
|
|
|
|
|
|
if (!_id) {
|
|
|
return reply.code(400).send({ status_code: 400, message: '_id (param) is required' });
|
|
|
}
|
|
|
if (!supplierId) {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'supplierId (body) is required' });
|
|
|
}
|
|
|
if (typeof status === 'undefined' || status === null || String(status).trim() === '') {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'status (body) is required' });
|
|
|
}
|
|
|
|
|
|
// Map short keywords to the stored values
|
|
|
let statusToSave = String(status).trim().toLowerCase();
|
|
|
if (statusToSave === 'accept') statusToSave = 'accepted_by_user';
|
|
|
else if (statusToSave === 'reject') statusToSave = 'rejected_by_user';
|
|
|
// otherwise keep the original (but normalized) value
|
|
|
|
|
|
// Atomic update using positional $ operator
|
|
|
const filter = { _id, 'requested_suppliers.supplierId': supplierId };
|
|
|
const update = { $set: { 'requested_suppliers.$.status': statusToSave } };
|
|
|
|
|
|
const updated = await RequestedBooking.findOneAndUpdate(filter, update, {
|
|
|
new: true,
|
|
|
runValidators: true,
|
|
|
}).lean();
|
|
|
|
|
|
if (!updated) {
|
|
|
// either booking _id not found OR supplierId not found inside requested_suppliers
|
|
|
const bookingExists = await RequestedBooking.findById(_id).lean();
|
|
|
if (!bookingExists) {
|
|
|
return reply.code(404).send({ status_code: 404, message: `Booking with _id ${_id} not found` });
|
|
|
}
|
|
|
|
|
|
// booking exists but supplier entry missing
|
|
|
return reply.code(404).send({
|
|
|
status_code: 404,
|
|
|
message: `Supplier ${supplierId} not found in requested_suppliers for booking ${_id}`,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return reply.code(200).send({
|
|
|
status_code: 200,
|
|
|
message: `status updated for supplier ${supplierId}`,
|
|
|
data: updated,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error('updatestatusForSupplier error:', err);
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
exports.updateadvanceForSupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { _id } = req.params;
|
|
|
const { supplierId, advance_paid,advance_ref_number } = req.body;
|
|
|
|
|
|
if (!_id) {
|
|
|
return reply.code(400).send({ status_code: 400, message: '_id (param) is required' });
|
|
|
}
|
|
|
if (!supplierId) {
|
|
|
return reply.code(400).send({ status_code: 400, message: 'supplierId (body) is required' });
|
|
|
}
|
|
|
|
|
|
|
|
|
// Map short keywords to the stored values
|
|
|
|
|
|
|
|
|
// otherwise keep the original (but normalized) value
|
|
|
|
|
|
// Atomic update using positional $ operator
|
|
|
const filter = { _id, 'requested_suppliers.supplierId': supplierId };
|
|
|
const update = { $set: { 'requested_suppliers.$.advance_paid': advance_paid,'requested_suppliers.$.advance_ref_number': advance_ref_number } };
|
|
|
|
|
|
const updated = await RequestedBooking.findOneAndUpdate(filter, update, {
|
|
|
new: true,
|
|
|
runValidators: true,
|
|
|
}).lean();
|
|
|
|
|
|
if (!updated) {
|
|
|
// either booking _id not found OR supplierId not found inside requested_suppliers
|
|
|
const bookingExists = await RequestedBooking.findById(_id).lean();
|
|
|
if (!bookingExists) {
|
|
|
return reply.code(404).send({ status_code: 404, message: `Booking with _id ${_id} not found` });
|
|
|
}
|
|
|
|
|
|
// booking exists but supplier entry missing
|
|
|
return reply.code(404).send({
|
|
|
status_code: 404,
|
|
|
message: `Supplier ${supplierId} not found in requested_suppliers for booking ${_id}`,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return reply.code(200).send({
|
|
|
status_code: 200,
|
|
|
message: `status updated for supplier ${supplierId}`,
|
|
|
data: updated,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error('updatestatusForSupplier error:', err);
|
|
|
throw boom.boomify(err);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
exports.splitBookingForSupplier = async (req, reply) => {
|
|
|
try {
|
|
|
const { id } = req.params;
|
|
|
const { capacity, quantity, date, time, quoted_amount } = req.body;
|
|
|
|
|
|
// 1) Find existing booking
|
|
|
const existing = await RequestedBooking.findById(id);
|
|
|
if (!existing) {
|
|
|
return reply.code(404).send({ status_code: 404, message: "Booking not found" });
|
|
|
}
|
|
|
|
|
|
// 2) Update the original booking
|
|
|
existing.capacity = `${capacity} L`;
|
|
|
existing.quantity = "1";
|
|
|
existing.total_required_capacity = capacity;
|
|
|
if (date) existing.date = date;
|
|
|
if (time) existing.time = time;
|
|
|
if (quoted_amount) {
|
|
|
existing.requested_suppliers[0].quoted_amount = quoted_amount;
|
|
|
}
|
|
|
await existing.save();
|
|
|
|
|
|
// 3) Create new bookings for the rest
|
|
|
const newBookings = [];
|
|
|
for (let i = 1; i < quantity; i++) {
|
|
|
const newBooking = new RequestedBooking({
|
|
|
status: "pending",
|
|
|
customerId: existing.customerId,
|
|
|
type_of_water: existing.type_of_water,
|
|
|
capacity: `${capacity} L`,
|
|
|
quantity: "1",
|
|
|
total_required_capacity: capacity,
|
|
|
date: date || existing.date,
|
|
|
time: time || existing.time,
|
|
|
requested_suppliers: [
|
|
|
{
|
|
|
time: new Date().toISOString().slice(0, 16).replace("T", " "),
|
|
|
status: "pending",
|
|
|
supplierId: existing.requested_suppliers[0].supplierId,
|
|
|
quoted_amount: quoted_amount || existing.requested_suppliers[0].quoted_amount,
|
|
|
},
|
|
|
],
|
|
|
});
|
|
|
newBookings.push(newBooking);
|
|
|
}
|
|
|
|
|
|
if (newBookings.length > 0) {
|
|
|
await RequestedBooking.insertMany(newBookings);
|
|
|
}
|
|
|
|
|
|
return reply.code(200).send({
|
|
|
status_code: 200,
|
|
|
message: `${quantity} booking(s) created/updated successfully`,
|
|
|
updated: existing,
|
|
|
newEntries: newBookings,
|
|
|
});
|
|
|
} catch (err) {
|
|
|
console.error("splitBookingForSupplier error:", err);
|
|
|
return reply.code(500).send({ status_code: 500, message: "Internal Server Error" });
|
|
|
}
|
|
|
};
|
|
|
|