Untitled
unknown
javascript
2 years ago
14 kB
7
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