Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
16 kB
5
Indexable
Never
const mongoose = require('mongoose');
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 Client = require('../Models/clientModel.js');
const SalesMan = require('../Models/salesmanModel.js');
const Cart = require('../Models/cartModel.js');
const Order = require('../Models/orderModel.js');
const Retailer = require('../Models/retailerModel.js');
const Notification = require('../Models/notificationModel.js');
const Chat = require('../Models/chatModel.js');
const Message = require('../Models/messageModel.js');
const Email = require('./../utils/email');
const Socket = require('../socket/socketIndex.js');


async function getRandomSalesMan(province, retailer_id, next) {
  try {
    const salesmen = await SalesMan.find({ province: province });
    if (salesmen.length < 1) {
      return next(new AppError('no sales man available in your province', 400));
    }
    const salesmen_ids = salesmen.map((doc) => doc._id);
    const listchats = await Chat.find({ retailer: retailer_id, sales_man: { $in: salesmen_ids } });
    const verifier = (doc) => {
      for (let i = 0; i < listchats.length; i++) {
        if (doc._id.toString() == listchats[i].sales_man.toString()) {
          return false;
        }
      }
      return doc;
    };
    const results = salesmen.filter(verifier);
    console.log(salesmen)
    if (results.length < 1) {
      return next(new AppError('no anouther sales man available in your province', 400));
    }
    const random = Math.floor(Math.random() * results.length);
    const randomClient = results[random];

    return randomClient;
  } catch (error) {
    return next(new AppError('Error', 400));
  }
}


const sendEmailToSalesman = catchAsync(async (user,name) => {
  
  await new Email(user).sendNotificationToSalesMan(name);

});


exports.createNewChat = catchAsync(async (req, res, next) => {
  const { content, id } = req.body;

  if (!content) {
    return next(new AppError('message is require', 400));
  }
  if (!id) {
    return next(new AppError('user is require', 400));
  }
  const session = await mongoose.startSession();

  try {
    session.startTransaction();
    const user = await User.findOne({ _id: id });
    const retailer = await Retailer.findOne({ _id: user.profile });
    if(!retailer.sales_man){
      
    }
    const salesMan = await getRandomSalesMan(retailer.province, retailer._id, next);
    const chat = await Chat.find({ retailer: retailer._id, sales_man: salesMan._id });
    if (chat.length > 0) {
      const message = await Message.create([{ message: content, sender: retailer._id, receiver: salesMan._id }], {
        session
      });
      await Chat.updateOne({ _id: chat[0]._id }, { $push: { messages: message[0]._id } }, { session });
    } else {
      const newChat = await Chat.create([{ retailer: retailer._id, sales_man: salesMan._id }], { session });
      const message = await Message.create([{ message: content, sender: retailer._id, receiver: salesMan._id }], {
        session
      });
      await Chat.updateOne({ _id: newChat[0]._id }, { $push: { messages: message[0]._id } }, { session });
    }
    const users = await User.find({ profile:salesMan._id });
    const usersIds = [];
    for (let i = 0; i < users.length; i++) {
      const notification = await Notification.create([{ content: 'new conversation with '+user.name, type: 'chat' }], { session });
      await User.updateOne({ _id: users[i]._id }, { $push: { notifications: notification[0]._id } }, { session });
      usersIds.push({ id: users[i]._id.toString(), data: notification });
    }
    Socket.SocketConnectedList(usersIds);
    try{
      sendEmailToSalesman(users[0],user.name)
    }catch(error){
    }
    await session.commitTransaction();
    session.endSession();
    res.status(200).json({
      message: 'message successfully'
    });
  } catch (error) {
    await session.abortTransaction();
    session.endSession();
    return next(error);
  }
});

exports.getSalesManChat = catchAsync(async (req, res, next) => {
  const { id } = req.params;
  const retailer = await Retailer.findById(toObjectId(id, next));
  if (!retailer) {
    return next(new AppError('retailer not found', 400));
  }
  const results = await Chat.aggregate([
    { $match: { retailer: retailer._id } },
    {
      $lookup: {
        from: 'salesmen',
        localField: 'sales_man',
        foreignField: '_id',
        pipeline: [
          {
            $lookup: {
              from: 'users',
              localField: '_id',
              foreignField: 'profile',
              pipeline: [{ $project: { name: 1, photo: 1 } }],
              as: 'user'
            }
          }
        ],
        as: 'salesMan'
      }
    },
    {
      $lookup: {
        from: 'messages',
        localField: 'messages',
        foreignField: '_id',
        pipeline: [{ $match: { vu: false, receiver: retailer._id } }, { $count: 'messages_not_vu' }],
        as: 'messages'
      }
    }
  ]);
  const data = results.reduce((result, order) => {
    let obj = {};
    obj.salesMan_id = order.sales_man;
    obj.user_id = order.salesMan[0].user[0]?._id;
    obj.name = order.salesMan[0].user[0]?.name;
    obj.photo = order.salesMan[0].user[0]?.photo;
    obj.messages_not_vu = order.messages[0]?.messages_not_vu;
    result.push(obj);
    return result;
  }, []);
  res.status(200).json({
    message: 'successfully',
    data: data
  });
});


exports.getSalesManChatForRetailer = catchAsync(async (req, res, next) => {
  const { id } = req.params;
  const retailer = await Retailer.findById(toObjectId(id, next));
  if (!retailer) {
    return next(new AppError('retailer not found', 400));
  }
  const results = await Chat.aggregate([
    { $match: { retailer: retailer._id ,sales_man: retailer.sales_man} },
    {
      $lookup: {
        from: 'salesmen',
        localField: 'sales_man',
        foreignField: '_id',
        pipeline: [
          {
            $lookup: {
              from: 'users',
              localField: '_id',
              foreignField: 'profile',
              pipeline: [{ $project: { name: 1, photo: 1 } }],
              as: 'user'
            }
          }
        ],
        as: 'salesMan'
      }
    },
    {
      $lookup: {
        from: 'messages',
        localField: 'messages',
        foreignField: '_id',
        pipeline: [{ $match: { vu: false, receiver: retailer._id } }, { $count: 'messages_not_vu' }],
        as: 'messages'
      }
    }
  ]);
  const data = results.reduce((result, order) => {
    let obj = {};
    obj.salesMan_id = order.sales_man;
    obj.user_id = order.salesMan[0].user[0]?._id;
    obj.name = order.salesMan[0].user[0]?.name;
    obj.photo = order.salesMan[0].user[0]?.photo;
    obj.messages_not_vu = order.messages[0]?.messages_not_vu;
    result.push(obj);
    return result;
  }, []);
  res.status(200).json({
    message: 'successfully',
    data: data
  });
});


exports.getSalesMenList = catchAsync(async (req, res, next) => {
  const { id } = req.params;
  const retailer = await Retailer.findById(toObjectId(id, next));
  if (!retailer) {
    return next(new AppError('retailer not found', 400));
  }
  const salesmen = await SalesMan.aggregate([
    { $match: {province : retailer.province}},
    {
      $lookup: {
        from: 'users',
        localField: '_id',
        foreignField: 'profile',
        pipeline: [{ $project: { name: 1, photo: 1 } }],
        as: 'user'
      }
    }
  ])
  const data = salesmen.reduce((result, salesman) => {
    let obj = {};
    obj._id = salesman._id;
    obj.user_id = salesman.user[0]?._id;
    obj.name = salesman.user[0]?.name;
    obj.photo = salesman.user[0]?.photo;
    result.push(obj);
    return result;
  }, []);

  res.status(200).json({
    message: 'successfully',
    data: data
  });
});



exports.SetSalesmanToRetailer = catchAsync(async (req, res, next) => {
  const { salesMan_id,retailer_id } = req.body;
  if(!salesMan_id){
    return next(new AppError('salesman id is require', 400));
  }
  if(!retailer_id){
    return next(new AppError('retailer id is require', 400));
  }
  const retailer = await Retailer.findById(toObjectId(retailer_id, next));
  if (!retailer) {
    return next(new AppError('retailer not found', 400));
  }
  const sales_Man = await SalesMan.findById(toObjectId(salesMan_id, next));
  if (!sales_Man) {
    return next(new AppError('salesman not found', 400));
  }

  if(retailer.province == sales_Man.province){
    retailer.sales_man = toObjectId(salesMan_id, next)
  }else{
    return next(new AppError("salesman and salesman don't have the same province", 400));
  }
  await retailer.save()

  res.status(200).json({
    message: 'successfully',
    data: retailer
  });
});


exports.getRetailersChat = catchAsync(async (req, res, next) => {
  const { id } = req.params;
  const salesman = await SalesMan.findById(toObjectId(id, next));
  if (!salesman) {
    return next(new AppError('salesman not found', 400));
  }
  console.log(salesman);
  const results = await Chat.aggregate([
    { $match: { sales_man: salesman._id } },
    {
      $lookup: {
        from: 'retailers',
        localField: 'retailer',
        foreignField: '_id',
        pipeline: [
          {
            $lookup: {
              from: 'users',
              localField: '_id',
              foreignField: 'profile',
              pipeline: [{ $project: { name: 1, photo: 1 } }],
              as: 'user'
            }
          }
        ],
        as: 'Retailer'
      }
    },
    {
      $lookup: {
        from: 'messages',
        localField: 'messages',
        foreignField: '_id',
        pipeline: [{ $match: { vu: false, receiver: salesman._id } }, { $count: 'messages_not_vu' }],
        as: 'messages'
      }
    }
  ]);
  const data = results.reduce((result, order) => {
    let obj = {};
    obj.retailer_id = order.retailer;
    obj.user_id = order.Retailer[0].user[0]?._id;
    obj.name = order.Retailer[0].user[0]?.name;
    obj.photo = order.Retailer[0].user[0]?.photo;
    obj.messages_not_vu = order.messages[0]?.messages_not_vu;
    result.push(obj);
    return result;
  }, []);
  res.status(200).json({
    message: 'successfully',
    data: data
  });
});

exports.sendMessage = catchAsync(async (req, res, next) => {
  const { content, salesMan_id, retailer_id, sender } = req.body;
  if (!content) {
    return next(new AppError('message is require', 400));
  }
  if (!retailer_id) {
    return next(new AppError('retailer id is require', 400));
  }
  if (!salesMan_id) {
    return next(new AppError('salesMan id is require', 400));
  }
  if (sender != 'retailer' && sender != 'salesman') {
    return next(new AppError('sender is require', 400));
  }
  const session = await mongoose.startSession();

  try {
    session.startTransaction();
    const retailer = await Retailer.findById(toObjectId(retailer_id,next))
    if(!retailer){
      return next(new AppError('retailer not found', 400));
    }
    if(!retailer.sales_man){
      return next(new AppError('this retailer no have a salesman', 400));
    }
    const salesman = await SalesMan.findById(retailer.sales_man)
    if(!salesman){
      return next(new AppError('salesman not found', 400));
    }
    if(String(retailer.sales_man) != String(salesMan_id)){
      return next(new AppError("salesman can't chat with this retailer", 400));
    }

    const chat = await Chat.find({ retailer: toObjectId(retailer_id,next), sales_man: toObjectId(salesMan_id,next) });
    let message;
    if (sender == 'retailer') {
      message = await Message.create([{ message: content, sender: retailer_id, receiver: salesMan_id }], { session });
    } else {
      message = await Message.create([{ message: content, sender: salesMan_id, receiver: retailer_id }], { session });
    }
    if (chat.length < 1) {
      const newChat = await Chat.create([{ retailer: retailer._id, sales_man: retailer.sales_man }], { session });
      await Chat.updateOne({ _id: newChat[0]._id }, { $push: { messages: message[0]._id } }, { session });
    }else{
      await Chat.updateOne({ _id: chat[0]._id }, { $push: { messages: message[0]._id } }, { session });
    }
    await session.commitTransaction();
    session.endSession();
    res.status(200).json({
      message: 'message successfully'
    });
  } catch (error) {
    await session.abortTransaction();
    session.endSession();
    return next(error);
  }
});

exports.getMessagesChat = catchAsync(async (req, res, next) => {
  const { retailer_id, salesMan_id } = req.body;
  if (!salesMan_id) {
    return next(new AppError('salesman id is require', 400));
  }
  if (!retailer_id) {
    return next(new AppError('retailer id is require', 400));
  }
  const results = await Chat.aggregate([
    { $match: { sales_man: toObjectId(salesMan_id, next), retailer: toObjectId(retailer_id, next) } },
    {
      $lookup: {
        from: 'messages',
        localField: 'messages',
        foreignField: '_id',
        pipeline: [
          { $sort: { createdAt: -1 } },
          {
            $addFields: {
              senderRole: {
                $cond: [{ $eq: ['$sender', toObjectId(retailer_id,next)] }, 'retailer', 'salesman']
              }
            }
          },
          { $project: { vu: 1, senderRole: 1, createdAt: 1, message: 1 } }
        ],
        as: 'messages'
      }
    }
  ]);

  res.status(200).json({
    message: 'successfully',
    data: results[0]
  });
});

exports.setMessagesVue = catchAsync(async (req, res, next) => {
  const { chat_id, user_id, role } = req.body;
  const filter = {};
  if (!user_id) {
    return next(new AppError('id is require', 400));
  }
  // const user = await User.findById({ _id: toObjectId(user_id, next) });
  // if (!user) {
  //   return next(new AppError('user not found', 400));
  // }
  const chat = await Chat.findById({ _id: toObjectId(chat_id, next) });
  if (!chat) {
    return next(new AppError('user not found', 400));
  }
  if (role == 'retailer') {
    // console.log(user.profile);
    const retailer = await Retailer.findById({ _id: user_id });
    if (!retailer) {
      return next(new AppError('retailer not found', 400));
    }
    /* const results = await Chat.aggregate([
      { $match : {_id : chat._id}},
      {
          $lookup: {
            from: 'messages',
            localField: 'messages',
            foreignField: '_id',
            pipeline: [
              { $match : {receiver : toObjectId(retailer._id)}},
           //   { $set : {vu : true}}
            ],
            as: 'messages'
          }
      }  
     ]) */
    const results = await Message.updateMany({ _id: { $in: chat.messages }, receiver: retailer._id }, { vu: true });
    res.status(200).json({
      message: 'successfully',
      data: results
    });
  } else if (role == 'salesman') {
    const salesMan = await SalesMan.findById({ _id: user_id });
    if (!salesMan) {
      return next(new AppError('salesMan not found', 400));
    }
    const results = await Message.updateMany({ _id: { $in: chat.messages }, receiver: salesMan._id }, { vu: true });
    res.status(200).json({
      message: 'successfully',
      data: results
    });
  }
});

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