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

252 lines
5.7 KiB
TypeScript

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";
interface Request {
searchParam?: string;
pageNumber?: string;
status?: string;
date?: string;
showAll?: string;
userId: string;
withUnreadMessages?: string;
queueIds: number[];
unlimited?: string;
}
interface Response {
tickets: Ticket[];
count: number;
hasMore: boolean;
}
const ListTicketsService = async ({
searchParam = "",
pageNumber = "1",
queueIds,
status,
date,
showAll,
userId,
withUnreadMessages,
unlimited = 'false'
}: Request): Promise<Response> => {
let whereCondition: Filterable["where"] = { [Op.or]: [{ userId }, { status: "pending" }], queueId: { [Op.or]: [queueIds, null] } };
console.log('PAGE NUMBER TICKET: ', pageNumber)
//TEST DEL
// const url = await getWbot(46)
// console.log('---------> URL: ', url)
//
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) {
whereCondition = { ...whereCondition, status };
if (unlimited === 'true' && status !== 'pending') {
whereCondition = {
...whereCondition,
createdAt: {
[Op.gte]: dateToday.fullDate + ' 00:00:00.000000',
[Op.lte]: dateToday.fullDate + ' 23:59:59.999999'
}
}
}
}
if (searchParam) {
const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim();
// includeCondition = [
// ...includeCondition,
// {
// model: Message,
// as: "messages",
// attributes: ["id", "body"],
// where: {
// body: where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParam}%`)
// },
// required: false,
// duplicating: false
// }
// ];
includeCondition = [
...includeCondition,
{
model: Message,
as: "messages",
attributes: ["id", "body"],
where: {
body: where(fn("LOWER", col("body")), "LIKE", `%ADRIANO ROB%`)
},
required: false,
duplicating: false
}
];
whereCondition = {
...whereCondition,
[Op.or]: [
{
"$contact.name$": where(fn("LOWER", col("contact.name")), "LIKE", `%${sanitizedSearchParam}%`)
},
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } },
// {
// "$message.body$": where(fn("LOWER", col("body")), "LIKE", `%${sanitizedSearchParam}%`)
// }
],
"$message.body$": where(fn("LOWER", col("body")), "LIKE", `%ADRIANO ROB%`)
};
// whereCondition = {
// ...whereCondition,
// "$message.body$": where(
// fn("LOWER", col("body")),
// "LIKE",
// `%${sanitizedSearchParam}%`
// )
// };
}
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 }
};
}
const limit = unlimited === 'true' ? 100000 : 40;
const offset = limit * (+pageNumber - 1);
const { count, rows: tickets } = await Ticket.findAndCountAll({
where: whereCondition,
include: includeCondition,
distinct: true,
limit,
offset,
order: [["updatedAt", "DESC"]]
});
const hasMore = count > offset + tickets.length;
return {
tickets,
count,
hasMore
};
};
export default ListTicketsService;