projeto-hit/backend/src/services/TicketServices/ListTicketsService.ts

257 lines
6.3 KiB
TypeScript
Raw Normal View History

import { Op, fn, where, col, Filterable, Includeable } from "sequelize";
import { startOfDay, endOfDay, parseISO, format } from "date-fns";
import ptBR from "date-fns/locale/pt-BR";
import Ticket from "../../models/Ticket";
import Contact from "../../models/Contact";
import Message from "../../models/Message";
import Queue from "../../models/Queue";
import ShowUserService from "../UserServices/ShowUserService";
const unflatten = require("flat").unflatten;
import { splitDateTime } from "../../helpers/SplitDateTime";
const dateToday = splitDateTime(
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
);
import ListTicketServiceCache from "./ListTicketServiceCache";
import { searchTicketCache, loadTicketsCache } from "../../helpers/TicketCache";
import { getWbot } from "../../libs/wbot";
import User from "../../models/User";
import { get } from "../../helpers/RedisClient";
interface Request {
searchParam?: string;
pageNumber?: string;
status?: string;
date?: string;
showAll?: string;
userId: string;
withUnreadMessages?: string;
queueIds: number[];
unlimited?: string;
searchParamContent?: string;
}
interface Response {
tickets: Ticket[];
count: number;
hasMore: boolean;
remoteTicketsControll?: object[];
}
const ListTicketsService = async ({
searchParam = "",
pageNumber = "1",
queueIds,
status,
date,
showAll,
userId,
withUnreadMessages,
unlimited = "false",
searchParamContent = ""
}: Request): Promise<Response> => {
console.log("----------> searchParamContent: ", searchParamContent);
let whereCondition: Filterable["where"] = {
[Op.or]: [{ userId }, { status: "pending" }],
queueId: { [Op.or]: [queueIds, null] }
};
console.log("PAGE NUMBER TICKET: ", pageNumber);
if (pageNumber.trim().length == 0) {
pageNumber = "1";
}
if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
try {
const offset = 40 * (+pageNumber - 1);
searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
console.log("QUERY TICKET SEARCH PARAM FROM CACHE: ", searchParam);
let tickets: any = await searchTicketCache(searchParam, offset, 40);
if (tickets) {
console.log(
"QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ",
tickets.length
);
tickets.map((t: any) => {
t["contact.number"] = t["contact_number"];
delete t["contact_number"];
return { ...["contact_number"] };
});
tickets = tickets.map((e: any) => unflatten(e));
return {
tickets,
count: tickets.length,
hasMore: tickets.length > 0 ? true : false
};
}
} catch (error) {
console.log(
"There was an error on search ListTicketservice.ts search cache: ",
error
);
}
console.log("QUERY TICKETS FROM DATABASE...");
}
let includeCondition: Includeable[];
includeCondition = [
{
model: Contact,
as: "contact",
attributes: ["id", "name", "number", "profilePicUrl"]
},
{
model: Queue,
as: "queue",
attributes: ["id", "name", "color"]
}
];
if (showAll === "true") {
whereCondition = { queueId: { [Op.or]: [queueIds, null] } };
}
if (status) {
2022-07-28 21:21:14 +00:00
whereCondition = { ...whereCondition, status };
if (unlimited === "current" && status !== "pending") {
2022-07-28 21:21:14 +00:00
whereCondition = {
...whereCondition,
createdAt: {
[Op.gte]: dateToday.fullDate + " 00:00:00.000000",
[Op.lte]: dateToday.fullDate + " 23:59:59.999999"
2022-07-28 21:21:14 +00:00
}
};
2022-07-28 21:21:14 +00:00
}
}
if (searchParam) {
const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim();
const sanitizedSearchParamContent = searchParamContent
.toLocaleLowerCase()
.trim();
if (searchParamContent.length > 0) {
includeCondition = [
...includeCondition,
{
model: Message,
as: "messages",
attributes: ["id", "body"],
where: {
body: where(
fn("LOWER", col("body")),
"LIKE",
`%${sanitizedSearchParamContent}%`
)
},
required: false,
duplicating: false
}
];
whereCondition = {
...whereCondition,
"$message.body$": where(
fn("LOWER", col("body")),
"LIKE",
`%${sanitizedSearchParamContent}%`
)
};
}
whereCondition = {
...whereCondition,
[Op.or]: [
{
"$contact.name$": where(
fn("LOWER", col("contact.name")),
"LIKE",
`%${sanitizedSearchParam}%`
)
},
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }
]
};
const userProfile: any = await User.findByPk(userId);
if (
userProfile.dataValues.profile != "admin" &&
userProfile.dataValues.profile != "master" &&
userProfile.dataValues.profile != "supervisor"
) {
whereCondition = { ...whereCondition, userId };
}
}
if (date) {
whereCondition = {
createdAt: {
[Op.between]: [+startOfDay(parseISO(date)), +endOfDay(parseISO(date))]
}
};
}
if (withUnreadMessages === "true") {
const user = await ShowUserService(userId);
const userQueueIds = user.queues.map(queue => queue.id);
whereCondition = {
[Op.or]: [{ userId }, { status: "pending" }],
queueId: { [Op.or]: [userQueueIds, null] },
unreadMessages: { [Op.gt]: 0 }
};
}
let limit;
if (unlimited === "current") limit = 10000;
else if (unlimited === "all") limit = 100;
else limit = 40;
// const limit = unlimited === "current" || unlimited === "all" ? 1000 : 40;
const offset = limit * (+pageNumber - 1);
console.log("kkkkkkkkk limit: ", limit);
let { count, rows: tickets } = await Ticket.findAndCountAll({
where: whereCondition,
include: includeCondition,
distinct: true,
2022-07-28 21:21:14 +00:00
limit,
offset,
order: [["updatedAt", "DESC"]]
});
const hasMore = count > offset + tickets.length;
const ticketIds = await get({ key: `remote:controll`, parse: true });
return {
tickets,
count,
hasMore,
remoteTicketsControll: ticketIds ? ticketIds : []
};
};
export default ListTicketsService;