Untitled
unknown
javascript
2 years ago
14 kB
5
Indexable
import asyncHandler from "express-async-handler"; import User from "../models/userModule.js"; import mongoose from "mongoose"; import Item from "../models/itemModule.js"; import Relation from "../models/BoToCcaRelation.js"; import callCenterAgent from "../models/callCenterAgentModule.js"; import { getServiceTypes, isValidServiceType, updateItemCcaSplit, validateItemServiceTypes, } from "../services/util.js"; import Lead from "../models/leadModule.js"; import dailyRating from "../models/ccaRatingModule.js"; const getAgents = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const agregation = []; const page = req.query.page || 0; const elementsPerPage = 18; const performance = req.query.performance; const date = req.query.date; const rating = req.query.rating; let sortObj = { $sort: {}, }; let matchOBJ = { $match: { type: "CCA", status: "Active", }, }; agregation.push({ $lookup: { from: "callcenteragents", localField: "profile", foreignField: "_id", as: "ccaData", }, }); agregation.push({ $unwind: "$ccaData", }); if (typeof rating === "string") { let minVal = -1; let maxVal = -1; switch (rating) { case "1": minVal = 3; maxVal = 3.5; break; case "2": minVal = 3.5; maxVal = 4; break; case "3": minVal = 4; maxVal = 4.5; break; case "4": minVal = 4.5; maxVal = 5; break; } if (minVal !== -1 && maxVal !== -1) { matchOBJ.$match = { ...matchOBJ.$match, "ccaData.globalReview": { $gte: minVal, $lte: maxVal }, }; } } if (typeof performance === "string") { let minVal = 0; let maxVal = 0; switch (performance) { case "1": minVal = 40; maxVal = 60; break; case "2": minVal = 60; maxVal = 80; break; case "3": minVal = 80; maxVal = 100; break; } if (minVal !== 0 && maxVal !== 0) { matchOBJ.$match = { ...matchOBJ.$match, "ccaData.performance": { $gte: minVal, $lte: maxVal }, }; } } agregation.push(matchOBJ); const count = await User.countDocuments({ type: "CCA" }); if (typeof date === "string" && (date === "OLD" || date === "NEW")) { sortObj.$sort = { ...sortObj.$sort, creationDate: date === "OLD" ? 1 : -1 }; agregation.push(sortObj); } agregation.push({ $skip: page * elementsPerPage, }); agregation.push({ $limit: elementsPerPage, }); agregation.push({ $project: { ccaData: 1, avatar: 1, firstName: 1, lastName: 1, boCapacity: "$ccaData.boCapacity", }, }); const agents = await User.aggregate(agregation); for (let i = 0; i < agents.length; i++) { const ratings = await dailyRating.aggregate([ { $match: { ccaId: agents[i]._id, }, }, { $group: { _id: 1, performance: { $sum: "$performance" }, confermationRate: { $sum: "$confermationRate" }, goalAchivement: { $sum: "$goalAchivement" }, }, }, ]); if (ratings[0]) { agents[i].ccaData.performance = ratings[0].performance.toFixed(2); agents[i].ccaData.confermationRate = ratings[0].confermationRate.toFixed(2); agents[i].ccaData.goalAchivement = ratings[0].goalAchivement.toFixed(2); } } res.status(200).json({ count, agents: agents, }); }); const getAgentInfo = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const agentID = req.params.id; if (!agentID || typeof agentID !== "string") { res.status(400); throw new Error("invalid agentID type"); } const agent = await User.aggregate([ { $match: { _id: new mongoose.Types.ObjectId(agentID), }, }, { $lookup: { from: "callcenteragents", localField: "profile", foreignField: "_id", as: "ccaData", }, }, ]); const ratings = await dailyRating.aggregate([ { $match: { ccaId: agent[0]._id, }, }, { $group: { _id: 1, performance: { $sum: "$performance" }, confermationRate: { $sum: "$confermationRate" }, goalAchivement: { $sum: "$goalAchivement" }, }, }, ]); if (agent.lenght === 0) { res.status(404); throw new Error("CCA agent not found"); } if (ratings[0]) { agent[0].ccaData[0].performance = ratings[0].performance.toFixed(2); agent[0].ccaData[0].confermationRate = ratings[0].confermationRate.toFixed(2); agent[0].ccaData[0].goalAchivement = ratings[0].goalAchivement.toFixed(2); } res.status(200).json(agent); }); const sendrequest = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const { items, ccaId, serviceType } = req.body; if (!ccaId) { res.status(400); throw new Error("missing Call Center Agent id"); } if (items instanceof Array === false) { res.status(400); throw new Error("invalid request items"); } if (isValidServiceType(serviceType) === false) { res.status(400); throw new Error("invalid request serviceType"); } const boUser = await User.findById(req.user._id); const maxCcas = boUser.maxCCAs; const currentCcaCount = await Relation.countDocuments({ boId: req.user._id, status: "accepted", }); if (currentCcaCount >= maxCcas) { return res .status(400) .json({ message: "CCA limit reached. Cannot add more CCAs." }); } const ccaInfo = await User.aggregate([ { $match: { _id: new mongoose.Types.ObjectId(ccaId), }, }, { $lookup: { from: "callcenteragents", localField: "profile", foreignField: "_id", as: "ccaData", }, }, ]); const cca = ccaInfo[0]; if (!cca) { res.status(404); throw new Error("cca not found"); } if (cca.ccaData[0].boCapacity === "Full") { res.status(400); throw new Error("cca cant accept any more work"); } if (cca.ccaData[0].serviceType.length === 0) { res.status(400); throw new Error("cca has no service type yet"); } getServiceTypes(serviceType).forEach((type) => { if (cca.ccaData[0].serviceType.indexOf(type) === -1) { res.status(400); throw new Error("service type miss match"); } }); if ( (await validateItemServiceTypes(items, getServiceTypes(serviceType))) === false ) { res.status(400); throw new Error("item serviceType dose not match the selected serviceType"); } const request = await Relation.findOne({ ccaId, boId: req.user._id, }); if (request && request.status === "pending") { res.status(400); throw new Error("request sent already"); } else if (request && request.status === "accepted") { res.status(400); throw new Error("request already accepted"); // items.forEach((item) => { // if (request.items.indexOf(item) === -1) { // request.items.push(item); // } // }) // getServiceTypes(serviceType).forEach((type) => { // if (cca.ccaData[0].serviceType.indexOf(type) === -1) { // cca.ccaData[0].serviceType.push(type); // } // }) // await request.save(); // const ccaupdate = await callCenterAgent.replaceOne({ _id: cca.ccaData[0]._id }, cca.ccaData[0]); // res.status(200).json({ // message: 'relation updates', // }); // return; } else if (request && request.status === "canceled") { await Relation.deleteOne(request._id); } const dbItems = await Item.find({ _id: { $in: items } }); if (dbItems.length === 0) { res.status(404); throw new Error("No Items In The Database"); } const cca_bo_relation = await Relation.create({ boId: req.user._id, ccaId: cca._id, status: "pending", items, sentDate: new Date(), performance: 0, confermationRate: 0, goalAchivement: 0, serviceType: getServiceTypes(serviceType), review: 0, }); if (!cca_bo_relation) { res.status(500); throw new Error("SERVER IN MAINTENANCE"); } items.forEach(async (item) => { const leads = await Lead.find({ boID: req.user._id, status: "Pending", itemID: item._id, serviceType: cca.ccaData.serviceType, }); leads.forEach(async (lead) => { (lead.ccaID = ccaId), await Lead.updateOne({ _id: lead._id }, { $set: lead }); }); }); res.status(200).json(cca_bo_relation); }); const getRequests = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const page = req.query.page || 0; const elementsPerPage = 7; const count = await Relation.countDocuments({ boId: req.user._id }); if (count === 0) { res.status(200).json({ message: "no agents", }); return; } const requrstList = await Relation.aggregate([ { $match: { boId: req.user._id, }, }, { $lookup: { from: "users", localField: "ccaId", foreignField: "_id", as: "user", }, }, { $lookup: { from: "callcenteragents", localField: "user.profile", foreignField: "_id", as: "ccaData", }, }, { $sort: { sentDate: -1, // 1 ascending order }, }, { $skip: page * elementsPerPage, }, { $limit: elementsPerPage, }, ]); const ccas = []; for (let i = 0; i < requrstList.length; i++) { ccas.push({ user: requrstList[i].user, date: requrstList[i].sentDate.toString().split(" GMT")[0], performance: requrstList[i].performance.toFixed(2), confermationRate: requrstList[i].confermationRate.toFixed(2), goalAchivement: requrstList[i].goalAchivement.toFixed(2), review: requrstList[i].review, status: requrstList[i].status, avatar: requrstList[i].user[0].avatar ? requrstList[i].user[0].avatar : null, }); } res.status(200).json({ count, requrstList: ccas, }); }); const leaveReview = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const { starCount, ccaId } = req.body; if (!ccaId) { res.status(400); throw new Error("missing call center agent id"); } if (!starCount || typeof starCount !== "string") { res.status(400); throw new Error("missing star count"); } const count = Number(starCount).toFixed(1); if (Number.isNaN(count) || count < 0 || count > 5) { res.status(400); throw new Error("invalid star count"); } const relation = await Relation.findOne({ ccaId: ccaId, boId: req.user._id, }); // if (relation.review !== -1) { // res.status(400); // throw new Error("review already submited"); // } if (relation.status !== "accepted") { res.status(400); throw new Error("cant leave review"); } const users = await User.aggregate([ { $match: { _id: relation.ccaId, }, }, { $lookup: { from: "callcenteragents", localField: "profile", foreignField: "_id", as: "ccaData", }, }, ]); if (users.length === 0) { res.status(404); throw new Error("cca not found"); } const ccaData = users[0].ccaData[0]; relation.review = count; await relation.save(); ccaData.reviews.push(count); ccaData.totalReviews += count; ccaData.reviewCount++; ccaData.globalReview = Math.min( 5, Math.max(0, ccaData.totalReviews / ccaData.reviewCount) ); const ccaupdate = await callCenterAgent.replaceOne( { _id: ccaData._id }, ccaData ); if (ccaupdate.modifiedCount === 1) { res.status(200).json({ message: "review submitted successfully", }); } else { res.status(500); throw new Error("SERVER IN MAINTENANCE"); } }); const cancelRequest = asyncHandler(async (req, res) => { if (req.user.type === "CCA") { res.status(400); throw new Error("invalid user type"); } const ccaId = req.params.id; if (!ccaId) { res.status(400); throw new Error("missing cca id"); } const relation = await Relation.findOne({ boId: req.user._id, ccaId, }); for (let i = 0; i < relation.items.length; i++) { const item = await Item.findById(relation.items[i]); if (item?.ccaSplit && item.ccaSplit.length !== 0) { item.ccaSplit = updateItemCcaSplit(item.ccaSplit, ccaId); await item.save(); } } const deleteRelation = await Relation.deleteOne(relation._id); const leads = await Lead.find({ boID: req.user._id, ccaID: ccaId, }); if (deleteRelation.deletedCount === 1) { for (let i = 0; i < leads.length; i++) { leads[i].ccaID = null; const leadUpdate = await Lead.replaceOne({ _id: leads[i]._id }, leads[i]); } res.status(200).json({ message: "request deleted", }); } else { res.status(500); throw new Error("SERVER IN MAINTENANCE"); } }); export { getAgents, getAgentInfo, sendrequest, getRequests, leaveReview, cancelRequest, };
Editor is loading...
Leave a Comment