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"; 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; } const ListTicketsService = async ({ searchParam = "", pageNumber = "1", queueIds, status, date, showAll, userId, withUnreadMessages, unlimited = "false", searchParamContent = "" }: Request): Promise => { 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) { whereCondition = { ...whereCondition, status }; if (unlimited === "current" && 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(); 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); 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;