Untitled

mail@pastecode.io avatar
unknown
plain_text
13 days ago
32 kB
1
Indexable
Never
const mongoose = require('mongoose');
const Fuse = require('fuse.js');
const User = require('../Models/userModel.js');
const SubCategory = require('../Models/subcategoryModel.js');
const Group = require('../Models/groupModel.js');
const Brand = require('../Models/brandModel.js');
const Category = require('../Models/categoryModel.js');
const Product = require('../Models/productModel.js');
const AppError = require('../utils/appError.js');
const catchAsync = require('../utils/catchAsync.js');
const { isDecimal } = require('validator');
const Client = require('../Models/clientModel.js');
const Cart = require('../Models/cartModel.js');
const { createAndSendToken } = require('./authController.js');
const Order = require('../Models/orderModel.js');
const { isValidEmail, isValidName, isValidPhoneNumber } = require('./../utils/validationfunctions.js');

const fuseOptions = {
  threshold: 0.3,
  keys: ['name.fr', 'name.en', 'categories.category', 'subcategories.subcategory', 'groups.group', 'brand.brand']
};
exports.productFilter = catchAsync(async (req, res, next) => {
  let { brands, subcategories, groups, id_category, pricing } = req.body;
  console.log('req.body :', req.body);
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  let arrayOR = new Array();
  let arrayAND = new Array();
  let obj = {};
  if (id_category) {
    const Id = toObjectId(id_category);
    let category = await Category.findById(Id);
    if (category) {
      arrayAND.push({ categories: Id });
    } else {
      return next(new AppError('invalid categorie value', 400));
    }
  } else {
    return next(new AppError('category required', 400));
  }

  if (subcategories) {
    const ids = await checkSubCategories(subcategories, id_category, next);
    if (ids.length > 0) {
      arrayOR.push({ subcategories: { $in: ids } });
    }
  }
  if (groups) {
    const ids = await checkGroups(groups, id_category, next);
    if (ids.length > 0) {
      arrayOR.push({ groups: { $in: ids } });
    }
  }
  if (brands) {
    const ids = await checkBrands(brands, next);
    if (ids.length > 0) {
      arrayOR.push({ brand: { $in: ids } });
    }
  }
  if (arrayOR.length) {
    arrayAND.push({ $or: arrayOR });
  }
  obj.$and = arrayAND;
  console.log(obj);

  if (pricing) {
    console.log(pricing);
    if (pricing != -1 && pricing != 1) {
      return next(new AppError('invalid pricing value ', 400));
    }
  }

  const paths = ['subcategories', 'categories', 'groups', 'brand'];
  const pathsAndFields = [
    { path: 'subcategories', select: 'subcategory' },
    { path: 'categories', select: 'category' },
    { path: 'groups', select: 'group' },
    { path: 'brand', select: 'brand' },
    { path: 'offer', select: ['discount','status'] }
  ];
  const count = await Product.find(obj).count();
  let countPages = count % limit == 0 ? parseInt(count / limit) : parseInt(count / limit) + 1;
  let products = [];
  if (pricing) {
    products = await Product.find(obj)
      .sort({ 'pricing.publicPrice': pricing })
      .populate(pathsAndFields)
      .skip((page - 1) * limit)
      .limit(limit);
  } else {
    products = await Product.find(obj)
      .populate(pathsAndFields)
      .skip((page - 1) * limit)
      .limit(limit);
  }

  if (products) {
    res.status(200).json({
      products,
      count
    });
  } else {
    return next(new AppError('this product no existe', 400));
  }
});

exports.getAllByCategory = catchAsync(async (req, res, next) => {
  let { id_category } = req.body;
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  let obj = {};

  if (id_category) {
    const Id = toObjectId(id_category);
    let category = await Category.findById(Id);
    if (category) {
      obj.categories = Id;
    } else {
      return next(new AppError('invalid category value', 400));
    }
  } else {
    return next(new AppError('category required', 400));
  }
  const subcategories = await SubCategory.find({ category: id_category });
  let groups = new Array();
  if (subcategories?.length > 0) {
    const ids = new Array();
    for (let i = 0; i < subcategories.length; i++) {
      ids.push(subcategories[i]._id);
    }
    groups = await Group.find({ subcategory: { $in: ids } });
  }

  const id_brands = await Product.distinct('brand', { categories: id_category });
  const brands = await Brand.find({ _id: { $in: id_brands } });

  const paths = ['subcategories', 'categories', 'groups', 'brand'];
  const pathsAndFields = [
    { path: 'subcategories', select: 'subcategory' },
    { path: 'categories', select: 'category' },
    { path: 'groups', select: 'group' },
    { path: 'brand', select: 'brand' }
  ];
  const count = await Product.find(obj).count();
  let countPages = count % limit == 0 ? parseInt(count / limit) : parseInt(count / limit) + 1;
  let products = [];

  products = await Product.find(obj)
    .populate(pathsAndFields)
    .skip((page - 1) * limit)
    .limit(limit);

  if (products) {
    res.status(200).json({
      products,
      subcategories,
      groups,
      count,
      brands
    });
  } else {
    return next(new AppError('this product no existe', 400));
  }
});

exports.searchGlobal = catchAsync(async (req, res, next) => {
  const { filter } = req.query;
  let { page, limit } = req.query;

  if (!filter) {
    return next(new AppError('filter is required', 400));
  }
  page = page ? parseInt(page, 10) : 1;
  limit = limit ? parseInt(limit, 10) : 10;

  const skip = (page - 1) * limit;

  const results = await Product.aggregate([
    {
      $lookup: {
        from: 'categories',
        localField: 'categories',
        foreignField: '_id',
        as: 'categories'
      }
    },
    {
      $lookup: {
        from: 'subcategories',
        localField: 'subcategories',
        foreignField: '_id',
        as: 'subcategories'
      }
    },
    {
      $lookup: {
        from: 'groups',
        localField: 'groups',
        foreignField: '_id',
        as: 'groups'
      }
    },
    {
      $lookup: {
        from: 'brands',
        localField: 'brand',
        foreignField: '_id',
        as: 'brand'
      }
    },
    {
      $lookup: {
        from: 'offers',
        localField: 'offer',
        foreignField: '_id',
        pipeline:[ {$project : {discount : 1,status:1}}],
        as: 'offer'
      }
    }
  ]);
  const array = new Array();
  for (let i = 0; i < results.length; i++) {
    array[i] = {
      name: {
        fr: results[i]?.name.fr,
        en: results[i]?.name.en
      },
      categories: [],
      subcategories: [],
      groups: [],
      brand: []
    };
    for (let j = 0; j < results[i]?.categories.length; j++) {
      if (results[i]?.categories[j].category) {
        array[i].categories.push({ category: results[i]?.categories[j].category });
      }
    }
    for (let j = 0; j < results[i]?.subcategories.length; j++) {
      array[i].subcategories[j] = { subcategory: results[i]?.subcategories[j].subcategory };
    }
    for (let j = 0; j < results[i]?.groups.length; j++) {
      array[i].groups[j] = { group: results[i]?.groups[j].group };
    }
    for (let j = 0; j < results[i]?.brand.length; j++) {
      array[i].brand[j] = { brand: results[i]?.brand[j].brand };
    }
  }
  const fuse = new Fuse(array, fuseOptions);

  const lists = fuse.search(filter);
  let indexs = new Array();
  for (const list of lists) {
    indexs.push(list.refIndex);
  }

  let ProductsList = indexs.map(function (item) {
    return results[item];
  });
  let products = ProductsList.slice((page - 1) * limit, page * limit);
  res.status(200).json({
    products,
    count: products.length
  });
});

const checkSubCategories = async (subcategories, id_category, next) => {
  let ids = new Array();
  if (subcategories.length > 0) {
    for (const subcategory of subcategories) {
      if (!subcategory) {
        return next(new AppError('id is required', 400));
      }
      let id = toObjectId(subcategory, next);
      const existingSubCategory = await SubCategory.find({ _id: id, category: id_category });
      ids.push(id);
      if (existingSubCategory?.length < 1) {
        return next(new AppError('SubCategory not found in this category', 400));
      }
    }
  }
  return ids;
};

const checkGroups = async (groups, id_category, next) => {
  let ids = new Array();
  if (groups.length > 0) {
    for (const group of groups) {
      if (!group) {
        return next(new AppError('id is required', 400));
      }
      let id = toObjectId(group, next);
      const subcategories = await SubCategory.find({ category: id_category });

      if (subcategories?.length > 0) {
        const ids_subcat = new Array();
        for (let i = 0; i < subcategories.length; i++) {
          ids_subcat.push(subcategories[i]._id);
        }
        const existingGroup = await Group.find({ _id: id, subcategory: { $in: ids_subcat } });
        ids.push(id);
        if (existingGroup?.length < 1) {
          return next(new AppError('group not found in this category', 400));
        }
      }
    }
  }
  return ids;
};

const checkBrands = async (brands, next) => {
  let ids = new Array();
  if (brands.length > 0) {
    for (const brand of brands) {
      if (!brand) {
        return next(new AppError('id is required', 400));
      }
      let id = toObjectId(brand, next);
      const existingBrand = await Brand.findById(id);
      ids.push(id);
      if (!existingBrand) {
        return next(new AppError('Brand not found', 400));
      }
    }
  }
  return ids;
};

const toObjectId = (id, next) => {
  try {
    return new mongoose.Types.ObjectId(id);
  } catch (e) {
    return next(new AppError('Invalid id.', 401));
  }
};

exports.AddToCart = catchAsync(async (req, res, next) => {
  // Extracting necessary information from the request body
  const { productQuantities, userId } = req.body;

  // Find the user by ID and populate the profile
  const user = await User.findById(userId);

  if (!user) {
    return next(new AppError('User not found', 400));
  }

  // Extract the client profile from the user
  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client profile not found', 400));
  }

  // Get the user's cart from the profile
  let cart = client.cart;

  // If the user doesn't have a cart, create a new one
  if (!cart) {
    newCart = await Cart.create({ products: [] });
    client.cart = newCart._id;
    await client.save();
    cart = newCart._id;
  }
  console.log(cart);
  // Find the user's cart and populate products
  if (!Array.isArray(productQuantities)) {
    return next(new AppError('Products is not an array', 400));
  }
  const userCart = await Cart.findById(cart).populate('products.product');

  // Check if the product exists
  for (const { productId, quantity } of productQuantities) {
    // Check if the product exists
    const product = await Product.findById(toObjectId(productId));
    if (!product) {
      return next(new AppError(`Product with ID ${productId} not found`, 404));
    }
    console.log(userCart);
    if (userCart && userCart.products) {
      // Check if the product is already in the cart
      const existingProductIndex = userCart.products.findIndex(
        (item) => item.product && item.product.equals(productId)
      );
      const product = await Product.findById(productId);
      if (existingProductIndex !== -1) {
        // If the product is already in the cart, update the quantity
        userCart.products[existingProductIndex].quantity += parseInt(quantity);
        userCart.products[existingProductIndex].price =
          product.pricing.publicPrice * parseInt(userCart.products[existingProductIndex].quantity);
        if (userCart.products[existingProductIndex].quantity > product.quantity) {
          return next(new AppError(`Requested quantity of Product ${product.sku} exceeds available stock`, 400));
        }
      } else {
        // Otherwise, add the product to the cart with the specified quantity
        userCart.products.push({
          product: productId,
          quantity: quantity,
          price: parseInt(product.pricing.publicPrice) * parseInt(quantity)
        });

        // Update the total price of the cart
        userCart.totalPrice = userCart.products.reduce((total, item) => total + item.price, 0);
      }
    } else {
      // Handle the case where userCart or userCart.products is null or undefined
      return next(new AppError('Error: userCart or userCart.products is null or undefined', 400));
    }
  }
  await userCart.save();

  res.status(200).json({ message: 'Product added to cart successfully', cart: userCart });

  // Save the changes to the user's cart

  // Return success response with updated cart details
});

exports.getWishList = catchAsync(async (req, res, next) => {
  const { userId } = req.body;
  console.log(userId);
  const client = await User.aggregate([
    {
      $match: { _id: toObjectId(userId) }
    },
    {
      $lookup: {
        from: 'clients',
        localField: 'profile',
        foreignField: '_id',
        as: 'client',
        pipeline: [
          {
            $lookup: {
              from: 'products',
              localField: 'wishlist',
              foreignField: '_id',
              pipeline: [{
                $lookup: {
                  from: 'offers',
                  localField: 'offer',
                  foreignField: '_id',
                  pipeline: [{$project:{discount:1,status:1}}],
                  as: 'offer'
                }
              }],
              as: 'wishlist'
            }
          }
        ]
      }
    }
  ]);
  if(!client.length){
    return next(new AppError('user not find', 400));
  }
  res.status(200).json({ message: 'wishlist', wishlist: client[0]?.client[0]?.wishlist });
});

exports.RemoveFromCart = catchAsync(async (req, res, next) => {
  // Extract necessary information from the request body
  const { productId, userId } = req.body;

  // Find the user by ID
  const user = await User.findById(userId);

  if (!user) {
    return next(new AppError('User not found', 404));
  }

  // Extract the client profile from the user
  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client profile not found', 404));
  }

  // Get the user's cart from the profile
  const cart = client.cart;

  if (!cart) {
    return next(new AppError('Cart not found', 404));
  }

  // Find the user's cart and populate products
  const userCart = await Cart.findById(cart).populate('products.product');

  // Check if userCart is not null or undefined
  if (userCart && userCart.products) {
    // Find the index of the product to remove
    const indexToRemove = userCart.products.findIndex((item) => item.product && item.product.equals(productId));

    if (indexToRemove !== -1) {
      // Remove the product from the cart
      userCart.products.splice(indexToRemove, 1);
      // Save the changes to the user's cart
      await userCart.save();

      // Return success response
      return res.status(200).json({ message: 'Product removed from cart successfully', cart: userCart.products });
    } else {
      // Product not found in the cart
      return next(new AppError('Product not found in the cart', 404));
    }
  } else {
    // Handle the case where userCart or userCart.products is null or undefined
    console.error('Error: userCart or userCart.products is null or undefined');
    return next(new AppError('Error processing request', 500));
  }
});


exports.decrementQuantity = catchAsync(async (req, res, next) => {
  // Extract necessary information from the request body
  const { productId, userId } = req.body;

  // Find the user by ID
  const user = await User.findById(userId);

  if (!user) {
    return next(new AppError('User not found', 404));
  }

  // Extract the client profile from the user
  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client profile not found', 404));
  }

  // Get the user's cart from the profile
  const cart = client.cart;

  if (!cart) {
    return next(new AppError('Cart not found', 404));
  }

  // Find the user's cart and populate products
  const userCart = await Cart.findById(cart).populate('products.product');

  // Check if userCart is not null or undefined
  if (userCart && userCart.products) {
    // Find the index of the product to update
    const indexToUpdate = userCart.products.findIndex((item) => item.product && item.product.equals(productId));

    if (indexToUpdate !== -1) {
      // Decrement the quantity of the product
      userCart.products[indexToUpdate].quantity--;

      // If the quantity becomes zero, remove the product from the cart
      if (userCart.products[indexToUpdate].quantity === 0) {
        userCart.products.splice(indexToUpdate, 1);
      }

      // Update the price of the product
      const product = userCart.products[indexToUpdate].product;
      userCart.products[indexToUpdate].price = product.pricing.publicPrice * userCart.products[indexToUpdate].quantity;

      // Update the total price of the cart
      userCart.totalPrice = userCart.products.reduce((total, item) => total + item.price, 0);

      // Save the changes to the user's cart
      await userCart.save();

      // Return success response
      return res.status(200).json({ message: 'Product quantity decremented successfully', cart: userCart.products });
    } else {
      // Product not found in the cart
      return next(new AppError('Product not found in the cart', 404));
    }
  } else {
    // Handle the case where userCart or userCart.products is null or undefined
    console.error('Error: userCart or userCart.products is null or undefined');
    return next(new AppError('Error processing request', 500));
  }
});

exports.incrementQuantity = catchAsync(async (req, res, next) => {
  // Extract necessary information from the request body
  const { productId, userId } = req.body;

  // Find the user by ID
  const user = await User.findById(userId);

  if (!user) {
    return next(new AppError('User not found', 404));
  }

  // Extract the client profile from the user
  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client profile not found', 404));
  }

  // Get the user's cart from the profile
  const cart = client.cart;

  if (!cart) {
    return next(new AppError('Cart not found', 404));
  }

  // Find the user's cart and populate products
  const userCart = await Cart.findById(cart).populate('products.product');

  // Check if userCart is not null or undefined
  if (userCart && userCart.products) {
    // Find the index of the product to update
    const indexToUpdate = userCart.products.findIndex((item) => item.product && item.product.equals(productId));

    if (indexToUpdate !== -1) {
      // Increment the quantity of the product
      userCart.products[indexToUpdate].quantity++;

      // Update the price of the product
      const product = userCart.products[indexToUpdate].product;
      userCart.products[indexToUpdate].price = product.pricing.publicPrice * userCart.products[indexToUpdate].quantity;

      // Update the total price of the cart
      userCart.totalPrice = userCart.products.reduce((total, item) => total + item.price, 0);

      // Save the changes to the user's cart
      await userCart.save();
    }
  } else {
    // Handle the case where userCart or userCart.products is null or undefined
    console.error('Error: userCart or userCart.products is null or undefined');
    return next(new AppError('Error processing request', 500));
  }
});

exports.AddToWishlist = catchAsync(async (req, res, next) => {
  // Extract necessary information from the request body
  const { userID, productID } = req.body;

  // Find the user by ID and check if the client profile and wishlist exist
  const user = await User.findById(userID);
  if (!user) {
    return next(new AppError('User not found', 404));
  }

  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client not found', 404));
  }

  // Check if the product exists and is available for wishlisting
  const product = await Product.findById(productID);
  if (!product) {
    return next(new AppError(`Product with ID ${productID} not found`, 404));
  }

  // Check if the product already exists in the client's wishlist
  const productExistsInWishlist = await Client.findOne({ _id: user.profile, wishlist: { $in: [productID] } });
  if (productExistsInWishlist) {
    return res.status(400).json({ message: 'Product already exists in the wishlist' });
  }

  // Add the product to the wishlist
  client.wishlist.push(product);
  await client.save();

  // Return success response
  res.status(200).json({ message: 'Product added to wishlist successfully', wishlist: client.wishlist });
});

exports.RemoveFromWishlist = catchAsync(async (req, res, next) => {
  // Extract necessary information from the request body
  const { userID, productID } = req.body;

  // Find the user by ID and check if the client profile and wishlist exist
  const user = await User.findById(userID);
  if (!user) {
    return next(new AppError('User not found', 404));
  }

  const client = await Client.findById(user.profile);
  if (!client) {
    return next(new AppError('Client not found', 404));
  }

  // Check if the product exists in the client's wishlist
  if (!client.wishlist.includes(productID)) {
    return res.status(400).json({ message: 'Product does not exist in the wishlist' });
  }

  // Remove the product from the client's wishlist using $pull
  await Client.findByIdAndUpdate(client._id, { $pull: { wishlist: productID } });

  // Return success response
  res.status(200).json({ message: 'Product removed from wishlist successfully' });
});

exports.getProductDetails = catchAsync(async (req, res, next) => {
  // Get product details
  const productId = req.params.productId;
  const product = await Product.findById(productId);

  if (!product) {
    return next(new AppError('Product not found', 404));
  }

  // Check if the product is already in the user's cart
  let isInCart = false;
  if (req.user) {
    const user = await User.findById(req.user.id);
    const client = await Client.findById(user.profile);
    const cart = await Cart.findById(client.cart).populate('products.product');
    isInCart = cart.products.some((item) => item.product.equals(productId));
  }

  // Find related products (either in category, subcategories, or groups)
  const relatedProducts = await Product.find({
    $or: [
      { categories: { $in: product.categories } },
      { subcategories: { $in: product.subcategories } },
      { groups: { $in: product.groups } }
    ]
  }).populate({ path: 'offer', select: ['discount','status'] })
    .limit(10); // Limit to 10 related products

  // Get the number of products sold in the last 7 days
  const startDate = new Date();
  startDate.setDate(startDate.getDate() - 7); // Calculate the date 7 days ago
  const endDate = new Date();
  const productsSoldLast7Days = await Order.aggregate([
    {
      $match: {
        createdAt: { $gte: startDate, $lte: endDate },
        'products.product': mongoose.Types.ObjectId(productId)
      }
    },
    {
      $group: {
        _id: null,
        totalSold: { $sum: '$products.quantity' }
      }
    }
  ]);

  const soldLast7Days = productsSoldLast7Days.length > 0 ? productsSoldLast7Days[0].totalSold : 0;

  res.status(200).json({ product, isInCart, relatedProducts, soldLast7Days });
});

exports.checkout = async (req, res, next) => {
  try {
    // Get the user's cart
    const cart = await Cart.findOne({ user: req.user.id }).populate('products.product');
    if (!cart) {
      return res.status(404).json({ message: 'Cart not found' });
    }

    // Create order
    const order = new Order({
      user: req.user.id,
      products: cart.products.map((item) => ({
        product: item.product,
        quantity: item.quantity
      })),
      shipping: {
        method: req.body.shippingMethod, // Assuming the shipping method is passed in the request body
        cost: req.body.shippingCost // Assuming the shipping cost is passed in the request body
      },
      status: 'pending' // Set the initial status of the order
    });

    // Calculate total price of the order
    order.totalPrice = cart.products.reduce((total, item) => total + item.price, 0) + order.shipping.cost;

    // Save the order
    await order.save();

    // Clear user's cart after checkout
    cart.products = [];
    cart.totalPrice = 0;
    await cart.save();

    // Return success response
    res.status(200).json({ message: 'Order placed successfully', order });
  } catch (error) {
    next(error);
  }
};
exports.viewProduct = catchAsync(async (req, res, next) => {
  const productId = toObjectId(req.query.id);
  const pathsAndFields = [
    { path: 'subcategories', select: 'subcategory' },
    { path: 'categories', select: 'category' },
    { path: 'groups', select: 'group' },
    { path: 'brand', select: 'brand' },
    { path: 'offer', select: ['discount','status'] },
  ];

  const product = await Product.findById(productId).populate({ path: 'offer', select: ['discount','status'] });

  if (!product) {
    return next(new AppError('Product not found', 400));
  }

  const solds = await Order.aggregate([
    {
      $match: { 'products.product': productId }
    },
    {
      $unwind: '$products'
    },
    {
      $match: { 'products.product': productId }
    },
    {
      $group: {
        _id: null,
        totalQuantity: { $sum: '$products.quantity' }
      }
    }
  ]);
  const relatedProducts = await RelatedProducts(productId, next);
  res.status(200).json({
    message: 'Product fetched successfully',
    product: product,
    relatedProducts: relatedProducts,
    sold: solds[0]?.totalQuantity ? solds[0].totalQuantity : 0
  });
});
const RelatedProducts = async (id, next) => {
  let list = new Array();
  let ids_list = new Set();
  ids_list.add(id.toString());
  let prod = await Product.findById(id);
  if (prod.groups.length > 0) {
    list.push(
      ...(await Product.find({
        groups: { $in: prod.groups },
        _id: { $nin: Array.from(ids_list).map((id) => toObjectId(id)) }
      }).populate({ path: 'offer', select: ['discount','status'] })
      .limit(10))
    );
    for (const product of list) {
      ids_list.add(product._id.toString());
    }
  }
  if (list.length < 10) {
    if (prod.subcategories.length > 0) {
      list.push(
        ...(await Product.find({
          subcategories: { $in: prod.subcategories },
          _id: { $nin: Array.from(ids_list).map((id) => toObjectId(id)) }
        }).populate({ path: 'offer', select: ['discount','status'] })
        .limit(10 - list.length))
      );
    }
    for (const product of list) {
      ids_list.add(product._id.toString());
    }
  }
  if (list.length < 10) {
    if (prod.categories.length > 0) {
      list.push(
        ...(await Product.find({
          categories: { $in: prod.categories },
          _id: { $nin: Array.from(ids_list).map((id) => toObjectId(id)) }
        }).populate({ path: 'offer', select: ['discount','status'] })
        .limit(10 - list.length))
      );
    }
    for (const product of list) {
      ids_list.add(product._id.toString());
    }
  }
  return list;
};

exports.updateClientProfile = catchAsync(async (req, res, next) => {
  console.log(req.user);
  const user = await User.findById(req.user.id); // Assuming req.user.id contains the ObjectId of the user

  if (!user) {
    return next(new AppError('User not found', 404));
  }

  console.log(req.body);

  const { firstName, lastName, email, phone, address, gender } = req.body;

  if (firstName || lastName) {
    const fullName = [firstName, lastName].filter(Boolean).join(' ');
    user.name = fullName;
  }
  if (email) {
    user.email = email;
  }
  if (phone) {
    user.phone = phone;
  }
  // Update address if provided
  if (address) {
    user.fulladdress.address = address?.address;
    user.fulladdress.zipCode = address?.zipCode;
    user.fulladdress.city = address?.city;
  }

  if (gender) {
    user.gender = gender;
  }
  await user.save();
  res.status(200).json({
    status: ' the client profile is updated successfully',
    data: user
  });
});


exports.getClients = catchAsync(async (req, res, next) => {
  const {phone} = req.query;
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  console.log(page +" "+limit)
  let search = {role : "client"}
  if(phone){ 
    search.phone = { $regex: phone , $options: 'i' }
  }

  const count = await User.find(search).count();
  console.log(count);
  let clients = null
  let countPages = count % limit == 0 ? parseInt(count / limit) : parseInt(count / limit) + 1;
 // if(count > 10){
    clients = await User.find(search)
    .skip((page - 1) * limit)
    .limit(limit);
 /* }else{
     clients = await User.find(search)
  } */
  
  const data = clients.reduce((result, client) => {
  
      let obj = {};
      obj._id = client._id;
      obj.name = client.name;
      obj.joiningDate = client.createdAt;
      obj.email = client.email;
      obj.phone = client.phone;
      obj.profileImage = client.photo;
      result.push(obj);
  
    return result;
  }, []);

  res.status(200).json({
    status: "success",
    data: data,
    count : count
  });
  
})


exports.deleteClient = catchAsync(async (req, res, next) => {
  const clientId = req.params.id;

  if (!clientId) {
    return next(new AppError('Please provide the client ID', 400));
  }

  // Start a Mongoose session
  const session = await mongoose.startSession();

  try {
    // Use the session for transaction
    await session.withTransaction(async () => {
      // 1. Get the user document
      const user = await User.findById(clientId).session(session);

      // 2. Check if the user exists
      if (!user) {
        return next(new AppError('client not found', 404));
      }

      // 3. Determine the type of profile based on the user's role
      if (user.role !== 'client') {
        return next(new AppError('Invalid role', 400));
      }

      // 4. Delete the client's profile document
      await Client.findByIdAndDelete(user.profile).session(session);

      // Additional Step: Delete the image document if it exists
      if (user.photo) {
        await Image.findByIdAndDelete(user.photo).session(session);
      }

      // 6. Delete the user document
      await User.findByIdAndDelete(clientId).session(session);
    });

    // Commit the session if everything went well
    await session.commitTransaction();

    // Respond with a success message
    res.status(200).json({
      status: 'success',
      message: 'Client deleted successfully'
    });
  } catch (err) {
    // If any error occurs, abort the session
    await session.abortTransaction();
    // Pass the error to the error handling middleware
    next(err);
  } 
  finally {
    session.endSession();
  } 
});
Leave a Comment