Sindbad~EG File Manager

Current Path : /home/infinitibizsol/.trash/controllers.1/
Upload File :
Current File : /home/infinitibizsol/.trash/controllers.1/auctioneerController.js

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");

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: "user does not existed" });
    }
    const isMatched = await brcrypt.compare(password, result[0].password);
    console.log("isMatched", isMatched);
    if (!isMatched) {
      return res.status(403).json({ status: 403, message: "Invalid Password" });
    }
    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 updateAuctioneerPassword = async (req, res) => {
  try {
    let { auctioneer_id, newPassword } = req.body;

    if (newPassword) {
      const salt = await brcrypt.genSalt(10);
      const encrypPassword = await brcrypt.hash(newPassword, salt);
      let result = await db.tblAuctioneer.update(
        { password: encrypPassword },
        { 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.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: ["opportunity_id"],
              raw: true,
              include: [
                {
                  model: db.tblAuctioneer,
                  attributes: ["per_unit_fee"],
                  raw: true,
                },
              ],
              where: {
                auctioneer_id: auctioneerId,
                week_id: parseInt(weekId),
              },
              raw: true,
            },
            {
              model: db.tblVehicleRun,
              attributes: [
                "reserve",
                "sale_status",
                "sale_price",
                "condition_light",
                "announcements",
              ],
              raw: true,
              include: [
                {
                  model: db.tblAuctionLane,
                  attributes: ["lane_id", "name"],
                  raw: true,
                  include: [
                    {
                      model: db.tblAuction,
                      attributes: ["auction_id", "name"],
                      raw: true,
                    },
                  ],
                },
              ],
            },
          ],
          where: {
            // user_id: userIds,
            createdAt: {
              [Op.between]: [weekRange.startDate, weekRange.endDate],
            },
          },
          raw: true,
          order: [[sortBy || "Vehilce_id", orderDirection || "ASC"]],
        },
      ],
    });

    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,
        auction_fee: vehicle.tblOpportunity.tblAuctioneer.per_unit_fee || null,
        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,
        lane_id:
          vehicle.tblVehicleRuns[0]?.tblAuctionLane?.tblAuctionLane.lane_id ||
          null,
        lane_name: vehicle.tblVehicleRuns[0]?.tblAuctionLane?.name || null,
        auction_name:
          vehicle.tblVehicleRuns[0]?.tblAuctionLane?.tblAuction?.name || null,
      })),
    }));
    return res.json({ status: 200, data: formattedData });
  } catch (error) {
    return res.json(error.message);
  }
};

const GetAuctioneerUsersOnly = async (req, res) => {
  try {
    const { auctioneerId, weekId, orderDirection } = 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.tblVehicles.opportunity_id")
          ),
          "units",
        ],
      ],
      include: [
        {
          model: tblOpportunity,
          attributes: [],
          include: [
            {
              model: tblVehicle,
              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 });

    /*   const transformedResult = result.map((user) => ({
      user_id: user.user_id,
      first_name: user.first_name,
      last_name: user.last_name,
      units: user.tblOpportunities.map(
        (opportunity) => opportunity.vehicle_count
      ),
    }));
    return res.json({ status: 200, data: transformedResult }); */
  } catch (error) {
    console.log(error);
    return res.json(error.message);
  }
};

const updateCarStatus = 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 brcrypt.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}` });
  }
};

const getAllCarsByAuctioneerId = 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();
    console.log(timeRange);
    let startDate;

    switch (timeRange) {
      case "last24hours":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0);
        break;
      case "currentweek":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0 - currentDate.getDay());
        startDate.setDate(startDate.getDate() - 3);
        break;
      case "lastweek":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0 - currentDate.getDay());
        startDate.setDate(startDate.getDate() - 7);
        break;
      case "last4weeks":
        startDate = new Date(currentDate);
        startDate.setDate(currentDate.getDate() - 28);
        break;
      default:
        throw new Error("Invalid time range specified");
    }
    /* 
    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,
          include:[
            {
              model:db.tblVehicleRun,
              raw:true,

            }
          ],
          where: {
            user_id: user_id,
          },
        },
      ],

      // order: [["createdAt", "ASC"]]
    });

    const transformedData = result.flatMap((opportunity) =>
      opportunity.tblVehicles.map((vehicle) => ({
        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: opportunity.opportunity_id,
        user_id: vehicle.user_id,
        createdAt: vehicle.createdAt,
        updatedAt: vehicle.updatedAt,
      }))
    ); */

    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 getAllCarsByAuctioneerIdOnly = async (req, res) => {
  try {
    const { auctioneer_id, user_id, weekId, sortBy, orderDirection } = 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();
    console.log(timeRange);
    let startDate;

    switch (timeRange) {
      case "last24hours":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0);
        break;
      case "currentweek":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0 - currentDate.getDay());
        startDate.setDate(startDate.getDate() - 3);
        break;
      case "lastweek":
        startDate = new Date(currentDate);
        startDate.setHours(0, 0, 0, 0 - currentDate.getDay());
        startDate.setDate(startDate.getDate() - 7);
        break;
      case "last4weeks":
        startDate = new Date(currentDate);
        startDate.setDate(currentDate.getDate() - 28);
        break;
      default:
        throw new Error("Invalid time range specified");
    }

    /*     let [result] = await db.sequelize.query(`
        select t2.*
        from tblOpportunities AS t1
        join tblVehicles as t2 on t1.opportunity_id=t2.opportunity_id
        where t1.user_id=${user_id} AND t1.week_id=${week_Id} AND t1.auctioneer_id=${auctioneer_id};

    `); */

    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: [[sortBy || "vehicle_id", orderDirection || "ASC"]],
        },
      ],

      // 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,
        };
      })
    );

    /*  [
      {
        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: formattedData });
  } catch (error) {
    return res.json(error.message);
  }
};

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";
      /*  whereClause.sold_price = {
        [Op.not]: null,
      }; */
    }

    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 calculateLength = (data) => {
  return data.map((group) => ({
    sale_status: group.sale_status,
    vehicles_list_length: group.vehicles_list.length,
    vehicles_list: group.vehicles_list,
  }));
};

/* const sortByConditionLight = async (req, res) => {
  try {
    const { auctioneer_id, week_id } = req.body;

    const results = await db.tblOpportunity.findAll({
      attributes: ["opportunity_id", "auctioneer_id"],
      where: { auctioneer_id: auctioneer_id, week_id: week_id },
      include: [
        {
          model: db.tblVehicle,
          attributes: ["vehicle_id"],
          include: [
            {
              model: db.tblVehicleRun,
              attributes: ["condition_light"],
              order: [["condition_light", "ASC"]],
            },
          ],
        },
      ],
    });

    const groupedData = results.flatMap(
      ({ auctioneer_id, opportunity_id, tblVehicles }) => {
        const groupedByCondition = tblVehicles.reduce((acc, vehicle) => {
          const condition_light =
            vehicle.tblVehicleRuns[0]?.condition_light || 0;

          if (!acc[condition_light]) {
            acc[condition_light] = [];
          }

          acc[condition_light].push({
            vehicle_id: vehicle.vehicle_id,
            year: vehicle.year,
            make: vehicle.make,
            model: vehicle.model,
            imageUrl: vehicle.imageUrl,
            condition_light: condition_light || 0,
            sale_price: vehicle.tblVehicleRuns[0]?.sale_price || null,
            sale_status: vehicle.tblVehicleRuns[0]?.sale_status || null,
            lane_id: vehicle.tblVehicleRuns[0]?.lane_id || null,
          });

          return acc;
        }, {});

        return Object.entries(groupedByCondition).map(
          ([condition_light, vehicles_list]) => ({
            opportunity_id,
            auctioneer_id,
            condition_light: Number(condition_light),
            units: vehicles_list.length, // Add the units property
            // vehicles_list,
          })
        );
      }
    );

    const conditionLightValues = [0, 1, 2, 3];
    // Check for missing condition_light values
    const missingValues = conditionLightValues.filter((value) => {
      return !groupedData.some((item) => item.condition_light === value);
    });

    // Add missing values to the existing data
    const newData = groupedData.concat(
      missingValues.map((value) => ({
        opportunity_id: 0, // Replace with the appropriate value
        auctioneer_id: 0, // Replace with the appropriate value
        condition_light: value,
        units: 0, // Replace with the appropriate value
      }))
    );
    const filteredData = newData.filter((item) => item.condition_light != 0);
    return res.json({ status: 200, Message: "Success", data: filteredData });
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};

const getConditionLightVehicles = async (req, res) => {
  try {
    const { condition_light, opportunity_id } = req.body;

    const results = await db.tblVehicle.findAll({
      attributes: [
        "vehicle_id",
        "year",
        "make",
        "model",
        "vin",
        "mileage",
        "imageUrl",
        "color",
      ],
      where: { opportunity_id: opportunity_id },
      include: [
        {
          model: db.tblVehicleRun,
          attributes: [
            "condition_light",
            "announcements",
            "sale_price",
            "auction_fee",
            "net_profit",
            "reserve",
            "sale_status",
            "lane_id",
          ],
          where: { condition_light: condition_light },
          raw: true,
          include: [
            {
              model: db.tblAuctionLane,
              attributes: ["name"],
              raw: true,
              // required: true,
              include: [
                {
                  model: db.tblAuction,
                  attributes: ["auction_id", "name"],
                  raw: true,
                  required: false,
                },
              ],
            },
          ],
        },
      ],
    });

    const outputArray = results.map((vehicle) => {
      const vehicleRun = vehicle.tblVehicleRuns[0];
      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,
        vehicle_run_id: vehicleRun.vehicle_run_id,
        condition_light: vehicleRun.condition_light,
        announcements: vehicleRun.announcements,
        reserve: vehicleRun.reserve,
        sale_price: vehicleRun.sale_price,
        auction_fee: vehicleRun.auction_fee,
        net_profit: vehicleRun.net_profit,
        sale_status: vehicleRun.sale_status,
        run_no: vehicleRun.run_no,
        lane_id: vehicleRun.lane_id,
        lane_name: auctionLane.name,
        auction_id: auction.auction_id || null,
        auction_name: auction.name || null,
      };
    });
    return res.json({ status: true, message: "Success", data: outputArray });
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};

const sortBySaleStatus = async (req, res) => {
  try {
    const { auctioneer_id, user_id, week_id } = req.body;
    const result = await db.tblOpportunity.findAll({
      attributes: ["opportunity_id", "auctioneer_id"],
      where: { auctioneer_id: auctioneer_id, week_id: week_id },
      include: [
        {
          model: db.tblVehicle,
          attributes: ["vehicle_id", "opportunity_id"],
          where: { opportunity_id: col("tblOpportunity.opportunity_id") },
          raw: true,
          include: [
            {
              model: db.tblVehicleRun,
              attributes: ["condition_light", "sale_status"],
              where: { vehicle_id: col("tblVehicles.vehicle_id") },
            },
          ],
        },
      ],
    });
    // return res.json({ result });
    if (result.length <= 0) {
      return res.json({ status: 200, message: "Success", data: result });
    }
    let outputData = result[0].tblVehicles.flatMap((vehicle) => {
      return vehicle.tblVehicleRuns.map((run) => ({
        vehicle_id: vehicle.vehicle_id,
        opportunity_id: vehicle.opportunity_id,
        auctioneer_id: result[0].auctioneer_id,
        condition_light: run.condition_light,
        sale_status: run.sale_status,
      }));
    });

    const groupedData = outputData.reduce((acc, item) => {
      const { sale_status, ...rest } = item;

      if (!acc[sale_status]) {
        acc[sale_status] = { units: 0, data: [] };
      }

      acc[sale_status].units += 1;
      acc[sale_status].data.push(rest);

      return acc;
    }, {});

    // Transform groupedData into the desired format
    outputData = Object.keys(groupedData).map((sale_status) => {
      return {
        ...groupedData[sale_status].data[0], // Assuming all items in a group have the same vehicle_id, condition_light, and sale_status
        sale_status: sale_status,
        // sale_status: false,
        units: groupedData[sale_status].units,
      };
    });

    const saleStatusValues = ["true", "false"];
    // Check for missing sale_status values
    const missingValues = saleStatusValues.filter((value) => {
      return !outputData.some((item) => item.sale_status === value);
    });
    // Add missing values to the existing data
    const newData = outputData.concat(
      missingValues.map((value) => ({
        vehicle_id: 0, // Replace with the appropriate value
        opportunity_id: 0, // Replace with the appropriate value
        auctioneer_id: 0, // Replace with the appropriate value
        condition_light: 0, // Replace with the appropriate value
        sale_status: value,
        units: 0, // Replace with the appropriate value
      }))
    );
    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.tblVehicle.findAll({
      attributes: [
        "vehicle_id",
        "year",
        "make",
        "model",
        "vin",
        "mileage",
        "imageUrl",
        "color",
      ],
      where: { opportunity_id: opportunity_id },
      include: [
        {
          model: db.tblVehicleRun,
          attributes: [
            "condition_light",
            "announcements",
            "sale_price",
            "auction_fee",
            "net_profit",
            "reserve",
            "sale_status",
            "lane_id",
          ],
          where: { sale_status: sale_status },
          raw: true,
          include: [
            {
              model: db.tblAuctionLane,
              attributes: ["name"],
              raw: true,
              // required: true,
              include: [
                {
                  model: db.tblAuction,
                  attributes: ["auction_id", "name"],
                  raw: true,
                  required: false,
                },
              ],
            },
          ],
        },
      ],
      order: [[sortBy || "vehicle_id", orderDirection || "ASC"]],
    });

    const outputArray = results.map((vehicle) => {
      const vehicleRun = vehicle.tblVehicleRuns[0];
      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,
        vehicle_run_id: vehicleRun.vehicle_run_id,
        condition_light: vehicleRun.condition_light,
        announcements: vehicleRun.announcements,
        reserve: vehicleRun.reserve,
        sale_price: vehicleRun.sale_price,
        auction_fee: vehicleRun.auction_fee,
        net_profit: vehicleRun.net_profit,
        sale_status: vehicleRun.sale_status,
        run_no: vehicleRun.run_no,
        lane_id: vehicleRun.lane_id,
        lane_name: auctionLane.name,
        auction_id: auction.auction_id || null,
        auction_name: auction.name || null,
      };
    });
    return res.json({ status: true, message: "Success", data: outputArray });
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};
 */

const sortByConditionLight = async (req, res) => {
  try {
    const { auctioneer_id, week_id } = req.body;

    const results = await db.tblOpportunity.findAll({
      attributes: ["opportunity_id", "auctioneer_id"],
      where: { auctioneer_id: auctioneer_id, week_id: week_id },
      include: [
        {
          model: db.tblVehicle,
          attributes: ["vehicle_id"],
          include: [
            {
              model: db.tblVehicleRun,
              attributes: ["condition_light"],
            },
          ],
        },
      ],
    });

    const groupedData = results.flatMap(
      ({ auctioneer_id, opportunity_id, tblVehicles }) => {
        const groupedByCondition = tblVehicles.reduce((acc, vehicle) => {
          const condition_light =
            vehicle.tblVehicleRuns[0]?.condition_light || 0;

          if (!acc[condition_light]) {
            acc[condition_light] = [];
          }

          acc[condition_light].push({
            vehicle_id: vehicle.vehicle_id,
            year: vehicle.year,
            make: vehicle.make,
            model: vehicle.model,
            imageUrl: vehicle.imageUrl,
            condition_light: condition_light || 0,
            sale_price: vehicle.tblVehicleRuns[0]?.sale_price || null,
            sale_status: vehicle.tblVehicleRuns[0]?.sale_status || null,
            lane_id: vehicle.tblVehicleRuns[0]?.lane_id || null,
          });

          return acc;
        }, {});

        return Object.entries(groupedByCondition).map(
          ([condition_light, vehicles_list]) => ({
            opportunity_id,
            auctioneer_id,
            condition_light: Number(condition_light),
            units: vehicles_list.length, // Add the units property
            // vehicles_list,
          })
        );
      }
    );

    const conditionLightValues = [0, 1, 2, 3];
    // Check for missing condition_light values
    const missingValues = conditionLightValues.filter((value) => {
      return !groupedData.some((item) => item.condition_light === value);
    });

    // Add missing values to the existing data
    const newData = groupedData.concat(
      missingValues.map((value) => ({
        opportunity_id: 0, // Replace with the appropriate value
        auctioneer_id: 0, // Replace with the appropriate value
        condition_light: value,
        units: 0, // Replace with the appropriate value
      }))
    );

    const filteredData = newData.filter((item) => item.condition_light != 0);
    return res.json({ status: 200, Message: "Success", data: filteredData });
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};

const getConditionLightVehicles = async (req, res) => {
  try {
    const { condition_light, opportunity_id } = req.body;

    const results = await db.tblVehicle.findAll({
      attributes: [
        "vehicle_id",
        "year",
        "make",
        "model",
        "vin",
        "mileage",
        "imageUrl",
        "color",
        "color_name",
      ],
      where: { opportunity_id: opportunity_id },
      include: [
        {
          model: db.tblVehicleRun,
          attributes: [
            "condition_light",
            "announcements",
            "sale_price",
            "auction_fee",
            "net_profit",
            "reserve",
            "sale_status",
            "lane_id",
          ],
          where: { condition_light: condition_light },
          raw: true,
          include: [
            {
              model: db.tblAuctionLane,
              attributes: ["name"],
              raw: true,
              // required: true,
              include: [
                {
                  model: db.tblAuction,
                  attributes: ["auction_id", "name"],
                  raw: true,
                  required: false,
                },
              ],
            },
          ],
        },
      ],
    });

    const outputArray = results.map((vehicle) => {
      const vehicleRun = vehicle.tblVehicleRuns[0];
      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,
        announcements: vehicleRun.announcements,
        reserve: vehicleRun.reserve,
        sale_price: vehicleRun.sale_price,
        auction_fee: vehicleRun.auction_fee,
        net_profit: vehicleRun.net_profit,
        sale_status: vehicleRun.sale_status,
        run_no: vehicleRun.run_no,
        lane_id: vehicleRun.lane_id,
        lane_name: auctionLane.name,
        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 sortBySaleStatus = async (req, res) => {
  try {
    const { auctioneer_id, user_id, week_id } = req.body;
    const result = await db.tblOpportunity.findAll({
      attributes: ["opportunity_id", "auctioneer_id"],
      where: { auctioneer_id: auctioneer_id, week_id: week_id },

      include: [
        {
          model: db.tblVehicle,
          attributes: ["vehicle_id", "opportunity_id"],
          where: { opportunity_id: col("tblOpportunity.opportunity_id") },
          raw: true,
          include: [
            {
              model: db.tblVehicleRun,
              attributes: ["condition_light", "sale_status"],
              where: { vehicle_id: col("tblVehicles.vehicle_id") },
            },
          ],
        },
      ],
    });
    // return res.json({ result });

    const saleStatusValues = ["true", "false"];

    // Initialize newData with default objects if existingData is empty
    let newData = [];

    if (result.length === 0) {
      newData = saleStatusValues.map((value) => ({
        vehicle_id: 0, // Replace with the appropriate value
        opportunity_id: 0, // Replace with the appropriate value
        auctioneer_id: 0, // Replace with the appropriate value
        condition_light: 0, // Replace with the appropriate value
        sale_status: value,
        units: 0, // Replace with the appropriate value
      }));

      return res.json({ status: 200, message: "Success", data: newData });
    }

    let outputData = result[0].tblVehicles.flatMap((vehicle) => {
      return vehicle.tblVehicleRuns.map((run) => ({
        vehicle_id: vehicle.vehicle_id,
        opportunity_id: vehicle.opportunity_id,
        auctioneer_id: result[0].auctioneer_id,
        condition_light: run.condition_light,
        sale_status: run.sale_status,
      }));
    });

    const groupedData = outputData.reduce((acc, item) => {
      const { sale_status, ...rest } = item;

      if (!acc[sale_status]) {
        acc[sale_status] = { units: 0, data: [] };
      }

      acc[sale_status].units += 1;
      acc[sale_status].data.push(rest);

      return acc;
    }, {});

    // Transform groupedData into the desired format
    outputData = Object.keys(groupedData).map((sale_status) => {
      return {
        ...groupedData[sale_status].data[0], // Assuming all items in a group have the same vehicle_id, condition_light, and sale_status
        sale_status: sale_status,
        units: groupedData[sale_status].units,
      };
    });

    if (outputData.length === 0) {
      newData = saleStatusValues.map((value) => ({
        vehicle_id: 0, // Replace with the appropriate value
        opportunity_id: 0, // Replace with the appropriate value
        auctioneer_id: 0, // Replace with the appropriate value
        condition_light: 0, // Replace with the appropriate value
        sale_status: value,
        units: 0, // Replace with the appropriate value
      }));
    } else {
      // Check for missing sale_status values
      const missingValues = saleStatusValues.filter((value) => {
        return !outputData.some((item) => item.sale_status === value);
      });

      // Add missing values to the existing data
      newData = outputData.concat(
        missingValues.map((value) => ({
          vehicle_id: 0, // Replace with the appropriate value
          opportunity_id: 0, // Replace with the appropriate value
          auctioneer_id: 0, // Replace with the appropriate value
          condition_light: 0, // Replace with the appropriate value
          sale_status: value,
          units: 0, // Replace with the appropriate value
        }))
      );
    }

    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.tblVehicle.findAll({
      attributes: [
        "vehicle_id",
        "year",
        "make",
        "model",
        "vin",
        "mileage",
        "imageUrl",
        "color",
        "color_name",
      ],
      where: { opportunity_id: opportunity_id },
      include: [
        {
          model: db.tblVehicleRun,
          attributes: [
            "condition_light",
            "announcements",
            "sale_price",
            "auction_fee",
            "net_profit",
            "reserve",
            "sale_status",
            "lane_id",
          ],
          where: { sale_status: sale_status },
          raw: true,
          include: [
            {
              model: db.tblAuctionLane,
              attributes: ["name"],
              raw: true,
              // required: true,
              include: [
                {
                  model: db.tblAuction,
                  attributes: ["auction_id", "name"],
                  raw: true,
                  required: false,
                },
              ],
            },
          ],
        },
      ],
      order: [[sortBy || "vehicle_id", orderDirection || "ASC"]],
    });

    const outputArray = results.map((vehicle) => {
      const vehicleRun = vehicle.tblVehicleRuns[0];
      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,
        announcements: vehicleRun.announcements,
        reserve: vehicleRun.reserve,
        sale_price: vehicleRun.sale_price,
        auction_fee: vehicleRun.auction_fee,
        net_profit: vehicleRun.net_profit,
        sale_status: vehicleRun.sale_status.toString(),
        run_no: vehicleRun.run_no,
        lane_id: vehicleRun.lane_id,
        lane_name: auctionLane.name,
        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 } = req.body;

    const result = await db.tblAuctionLane.findAll({
      attributes: [],
      where: { auctioneer_id },
      include: [
        {
          model: db.tblAuction,
          attributes: ["auction_id", "name"],
          raw: true,
        },
      ],
    });

    let uniqueAuctions = Object.values(
      result.reduce((uniqueMap, item) => {
        const auction_id = item.tblAuction.auction_id;
        if (!uniqueMap[auction_id]) {
          uniqueMap[auction_id] = {
            lane_id: item.lane_id,
            lane_name: item.lane_id,
            auction_id,
            auction_name: item.tblAuction.name,
          };
        }
        return uniqueMap;
      }, {})
    );
    const laneIdsResult = await Promise.all(
      uniqueAuctions.map(async (item) => {
        const laneIds = await db.tblAuctionLane.findAll({
          attributes: ["lane_id"],
          where: { auction_id: item.auction_id },
        });

        return {
          auction_id: item.auction_id,
          auction_name: item.auction_name,
          laneIds: laneIds.map((lane) => lane.lane_id),
        };
      })
    );

    // return res.json(uniqueAuctions);
    uniqueAuctions = await Promise.all(
      laneIdsResult.map(async (item) => {
        const totalMatchingIds = await db.tblVehicleRun.count({
          where: {
            lane_id: {
              [Op.in]: item.laneIds,
            },
          },
        });

        return {
          auction_id: item.auction_id,
          auction_name: item.auction_name,
          units: totalMatchingIds || 0,
        };
      })
    );
    return res.json({
      status: 200,
      message: "Success",
      data: uniqueAuctions,
    });

    [
      {
        auction_id: 1,
        auction_name: "America's Auto Auction",
        laneIds: [1, 2, 3, 4],
      },
      {
        auction_id: 2,
        auction_name: "Dallas Auto Auction",
        laneIds: [A, B, C],
      },
    ];
  } catch (error) {
    return res.json({ status: 502, errorMessage: 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.tblUser.findAll({
      attributes: ["user_id", "first_name", "last_name"],
      include: [
        {
          model: db.tblOpportunity,
          attributes: ["opportunity_id"],
          raw: true,
          where: {
            auctioneer_id: auctioneerId,
            week_id: parseInt(weekId),
          },
        },
        {
          model: db.tblVehicle,
          attributes: [
            "vin",
            "year",
            "make",
            "model",
            "imageUrl",
            "trim",
            "mileage",
            "color",
            "color_name",
            "details",
          ],
          include: [
            {
              model: db.tblVehicleRun,
              where: {
                sale_status: {
                  [db.Sequelize.Op.in]: [true, false],
                },
              },
              attributes: [
                "reserve",
                "sale_status",
                "sale_price",
                "condition_light",
                "announcements",
                "auction_fee",
                "run_no",
              ],
              raw: true,
              include: [
                {
                  model: db.tblAuctionLane,
                  attributes: ["lane_id", "name"],
                  raw: true,
                  include: [
                    {
                      model: db.tblAuction,
                      attributes: ["name"],
                      raw: true,
                    },
                  ],
                },
              ],
            },
          ],
          where: {
            user_id: userIds,
          },
          raw: true,
        },
      ],
    });

    const modifiedData = result.map((item) => ({
      user_id: item.user_id,
      first_name: item.first_name,
      last_name: item.last_name,

      sold_vehicles: item.tblVehicles
        .filter((vehicle) =>
          vehicle.tblVehicleRuns.some((run) => run.sale_status === true)
        )
        .map((vehicle) => {
          const run = vehicle.tblVehicleRuns[0];
          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.auction_fee,
            run_no: run.run_no || null,
            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,
          };
        }),
      notsold_vehicles: item.tblVehicles
        .filter((vehicle) =>
          vehicle.tblVehicleRuns.every((run) => run.sale_status === false)
        )
        .map((vehicle) => {
          const run = vehicle.tblVehicleRuns[0];
          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.auction_fee,
            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,
          };
        }),
    }));

    console.log(modifiedData);

    return res.json({
      status: 200,
      data: modifiedData,
    });

    [
      {
        user_id: 1,
        first_name: "Mike",
        last_name: "Jhon",
        sold_vehicles: [
          {
            vin: "DF54FG654C",
            year: 2012,
            make: "Mercedez",
            model: "G-Class",
            imageUrl: "preview.png",
            trim: "HDHDHYE",
            mileage: 6500,
            color: "fff44336",
            color_name: "Red",
            details:
              "SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",
            reserve: null,
            sale_status: true,
            sale_price: 1500,
            condition_light: 2,
            announcements: null,
            auction_fee: 250,
            lane_id: 2,
            lane_name: "B",
            auction_name: "America's Auto Auction",
          },
        ],
        notsold_vehicles: [
          {
            vin: "DF54FG654C",
            year: 2015,
            make: "Audi",
            model: "A-6",
            imageUrl: "preview.png",
            trim: "HDHDHYE",
            mileage: 8000,
            color: "fff44336",
            color_name: "Red",
            details:
              "SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",

            reserve: 2000,
            sale_status: false,
            sale_price: null,
            condition_light: 2,
            announcements: "RING PISTON BLOWN",
            auction_fee: null,
            lane_id: null,
            lane_name: null,
            auction_name: null,
          },
          {
            vin: "DF54FG654C",
            year: 2020,
            make: "Toyota",
            model: "RAV-4",
            imageUrl: "preview.png",
            trim: "HDHDHYE",
            mileage: 7000,
            color: "fff44336",
            color_name: "Red",
            details:
              "SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",
            reserve: null,
            sale_status: false,
            sale_price: 1500,
            condition_light: 2,
            announcements: null,
            auction_fee: 250,
            lane_id: null,
            lane_name: null,
            auction_name: null,
          },
          {
            vin: "DF54FG654C",
            year: 2012,
            make: "Mercedez",
            model: "G-Class",
            imageUrl: "preview.png",
            trim: "HDHDHYE",
            mileage: 6500,
            color: "fff44336",
            color_name: "Red",
            details:
              "SE.ONE OWNER CAR VERY CLEAN AND NICE INSIDE AND OUTSIDE.NO ACCIDENTS.",

            reserve: null,
            sale_status: false,
            sale_price: 1500,
            condition_light: 2,
            announcements: null,
            auction_fee: 250,
            lane_id: 2,
            lane_name: "B",
            auction_name: "America's Auto Auction",
          },
        ],
      },
    ];
  } catch (error) {
    return res.json(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.tblUser.findAll({
      attributes: ["user_id", "first_name", "last_name"],
      include: [
        {
          model: db.tblOpportunity,
          attributes: ["opportunity_id"],
          raw: true,
          where: {
            auctioneer_id: auctioneerId,
            week_id: parseInt(weekId),
          },
        },
        {
          model: db.tblVehicle,
          attributes: [
            "vin",
            "year",
            "make",
            "model",
            "imageUrl",
            "trim",
            "mileage",
            "color",
            "color_name",
            "details",
          ],
          raw: true,
          include: [
            {
              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: ["name"],
                      raw: true,
                    },
                  ],
                },
              ],
            },
          ],
          where: {
            user_id: userIds,
          },
        },
      ],
    });

    // return res.json({ data: result });
    const modifiedData = result.map((item) => {
      const redVehicles = item.tblVehicles
        .filter((vehicle) =>
          vehicle.tblVehicleRuns.some((run) => run.condition_light === 1)
        )
        .map((vehicle) => {
          const run = vehicle.tblVehicleRuns[0];
          const lane_details = run.tblAuctionLane || {};
          console.log(run);
          return {
            vin: vehicle.get("vin"),
            year: vehicle.get("year"),
            make: vehicle.get("make"),
            model: vehicle.get("model"),
            mileage: vehicle.get("mileage"),
            trim: vehicle.get("trim"),
            imageUrl: vehicle.get("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.auction_fee,
            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,
          };
        });

      const yellowVehicles = item.tblVehicles
        .filter((vehicle) =>
          vehicle.tblVehicleRuns.some((run) => run.condition_light === 2)
        )
        .map((vehicle) => {
          const run = vehicle.tblVehicleRuns[0];
          const lane_details = run.tblAuctionLane || {};
          console.log(run);
          return {
            vin: vehicle.get("vin"),
            year: vehicle.get("year"),
            make: vehicle.get("make"),
            model: vehicle.get("model"),
            mileage: vehicle.get("mileage"),
            trim: vehicle.get("trim"),
            imageUrl: vehicle.get("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.auction_fee,
            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,
          };
        });

      const greenVehicles = item.tblVehicles
        .filter((vehicle) =>
          vehicle.tblVehicleRuns.some((run) => run.condition_light === 3)
        )
        .map((vehicle) => {
          const run = vehicle.tblVehicleRuns[0];

          const lane_details = run.tblAuctionLane || {};
          console.log(run);
          return {
            vin: vehicle.get("vin"),
            year: vehicle.get("year"),
            make: vehicle.get("make"),
            model: vehicle.get("model"),
            mileage: vehicle.get("mileage"),
            trim: vehicle.get("trim"),
            imageUrl: vehicle.get("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.auction_fee,
            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 {
        user_id: item.get("user_id"),
        first_name: item.get("first_name"),
        last_name: item.get("last_name"),
        red_vehicles: redVehicles,
        yellow_vehicles: yellowVehicles,
        green_vehicles: greenVehicles,
      };
    });

    return res.json({
      status: 200,
      data: modifiedData,
    });
  } catch (error) {
    return res.json(error.message);
  }
};

/* const auctioneerTotalSaleAndNetProfit = 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.tblVehicle,
          raw: true,
          where: {
            createdAt: {
              [Op.between]: [weekRange.startDate, weekRange.endDate],
            },
          },
          include: [
            {
              model: tblVehicleRun,
              raw: true,
              where: {
                vehicle_id: col("tblVehicle.vehicle_id"),
              },
            },
          ],
        },
      ],
      where: {
        auctioneer_id: auctioneer_id,
      },
    });
    if (results.length === 0) {
      return res.json({
        status: 200,
        message: "Success",
        net_profit: 0,
        total_profit: 0,
        unit_sold: 0,
      });
    }
    const transformedData = results.reduce((result, vehicle) => {
      const existingUser = result.find(
        (user) => user.user_id === vehicle.user_id
      );

      if (existingUser) {
        // If user exists, update totals
        existingUser.total_profit += vehicle.tblVehicleRuns.reduce(
          (sum, run) => sum + run.sale_price,
          0
        );
        existingUser.net_profit += vehicle.tblVehicleRuns.reduce(
          (sum, run) => sum + run.net_profit,
          0
        );
        existingUser.sold_units += vehicle.tblVehicleRuns.length;
      } else {
        // If user doesn't exist, add a new user entry
        const newUser = {
          user_id: vehicle.user_id,
          total_profit: vehicle.tblVehicleRuns.reduce(
            (sum, run) => sum + run.sale_price,
            0
          ),
          net_profit: vehicle.tblVehicleRuns.reduce(
            (sum, run) => sum + run.net_profit,
            0
          ),
          sold_units: vehicle.tblVehicleRuns.length,
        };
        result.push(newUser);
      }

      return result;
    }, []);

    return res.json({
      status: 200,
      message: "Success",
      net_profit: transformedData[0]?.net_profit || 0,
      total_profit: transformedData[0]?.total_profit || 0,
      unit_sold: transformedData[0]?.sold_units || 0,
    });
  } catch (error) {
    return res.status(500).json({ status: 500, error: error.message });
  }
}; */

const auctioneerTotalSaleAndNetProfit = async (req, res) => {
  try {
    let { auctioneer_id } = req.body;
    // return res.json(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.tblVehicle,
          attributes: ["year", "make", "model", "mileage"],
          raw: true,
          where: {
            createdAt: {
              [Op.between]: [weekRange.startDate, weekRange.endDate],
            },
          },
          include: [
            {
              model: db.tblVehicleRun,
              attributes: [
                "sale_price",
                "auction_fee",
                "net_profit",
                "sale_status",
              ],
              raw: true,
            },
          ],
        },
      ],
      where: {
        auctioneer_id: auctioneer_id,
      },
    });
    // return res.json(results);
    if (results.length === 0) {
      return res.json({
        status: 200,
        message: "Success",
        net_profit: 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_profit: totalNetProfit,
      total_profit: totalSalePrice || 0,
      unit_sold: soldUnits || 0,
      // unit_sold: transformedData[0]?.sold_units || 0,
    });
    /* 
    return res.json({
      status: 200,
      message: "Success",
      net_profit: transformedData[0]?.net_profit || 0,
      total_profit: transformedData[0]?.total_profit || 0,
      unit_sold: transformedData[0]?.sold_units || 0,
    }); */
  } catch (error) {
    return res.status(500).json({ status: 500, error: error.message });
  }
};

module.exports = {
  auctioneerLogin,
  updateAuctioneerPassword,
  GetAuctioneerUsers,
  updateCarStatus,
  updateAuctioneerProfile,
  getAllCarsByAuctioneerId,
  sortAuctioneerVehicles,
  sortByConditionLight,
  sortBySaleStatus,
  GetVehicleCountBySaleStatus,
  GetVehicleCountByConditionLight,
  GetAuctioneerUsersOnly,
  getAllCarsByAuctioneerIdOnly,
  filterByAuctioneerAuctions,
  auctioneerTotalSaleAndNetProfit,
  getConditionLightVehicles,
  getSaleStatusVehicles,
};

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists