From 3b6d78152d6c4ee4fbaaaf29f9e17e0e3e285045 Mon Sep 17 00:00:00 2001 From: Rafael Lopes Date: Fri, 10 Oct 2025 08:12:26 -0300 Subject: [PATCH] WIP --- src/app.js | 2 +- src/controllers/glpiController.js | 4 +- src/controllers/hubsoftController.js | 0 src/controllers/servicenowController.js | 4 +- src/models/ticketSyncModel.js | 17 ++++++- src/models/ticketUpdateModel.js | 30 ++++++++++-- src/services/glpiCommentService.js | 22 ++++++++- src/services/servicenowCommentService.js | 12 ----- src/services/servicenowService.js | 62 +++++++++++++++++++++++- 9 files changed, 126 insertions(+), 27 deletions(-) delete mode 100644 src/controllers/hubsoftController.js delete mode 100644 src/services/servicenowCommentService.js diff --git a/src/app.js b/src/app.js index e71b555..d82acbc 100644 --- a/src/app.js +++ b/src/app.js @@ -11,7 +11,7 @@ logInfo('Aplicação iniciada', { async function main() { try { await snServices(); - //await glpiServices(); + await glpiServices(); } catch (error) { logInfo('Erro na aplicação:', error); } diff --git a/src/controllers/glpiController.js b/src/controllers/glpiController.js index 7845e04..a80268a 100644 --- a/src/controllers/glpiController.js +++ b/src/controllers/glpiController.js @@ -1,10 +1,10 @@ // src/controllers/glpiController.js const { syncTicketsToGlpi } = require('../services/glpiTicketService'); -const { syncCommentsGlpi } = require('../services/glpiCommentService'); +const { syncCommentsGlpitoSN } = require('../services/glpiCommentService'); const glpiServices = async () => { //await syncTicketsToGlpi(); - await syncCommentsGlpi(); + await syncCommentsGlpitoSN(); } module.exports = { diff --git a/src/controllers/hubsoftController.js b/src/controllers/hubsoftController.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/controllers/servicenowController.js b/src/controllers/servicenowController.js index 32d19ce..303bd11 100644 --- a/src/controllers/servicenowController.js +++ b/src/controllers/servicenowController.js @@ -1,9 +1,9 @@ -const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, getAllCommentsFromServiceNow } = require('../services/servicenowService'); +const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, fetchCommentsFromServiceNow } = require('../services/servicenowService'); const snServices = async () => { //await fetchTicketsFromServiceNow(); //await fetchRequestsFromServiceNow(); - await getAllCommentsFromServiceNow(626) + await fetchCommentsFromServiceNow(626) } module.exports = { diff --git a/src/models/ticketSyncModel.js b/src/models/ticketSyncModel.js index 4beee2b..6100691 100644 --- a/src/models/ticketSyncModel.js +++ b/src/models/ticketSyncModel.js @@ -26,7 +26,8 @@ class TicketSyncModel { throw error; } } - + + // Buscar o ID de sincronização baseado no glpi_ticket_id static async getIdSyncByGlpiId(glpiTicketId) { try { @@ -39,6 +40,20 @@ class TicketSyncModel { } } + // Buscar o ID de sincronização baseado no sn_ticket_id + static async getIdSyncBySnId(snTicketId) { + try { + const query = 'SELECT id FROM ticket_sync WHERE sn_ticket_id = $1'; + const { rows } = await pool.query(query, [snTicketId]); + return rows[0] ? rows[0].id : null; + } catch (error) { + logError(error, `❌ Erro ao buscar ID de sincronização por GLPI ID: ${glpiTicketId}`); + throw error; + } + } + + + } /** * @module TicketSyncModel diff --git a/src/models/ticketUpdateModel.js b/src/models/ticketUpdateModel.js index 6a68fe9..93df78a 100644 --- a/src/models/ticketUpdateModel.js +++ b/src/models/ticketUpdateModel.js @@ -8,6 +8,15 @@ class TicketUpdateModel { const query = ` INSERT INTO ticket_updates (ticket_sync_id, update_type, source_system, content, author, created_at, updated_at, source_id, destiny_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (source_id) DO UPDATE SET + ticket_sync_id = $1, + update_type = $2, + source_system = $3, + content = $4, + author = $5, + created_at = $6, + updated_at = $7, + destiny_id = $9 RETURNING id; `; const values = [ @@ -15,7 +24,7 @@ class TicketUpdateModel { 'note', updateData.source_system, updateData.content, - 'Sothis', + updateData.author, updateData.created_at, updateData.updated_at, updateData.source_id, @@ -30,6 +39,19 @@ class TicketUpdateModel { } } + //Buscar o ID de sincronização baseado no source_id + static async getIdSyncBySourceId(sourceId) { + try { + const query = 'SELECT id FROM ticket_updates WHERE source_id = $1'; + const { rows } = await pool.query(query, [sourceId]); + return rows[0] ? rows[0].id : null; + } catch (error) { + logError(error, `❌ Erro ao buscar ID de sincronização por GLPI ID: ${sourceId}`); + throw error; + } + } + + static async getByTicketSyncIdAndSourceId(ticketSyncId, sourceId) { try { const query = ` @@ -43,11 +65,9 @@ class TicketUpdateModel { throw error; } } - static async getCommentSync(glpiTicketId, sourceId) { + static async getCommentSync(glpiTicketId, sourceId) { const ticketSyncModel = require('./ticketSyncModel'); - const ticketSyncId = await ticketSyncModel.getIdSyncByGlpiId(glpiTicketId); - - + const ticketSyncId = await TicketUpdateModel.getIdSyncBySourceId(sourceId); if (!ticketSyncId) { return null; diff --git a/src/services/glpiCommentService.js b/src/services/glpiCommentService.js index e7bee36..016a5e8 100644 --- a/src/services/glpiCommentService.js +++ b/src/services/glpiCommentService.js @@ -8,7 +8,7 @@ const { existingCommentInServiceNow, syncCommentToServiceNow } = require('./serv const { sanitizeGLPIComment } = require('../utils/commentSanitizer'); // Sincroniza comentários do GLPI para o Banco de Dados local -const syncCommentsGlpi = async () => { +const syncCommentsGlpitoSN = async () => { try { logInfo('🔄 Iniciando sincronização de comments do GLPI para o Service Now...'); @@ -52,6 +52,7 @@ const syncCommentsGlpi = async () => { source_system: 'glpi', content: sanitizedContent, // ✅ Usa o conteúdo sanitizado created_at: new Date(comment.date_creation), + author: 'Sothis', updated_at: new Date(comment.date_mod), source_id: comment.id, destiny_id: commentExistsInSN.destiny_id @@ -110,6 +111,21 @@ const syncCommentsGlpi = async () => { } } +const syncCommentsSNtoGlpi = async () => { + try { + logInfo('🔄 Iniciando sincronização de comments do Service Now para o GLPI...'); + + + + + } + catch (error) { + logError(error, 'ServiceNow Comments'); + } +} + + + /** * @module glpiCommentService @@ -120,7 +136,9 @@ const syncCommentsGlpi = async () => { * Atualiza o status de sincronização após cada comentário processado. * Inclui logging detalhado para monitorar o progresso e identificar erros durante o processo de sincronização. */ + module.exports = { - syncCommentsGlpi + syncCommentsGlpitoSN, + syncCommentsSNtoGlpi }; diff --git a/src/services/servicenowCommentService.js b/src/services/servicenowCommentService.js deleted file mode 100644 index c442c6d..0000000 --- a/src/services/servicenowCommentService.js +++ /dev/null @@ -1,12 +0,0 @@ -const axios = require('axios'); -const apiConfig = require('../../config/apiConfig'); -const TicketSnModel = require('../models/ticketSnModel'); -const { logInfo, logError, logSync } = require('../utils/logger'); - -const syncCommentsInServiceNow = async () => { - try { - - } catch (error) { - - } -} \ No newline at end of file diff --git a/src/services/servicenowService.js b/src/services/servicenowService.js index 33e1e7d..a46a0bb 100644 --- a/src/services/servicenowService.js +++ b/src/services/servicenowService.js @@ -4,6 +4,8 @@ const apiConfig = require('../../config/apiConfig'); const TicketSnModel = require('../models/ticketSnModel'); const { logInfo, logError, logSync } = require('../utils/logger'); const fs = require('fs'); +const TicketUpdateModel = require('../models/ticketUpdateModel'); +const TicketSyncModel = require('../models/ticketSyncModel'); const fetchTicketsFromServiceNow = async () => { try { @@ -202,8 +204,10 @@ const syncCommentToServiceNow = async (ticketId, comment) => { // Deve-se atentar para a paginação da API do ServiceNow // para fins de teste, gerar um arquivo JSON com os comentários de um ticket específico -const getAllCommentsFromServiceNow = async (ticketId) => { +const fetchCommentsFromServiceNow = async (ticketId) => { try { + + console.log(`Iniciando busca de comentários do ServiceNow para o ticket SN Ticket: ${ticketId}`); const sys_id = await getTicketSysId(ticketId); if (!sys_id) { logError('sys_id não encontrado para ticket', { ticketId }); @@ -256,7 +260,61 @@ const getAllCommentsFromServiceNow = async (ticketId) => { // salvar em arquivo para análise const filename = `servicenow_comments_ticket_${ticketId}.json`; + + // Salva no arquivo fs.writeFileSync(filename, JSON.stringify(allComments, null, 2)); + + + //Trata os dados para inserir no banco intermediario apenas os tickets que não são do sys_created_by: "SOTHIS.CAOA" + const filteredComments = allComments.filter(comment => comment.sys_created_by !== 'SOTHIS.CAOA'); + + // Insere cada comment no banco intermediario + for (const comment of filteredComments) { + + + const existingComment = await TicketUpdateModel.getCommentSync(ticketId, comment.sys_id); + + + if (existingComment) { + logInfo(`Comentário: ${comment.sys_id} já existe no banco de dados`, { step: 3 }); + continue; + } else { + + + console.log(comment); + + const ticketSnId = await TicketSyncModel.getIdSyncBySnId(ticketId); + + + const commentData = { + ticket_sync_id: parseInt(ticketSnId), + source_system: 'servicenow', + content: comment.value, + created_at: new Date(comment.sys_created_on), + author: "CAOA", + updated_at: new Date(), + source_id: comment.sys_id, + destiny_id: null + }; + + commentInserted = await TicketUpdateModel.insert(commentData); + + if (commentInserted.success) { + // Insere Glpi status como pending e SN status como synced + await TicketSyncModel.updateStatus(ticketGlpiId.id, 'pending', 'synced'); + logInfo(`✅ Comentário ID ${comment.sys_id} inserido no banco! Novo ID: ${commentInserted.newId}`, { step: 4 }); + } else { + logError(`❌ Erro ao inserir comentário ID ${comment.sys_id} no banco: ${commentInserted.error}`, { step: 4 }); + } + + if (!ticketSyncId) { + logError(`❌ TicketSyncId não encontrado para o ticket GLPI ID: ${ticketId}`, { step: 4 }); + continue; + } else { + continue; + } + } + } logInfo(`💾 Backup JSON de comentários salvo: ${filename}`, { count: allComments.length }); } catch (error) { logError(error, '🚨Falha ao buscar comentários do ServiceNow'); @@ -272,5 +330,5 @@ module.exports = { getCommentId, existingCommentInServiceNow, syncCommentToServiceNow, - getAllCommentsFromServiceNow + fetchCommentsFromServiceNow } \ No newline at end of file