Sindbad~EG File Manager
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const db = require("../models");
const { Op } = require("sequelize");
const { col } = require("sequelize");
const bodyParser = require("body-parser");
const crypto = require("crypto");
// const nodemailer = require("nodemailer");
// const { google } = require("googleapis");
// const { OAuth2Client } = require("google-auth-library");
function calculateDateRange(timeRange) {
const currentDate = new Date();
switch (timeRange) {
case "currentweek":
const currentWeekStartDate = new Date(currentDate);
currentWeekStartDate.setDate(
currentDate.getDate() - currentDate.getDay()
);
currentWeekStartDate.setHours(0, 0, 0, 0);
const currentWeekEndDate = new Date(currentDate);
currentWeekEndDate.setDate(
currentWeekEndDate.getDate() + (6 - currentWeekEndDate.getDay())
);
currentWeekEndDate.setHours(23, 59, 59, 999);
return { startDate: currentWeekStartDate, endDate: currentWeekEndDate };
case "lastweek":
const lastWeekStartDate = new Date(currentDate);
lastWeekStartDate.setDate(
lastWeekStartDate.getDate() - lastWeekStartDate.getDay() - 7
);
lastWeekStartDate.setHours(0, 0, 0, 0);
const lastWeekEndDate = new Date(currentDate);
lastWeekEndDate.setDate(
lastWeekEndDate.getDate() - lastWeekEndDate.getDay() - 1
);
lastWeekEndDate.setHours(23, 59, 59, 999);
return { startDate: lastWeekStartDate, endDate: lastWeekEndDate };
case "last4weeks":
const last4WeeksStartDate = new Date(currentDate);
last4WeeksStartDate.setDate(last4WeeksStartDate.getDate() - 28);
last4WeeksStartDate.setHours(0, 0, 0, 0);
const last4WeeksEndDate = new Date(currentDate);
last4WeeksEndDate.setDate(last4WeeksEndDate.getDate());
last4WeeksEndDate.setHours(23, 59, 59, 999);
return { startDate: last4WeeksStartDate, endDate: last4WeeksEndDate };
case "last12weeks":
const last12WeeksStartDate = new Date(currentDate);
last12WeeksStartDate.setDate(last12WeeksStartDate.getDate() - 84);
last12WeeksStartDate.setHours(0, 0, 0, 0);
const last12WeeksEndDate = new Date(currentDate);
last12WeeksEndDate.setDate(last12WeeksEndDate.getDate());
last12WeeksEndDate.setHours(23, 59, 59, 999);
return { startDate: last12WeeksStartDate, endDate: last12WeeksEndDate };
default:
// Handle other cases or return an error
return null;
}
}
const auctioneerLogin = async (req, res) => {
try {
const { email, password } = req.body;
let result = await db.tblAuctioneer.findAll({
where: {
email: email,
},
});
if (result.length <= 0) {
return res
.status(404)
.json({ status: 404, message: "Invalid credentials" });
}
const isMatched = await bcrypt.compare(password, result[0].password);
console.log("isMatched", isMatched);
// return res.json(result);
if (!isMatched) {
return res.status(403).json({ status: 403, message: "Invalid credentials" });
}
let token = await jwt.sign(
{ email: result[0].email, auctioneerId: result[0].auctioneer_id },
process.env.JWT_KEY
);
return res.json({
status: 200,
message: "Auctioneer loggedIn Success",
data: [{ token, ...result[0].dataValues }],
});
} catch (error) {
return res.json({ status: 500, message: `${error.message}` });
}
};
const getAuctioneerProfile = async (req, res) => {
const auctioneer_id = req.params.id;
try {
let [result] = await db.tblAuctioneer.findAll({
where: {
auctioneer_id: auctioneer_id,
},
});
if (!result) {
return res.json({ status: 402, message: "No user Found" });
}
return res.json({
status: 200,
message: "Success",
data: [
{
user_id: result.auctioneer_id,
first_name: result.first_name,
last_name: result.last_name,
email: result.email,
contact: result.contact,
address: result.address,
business_address: result.business_address,
business_name: result.business_name,
username: result.username,
},
],
});
} catch (error) {
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
// // Configuring OAuth2 credentials
// const oAuth2Client = new google.auth.OAuth2(
// process.env.OAUTH_CLIENT_ID,
// process.env.OAUTH_CLIENT_SECRET,
// process.env.OAUTH_REDIRECT_URL
// );
// oAuth2Client.setCredentials({
// refresh_token: process.env.OAUTH_REFRESH_TOKEN,
// });
// let transporter;
// // Obtain an access token using the refresh token
// oAuth2Client
// .getAccessToken()
// .then((response) => {
// const accessToken = response.token;
// transporter = nodemailer.createTransport({
// service: "gmail",
// auth: {
// type: "OAuth2",
// user: process.env.EMAIL_USERNAME,
// clientId: process.env.OAUTH_CLIENT_ID,
// clientSecret: process.env.OAUTH_CLIENT_SECRET,
// refreshToken: process.env.OAUTH_REFRESH_TOKEN,
// accessToken: accessToken, // Use the access token obtained
// expires: 1484314697598,
// },
// });
// // Now, you can use the transporter to send mail
// })
// .catch((error) => {
// console.error("Error retrieving access token", error);
// });
// // Helper functions for password hashing
// const generateHash = (password) => {
// return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
// };
// const validPassword = (password, storedHash) => {
// return bcrypt.compareSync(password, storedHash);
// };
// const forgotPassword = async (req, res) => {
// const { email } = req.body;
// // Generate token
// const token = crypto.randomBytes(20).toString("hex");
// try {
// const user = await db.tblAuctioneer.findOne({ where: { email: email } });
// if (!user) {
// return res.status(400).json({
// status: 400,
// error: "No account with that email address exists.",
// });
// }
// user.resetPasswordToken = token;
// user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
// await user.save();
// /* const mailOptions = {
// to: user.email,
// from: process.env.EMAIL_USERNAME,
// subject: "Password Reset Confirmation",
// text: `Please click on the following link, or paste this into your browser to complete the process:\n\n`,
// html: `
// <html>
// <body>
// <p>Please click on the following link, or paste this into your browser to complete the process:\n\n</p>
// <a href="${process.env.CLIENT_URL}/reset/${token}\n\n" target="_blank">Reset Password</a>
// <p>If you did not request a password reset, please ignore this email.</p>
// </body>
// </html>`,
// };
// await transporter.sendMail(mailOptions);
// */
// res.json({
// status: 200,
// message: "Success",
// data: {
// notification: `An e-mail has been sent to ${user.email} with further instructions.`,
// token: token,
// },
// });
// } catch (error) {
// res.status(500).send(error.message);
// }
// };
// const resetPasswordViaToken = async (req, res) => {
// const { token } = req.params;
// const { newPassword } = req.body;
// try {
// const user = await db.tblAuctioneer.findOne({
// where: {
// resetPasswordToken: token,
// resetPasswordExpires: { [Op.gt]: Date.now() },
// },
// });
// if (!user) {
// return res.status(400).json({
// status: 400,
// error: "Password reset token is invalid or has expired.",
// });
// }
// user.password = generateHash(newPassword);
// user.resetPasswordToken = null;
// user.resetPasswordExpires = null;
// await user.save();
// res.status(200).json({
// status: 200,
// message: "Success! Your password has been changed.",
// });
// } catch (error) {
// res.status(500).send(error.message);
// }
// };
const removeAuctioneer = async (req, res) => {
const { email } = req.body;
let transaction;
try {
transaction = await db.sequelize.transaction(); // Start a new transaction
const auctioneer = await db.tblAuctioneer.findOne({
where: { email },
transaction,
});
if (!auctioneer) {
await transaction.rollback(); // Ensure transaction is rolled back if auctioneer does not exist
return res
.status(404)
.json({ status: 404, message: "Auctioneer not found." });
}
const opportunities = await db.tblOpportunity.findAll({
where: { auctioneer_id: auctioneer.auctioneer_id },
transaction,
});
const opportunity_ids = opportunities.map(
(opportunity) => opportunity.opportunity_id
);
vehicle_run = await db.tblVehicleRun.findAll({
where: {
opportunity_id: {
[Op.in]: opportunity_ids, // Use the `Op.in` operator to look for any opportunity_id in the provided array
},
},
transaction,
});
const vehicle_run_ids = vehicle_run.map((item) => item.vehicle_run_id);
const vehicle_run_fee_deleted_count = await db.tblVehicleRunFee.destroy({
where: { vehicle_run_id: vehicle_run_ids },
transaction,
});
const auctioneer_feeses_deleted_count = await db.tblAuctioneerFee.destroy({
where: { auctioneer_id: auctioneer.auctioneer_id },
transaction,
});
const vehicle_run_deleted_count = await db.tblVehicleRun.destroy({
where: { opportunity_id: opportunity_ids },
transaction,
});
const opportunity_deleted_count = await db.tblOpportunity.destroy({
where: { opportunity_id: opportunity_ids },
transaction,
});
const subscription_deleted_count = await db.tblUserSubAuctioneer.destroy({
where: { auctioneer_id: auctioneer.auctioneer_id },
transaction,
});
const auctioneer_deleted_count = await db.tblAuctioneer.destroy({
where: { auctioneer_id: auctioneer.auctioneer_id },
transaction,
});
await transaction.commit(); // Commit all changes
return res.status(200).json({
message: "Auctioneer and related data successfully deleted.",
details: {
vehicle_runs: vehicle_run_deleted_count,
vehicle_runs_fee: vehicle_run_fee_deleted_count,
opportunities: opportunity_deleted_count,
subscriptions: subscription_deleted_count,
auctioneer_fee: auctioneer_feeses_deleted_count,
auctioneer: auctioneer_deleted_count,
},
});
} catch (error) {
if (transaction) {
try {
// Additional safeguard to ensure that we do not call rollback on an already finished transaction.
if (!transaction.finished) {
await transaction.rollback();
}
} catch (rollbackError) {
console.error("Rollback error:", rollbackError);
}
}
return res.status(500).json({
message: "Internal Server Error",
error: error.message,
});
}
};
const updateAuctioneerPassword = async (req, res) => {
try {
let { auctioneer_id, newPassword } = req.body;
if (newPassword) {
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(newPassword, salt);
let result = await db.tblAuctioneer.update(
{ password: hashedPassword },
{ where: { auctioneer_id: auctioneer_id } }
);
return res.status(200).json({ status: 200, message: "password updated" });
} else {
return res.json({ status: 400, message: "newpassword undefined" });
}
} catch (error) {
return res.json({ status: 500, message: `${error.message}` });
}
};
//Hamza Ali
const GetAuctioneerUsers = async (req, res) => {
try {
let { auctioneerId, weekId, sortBy, orderDirection } = req.body;
if (sortBy === "sold_price") {
sortBy = "vehicle_id";
}
let timeRange;
if (!req.body.timeRange) {
timeRange = "currentweek";
} else {
timeRange = req.body.timeRange;
}
timeRange = timeRange.replace(/\s/g, "");
timeRange = timeRange.toLowerCase();
const currentDate = new Date();
const weekRange = calculateDateRange(timeRange);
const result = await db.tblOpportunity.findAll({
attributes: ["opportunity_id"],
where: {
week_id: weekId,
auctioneer_id: auctioneerId,
},
include: [
{
model: db.tblUser,
attributes: ["user_id", "first_name", "last_name"],
},
{
model: db.tblVehicleRun,
include: [
{
model: db.tblVehicle,
},
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
},
],
},
],
},
],
});
// return res.json(result);
const formattedData = result.map((item) => ({
user_id: item.tblUser.user_id,
first_name: item.tblUser.first_name,
last_name: item.tblUser.last_name,
tblVehicles: item.tblVehicleRuns.map((vehicleRun) => {
const vehicle = vehicleRun.tblVehicle || {};
const auctionLane = vehicleRun.tblAuctionLane || {
lane_id: null,
name: null,
tblAuction: {
auction_id: null,
name: null,
},
};
const auction = auctionLane.tblAuction;
return {
vehicle_id: vehicle.vehicle_id,
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name || null,
imageUrl: vehicle.imageUrl,
details: vehicle.details || null,
condition_light: vehicleRun.condition_light,
announcements: vehicleRun.announcements,
reserve: vehicleRun.reserve,
sale_price: vehicleRun.sale_price,
vehicle_total_fee: vehicleRun.vehicle_total_fee || null,
net_proceed: vehicleRun.net_proceed || null,
sale_status: vehicleRun.sale_status,
run_no: vehicleRun.run_no,
lane_id: auctionLane.lane_id,
lane_name: auctionLane.name,
auction_name: auction.name,
};
}),
}));
return res.json({ status: 200,message:"Success",filter_type:"whole_saler", data: formattedData });
} catch (error) {
return res.json(error.message);
}
};
const GetAuctioneerUsersOnly = async (req, res) => {
try {
const { auctioneerId, weekId, orderDirection, sortBy } = req.body;
const { sequelize, tblUser, tblOpportunity, tblVehicle } = db;
const result = await tblUser.findAll({
attributes: [
"user_id",
"first_name",
"last_name",
[
sequelize.fn(
"COUNT",
sequelize.col("tblOpportunities.tblVehicleRuns.opportunity_id")
),
"units",
],
],
include: [
{
model: tblOpportunity,
attributes: [],
include: [
{
model: db.tblVehicleRun,
attributes: [],
raw: true,
},
],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
},
],
group: ["tblUser.user_id", "tblOpportunities.opportunity_id"],
});
return res.json({ status: 200, message: "Success", data: result });
} catch (error) {
console.log(error);
return res.json(error.message);
}
};
const updateVehicleStatus = async (req, res) => {
try {
let result;
const vehicle_id = req.body.vehicle_id;
[result] = await db.tblVehicleRun.findAll({
where: {
vehicle_id: vehicle_id,
},
});
if (!result) {
await db.tblVehicleRun.create(req.body);
} else {
await db.tblVehicleRun.update(req.body, {
where: {
vehicle_id: vehicle_id,
},
});
}
return res.json({ status: 200, message: "Success" });
} catch (error) {
console.log(error);
return res.json(error.message);
}
};
const updateAuctioneerProfile = async (req, res) => {
const { auctioneer_id, ...data } = req.body;
if (req.body.password) {
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
data.password = hashedPassword;
}
try {
let result = await db.tblAuctioneer.update(data, {
where: {
auctioneer_id: req.body.auctioneer_id,
},
});
return res.json({
status: 200,
message: "profile updated",
});
} catch (error) {
console.log(error.message);
return res.json({ status: 500, message: `${error.message}` });
}
};
//Auctioneer Side
const getAllAssignedVehicles = async (req, res) => {
try {
const { auctioneer_id, user_id, weekId } = req.body;
const week_Id = parseInt(weekId);
let timeRange;
if (!req.body.timeRange) {
timeRange = "last4weeks";
} else {
timeRange = req.body.timeRange;
}
timeRange = timeRange.replace(/\s/g, "");
timeRange = timeRange.toLowerCase();
const currentDate = new Date();
const weekRange = calculateDateRange(timeRange);
let result = await db.tblOpportunity.findAll({
attributes: ["opportunity_id"],
where: {
user_id: user_id,
week_id: week_Id,
auctioneer_id: auctioneer_id,
},
include: [
{
model: db.tblVehicle,
raw: true,
where: {
user_id: user_id,
opportunity_id: col("tblOpportunity.opportunity_id"),
},
include: [
{
model: db.tblVehicleRun,
raw: true,
include: [
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
raw: true,
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
raw: true,
},
],
},
],
},
],
},
],
// order: [["createdAt", "ASC"]]
});
// return res.json(result);
const formattedData = result.flatMap((user) =>
user.tblVehicles.flatMap((vehicle) => {
const run = vehicle.tblVehicleRuns[0];
return {
vehicle_id: vehicle.vehicle_id,
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name,
details: vehicle.details,
imageUrl: vehicle.imageUrl,
opportunity_id: vehicle.opportunity_id,
user_id: vehicle.user_id,
createdAt: vehicle.createdAt,
updatedAt: vehicle.updatedAt,
vehicle_run_id: run.vehicle_run_id,
condition_light: run.condition_light,
announcements: run.announcements || null,
reserve: run.reserve || null,
sale_price: run.sale_price || null,
auction_fee: run.auction_fee || null,
net_profit: run.net_profit || null,
sale_status: run.sale_status || false,
run_no: run.run_no || null,
lane_id: run.lane_id || null,
lane_name: run.tblAuctionLane
? run.tblAuctionLane.name || null
: null,
auction_id:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.auction_id || null
: null,
auction_name:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.name || null
: null,
};
})
);
return res.json({ status: 200, message: "Success", data: formattedData });
} catch (error) {
return res.json(error.message);
}
};
const getAllAssignedVehiclesOnly = async (req, res) => {
try {
const {
auctioneer_id,
user_id,
weekId,
sortBy = "vehicle_id",
orderDirection = "ASC",
} = req.body;
const week_Id = parseInt(weekId);
let timeRange;
if (!req.body.timeRange) {
timeRange = "last4weeks";
} else {
timeRange = req.body.timeRange;
}
timeRange = timeRange.replace(/\s/g, "");
timeRange = timeRange.toLowerCase();
let result;
result = await db.tblOpportunity.findAll({
attributes: ["opportunity_id"],
where: {
user_id: user_id,
week_id: week_Id,
auctioneer_id: auctioneer_id,
},
include: [
{
model: db.tblVehicleRun,
raw: true,
where: {
opportunity_id: col("tblOpportunity.opportunity_id"),
},
include: [
{
model: db.tblVehicle,
raw: true,
},
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
raw: true,
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
raw: true,
},
],
},
],
},
],
order: [[db.tblVehicleRun, db.tblVehicle, sortBy, orderDirection]],
});
// return res.json(result);
const transformedData = result.flatMap((opportunity) =>
opportunity.tblVehicleRuns.map((run) => ({
vehicle_id: run.vehicle_id,
vin: run.tblVehicle.vin,
year: run.tblVehicle.year,
make: run.tblVehicle.make,
model: run.tblVehicle.model,
trim: run.tblVehicle.trim,
mileage: run.tblVehicle.mileage,
color: run.tblVehicle.color,
color_name: run.tblVehicle.color_name,
details: run.tblVehicle.details,
imageUrl: run.tblVehicle.imageUrl,
opportunity_id: run.opportunity_id,
user_id: run.tblVehicle.user_id,
vehicle_run_id: run.vehicle_run_id,
condition_light: run.condition_light || 0,
announcements: run.announcements,
reserve: run.reserve || 0,
sale_price: run.sale_price || 0,
vehicle_total_fee: run.vehicle_total_fee || 0,
net_proceed: run.net_proceed || 0,
sale_status: run.sale_status || false,
run_no: run.run_no || null,
auction_fee: run.auction_fee || 300,
lane_id: run.lane_id || null,
// Additional fields from tblAuctionLane and nested tblAuction if present
lane_name: run.tblAuctionLane ? run.tblAuctionLane.name : null,
auction_id:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.auction_id
: null,
auction_name:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.name
: null,
}))
);
/* const formattedData = result.flatMap((user) =>
user.tblVehicles.flatMap((vehicle) => {
const run = vehicle.tblVehicleRuns[0];
return {
vehicle_id: vehicle.vehicle_id,
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name,
details: vehicle.details,
imageUrl: vehicle.imageUrl,
opportunity_id: vehicle.opportunity_id,
user_id: vehicle.user_id,
createdAt: vehicle.createdAt,
updatedAt: vehicle.updatedAt,
vehicle_run_id: run.vehicle_run_id,
condition_light: run.condition_light,
announcements: run.announcements || null,
reserve: run.reserve || null,
sale_price: run.sale_price || null,
auction_fee: run.auction_fee || null,
net_profit: run.net_profit || null,
sale_status: run.sale_status || false,
run_no: run.run_no || null,
lane_id: run.lane_id || null,
lane_name: run.tblAuctionLane
? run.tblAuctionLane.name || null
: null,
auction_id:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.auction_id || null
: null,
auction_name:
run.tblAuctionLane && run.tblAuctionLane.tblAuction
? run.tblAuctionLane.tblAuction.name || null
: null,
};
})
);
*/
/* [
{
vehicle_id: 2,
vin: "DF54FG654C",
year: 2020,
make: "Toyota",
model: "RAV-4",
trim: "HDHDHYE",
mileage: 7000,
color: "fff44336",
color_name: "Red",
details:
"SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",
imageUrl: "preview.png",
opportunity_id: 10,
user_id: 1,
createdAt: "2023-12-26T06:28:06.000Z",
updatedAt: "2024-01-03T18:39:22.000Z",
vehicle_run_id: 2,
vehicle_id: 2,
condition_light: 2,
announcements: null,
reserve: null,
sale_price: 1500,
auction_fee: 250,
net_profit: null,
sale_status: false,
run_no: null,
lane_id: 1,
lane_id: 1,
name: "A",
auction_id: 1,
auction_name: "America's Auto Auction",
},
{
vehicle_id: 3,
vin: "DF54FG654C",
year: 2012,
make: "Mercedez",
model: "G-Class",
trim: "HDHDHYE",
mileage: 6500,
color: "fff44336",
color_name: "Red",
details:
"SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",
imageUrl: "preview.png",
opportunity_id: 10,
user_id: 1,
createdAt: "2023-12-26T06:28:31.000Z",
updatedAt: "2024-01-03T18:36:03.000Z",
vehicle_run_id: 3,
vehicle_id: 3,
condition_light: 2,
announcements: null,
reserve: null,
sale_price: 1500,
auction_fee: 250,
net_profit: null,
sale_status: false,
run_no: null,
lane_id: 2,
lane_id: null,
lane_name: null,
auction_id: null,
auction_name: null,
},
]; */
return res.json({ status: 200, message: "Success", data: transformedData });
} catch (error) {
return res.json(error.message);
}
};
//Hamza Ali
const sortAuctioneerVehicles = async (req, res) => {
try {
const { auctioneerId, weekId, orderDirection, sortBy } = req.body;
// Find user_ids from tblOpportunity based on auctioneerId and weekId
const userOpportunityIds = await db.tblOpportunity.findAll({
attributes: ["user_id"],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
raw: true,
});
// Extract user_ids from the result
const userIds = userOpportunityIds.map(
(opportunity) => opportunity.user_id
);
// Find user data from tblUser and tblVehicle based on the obtained user_ids
let whereClause = {};
// Adjust the where clause based on sortBy
if (sortBy == "sold_price") {
sortBy = "vehicle_id";
}
const result = await db.tblUser.findAll({
attributes: ["user_id", "first_name", "last_name"],
include: [
{
model: db.tblVehicle,
attributes: [
"vin",
"year",
"make",
"model",
"trim",
"mileage",
"color",
"color_name",
"imageUrl",
"details",
],
include: [
{
model: db.tblOpportunity,
attributes: [],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
raw: true,
},
{
model: db.tblVehicleRun,
attributes: [
"reserve",
"sale_status",
"sale_price",
"condition_light",
"announcements",
"auction_fee",
],
raw: true,
include: [
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
raw: true,
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
raw: true,
},
],
},
],
},
],
raw: true,
where: whereClause,
},
],
order: [[db.tblVehicle, sortBy || "vehicle_id", orderDirection || "ASC"]],
});
// Format the result as needed
const formattedData = result.map((user) => ({
user_id: user.user_id,
first_name: user.first_name,
last_name: user.last_name,
tblVehicles: user.tblVehicles.map((vehicle) => ({
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name,
imageUrl: vehicle.imageUrl,
details: vehicle.details,
reserve: vehicle.tblVehicleRuns[0].reserve,
sale_status: vehicle.tblVehicleRuns[0].sale_status,
sale_price: vehicle.tblVehicleRuns[0].sale_price,
condition_light: vehicle.tblVehicleRuns[0].condition_light,
announcements: vehicle.tblVehicleRuns[0].announcements,
auction_fee: vehicle.tblVehicleRuns[0].auction_fee,
lane_id: vehicle.tblVehicleRuns[0].tblAuctionLane.lane_id,
lane_name: vehicle.tblVehicleRuns[0].tblAuctionLane.name,
auction_name: vehicle.tblVehicleRuns[0].tblAuctionLane.tblAuction.name,
})),
}));
return res.json({ status: 200, data: formattedData });
} catch (error) {
return res.json(error.message);
}
};
const filterByConditionLight = async (req, res) => {
try {
const { auctioneerId, weekId } = req.body;
const auctioneer_id = auctioneerId;
const week_id = weekId;
let result = await db.sequelize.query(
"CALL aFilterByConditionLight(:auctioneer_id,:week_id)",
{
replacements: { auctioneer_id, week_id },
type: db.Sequelize.QueryTypes.SELECT,
}
);
let data = result[0];
const formattedData = Object.values(data)
.flat()
.filter(
(item) => typeof item === "object" && !item.hasOwnProperty("fieldCount")
);
// return res.json(formattedData);
const conditionLightValues = [0, 1, 2, 3, 4];
// Check for missing condition_light values
const missingValues = conditionLightValues.filter((value) => {
return !formattedData.some((item) => item.condition_light === value);
});
// Add missing values to the existing data
const newData = formattedData.concat(
missingValues.map((value) => ({
condition_light: value,
units: 0,
}))
);
const filteredData = newData.filter((item) => item.condition_light != 0);
// # Sorting the list in-place in ascending order of 'condition_light'
filteredData.sort((a, b) => a.condition_light - b.condition_light);
return res.json({
status: 200,
message: "Success",
filter_type: "condition_light",
data: filteredData,
});
} catch (error) {
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
const getConditionLightVehicles = async (req, res) => {
try {
const { condition_light, opportunity_id, sortBy, orderDirection } =
req.body;
const results = await db.tblVehicleRun.findAll({
where: {
opportunity_id: opportunity_id,
condition_light: condition_light,
},
include: [
{
model: db.tblVehicle,
raw: true,
},
{
model: db.tblAuctionLane,
attributes: ["name"],
raw: true,
// required: true,
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
raw: true,
required: false,
},
],
},
],
order: [[db.tblVehicle, sortBy || "vehicle_id", orderDirection || "ASC"]],
});
// return res.json({ status: 200, data: results });
const outputArray = results.map((vehicleRun) => {
const vehicle = vehicleRun.tblVehicle || {};
const auctionLane = vehicleRun.tblAuctionLane || {};
const auction = auctionLane.tblAuction || {};
return {
vehicle_id: vehicle.vehicle_id,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
vin: vehicle.vin,
mileage: vehicle.mileage,
details: vehicle.details,
imageUrl: vehicle.imageUrl,
color: vehicle.color,
color_name: vehicle.color_name,
vehicle_run_id: vehicleRun.vehicle_run_id,
condition_light: vehicleRun.condition_light || 0,
announcements: vehicleRun.announcements,
reserve: vehicleRun.reserve || 0,
sale_price: vehicleRun.sale_price || 0,
vehicle_total_fee: vehicleRun.vehicle_total_fee || 0,
auction_fee: vehicleRun.auction_fee || 300,
net_proceed: vehicleRun.net_proceed || 0,
sale_status: vehicleRun.sale_status || false,
run_no: vehicleRun.run_no || null,
lane_id: vehicleRun.lane_id || null,
lane_name: auctionLane.name || null,
auction_id: auction.auction_id || null,
auction_name: auction.name || null,
};
});
return res.json({ status: 200, message: "Success", data: outputArray });
} catch (error) {
return res.status(500).json({ error: error.message });
}
};
const filterBySaleStatus = async (req, res) => {
try {
const { auctioneer_id, user_id, week_id } = req.body;
let result = await db.sequelize.query(
"CALL aFilterBySaleStatus(:auctioneer_id,:week_id)",
{
replacements: { auctioneer_id, week_id },
type: db.Sequelize.QueryTypes.SELECT,
}
);
let data = result[0];
const formattedData = Object.values(data)
.flat()
.filter(
(item) => typeof item === "object" && !item.hasOwnProperty("fieldCount")
);
const saleStatusValues = ["true", "false"];
// Initialize newData with default objects if existingData is empty
let newData = [];
if (result.length === 0) {
newData = saleStatusValues.map((value) => ({
opportunity_id: 0,
auctioneer_id: 0,
sale_status: value,
units: 0,
}));
return res.json({ status: 200, message: "Success", data: newData });
}
const missingValues = saleStatusValues.filter((value) => {
return !formattedData.some((item) => item.sale_status === value);
});
// Add missing values to the existing data
newData = formattedData.concat(
missingValues.map((value) => ({
opportunity_id: 0,
auctioneer_id: 0,
sale_status: value,
units: 0,
}))
);
return res.json({ status: 200, message: "Success", data: newData });
} catch (error) {
return res.json(error.message);
}
};
const getSaleStatusVehicles = async (req, res) => {
try {
const { sale_status, opportunity_id, sortBy, orderDirection } = req.body;
const results = await db.tblVehicleRun.findAll({
where: { opportunity_id: opportunity_id, sale_status: sale_status },
include: [
{
model: db.tblVehicle,
raw: true,
},
{
model: db.tblAuctionLane,
attributes: ["name"],
raw: true,
// required: true,
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
raw: true,
required: false,
},
],
},
],
order: [[db.tblVehicle, sortBy || "vehicle_id", orderDirection || "ASC"]],
});
// return res.json({ status: 200, data: results });
const outputArray = results.map((vehicleRun) => {
const vehicle = vehicleRun.tblVehicle || {};
const auctionLane = vehicleRun.tblAuctionLane || {};
const auction = auctionLane.tblAuction || {};
return {
vehicle_id: vehicle.vehicle_id,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
vin: vehicle.vin,
mileage: vehicle.mileage,
imageUrl: vehicle.imageUrl,
color: vehicle.color,
color_name: vehicle.color_name,
vehicle_run_id: vehicleRun.vehicle_run_id,
condition_light: vehicleRun.condition_light || 0,
announcements: vehicleRun.announcements || null,
reserve: vehicleRun.reserve || 0,
sale_price: vehicleRun.sale_price || 0,
auction_fee: vehicleRun.auction_fee || 300,
vehicle_total_fee: vehicleRun.vehicle_total_fee || 0,
net_proceed: vehicleRun.net_proceed || 0,
sale_status: vehicleRun.sale_status || false,
run_no: vehicleRun.run_no || null,
lane_id: vehicleRun.lane_id || null,
lane_name: auctionLane.name || null,
auction_id: auction.auction_id || null,
auction_name: auction.name || null,
};
});
return res.json({ status: 200, message: "Success", data: outputArray });
} catch (error) {
return res.status(500).json({ error: error.message });
}
};
const filterByAuctioneerAuctions = async (req, res) => {
try {
const { auctioneer_id, week_id } = req.body;
let result;
[result] = await db.sequelize.query(`SELECT
o.opportunity_id,
a.auctioneer_id,
au.auction_id,
au.name as auction_name,
COUNT(vr.vehicle_run_id) AS units
FROM tblOpportunities AS o
JOIN tblAuctioneers AS a ON o.auctioneer_id = a.auctioneer_id
JOIN tblAuctionLanes AS al ON a.auctioneer_id = al.auctioneer_id
JOIN tblAuctions AS au ON al.auction_id = au.auction_id
LEFT JOIN tblVehicleRuns AS vr ON al.lane_id = vr.lane_id AND vr.opportunity_id = o.opportunity_id
WHERE o.auctioneer_id=${auctioneer_id} AND o.week_id=${week_id}
GROUP BY o.opportunity_id, a.auctioneer_id, au.auction_id;
`);
// Returning the result as a response
return res.json({ status: 200, message: "Success", data: result });
} catch (error) {
console.error("Error fetching the data: ", error);
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
const GetVehicleCountByAuction = async (req, res) => {
try {
const { auctioneerId, weekId } = req.body;
// Find user_ids from tblOpportunity based on auctioneerId and weekId
const userOpportunityIds = await db.tblOpportunity.findAll({
attributes: ["user_id"],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
raw: true,
});
// Extract user_ids from the result
const userIds = userOpportunityIds.map(
(opportunity) => opportunity.user_id
);
// Find user data from tblUser and tblVehicle based on the obtained user_ids
const [result] = await db.sequelize.query(`
SELECT
o.opportunity_id,
auc.auction_id as auction_id,
auc.name as auction_name,
v.vin,
v.year,
v.make,
v.model,
al.lane_id,
al.name as lane_name,
vr.announcements,
vr.condition_light,
vr.sale_price,
vr.sale_status
from tblOpportunities as o
inner join tblAuctioneers as a on a.auctioneer_id=o.auctioneer_id
inner join tblAuctionLanes as al on al.auctioneer_id=a.auctioneer_id
inner join tblAuctions as auc on auc.auction_id=al.auction_id
inner join tblVehicleRuns as vr on vr.lane_id=al.lane_id
inner join tblVehicles as v on v.vehicle_id=vr.vehicle_id
where o.auctioneer_id=${auctioneerId} and o.week_id=${weekId};`);
const groupByAuctionID = (data) => {
return data.reduce((acc, currentValue) => {
// Find an auction in the accumulator array.
let auction = acc.find((a) => a.auction_id === currentValue.auction_id);
// If the auction doesn't exist, create it and push it to the accumulator.
if (!auction) {
auction = {
auction_id: currentValue.auction_id,
auction_name: currentValue.auction_name,
data: [],
};
acc.push(auction);
}
// Add the current value to the data array of the found/created auction.
auction.data.push({
opportunity_id: currentValue.opportunity_id,
vin: currentValue.vin.trim(),
year: currentValue.year,
make: currentValue.make.trim(),
model: currentValue.model.trim(),
lane_id: currentValue.lane_id,
lane_name: currentValue.lane_name,
announcements: currentValue.announcements,
condition_light: currentValue.condition_light,
sale_price: currentValue.sale_price,
sale_status: currentValue.sale_status,
});
return acc;
}, []);
};
const transformedData = groupByAuctionID(result);
return res.json({
status: 200,
message: "Success",
filter_type:"auction",
data: transformedData,
});
} catch (error) {
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
const GetVehicleCountBySaleStatus = async (req, res) => {
try {
const { auctioneerId, weekId } = req.body;
// Find user_ids from tblOpportunity based on auctioneerId and weekId
const userOpportunityIds = await db.tblOpportunity.findAll({
attributes: ["user_id"],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
raw: true,
});
// Extract user_ids from the result
const userIds = userOpportunityIds.map(
(opportunity) => opportunity.user_id
);
// Find user data from tblUser and tblVehicle based on the obtained user_ids
const result = await db.tblOpportunity.findAll({
attributes: ["opportunity_id"],
where: {
week_id: weekId,
auctioneer_id: auctioneerId,
},
include: [
{
model: db.tblUser,
attributes: ["user_id", "first_name", "last_name"],
},
{
model: db.tblVehicleRun,
include: [
{
model: db.tblVehicle,
},
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
},
],
},
],
},
],
});
// return res.json(result);
const modifiedData = result.map((item) => {
return {
user_id: item.tblUser.user_id,
first_name: item.tblUser.first_name,
last_name: item.tblUser.last_name,
sold_vehicles: item.tblVehicleRuns
.filter((run) => run.sale_status === true)
.map((run) => {
const vehicle = run.tblVehicle;
return {
vehicle_id: vehicle.vehicle_id,
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
imageUrl: vehicle.imageUrl,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name,
details: vehicle.details,
reserve: run.reserve,
sale_status: run.sale_status,
sale_price: run.sale_price,
condition_light: run.condition_light,
announcements: run.announcements,
auction_fee: run.vehicle_total_fee, // Assuming auction_fee refers to 'vehicle_total_fee' field.
run_no: run.run_no,
lane_id: run.tblAuctionLane.lane_id,
lane_name: run.tblAuctionLane.name,
auction_name: run.tblAuctionLane.tblAuction.name,
};
}),
not_sold_vehicles: item.tblVehicleRuns
.filter((run) => run.sale_status === false)
.map((run) => {
const vehicle = run.tblVehicle;
return {
vin: vehicle.vin,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
imageUrl: vehicle.imageUrl,
trim: vehicle.trim,
mileage: vehicle.mileage,
color: vehicle.color,
color_name: vehicle.color_name,
details: vehicle.details,
reserve: run.reserve,
sale_status: run.sale_status,
sale_price: run.sale_price,
condition_light: run.condition_light,
announcements: run.announcements,
auction_fee: run.vehicle_total_fee, // Assuming auction_fee refers to 'vehicle_total_fee' field.
run_no: run.run_no,
lane_id: run.tblAuctionLane ? run.tblAuctionLane.lane_id : null,
lane_name: run.tblAuctionLane ? run.tblAuctionLane.name : null,
auction_name: run.tblAuctionLane
? run.tblAuctionLane.tblAuction.name
: null,
};
}),
};
});
return res.json({
status: 200,
message: "Success",
filter_type: "sale_status",
data: modifiedData,
});
} catch (error) {
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
const GetVehicleCountByConditionLight = async (req, res) => {
try {
const { auctioneerId, weekId } = req.body;
// Find user_ids from tblOpportunity based on auctioneerId and weekId
const userOpportunityIds = await db.tblOpportunity.findAll({
attributes: ["user_id"],
where: {
auctioneer_id: auctioneerId,
week_id: parseInt(weekId),
},
raw: true,
});
// Extract user_ids from the result
const userIds = userOpportunityIds.map(
(opportunity) => opportunity.user_id
);
// Find user data from tblUser and tblVehicle based on the obtained user_ids
const result = await db.tblOpportunity.findAll({
attributes: ["opportunity_id"],
where: {
week_id: weekId,
auctioneer_id: auctioneerId,
},
include: [
{
model: db.tblUser,
attributes: ["user_id", "first_name", "last_name"],
},
{
model: db.tblVehicleRun,
include: [
{
model: db.tblVehicle,
},
{
model: db.tblAuctionLane,
attributes: ["lane_id", "name"],
include: [
{
model: db.tblAuction,
attributes: ["auction_id", "name"],
},
],
},
],
},
],
});
const modifiedData = result.map((opportunity) => {
const { tblUser, tblVehicleRuns } = opportunity;
// Helper function to get vehicles based on condition light
const getVehiclesByConditionLight = (conditionLightValue) =>
tblVehicleRuns
.filter((run) => run.condition_light === conditionLightValue)
.map((run) => {
const { tblVehicle, tblAuctionLane } = run;
return {
vin: tblVehicle.vin,
year: tblVehicle.year,
make: tblVehicle.make,
model: tblVehicle.model,
mileage: tblVehicle.mileage,
trim: tblVehicle.trim,
imageUrl: tblVehicle.imageUrl,
condition_light: run.condition_light,
reserve: run.reserve,
announcements: run.announcements,
sale_price: run.sale_price,
sale_status: run.sale_status,
auction_fee: run.vehicle_total_fee,
lane_id: tblAuctionLane ? tblAuctionLane.lane_id : null,
lane_name: tblAuctionLane ? tblAuctionLane.name : null,
auction_name:
tblAuctionLane && tblAuctionLane.tblAuction
? tblAuctionLane.tblAuction.name
: null,
};
});
// Use the helper function for different condition lights
const redVehicles = getVehiclesByConditionLight(1); // Red condition light vehicles
const yellowVehicles = getVehiclesByConditionLight(2); // Yellow condition light vehicles
const greenVehicles = getVehiclesByConditionLight(3); // Green condition light vehicles
return {
user_id: tblUser.user_id,
first_name: tblUser.first_name,
last_name: tblUser.last_name,
red_vehicles: redVehicles,
yellow_vehicles: yellowVehicles,
green_vehicles: greenVehicles,
};
});
return res.json({
status: 200,
message: "Success",
filter_type: "condition_light",
data: modifiedData,
});
} catch (error) {
return res.status(500).json({
status: 500,
message: "Internal Server Error",
error: error.message,
});
}
};
const auctioneerTotalSaleAndNetProceed = async (req, res) => {
try {
let { auctioneer_id } = req.body;
let timeRange;
if (!req.body.timeRange) {
timeRange = "currentweek";
} else {
timeRange = req.body.timeRange;
}
timeRange = timeRange.replace(/\s/g, "");
timeRange = timeRange.toLowerCase();
const weekRange = calculateDateRange(timeRange);
const results = await db.tblOpportunity.findAll({
include: [
{
model: db.tblVehicleRun,
where: {
createdAt: {
[Op.between]: [weekRange.startDate, weekRange.endDate],
},
},
attributes: [
"sale_price",
"vehicle_total_fee",
"net_proceed",
"sale_status",
],
raw: true,
},
],
where: {
auctioneer_id: auctioneer_id,
},
});
// return res.json(results);
return res.json({
status: 200,
message: "success",
net_proceed: 0,
total_profit: 0,
unit_sold: 0,
});
if (results.length === 0) {
return res.json({
status: 200,
message: "Success",
net_proceed: 0,
total_profit: 0,
unit_sold: 0,
});
}
let totalSalePrice = 0;
let totalNetProfit = 0;
let soldUnits = 0;
// Iterate over each opportunity
results.forEach((opportunity) => {
// Iterate over each vehicle
opportunity.tblVehicles.forEach((vehicle) => {
// Iterate over each vehicle run
vehicle.tblVehicleRuns.forEach((run) => {
totalSalePrice += run.sale_price;
totalNetProfit += run.auction_fee;
soldUnits += run.sale_status ? 1 : 0;
});
});
});
return res.json({
status: 200,
message: "Success",
net_proceed: totalNetProfit,
total_profit: totalSalePrice || 0,
unit_sold: soldUnits || 0,
// unit_sold: transformedData[0]?.sold_units || 0,
});
} catch (error) {
return res.status(500).json({ status: 500, error: error.message });
}
};
module.exports = {
auctioneerLogin,
// forgotPassword,
// resetPasswordViaToken,
getAuctioneerProfile,
removeAuctioneer,
updateAuctioneerPassword,
GetAuctioneerUsers,
updateVehicleStatus,
updateAuctioneerProfile,
getAllAssignedVehicles,
sortAuctioneerVehicles,
filterByConditionLight,
filterBySaleStatus,
GetVehicleCountBySaleStatus,
GetVehicleCountByConditionLight,
GetAuctioneerUsersOnly,
getAllAssignedVehiclesOnly,
filterByAuctioneerAuctions,
auctioneerTotalSaleAndNetProceed,
getConditionLightVehicles,
getSaleStatusVehicles,
GetVehicleCountByAuction
};
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists