File: //home/arjun/projects/good-life-be/api/User/service.js
import bcrypt from 'bcrypt';
import { Op } from 'sequelize';
import moment from 'moment';
import Login from '../../models/Login.js';
import BadRequest from '../../helper/exception/badRequest.js';
import User from '../../models/User.js';
import {
deleteFromS3,
getS3SignedUrl,
uploadToS3,
} from '../../modules/s3/index.js';
// ---------------->>> User profile section <<<----------------
export const changePassService = async (body, userId) => {
const { currentPassword, newPassword } = body;
const user = await Login.findOne({ where: { user_id: userId } }); // Assuming `req.user.id` is set after authentication
// Check if user exists
if (!user) throw new BadRequest('User not found.');
// Check if the current password is correct
const isCurrentPasswordCorrect = await bcrypt.compare(
currentPassword,
user.password
);
if (!isCurrentPasswordCorrect) {
throw new BadRequest('Current password is incorrect.');
}
const hashedNewPassword = await bcrypt.hash(newPassword, 10);
const isSamePassword = await bcrypt.compare(newPassword, user.password);
if (isSamePassword) {
throw new BadRequest(
'New password cannot be the same as the previous password.'
);
}
// Update the user's password in the database
await Login.update(
{ password: hashedNewPassword },
{ where: { user_id: userId } }
);
};
export const profile = async (loginId) => {
const user = await Login.findOne({
where: { user_id: loginId },
attributes: ['email'],
include: {
model: User,
attributes: ['first_name', 'second_name', 'profile_image','status'],
where: { is_deleted: false },
},
});
if (user.user.profile_image !== '' && user.user.profile_image !== null) {
user.user.profile_image = await getS3SignedUrl(user?.user?.profile_image);
}
return user;
};
export const profileUpdate = async (body, files, userId) => {
let fileName = '';
if (files && files !== '' && files !== undefined) {
fileName = await uploadToS3(files?.name, files?.data, files?.mimetype);
body.profile_image = fileName;
}
await User.update(body, {
where: { id: userId },
});
};
export const profileImageRemove = async (userId) => {
const user = await User.findOne({ where: { id: userId } });
await deleteFromS3(user.profile_image);
await User.update(
{
profile_image: null,
},
{
where: { id: userId },
}
);
};
// ----------------->>> User module <<<----------------
export const userStatusUpdate = async (id, query) => {
// Fetch the user by ID
const user = await User.findOne({
where: { id },
attributes: ['id', 'status', 'is_deleted'],
});
// Throw an error if the user doesn't exist
if (!user) {
throw new BadRequest('User not found.');
}
// Prepare updates and message
const updates = {};
let message = 'No updates made.';
// Check and update the status if needed
if (query.status !== undefined && query.status !== user.status) {
updates.status = query.status;
message = 'User status updated successfully';
}
// Check and update the is_deleted flag if needed
if (query.is_deleted !== undefined) {
const isDeleted =
query.is_deleted === 'true' ? true : false || query.is_deleted === true;
if (isDeleted !== user.is_deleted) {
updates.is_deleted = isDeleted;
message = 'User deleted successfully';
}
}
// Update the user if there are changes
if (Object.keys(updates).length > 0) {
await user.update(updates); // Update the user instance
}
return { message };
};
export const listAllUsers = async ({
page = '1',
limit = '10',
sortBy = 'first_name',
sortOrder = 'ASC',
search = '', // Search parameter
fromDate = '', // Starting date filter
toDate = '', // Ending date filter
}) => {
// Convert page and limit to numbers
const pageNumber = parseInt(page, 10) || 1;
const limitNumber = parseInt(limit, 10) || 10;
// Calculate offset
const offset = (pageNumber - 1) * limitNumber;
// Build the search condition
const searchCondition = search
? {
[Op.or]: [
{
first_name: {
[Op.iLike]: `%${search}%`, // Case-insensitive match in PostgreSQL
},
},
{
second_name: {
[Op.iLike]: `%${search}%`, // Case-insensitive match in PostgreSQL
},
},
{
'$login.email$': {
[Op.iLike]: `%${search}%`, // Case-insensitive match in PostgreSQL
},
},
],
}
: {};
// Build the date range condition
const dateCondition =
fromDate || toDate
? {
createdAt: {
...(fromDate && {
[Op.gte]: moment(decodeURIComponent(fromDate))
.startOf('day')
.toDate(),
}),
...(toDate && {
[Op.lt]: moment(decodeURIComponent(toDate)).endOf('day').toDate(),
}),
},
}
: {};
const result = await User.findAndCountAll({
where: {
role: 'user',
is_deleted: false,
...searchCondition,
...dateCondition,
},
attributes: [
'id',
'first_name',
'second_name',
'createdAt',
'is_deleted',
'status',
],
include: [
{
model: Login,
attributes: ['email'],
},
],
limit: limitNumber, // Apply the limit
offset, // Apply the offset for pagination
order: [[sortBy, sortOrder.toUpperCase()]], // Apply sorting
});
// Structure the response
return {
total: result.count, // Total number of users matching the query
data: result.rows, // Paginated user data
};
};