const { fetchCommentsFromServiceNow, fetchTicketLiveStatusFromServiceNow } = require('../services/servicenowService'); const { syncCommentsGlpitoSN, syncCommentsSNtoGlpi } = require('../services/glpiCommentService'); const TicketSyncModel = require('../models/ticketSyncModel'); const TicketSnModel = require('../models/ticketSnModel'); const TicketGlpiModel = require('../models/ticketGlpiModel'); const { logInfo } = require('../utils/logger'); const ensureReopenFromSNWhenGlpiSolved = async (ticket) => { const glpiStatus = await TicketGlpiModel.getTicketStatus(ticket.glpi_ticket_id); const glpiIsSolved = glpiStatus === 5; if (!glpiIsSolved) { return { reopened: false, glpiSolved: false }; } // CORREÇÃO: Verificar se o ticket foi fechado recentemente. // Se o status já é 'solved', significa que o processGlpiClosureController // tentou fechar recentemente. O SN pode ainda estar processando o close, // então ignoramos a detecção de reopen para evitar falsos positivos. if (ticket.glpi_sync_status === 'solved' || ticket.sn_sync_status === 'solved') { logInfo(`Ticket GLPI ${ticket.glpi_ticket_id} fechou recentemente (status: ${ticket.glpi_sync_status}/${ticket.sn_sync_status}). Ignorando verificacao de reopen.`); return { reopened: false, glpiSolved: true }; } const ticketSn = await TicketSnModel.findById(ticket.sn_ticket_id); if (!ticketSn) { return { reopened: false, glpiSolved: true }; } const liveSnStatus = await fetchTicketLiveStatusFromServiceNow(ticketSn.sys_id, ticketSn.tipo); const snIsFinal = liveSnStatus === 'Resolvido' || liveSnStatus === 'Encerrado' || liveSnStatus === 'Encerrado - Omitido'; if (snIsFinal) { return { reopened: false, glpiSolved: true }; } await TicketGlpiModel.updateStatus(ticket.glpi_ticket_id, 'Em Atendimento'); await TicketSyncModel.updateStatus(ticket.sn_ticket_id, 'synced', 'synced'); logInfo(`Reabertura detectada no SN para ticket ${ticket.sn_ticket_id}. GLPI ${ticket.glpi_ticket_id} retornou para Em Atendimento.`); return { reopened: true, glpiSolved: true }; }; const processCommentsController = async () => { const ticketsToMonitor = await TicketSyncModel.getTicketsToMonitor(); logInfo(`Tickets em monitoramento: ${ticketsToMonitor.length}`); for (const ticket of ticketsToMonitor) { const reopenState = await ensureReopenFromSNWhenGlpiSolved(ticket); const reopenedThisCycle = reopenState.reopened; const glpiWasSolved = reopenState.glpiSolved; if (glpiWasSolved && !reopenedThisCycle) { logInfo(`Ticket ${ticket.glpi_ticket_id} permanece Solucionado no GLPI. Comentarios SN -> GLPI bloqueados ate reabertura.`); await syncCommentsGlpitoSN(ticket); continue; } const comments = await fetchCommentsFromServiceNow(ticket); if (comments.length !== 0) { await syncCommentsSNtoGlpi(comments, ticket, { highlightReopenContext: reopenedThisCycle }); } await syncCommentsGlpitoSN(ticket); } }; module.exports = { processCommentsController };