Merge remote-tracking branch 'origin/dual_session_test' into dialogflow
						commit
						4c510ed75b
					
				|  | @ -1,7 +1,11 @@ | ||||||
| import path from "path"; | import path from "path"; | ||||||
| import multer from "multer"; | import multer from "multer"; | ||||||
| 
 | 
 | ||||||
| const publicFolder = path.resolve(__dirname, "..", "..", "public"); | // const publicFolder = path.resolve(__dirname, "..", "..", "public");
 | ||||||
|  | const publicFolder = path.resolve(__dirname, "..", "..","..","..", "public"); | ||||||
|  | 
 | ||||||
|  | console.log('publicFolder: ',publicFolder) | ||||||
|  | 
 | ||||||
| export default { | export default { | ||||||
|   directory: publicFolder, |   directory: publicFolder, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,15 +4,8 @@ import { getIO } from "../libs/socket"; | ||||||
| import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService"; | import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService"; | ||||||
| import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService"; | import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService"; | ||||||
| import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService"; | import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService"; | ||||||
| 
 | import ShowSchedulingNotifyService from "../services/SchedulingNotifyServices/ShowSchedulingNotifyService";  | ||||||
| // const test = await ListSchedulingNotifyContactService('5517988310949','2022-03-18','2022-03-19'); 
 | import { deleteScheduleByTicketIdCache } from "../helpers/SchedulingNotifyCache"; | ||||||
| // const test = await ListSchedulingNotifyContactService('','2022-03-18','2022-03-19');
 |  | ||||||
| // const test = await ListSchedulingNotifyContactService('5517988310949'); 
 |  | ||||||
| // 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| type IndexQuery = { | type IndexQuery = { | ||||||
|  | @ -61,12 +54,16 @@ export const createOrUpdateScheduleNotify = async (req: Request, res: Response): | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const remove = async ( req: Request, res: Response ): Promise<Response> => { | export const remove = async (req: Request, res: Response): Promise<Response> => { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   const { scheduleId } = req.params; |   const { scheduleId } = req.params; | ||||||
| 
 | 
 | ||||||
|  |   let schedule: any = await ShowSchedulingNotifyService(scheduleId) | ||||||
|  | 
 | ||||||
|  |   await deleteScheduleByTicketIdCache(schedule.ticketId) | ||||||
|  | 
 | ||||||
|   await DeleteSchedulingNotifyService(scheduleId); |   await DeleteSchedulingNotifyService(scheduleId); | ||||||
| 
 | 
 | ||||||
|   return res.status(200).send(); |   return res.status(200).send(); | ||||||
|  |  | ||||||
|  | @ -94,7 +94,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => { | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   await stopWhoIsOnlineMonitor() |   // await stopWhoIsOnlineMonitor()
 | ||||||
|   await startWhoIsOnlineMonitor() |   await startWhoIsOnlineMonitor() | ||||||
| 
 | 
 | ||||||
|   return res.status(200).json(user); |   return res.status(200).json(user); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,219 @@ | ||||||
|  | 
 | ||||||
|  | import Redis from 'ioredis' | ||||||
|  | import { type } from 'os' | ||||||
|  | const unflatten = require('flat').unflatten | ||||||
|  | var flatten = require('flat') | ||||||
|  | import ListContactsServiceCache from "../services/ContactServices/ListContactsServiceCache" | ||||||
|  | import { redisConn } from './TicketCache' | ||||||
|  | 
 | ||||||
|  | import SchedulingNotify from '../models/SchedulingNotify' | ||||||
|  | 
 | ||||||
|  | import { format } from "date-fns"; | ||||||
|  | import ptBR from 'date-fns/locale/pt-BR'; | ||||||
|  | 
 | ||||||
|  | import { escapeCharCache } from './ContactsCache' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const deleteScheduleByTicketIdCache = async (ticketId: string | number) => { | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return | ||||||
|  | 
 | ||||||
|  |     const schedule_cache: any = await redis.hgetall(`schedule:${ticketId}`) | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         if (schedule_cache && Object.keys(schedule_cache).length > 0) { | ||||||
|  | 
 | ||||||
|  |             await redis.del(`schedule:${ticketId}`) | ||||||
|  | 
 | ||||||
|  |             console.log(`Schedule cache ticketId ${schedule_cache.ticketId} deleted!`) | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             console.log('SCHEDULE CACHE NOT FOUND!') | ||||||
|  |         } | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log(`There was an error on deleteScheduleByTicketIdCache:  ${error}`) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     redis.quit() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const updateScheduleCacheByTicketId = async (scheduleNotify: any) => { | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return | ||||||
|  | 
 | ||||||
|  |     const pipeline = redis.pipeline() | ||||||
|  | 
 | ||||||
|  |     let entries = Object.entries(scheduleNotify) | ||||||
|  | 
 | ||||||
|  |     entries.forEach((e: any) => { | ||||||
|  |         pipeline.hset(`schedule:${scheduleNotify.ticketId}`, e[0], e[1]) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     await pipeline.exec(() => { console.log("schedule Key/value inserted/updated") }); | ||||||
|  | 
 | ||||||
|  |     redis.quit() | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const createSchedulingNotifyCache = async (scheduleNotify: any) => { | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return   | ||||||
|  | 
 | ||||||
|  |     let date_time: any = format(new Date(scheduleNotify.schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ') | ||||||
|  | 
 | ||||||
|  |     delete scheduleNotify.schedulingTime | ||||||
|  |     delete scheduleNotify.updatedAt | ||||||
|  |     delete scheduleNotify.createdAt | ||||||
|  |     delete scheduleNotify.schedulingDate | ||||||
|  | 
 | ||||||
|  |     console.log('created date_time: ', date_time) | ||||||
|  | 
 | ||||||
|  |     scheduleNotify.date = date_time[0] | ||||||
|  |     scheduleNotify.date_escaped = escapeCharCache(date_time[0])  | ||||||
|  |     scheduleNotify.hour = date_time[1].split(':')[0] | ||||||
|  |     scheduleNotify.minute = date_time[1].split(':')[1]  | ||||||
|  | 
 | ||||||
|  |     await redis.hmset(`schedule:${scheduleNotify.ticketId}`, scheduleNotify); | ||||||
|  | 
 | ||||||
|  |     console.log(`${scheduleNotify.length} SCHEDULE NOTIFY INSERTED IN CACHE!`) | ||||||
|  | 
 | ||||||
|  |     redis.quit() | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | async function searchScheduleCache(date: string, hour: number | string, minute: number | string) { | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return null | ||||||
|  | 
 | ||||||
|  |     date = escapeCharCache(date).trim()  | ||||||
|  |   | ||||||
|  |     const response: any = await redis.call('FT.SEARCH', 'idx_schedule',  `(@date_escaped:${date}) (@hour:${hour}) (@minute:${minute})`) | ||||||
|  |     redis.quit() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     if (response.length === 1) { | ||||||
|  |         return [] | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const results: any = [] | ||||||
|  | 
 | ||||||
|  |     for (let n = 2; n < response.length; n += 2) { | ||||||
|  |         const result: any = {} | ||||||
|  |         const fieldNamesAndValues = response[n] | ||||||
|  | 
 | ||||||
|  |         for (let m = 0; m < fieldNamesAndValues.length; m += 2) { | ||||||
|  |             const k = fieldNamesAndValues[m] | ||||||
|  |             const v = fieldNamesAndValues[m + 1] | ||||||
|  |             result[k] = v | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         results.push(result) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return results | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const loadSchedulesCache = async () => { | ||||||
|  | 
 | ||||||
|  |     await createScheduleIndexCache('idx_schedule') | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return | ||||||
|  | 
 | ||||||
|  |     let schedules: any = await SchedulingNotify.findAll({ raw: true, attributes: ["id", "statusChatEndId", "ticketId", "schedulingTime", "message"] }); | ||||||
|  | 
 | ||||||
|  |     // console.log('SCHEDULE NOTIFY CACHE2: ', schedules)
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     const pipeline = redis.pipeline() | ||||||
|  | 
 | ||||||
|  |     for (let i = 0; i < schedules.length; i++) { | ||||||
|  | 
 | ||||||
|  |         let date_time: any = format(new Date(schedules[i].schedulingTime), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }).split(' ') | ||||||
|  | 
 | ||||||
|  |         delete schedules[i].schedulingTime | ||||||
|  | 
 | ||||||
|  |         console.log('date_time: ', date_time) | ||||||
|  | 
 | ||||||
|  |         schedules[i].date = date_time[0] | ||||||
|  |         schedules[i].date_escaped = escapeCharCache(date_time[0]) | ||||||
|  | 
 | ||||||
|  |         schedules[i].hour = date_time[1].split(':')[0] | ||||||
|  |         schedules[i].minute = date_time[1].split(':')[1] | ||||||
|  | 
 | ||||||
|  |         pipeline.hmset(`schedule:${schedules[i].ticketId}`, schedules[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     await pipeline.exec(() => { console.log(`${schedules.length} SCHEDULES NOTIFY INSERTED IN CACHE!`) }); | ||||||
|  | 
 | ||||||
|  |     redis.quit() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     // let test = await searchScheduleCache('2022-12-16', '18', '30')
 | ||||||
|  | 
 | ||||||
|  |     // console.log('--------------> TEST: ', test)
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const createScheduleIndexCache = async (hashIndex: string) => { | ||||||
|  | 
 | ||||||
|  |     const redis: any = await redisConn(); | ||||||
|  | 
 | ||||||
|  |     if (!redis) return | ||||||
|  | 
 | ||||||
|  |     if (redis.status !== 'connect') return | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  | 
 | ||||||
|  |         const lst_index_redis: any = await redis.call('FT._LIST') | ||||||
|  | 
 | ||||||
|  |         if (lst_index_redis.includes(hashIndex)) { | ||||||
|  |             console.log('entrou...') | ||||||
|  |             await redis.call('FT.DROPINDEX', hashIndex) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'schedule:', 'SCHEMA', 'id', 'TEXT', 'SORTABLE', 'date_escaped', 'TEXT', 'SORTABLE', 'hour', 'TEXT', 'SORTABLE', 'minute', 'TEXT', 'SORTABLE') | ||||||
|  | 
 | ||||||
|  |         console.log('Schedule index created: ', response) | ||||||
|  | 
 | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log('There was an error on createScheduleIndexCache: ', error) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     redis.quit() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { | ||||||
|  |     loadSchedulesCache, | ||||||
|  |     searchScheduleCache, | ||||||
|  |     updateScheduleCacheByTicketId, | ||||||
|  |     createSchedulingNotifyCache, | ||||||
|  |     deleteScheduleByTicketIdCache | ||||||
|  | } | ||||||
|  | @ -8,6 +8,8 @@ import { getIO } from "../libs/socket"; | ||||||
| import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService"; | import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService"; | ||||||
| import path from "path"; | import path from "path"; | ||||||
| import { convertBytes } from "./ConvertBytes"; | import { convertBytes } from "./ConvertBytes"; | ||||||
|  | import { deleteScheduleByTicketIdCache } from "./SchedulingNotifyCache"; | ||||||
|  | import SchedulingNotify from "../models/SchedulingNotify"; | ||||||
| 
 | 
 | ||||||
| const fastFolderSize = require('fast-folder-size') | const fastFolderSize = require('fast-folder-size') | ||||||
| const { promisify } = require('util') | const { promisify } = require('util') | ||||||
|  | @ -15,6 +17,8 @@ const fs = require('fs') | ||||||
| 
 | 
 | ||||||
| const { exec } = require("child_process"); | const { exec } = require("child_process"); | ||||||
| 
 | 
 | ||||||
|  | let _fifo: any | ||||||
|  | 
 | ||||||
| let scheduler_monitor: any; | let scheduler_monitor: any; | ||||||
| let timeInterval = 5 | let timeInterval = 5 | ||||||
| 
 | 
 | ||||||
|  | @ -36,23 +40,35 @@ const monitor = async () => { | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
| 
 | 
 | ||||||
|         // const { schedulingNotifies, count, hasMore } = await ListSchedulingNotifyService({ searchParam: dateParm, pageNumber: "1" });
 |         const { schedulingNotifies, count, hasMore } = await ListSchedulingNotifyService({ searchParam: dateParm, pageNumber: "1" }); | ||||||
|     |     | ||||||
|         // //  console.log('schedulingNotifies: ',schedulingNotifies)
 |         if (schedulingNotifies && schedulingNotifies.length > 0) {   | ||||||
| 
 | 
 | ||||||
|         // if (schedulingNotifies && schedulingNotifies.length > 0) {
 |             for (let i = 0; i < schedulingNotifies.length; i++) { | ||||||
| 
 | 
 | ||||||
|         //     const ticket = await ShowTicketService(schedulingNotifies[0].ticketId);
 |  | ||||||
| 
 | 
 | ||||||
|         //     SetTicketMessagesAsRead(ticket);
 |                 const ticket = await ShowTicketService(+schedulingNotifies[i].ticketId);  | ||||||
|   |   | ||||||
|         //     await SendWhatsAppMessage({
 |                 await new Promise(f => setTimeout(f, 3000)); | ||||||
|         //         body: schedulingNotifies[0].message, ticket
 |  | ||||||
|         //     });
 |  | ||||||
| 
 | 
 | ||||||
|         //     DeleteSchedulingNotifyService(schedulingNotifies[0].id)
 |                 if(!ticket.queue){  | ||||||
|  |                     await ticket.update({status: 'open'})  | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|         // }
 |                 SetTicketMessagesAsRead(ticket); | ||||||
|  | 
 | ||||||
|  |                 await SendWhatsAppMessage({ | ||||||
|  |                     body: schedulingNotifies[i].message, ticket | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 await deleteScheduleByTicketIdCache(schedulingNotifies[i].ticketId) | ||||||
|  | 
 | ||||||
|  |                 await DeleteSchedulingNotifyService(schedulingNotifies[i].id)   | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             }  | ||||||
|  |              | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         exec("df -h /", (error: any, stdout: any, stderr: any) => { |         exec("df -h /", (error: any, stdout: any, stderr: any) => { | ||||||
|  | @ -132,27 +148,32 @@ const monitor = async () => { | ||||||
| 
 | 
 | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|         console.log('>>> SchedulingNotifiySendMessage.ts error: ', error) |         console.log('>>> SchedulingNotifiySendMessage.ts error: ', error) | ||||||
|         stopSchedulingMonitor() |  | ||||||
|         startSchedulingMonitor(timeInterval) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const startSchedulingMonitor = async (mileseconds: number) => { | const SchedulingNotifySendMessage = async () => { | ||||||
| 
 | 
 | ||||||
|     timeInterval = mileseconds |     try { | ||||||
|  |         clearInterval(_fifo); | ||||||
| 
 | 
 | ||||||
|     scheduler_monitor = setInterval(monitor, mileseconds) |         await monitor() | ||||||
| 
 | 
 | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log('error on SchedulingNotifySendMessage: ', error) | ||||||
|  |     } | ||||||
|  |     finally { | ||||||
|  |         _fifo = setInterval(SchedulingNotifySendMessage, 5000); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | _fifo = setInterval(SchedulingNotifySendMessage, 5000); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module.exports = SchedulingNotifySendMessage | ||||||
| 
 | 
 | ||||||
| export const stopSchedulingMonitor = async () => { |  | ||||||
|   |   | ||||||
|     clearInterval(scheduler_monitor) |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ import { date } from "faker"; | ||||||
| import sumOnlineTimeNow from '../helpers/SumOlineTimeNow' | import sumOnlineTimeNow from '../helpers/SumOlineTimeNow' | ||||||
| import UserOnlineTime from "../models/UserOnlineTime"; | import UserOnlineTime from "../models/UserOnlineTime"; | ||||||
| 
 | 
 | ||||||
| 
 | let _fifo: any | ||||||
| 
 | 
 | ||||||
| let whoIsOnline_monitor: any; | let whoIsOnline_monitor: any; | ||||||
| // const listUserId:any[] = [{'id':8, status: 'offline'},{'id':3,  status: 'offline'},{'id':5,  status: 'offline'}] 
 | // const listUserId:any[] = [{'id':8, status: 'offline'},{'id':3,  status: 'offline'},{'id':5,  status: 'offline'}] 
 | ||||||
|  | @ -175,38 +175,70 @@ const monitor = async () => { | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|         console.log('>>> There was an error no WhoIsOnlineMonitor.ts: ',error) |         console.log('>>> There was an error no WhoIsOnlineMonitor.ts: ', error) | ||||||
|         stopWhoIsOnlineMonitor() | 
 | ||||||
|         startWhoIsOnlineMonitor() |         listUserId = [] | ||||||
|  |         count = 0 | ||||||
|  |         countTest = 0 | ||||||
|  |         uuid = 0 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const startWhoIsOnlineMonitor = async (mileseconds?: number) => { | 
 | ||||||
|  | const WhoIsOnlineMonitor = async () => { | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         clearInterval(_fifo); | ||||||
|  | 
 | ||||||
|  |         await monitor() | ||||||
|  | 
 | ||||||
|  |     } catch (error) { | ||||||
|  |         console.log('error on WhoIsOnlineMonitor: ', error) | ||||||
|  |     } | ||||||
|  |     finally { | ||||||
|  |         _fifo = setInterval(WhoIsOnlineMonitor, 3000); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | _fifo = setInterval(WhoIsOnlineMonitor, 3000); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const startWhoIsOnlineMonitor = async (mileseconds?: number) => { | ||||||
| 
 | 
 | ||||||
|     listUserId = [] |     listUserId = [] | ||||||
|     count = 0 |     count = 0 | ||||||
|     countTest = 0 |     countTest = 0 | ||||||
|     uuid = 0 |     uuid = 0 | ||||||
| 
 | 
 | ||||||
|     if (mileseconds) { |     clearInterval(_fifo); | ||||||
|         timeInterval = mileseconds |     _fifo = setInterval(WhoIsOnlineMonitor, 3000); | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     whoIsOnline_monitor = setInterval(monitor, timeInterval) |  | ||||||
| 
 | 
 | ||||||
|  |     // if (mileseconds) {
 | ||||||
|  |     //     timeInterval = mileseconds
 | ||||||
|  |     // } 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const stopWhoIsOnlineMonitor = async () => { | const stopWhoIsOnlineMonitor = async () => { | ||||||
| 
 | 
 | ||||||
|     clearInterval(whoIsOnline_monitor) |     clearInterval(_fifo); | ||||||
|  |     // _fifo = setInterval(WhoIsOnlineMonitor, 3000);
 | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | export { WhoIsOnlineMonitor, startWhoIsOnlineMonitor, stopWhoIsOnlineMonitor } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -3,10 +3,8 @@ import app from "./app"; | ||||||
| import { initIO } from "./libs/socket"; | import { initIO } from "./libs/socket"; | ||||||
| import { logger } from "./utils/logger"; | import { logger } from "./utils/logger"; | ||||||
| import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions"; | import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions"; | ||||||
| 
 | import "./helpers/SchedulingNotifySendMessage" | ||||||
| import { startSchedulingMonitor } from "./helpers/SchedulingNotifySendMessage" | import "./helpers/WhoIsOnlineMonitor" | ||||||
| import { startWhoIsOnlineMonitor } from "./helpers/WhoIsOnlineMonitor" |  | ||||||
| 
 |  | ||||||
| import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache' | import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache' | ||||||
| import { loadContactsCache } from './helpers/ContactsCache' | import { loadContactsCache } from './helpers/ContactsCache' | ||||||
|   |   | ||||||
|  | @ -14,6 +12,7 @@ import "./helpers/CloseBotTickets"; | ||||||
| import { loadWhatsappCache } from './helpers/WhatsCache' | import { loadWhatsappCache } from './helpers/WhatsCache' | ||||||
| import { delRestoreControllFile } from "./helpers/RestoreControll"; | import { delRestoreControllFile } from "./helpers/RestoreControll"; | ||||||
| import { createSessionDir } from "./helpers/CreateSessionDir"; | import { createSessionDir } from "./helpers/CreateSessionDir"; | ||||||
|  | import { loadSchedulesCache, } from "./helpers/SchedulingNotifyCache"; | ||||||
| 
 | 
 | ||||||
| const server = app.listen(process.env.PORT, () => { | const server = app.listen(process.env.PORT, () => { | ||||||
|   logger.info(`Server started on port: ${process.env.PORT}`); |   logger.info(`Server started on port: ${process.env.PORT}`); | ||||||
|  | @ -31,19 +30,19 @@ gracefulShutdown(server); | ||||||
| 
 | 
 | ||||||
|   console.log('cacheSize: ', cacheLength) |   console.log('cacheSize: ', cacheLength) | ||||||
| 
 | 
 | ||||||
|   if(cacheLength == 0){ |   if (cacheLength == 0) { | ||||||
|     console.log('Loading from cache...') |     console.log('Loading from cache...') | ||||||
|     await flushCache() |     await flushCache() | ||||||
|     await loadContactsCache() |     await loadContactsCache() | ||||||
|     await loadTicketsCache() |     await loadTicketsCache() | ||||||
|     await loadWhatsappCache() |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   await loadWhatsappCache() | ||||||
|  |   await loadSchedulesCache() | ||||||
| 
 | 
 | ||||||
| })() | })() | ||||||
|  | 
 | ||||||
| createSessionDir() | createSessionDir() | ||||||
| delRestoreControllFile() | delRestoreControllFile() | ||||||
| 
 | 
 | ||||||
| startSchedulingMonitor(5000) |  | ||||||
| startWhoIsOnlineMonitor(3000) |  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| import AppError from "../../errors/AppError"; | import AppError from "../../errors/AppError"; | ||||||
|  | import { createSchedulingNotifyCache } from "../../helpers/SchedulingNotifyCache"; | ||||||
| import SchedulingNotify from "../../models/SchedulingNotify"; | import SchedulingNotify from "../../models/SchedulingNotify"; | ||||||
| 
 | 
 | ||||||
|    |    | ||||||
|  | @ -56,9 +57,10 @@ const CreateSchedulingNotifyService = async ({ | ||||||
|                 message  |                 message  | ||||||
|              |              | ||||||
|             })  |             })  | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|  |     await createSchedulingNotifyCache(JSON.parse(JSON.stringify(schedulingNotify)))  | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     return schedulingNotify |     return schedulingNotify | ||||||
|  } |  } | ||||||
|  |  | ||||||
|  | @ -1,21 +1,22 @@ | ||||||
| import { Op, Sequelize } from "sequelize"; | import { Op, Sequelize } from "sequelize"; | ||||||
|  | import { searchScheduleCache } from "../../helpers/SchedulingNotifyCache"; | ||||||
| import SchedulingNotify from "../../models/SchedulingNotify"; | import SchedulingNotify from "../../models/SchedulingNotify"; | ||||||
| 
 | 
 | ||||||
| interface Request { | interface Request { | ||||||
|   searchParam?: string; |   searchParam?: string; | ||||||
|   pageNumber?: string; |   pageNumber?: string; | ||||||
|   } | } | ||||||
| 
 | 
 | ||||||
|   interface Response { | interface Response { | ||||||
|   schedulingNotifies: SchedulingNotify[]; |   schedulingNotifies: SchedulingNotify[]; | ||||||
|   count: number; |   count: number; | ||||||
|   hasMore: boolean; |   hasMore: boolean; | ||||||
|   } | } | ||||||
| 
 | 
 | ||||||
|   const ListSchedulingNotifyService = async ({ | const ListSchedulingNotifyService = async ({ | ||||||
|   searchParam = "", |   searchParam = "", | ||||||
|   pageNumber = "1" |   pageNumber = "1" | ||||||
|   }: Request): Promise<Response> => { | }: Request): Promise<Response> => { | ||||||
|   // const whereCondition = {
 |   // const whereCondition = {
 | ||||||
|   //   message: Sequelize.where( 
 |   //   message: Sequelize.where( 
 | ||||||
| 
 | 
 | ||||||
|  | @ -29,6 +30,21 @@ interface Request { | ||||||
|   let hour = searchParam.split(' ')[1].split(':')[0] |   let hour = searchParam.split(' ')[1].split(':')[0] | ||||||
|   let minute = searchParam.split(' ')[1].split(':')[1] |   let minute = searchParam.split(' ')[1].split(':')[1] | ||||||
| 
 | 
 | ||||||
|  |   let fromCache = null | ||||||
|  | 
 | ||||||
|  |   fromCache = await searchScheduleCache(date, hour, minute) | ||||||
|  | 
 | ||||||
|  |   if (fromCache) { | ||||||
|  | 
 | ||||||
|  |     return { | ||||||
|  |       schedulingNotifies: fromCache, | ||||||
|  |       count: 0, | ||||||
|  |       hasMore: false, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   const whereCondition = { |   const whereCondition = { | ||||||
|     [Op.and]: [ |     [Op.and]: [ | ||||||
|       { |       { | ||||||
|  | @ -62,7 +78,6 @@ interface Request { | ||||||
|     count, |     count, | ||||||
|     hasMore |     hasMore | ||||||
|   }; |   }; | ||||||
|   }; | }; | ||||||
|    |  | ||||||
|   export default ListSchedulingNotifyService; |  | ||||||
| 
 | 
 | ||||||
|  | export default ListSchedulingNotifyService; | ||||||
|  |  | ||||||
|  | @ -128,8 +128,14 @@ const verifyMediaMessage = async ( | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   try { |   try { | ||||||
|  |     // await writeFileAsync(
 | ||||||
|  |     //   join(__dirname, "..", "..", "..", "public", media.filename),
 | ||||||
|  |     //   media.data,
 | ||||||
|  |     //   "base64"
 | ||||||
|  |     // );
 | ||||||
|  | 
 | ||||||
|     await writeFileAsync( |     await writeFileAsync( | ||||||
|       join(__dirname, "..", "..", "..", "public", media.filename), |       join(__dirname, "..", "..", "..", "..", "..", "public", media.filename), | ||||||
|       media.data, |       media.data, | ||||||
|       "base64" |       "base64" | ||||||
|     ); |     ); | ||||||
|  | @ -821,20 +827,12 @@ const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: st | ||||||
| 
 | 
 | ||||||
| const _clear_lst = () => { | const _clear_lst = () => { | ||||||
| 
 | 
 | ||||||
|   console.log('WHATSAPP MESSAGE ID MULTI SESSION: ', lst.length) |  | ||||||
| 
 |  | ||||||
|   if (lst.length <= 200 ) return  |   if (lst.length <= 200 ) return  | ||||||
| 
 | 
 | ||||||
|   console.log('BEFORE lst SLICE: ', lst) |  | ||||||
| 
 |  | ||||||
|   console.log('lst whatsapp message id sliced! | lst.length: ', lst.length) |  | ||||||
| 
 |  | ||||||
|   const chunk: any = Math.floor((lst.length / 2)) |   const chunk: any = Math.floor((lst.length / 2)) | ||||||
| 
 | 
 | ||||||
|   lst = lst.slice(chunk, chunk + lst.length);  |   lst = lst.slice(chunk, chunk + lst.length);  | ||||||
|   |   | ||||||
|   console.log('AFTER lst SLICE: ', lst) |  | ||||||
|   |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -884,37 +882,6 @@ const handleMessage = async ( | ||||||
| 
 | 
 | ||||||
|   console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id)   |   console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id)   | ||||||
| 
 | 
 | ||||||
|   // const contact_message = await getLastId(`contact_message:5517988310949`)  
 |  | ||||||
| 
 |  | ||||||
|   // if (contact_message && contact_message.id == msg.id.id) {
 |  | ||||||
|   //   console.log('IGNORED MESSAGE SAME ID FROM CLIENT: ', contact_message.id)
 |  | ||||||
|   //   return
 |  | ||||||
|   // }
 |  | ||||||
| 
 |  | ||||||
|   // await insertMessageContactCache(`contact_message:5517988310949`,
 |  | ||||||
|   //   {
 |  | ||||||
|   //     from: msg.from.split("@")[0],
 |  | ||||||
|   //     to: msg.to.split("@")[0],
 |  | ||||||
|   //     id: msg.id.id
 |  | ||||||
|   //   })
 |  | ||||||
| 
 |  | ||||||
|   // console.log('PASSOU............................................... contact_message.id: ',contact_message.id)
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   // if (testLastId == msg.id.id) {
 |  | ||||||
|   //   console.log('IGNORED MESSAGE SAME ID!')
 |  | ||||||
|   //   return
 |  | ||||||
|   // } 
 |  | ||||||
|   // testLastId = msg.id.id  
 |  | ||||||
| 
 |  | ||||||
|   // console.log('PASSOU............................................... msg.id.id: ',msg.id.id)
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|   if (!isValidMsg(msg)) { |   if (!isValidMsg(msg)) { | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ import ErrorIcon from "@material-ui/icons/Error"; | ||||||
| import RemoveCircleIcon from "@material-ui/icons/RemoveCircle"; | import RemoveCircleIcon from "@material-ui/icons/RemoveCircle"; | ||||||
| import PowerSettingsNewIcon from "@material-ui/icons/PowerSettingsNew"; | import PowerSettingsNewIcon from "@material-ui/icons/PowerSettingsNew"; | ||||||
| 
 | 
 | ||||||
|  | import { i18n } from "../../translate/i18n"; | ||||||
|  | 
 | ||||||
| const TableUser = ({ classes, usersOnlineInfo, logout }) => { | const TableUser = ({ classes, usersOnlineInfo, logout }) => { | ||||||
|   const [search, setSearch] = React.useState(""); |   const [search, setSearch] = React.useState(""); | ||||||
|   const [filterStatus, setFilterStatus] = React.useState(null); |   const [filterStatus, setFilterStatus] = React.useState(null); | ||||||
|  | @ -48,7 +50,8 @@ const TableUser = ({ classes, usersOnlineInfo, logout }) => { | ||||||
|               color="primary" |               color="primary" | ||||||
|               style={{ marginBottom: "16px" }} |               style={{ marginBottom: "16px" }} | ||||||
|             > |             > | ||||||
|               Lista de Usuários |             | ||||||
|  |               {i18n.t("dashboard.table_users.title")} | ||||||
|             </Typography> |             </Typography> | ||||||
|           </Grid> |           </Grid> | ||||||
|           <Grid item sx={8} width="100%"> |           <Grid item sx={8} width="100%"> | ||||||
|  | @ -84,12 +87,12 @@ const TableUser = ({ classes, usersOnlineInfo, logout }) => { | ||||||
|             <Table> |             <Table> | ||||||
|               <TableHead> |               <TableHead> | ||||||
|                 <TableRow className={classes.tableRowHead}> |                 <TableRow className={classes.tableRowHead}> | ||||||
|                   <TableCell>Nome</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column0")}</TableCell> | ||||||
|                   <TableCell>Em Atendimento/Finalizado(s)</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column1")}</TableCell> | ||||||
|                   <TableCell>abertos Por Fila</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column2")}</TableCell> | ||||||
|                   <TableCell>Fechados Por Fila</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column3")}</TableCell> | ||||||
|                   <TableCell>Tempo Online</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column4")}</TableCell> | ||||||
|                   <TableCell>Ações</TableCell> |                   <TableCell>{i18n.t("dashboard.table_users.column5")}</TableCell> | ||||||
|                 </TableRow> |                 </TableRow> | ||||||
|               </TableHead> |               </TableHead> | ||||||
|                |                | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ import chat from '@material-ui/icons/Chat'; | ||||||
| 
 | 
 | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
|  | import { i18n } from '../../../translate/i18n'; | ||||||
|  | 
 | ||||||
| const MTable = (props) => { | const MTable = (props) => { | ||||||
| 
 | 
 | ||||||
|   const tableRef = React.useRef();  |   const tableRef = React.useRef();  | ||||||
|  | @ -79,7 +81,7 @@ const MTable = (props) => { | ||||||
|           if (props.hasChild) { |           if (props.hasChild) { | ||||||
|             render(<Modal data={selectedRow.messages} |             render(<Modal data={selectedRow.messages} | ||||||
|               hasChild={false} |               hasChild={false} | ||||||
|               modal_header={'Chat do atendimento pelo Whatsapp'} |               modal_header={i18n.t("reports.listTitles.title2_1")} | ||||||
|               user={selectedRow.user.name} |               user={selectedRow.user.name} | ||||||
|               clientContactNumber={selectedRow.contact.number} />) |               clientContactNumber={selectedRow.contact.number} />) | ||||||
|           } |           } | ||||||
|  |  | ||||||
|  | @ -10,23 +10,25 @@ import DialogTitle from '@mui/material/DialogTitle'; | ||||||
| //import DataGridTable from '../Table';
 | //import DataGridTable from '../Table';
 | ||||||
| import MTable from "../MTable";    | import MTable from "../MTable";    | ||||||
| 
 | 
 | ||||||
|  | import { i18n } from '../../../translate/i18n'; | ||||||
|  | 
 | ||||||
| import ExportCSV from '../ExportCSV' | import ExportCSV from '../ExportCSV' | ||||||
| //import { margin } from '@mui/system';
 | //import { margin } from '@mui/system';
 | ||||||
| 
 | 
 | ||||||
| let columns = [ | let columns = [ | ||||||
|   {  |   {  | ||||||
|     title: 'Atendente/Cliente',  |     title: `${i18n.t("reports.listColumns.column2_1")}`,  | ||||||
|     field: 'fromMe',  |     field: 'fromMe',  | ||||||
|      |      | ||||||
|   }, |   }, | ||||||
|    |    | ||||||
|   { |   { | ||||||
|     title: 'Mensagem',  |     title: `${i18n.t("reports.listColumns.column0_8")}`,  | ||||||
|     field: 'body',  |     field: 'body',  | ||||||
|     //cellStyle: {whiteSpace: 'nowrap'},
 |     //cellStyle: {whiteSpace: 'nowrap'},
 | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   { title: 'Criado', field: 'createdAt' } |   { title: `${i18n.t("reports.listColumns.column1_7")}`, field: 'createdAt' } | ||||||
| 
 | 
 | ||||||
|   /*cellStyle: { |   /*cellStyle: { | ||||||
|     backgroundColor: '#039be5', |     backgroundColor: '#039be5', | ||||||
|  |  | ||||||
|  | @ -23,6 +23,9 @@ import fileDownload from 'js-file-download' | ||||||
|   |   | ||||||
| import openSocket from "socket.io-client";   | import openSocket from "socket.io-client";   | ||||||
| 
 | 
 | ||||||
|  | import { i18n } from "../../translate/i18n"; | ||||||
|  |   | ||||||
|  | 
 | ||||||
| const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }] | const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }] | ||||||
| 
 | 
 | ||||||
|       |       | ||||||
|  | @ -206,17 +209,17 @@ Item.propTypes = { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| let columnsData = [ | let columnsData = [ | ||||||
|   { title: 'Unidade', field: 'whatsapp.name' }, |   { title: `${i18n.t("reports.listColumns.column1_1")}`, field: 'whatsapp.name' }, | ||||||
|   { title: 'Atendente', field: 'user.name' }, |   { title: `${i18n.t("reports.listColumns.column1_2")}`, field: 'user.name' }, | ||||||
|   { title: 'Contato', field: 'contact.number' }, |   { title: `${i18n.t("reports.listColumns.column0_4")}`, field: 'contact.number' }, | ||||||
|   { title: 'Nome', field: 'contact.name' }, |   { title: `${i18n.t("reports.listColumns.column0_3")}`, field: 'contact.name' }, | ||||||
|   { title: 'Assunto', field: 'queue.name' }, |   { title: `${i18n.t("reports.listColumns.column1_5")}`, field: 'queue.name' }, | ||||||
| 
 | 
 | ||||||
|   { title: 'Status', field: 'status' }, |   { title: 'Status', field: 'status' }, | ||||||
| 
 | 
 | ||||||
|   { title: 'Criado', field: 'createdAt' }, |   { title: `${i18n.t("reports.listColumns.column1_7")}`, field: 'createdAt' }, | ||||||
|   {title: 'Atualizado', field: 'updatedAt'}, |   {title: `${i18n.t("reports.listColumns.column1_8")}`, field: 'updatedAt'}, | ||||||
|   { title: 'Status de encerramento', field: 'statusChatEnd' }]; |   { title: `${i18n.t("reports.listColumns.column1_9")}`, field: 'statusChatEnd' }]; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| const Report = () => {   | const Report = () => {   | ||||||
|  | @ -630,12 +633,12 @@ const Report = () => { | ||||||
|         <MainContainer> |         <MainContainer> | ||||||
|           <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}> |           <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}> | ||||||
| 
 | 
 | ||||||
|             <Item><SelectField func={textFieldSelectUser} emptyField={true} header={'Usuário'} currencies={users.map((obj) => { |             <Item><SelectField func={textFieldSelectUser} emptyField={true} header={i18n.t("reports.user")} currencies={users.map((obj) => { | ||||||
|               return { 'value': obj.id, 'label': obj.name } |               return { 'value': obj.id, 'label': obj.name } | ||||||
|             })} /></Item> |             })} /></Item> | ||||||
| 
 | 
 | ||||||
|             <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={'Data inicio'} /></Item> |             <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateStart")} /></Item> | ||||||
|             <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'} /></Item> |             <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateEnd")} /></Item> | ||||||
| 
 | 
 | ||||||
|             <Item sx={{ display: 'grid', gridColumn: '4 / 5', }}> |             <Item sx={{ display: 'grid', gridColumn: '4 / 5', }}> | ||||||
| 
 | 
 | ||||||
|  | @ -672,7 +675,7 @@ const Report = () => { | ||||||
| 
 | 
 | ||||||
|                     handleScroll={handleScroll} |                     handleScroll={handleScroll} | ||||||
| 
 | 
 | ||||||
|                     table_title={'Atendimento por atendentes'} /> |                     table_title={i18n.t("reports.listTitles.title1_1")} /> | ||||||
| 
 | 
 | ||||||
|                 </> |                 </> | ||||||
| 
 | 
 | ||||||
|  | @ -689,7 +692,7 @@ const Report = () => { | ||||||
| 
 | 
 | ||||||
|                   }} |                   }} | ||||||
| 
 | 
 | ||||||
|                   title="Usuários online/offline" |                   title={i18n.t("reports.listTitles.title3_1")} | ||||||
|                   columns={ |                   columns={ | ||||||
|                     [ |                     [ | ||||||
| 
 | 
 | ||||||
|  | @ -724,8 +727,8 @@ const Report = () => { | ||||||
|                       }, |                       }, | ||||||
| 
 | 
 | ||||||
|                       { title: 'Tempo online', field: 'sumOnlineTime.sum' }, |                       { title: 'Tempo online', field: 'sumOnlineTime.sum' }, | ||||||
|                       { title: 'Data inicio', field: 'startDate' }, |                       { title: `${i18n.t("reports.dateStart")}`, field: 'startDate' }, | ||||||
|                       { title: 'Data fim', field: 'endDate' }, |                       { title: `${i18n.t("reports.dateStart")}`, field: 'endDate' }, | ||||||
|                       { title: 'Em atendimento', field: 'sumOpen.count' }, |                       { title: 'Em atendimento', field: 'sumOpen.count' }, | ||||||
|                       { title: 'Finalizado', field: 'sumClosed.count' }, |                       { title: 'Finalizado', field: 'sumClosed.count' }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ import { toast } from "react-toastify"; | ||||||
| import toastError from "../../errors/toastError"; | import toastError from "../../errors/toastError"; | ||||||
| import ConfirmationModal from "../../components/ConfirmationModal"; | import ConfirmationModal from "../../components/ConfirmationModal"; | ||||||
| 
 | 
 | ||||||
| 
 | import { i18n } from "../../translate/i18n"; | ||||||
| 
 | 
 | ||||||
| const reducerQ = (state, action) => { | const reducerQ = (state, action) => { | ||||||
| 
 | 
 | ||||||
|  | @ -467,8 +467,8 @@ const SchedulesReminder = () => { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("report.date.dateStart")} /></Item> |         <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("reports.dateStart")} /></Item> | ||||||
|         <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={'Data fim'} /></Item> |         <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={i18n.t("reports.dateEnd")} /></Item> | ||||||
| 
 | 
 | ||||||
|         <Item sx={{ gridColumn: '4 / 5' }}> |         <Item sx={{ gridColumn: '4 / 5' }}> | ||||||
|           {/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/} |           {/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/} | ||||||
|  | @ -503,18 +503,26 @@ const SchedulesReminder = () => { | ||||||
|           </ConfirmationModal> |           </ConfirmationModal> | ||||||
| 
 | 
 | ||||||
|           <MaterialTable |           <MaterialTable | ||||||
|             // title="Lembretes/Agendamentos"
 | 
 | ||||||
|             title={i18n.t("report.listTitle.title1")} |             localization={{ | ||||||
|  | 
 | ||||||
|  |               header: { | ||||||
|  |                 actions: `${i18n.t("reports.listColumns.column0_1")}` | ||||||
|  |               }, | ||||||
|  | 
 | ||||||
|  |             }} | ||||||
|  | 
 | ||||||
|  |             title={i18n.t("reports.listTitles.title0_1")} | ||||||
|             columns={ |             columns={ | ||||||
|               [ |               [ | ||||||
| 
 | 
 | ||||||
|                 { title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> }, |                 { title: `${i18n.t("reports.listColumns.column0_2")}`, field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> }, | ||||||
|                 { title: 'Nome', field: 'ticket.contact.name' }, |                 { title: `${i18n.t("reports.listColumns.column0_3")}`, field: 'ticket.contact.name' }, | ||||||
|                 { title: 'Contato', field: 'ticket.contact.number' }, |                 { title: `${i18n.t("reports.listColumns.column0_4")}`, field: 'ticket.contact.number' }, | ||||||
|                 { title: 'Lemb/Agen', field: 'scheduleReminder' }, |                 { title: `${i18n.t("reports.listColumns.column0_5")}`, field: 'scheduleReminder' }, | ||||||
|                 { title: 'Envio', field: 'schedulingTime' }, |                 { title: `${i18n.t("reports.listColumns.column0_6")}`, field: 'schedulingTime' }, | ||||||
|                 { title: 'Data', field: 'schedulingDate' }, |                 { title: `${i18n.t("reports.listColumns.column0_7")}`, field: 'schedulingDate' }, | ||||||
|                 { title: 'Mensagem', field: 'message', width: "80%" }, |                 { title: `${i18n.t("reports.listColumns.column0_8")}`, field: 'message', width: "80%" }, | ||||||
| 
 | 
 | ||||||
|               ] |               ] | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -49,6 +49,16 @@ const messages = { | ||||||
|           closed: { |           closed: { | ||||||
|             title: "Closed" |             title: "Closed" | ||||||
|           } |           } | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         table_users:{ | ||||||
|  |            title: 'User List', | ||||||
|  |            column0: 'Name', | ||||||
|  |            column1: 'In Service/Finished', | ||||||
|  |            column2: 'Open by Queue', | ||||||
|  |            column3: 'Closed by Queue', | ||||||
|  |            column4: 'Online time',  | ||||||
|  |            column5: 'Actions', | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       connections: { |       connections: { | ||||||
|  | @ -314,6 +324,7 @@ const messages = { | ||||||
|           administration: "Administration", |           administration: "Administration", | ||||||
|           users: "Users", |           users: "Users", | ||||||
|           settings: "Settings",  |           settings: "Settings",  | ||||||
|  |           schedules: "Schedules", | ||||||
|           dialogflow: "Dialogflow", |           dialogflow: "Dialogflow", | ||||||
|         }, |         }, | ||||||
|         appBar: { |         appBar: { | ||||||
|  | @ -323,13 +334,39 @@ const messages = { | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|       report: { |       reports: { | ||||||
|         listTitle: { |         listTitles: { | ||||||
|           title1: "Reminders/Schedules", |           title0_1: "Reminders/Schedulings", | ||||||
|  |           title1_1: "Calls by attendants", | ||||||
|  |           title2_1: "Whatsapp chat", | ||||||
|  |           title3_1: "Users online/offline" | ||||||
|         }, |         }, | ||||||
|         search: { |         listColumns:{ | ||||||
|           search1: "Number/Name...",           |           column0_1: 'Actions', | ||||||
|         } |           column0_2: 'Pic', | ||||||
|  |           column0_3: 'Name', | ||||||
|  |           column0_4: 'Contact', | ||||||
|  |           column0_5: 'Remin/Sched', | ||||||
|  |           column0_6: 'Send', | ||||||
|  |           column0_7: 'Date', | ||||||
|  |           column0_8: 'Message', | ||||||
|  | 
 | ||||||
|  |           column1_1: 'Store', | ||||||
|  |           column1_2: 'Attendant',  | ||||||
|  |           column1_5: 'Subject', | ||||||
|  |           column1_6: 'Status', | ||||||
|  |           column1_7: 'Created', | ||||||
|  |           column1_8: 'Updated', | ||||||
|  |           column1_9: 'Closing status', | ||||||
|  | 
 | ||||||
|  |           column2_1: 'Attendant/Client', | ||||||
|  |         }, | ||||||
|  |         search: 'Number/Name...', | ||||||
|  |         dateStart: 'Start date', | ||||||
|  |         dateEnd: 'End date', | ||||||
|  |         user: 'User' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|       }, |       }, | ||||||
|       notifications: { |       notifications: { | ||||||
|         noTickets: "No notifications.", |         noTickets: "No notifications.", | ||||||
|  |  | ||||||
|  | @ -50,6 +50,17 @@ const messages = { | ||||||
|           closed: { |           closed: { | ||||||
|             title: "Finalizado" |             title: "Finalizado" | ||||||
|           } |           } | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         table_users:{ | ||||||
|  |            | ||||||
|  |            title: 'Lista de usuarios', | ||||||
|  |            column0: 'Nombre', | ||||||
|  |            column1: 'En servicio/Terminado(S)', | ||||||
|  |            column2: 'Abrir por cola', | ||||||
|  |            column3: 'Cerrado por cola', | ||||||
|  |            column4: 'Tiempo Online',  | ||||||
|  |            column5: 'Actions', | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       connections: { |       connections: { | ||||||
|  | @ -319,6 +330,7 @@ const messages = { | ||||||
|           administration: "Administración", |           administration: "Administración", | ||||||
|           users: "Usuarios", |           users: "Usuarios", | ||||||
|           settings: "Configuración", |           settings: "Configuración", | ||||||
|  |           schedules: "Recordatorio", | ||||||
|           dialogflow: "Dialogflow", |           dialogflow: "Dialogflow", | ||||||
|         }, |         }, | ||||||
|         appBar: { |         appBar: { | ||||||
|  | @ -328,13 +340,38 @@ const messages = { | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|       report: { |       reports: { | ||||||
|         listTitle: { |         listTitles: { | ||||||
|           title1: "Recordatorios/Programación", |           title0_1: "Recordatorios/Programación", | ||||||
|  |           title1_1: "Llamadas de asistentes", | ||||||
|  |           title2_1: "Chat de whatsapp", | ||||||
|  |           title3_1: "Usuarios online/offline" | ||||||
|         }, |         }, | ||||||
|         search: { |         listColumns:{ | ||||||
|           search1: "Número/Nombre...",           |           column0_1: 'Acción', | ||||||
|         } |           column0_2: 'Pic', | ||||||
|  |           column0_3: 'Nombre', | ||||||
|  |           column0_4: 'Contacto', | ||||||
|  |           column0_5: 'Record/Progr', | ||||||
|  |           column0_6: 'Envío', | ||||||
|  |           column0_7: 'Fecha', | ||||||
|  |           column0_8: 'Mensaje', | ||||||
|  | 
 | ||||||
|  |           column1_1: 'Almacenar', | ||||||
|  |           column1_2: 'Secretario',  | ||||||
|  |           column1_5: 'Tema', | ||||||
|  |           column1_6: 'Status', | ||||||
|  |           column1_7: 'Creado', | ||||||
|  |           column1_8: 'Actualizado', | ||||||
|  |           column1_9: 'Estado de cierre', | ||||||
|  | 
 | ||||||
|  |           column2_1: 'Secretario/Cliente', | ||||||
|  |         }, | ||||||
|  |         search: 'Número/Nombre...', | ||||||
|  |         dateStart: 'Fecha de inicio', | ||||||
|  |         dateEnd: 'Fecha final', | ||||||
|  |         user: 'Usuario' | ||||||
|  | 
 | ||||||
|       }, |       }, | ||||||
|       notifications: { |       notifications: { | ||||||
|         noTickets: "Sin notificaciones.", |         noTickets: "Sin notificaciones.", | ||||||
|  |  | ||||||
|  | @ -49,6 +49,16 @@ const messages = { | ||||||
|           closed: { |           closed: { | ||||||
|             title: "Finalizado" |             title: "Finalizado" | ||||||
|           } |           } | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         table_users:{  | ||||||
|  |            title: 'Lista De Usuários', | ||||||
|  |            column0: 'Nome', | ||||||
|  |            column1: 'Em Atendimento/Finalizado(S)', | ||||||
|  |            column2: 'Abertos Por Fila', | ||||||
|  |            column3: 'Fechados Por Fila', | ||||||
|  |            column4: 'Tempo Online',  | ||||||
|  |            column5: 'Ações', | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       connections: { |       connections: { | ||||||
|  | @ -317,6 +327,7 @@ const messages = { | ||||||
|           administration: "Administração", |           administration: "Administração", | ||||||
|           users: "Usuários", |           users: "Usuários", | ||||||
|           settings: "Configurações", |           settings: "Configurações", | ||||||
|  |           schedules: "Lembretes", | ||||||
|           dialogflow: "Dialogflow", |           dialogflow: "Dialogflow", | ||||||
|         }, |         }, | ||||||
|         appBar: { |         appBar: { | ||||||
|  | @ -326,20 +337,40 @@ const messages = { | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|       report: { |       reports: { | ||||||
|         listTitle: { |         listTitles: { | ||||||
|           title1: "Lembretes/Agendamentos", |           title0_1: "Lembretes/Agendamentos", | ||||||
|  |           title1_1: "Atendimento por atendentes", | ||||||
|  |           title2_1: "Chat do atendimento pelo Whatsapp", | ||||||
|  |           title3_1: "Usuários online/offline" | ||||||
|         }, |         }, | ||||||
|         search: { |         listColumns:{ | ||||||
|           search1: "Numero/Nome...",           |           column0_1: 'Ações', | ||||||
|         }, |           column0_2: 'Foto', | ||||||
|         date:{ |           column0_3: 'Nome', | ||||||
|           dateStart: "Data início", |           column0_4: 'Contato', | ||||||
|           dateEnd: "Data fim" |           column0_5: 'Lemb/Agen', | ||||||
|         }, |           column0_6: 'Envio', | ||||||
|         button:{ |           column0_7: 'Data', | ||||||
|  |           column0_8: 'Mensagem', | ||||||
|  | 
 | ||||||
|  |           column1_1: 'Unidade', | ||||||
|  |           column1_2: 'Atendente',  | ||||||
|  |           column1_5: 'Assunto', | ||||||
|  |           column1_6: 'Status', | ||||||
|  |           column1_7: 'Criado', | ||||||
|  |           column1_8: 'Atualizado', | ||||||
|  |           column1_9: 'Status de encerramento', | ||||||
|  | 
 | ||||||
|  |           column2_1: 'Atendente/Cliente', | ||||||
|  |            | ||||||
|  |         }, | ||||||
|  |         search: 'Numer/Nome...', | ||||||
|  |         dateStart: 'Data início', | ||||||
|  |         dateEnd: 'Data fim', | ||||||
|  |         user: 'Usuário' | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         } |  | ||||||
|       }, |       }, | ||||||
|       notifications: { |       notifications: { | ||||||
|         noTickets: "Nenhuma notificação.", |         noTickets: "Nenhuma notificação.", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue