WIP
This commit is contained in:
parent
3208e83246
commit
3b6d78152d
@ -11,7 +11,7 @@ logInfo('Aplicação iniciada', {
|
|||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
await snServices();
|
await snServices();
|
||||||
//await glpiServices();
|
await glpiServices();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logInfo('Erro na aplicação:', error);
|
logInfo('Erro na aplicação:', error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
// src/controllers/glpiController.js
|
// src/controllers/glpiController.js
|
||||||
const { syncTicketsToGlpi } = require('../services/glpiTicketService');
|
const { syncTicketsToGlpi } = require('../services/glpiTicketService');
|
||||||
const { syncCommentsGlpi } = require('../services/glpiCommentService');
|
const { syncCommentsGlpitoSN } = require('../services/glpiCommentService');
|
||||||
|
|
||||||
const glpiServices = async () => {
|
const glpiServices = async () => {
|
||||||
//await syncTicketsToGlpi();
|
//await syncTicketsToGlpi();
|
||||||
await syncCommentsGlpi();
|
await syncCommentsGlpitoSN();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, getAllCommentsFromServiceNow } = require('../services/servicenowService');
|
const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, fetchCommentsFromServiceNow } = require('../services/servicenowService');
|
||||||
|
|
||||||
const snServices = async () => {
|
const snServices = async () => {
|
||||||
//await fetchTicketsFromServiceNow();
|
//await fetchTicketsFromServiceNow();
|
||||||
//await fetchRequestsFromServiceNow();
|
//await fetchRequestsFromServiceNow();
|
||||||
await getAllCommentsFromServiceNow(626)
|
await fetchCommentsFromServiceNow(626)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ class TicketSyncModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Buscar o ID de sincronização baseado no glpi_ticket_id
|
// Buscar o ID de sincronização baseado no glpi_ticket_id
|
||||||
static async getIdSyncByGlpiId(glpiTicketId) {
|
static async getIdSyncByGlpiId(glpiTicketId) {
|
||||||
try {
|
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
|
* @module TicketSyncModel
|
||||||
|
|||||||
@ -8,6 +8,15 @@ class TicketUpdateModel {
|
|||||||
const query = `
|
const query = `
|
||||||
INSERT INTO ticket_updates (ticket_sync_id, update_type, source_system, content, author, created_at, updated_at, source_id, destiny_id)
|
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)
|
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;
|
RETURNING id;
|
||||||
`;
|
`;
|
||||||
const values = [
|
const values = [
|
||||||
@ -15,7 +24,7 @@ class TicketUpdateModel {
|
|||||||
'note',
|
'note',
|
||||||
updateData.source_system,
|
updateData.source_system,
|
||||||
updateData.content,
|
updateData.content,
|
||||||
'Sothis',
|
updateData.author,
|
||||||
updateData.created_at,
|
updateData.created_at,
|
||||||
updateData.updated_at,
|
updateData.updated_at,
|
||||||
updateData.source_id,
|
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) {
|
static async getByTicketSyncIdAndSourceId(ticketSyncId, sourceId) {
|
||||||
try {
|
try {
|
||||||
const query = `
|
const query = `
|
||||||
@ -43,11 +65,9 @@ class TicketUpdateModel {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async getCommentSync(glpiTicketId, sourceId) {
|
static async getCommentSync(glpiTicketId, sourceId) {
|
||||||
const ticketSyncModel = require('./ticketSyncModel');
|
const ticketSyncModel = require('./ticketSyncModel');
|
||||||
const ticketSyncId = await ticketSyncModel.getIdSyncByGlpiId(glpiTicketId);
|
const ticketSyncId = await TicketUpdateModel.getIdSyncBySourceId(sourceId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!ticketSyncId) {
|
if (!ticketSyncId) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const { existingCommentInServiceNow, syncCommentToServiceNow } = require('./serv
|
|||||||
const { sanitizeGLPIComment } = require('../utils/commentSanitizer');
|
const { sanitizeGLPIComment } = require('../utils/commentSanitizer');
|
||||||
|
|
||||||
// Sincroniza comentários do GLPI para o Banco de Dados local
|
// Sincroniza comentários do GLPI para o Banco de Dados local
|
||||||
const syncCommentsGlpi = async () => {
|
const syncCommentsGlpitoSN = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
logInfo('🔄 Iniciando sincronização de comments do GLPI para o Service Now...');
|
logInfo('🔄 Iniciando sincronização de comments do GLPI para o Service Now...');
|
||||||
@ -52,6 +52,7 @@ const syncCommentsGlpi = async () => {
|
|||||||
source_system: 'glpi',
|
source_system: 'glpi',
|
||||||
content: sanitizedContent, // ✅ Usa o conteúdo sanitizado
|
content: sanitizedContent, // ✅ Usa o conteúdo sanitizado
|
||||||
created_at: new Date(comment.date_creation),
|
created_at: new Date(comment.date_creation),
|
||||||
|
author: 'Sothis',
|
||||||
updated_at: new Date(comment.date_mod),
|
updated_at: new Date(comment.date_mod),
|
||||||
source_id: comment.id,
|
source_id: comment.id,
|
||||||
destiny_id: commentExistsInSN.destiny_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
|
* @module glpiCommentService
|
||||||
@ -120,7 +136,9 @@ const syncCommentsGlpi = async () => {
|
|||||||
* Atualiza o status de sincronização após cada comentário processado.
|
* 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.
|
* Inclui logging detalhado para monitorar o progresso e identificar erros durante o processo de sincronização.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
syncCommentsGlpi
|
syncCommentsGlpitoSN,
|
||||||
|
syncCommentsSNtoGlpi
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,6 +4,8 @@ const apiConfig = require('../../config/apiConfig');
|
|||||||
const TicketSnModel = require('../models/ticketSnModel');
|
const TicketSnModel = require('../models/ticketSnModel');
|
||||||
const { logInfo, logError, logSync } = require('../utils/logger');
|
const { logInfo, logError, logSync } = require('../utils/logger');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const TicketUpdateModel = require('../models/ticketUpdateModel');
|
||||||
|
const TicketSyncModel = require('../models/ticketSyncModel');
|
||||||
|
|
||||||
const fetchTicketsFromServiceNow = async () => {
|
const fetchTicketsFromServiceNow = async () => {
|
||||||
try {
|
try {
|
||||||
@ -202,8 +204,10 @@ const syncCommentToServiceNow = async (ticketId, comment) => {
|
|||||||
// Deve-se atentar para a paginação da API do ServiceNow
|
// 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
|
// 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 {
|
try {
|
||||||
|
|
||||||
|
console.log(`Iniciando busca de comentários do ServiceNow para o ticket SN Ticket: ${ticketId}`);
|
||||||
const sys_id = await getTicketSysId(ticketId);
|
const sys_id = await getTicketSysId(ticketId);
|
||||||
if (!sys_id) {
|
if (!sys_id) {
|
||||||
logError('sys_id não encontrado para ticket', { ticketId });
|
logError('sys_id não encontrado para ticket', { ticketId });
|
||||||
@ -256,7 +260,61 @@ const getAllCommentsFromServiceNow = async (ticketId) => {
|
|||||||
|
|
||||||
// salvar em arquivo para análise
|
// salvar em arquivo para análise
|
||||||
const filename = `servicenow_comments_ticket_${ticketId}.json`;
|
const filename = `servicenow_comments_ticket_${ticketId}.json`;
|
||||||
|
|
||||||
|
// Salva no arquivo
|
||||||
fs.writeFileSync(filename, JSON.stringify(allComments, null, 2));
|
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 });
|
logInfo(`💾 Backup JSON de comentários salvo: ${filename}`, { count: allComments.length });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logError(error, '🚨Falha ao buscar comentários do ServiceNow');
|
logError(error, '🚨Falha ao buscar comentários do ServiceNow');
|
||||||
@ -272,5 +330,5 @@ module.exports = {
|
|||||||
getCommentId,
|
getCommentId,
|
||||||
existingCommentInServiceNow,
|
existingCommentInServiceNow,
|
||||||
syncCommentToServiceNow,
|
syncCommentToServiceNow,
|
||||||
getAllCommentsFromServiceNow
|
fetchCommentsFromServiceNow
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user