snglpi/src/services/glpiService.js

92 lines
3.5 KiB
JavaScript
Raw Normal View History

2025-08-30 19:04:35 -03:00
// src/services/glpiService.js
const TicketSnModel = require('../models/ticketSnModel'); // SEU MODEL do PostgreSQL
const TicketGlpiModel = require('../models/ticketGlpiModel'); // Model do GLPI
const { logInfo, logError } = require('../utils/logger');
2025-08-30 19:04:35 -03:00
class GlpiService {
// Método principal que o controller vai chamar
static async syncTicketsToGlpi() {
try {
logInfo('🔄 Iniciando sincronização para GLPI...');
// 1. Buscar tickets pendentes usando SEU MODEL
const pendingTickets = await TicketSnModel.getPendingTickets();
if (pendingTickets.length === 0) {
logInfo('✅ Nenhum ticket pendente para sincronizar');
return;
2025-08-30 19:04:35 -03:00
}
logInfo(`📋 Encontrados ${pendingTickets.length} tickets para sincronizar`);
// 2. Processar cada ticket
for (const ticket of pendingTickets) {
await this.processSingleTicket(ticket);
2025-08-30 19:04:35 -03:00
}
logInfo('🎉 Sincronização com GLPI concluída!');
} catch (error) {
logError(error, '❌ Erro na sincronização GLPI');
throw error;
}
2025-08-30 19:04:35 -03:00
}
// Processar um ticket individual
static async processSingleTicket(ticket) {
try {
logInfo(`🔍 Processando ticket: ${ticket.ticket_number}`);
// 1. Verificar se já existe no GLPI (evitar duplicatas)
const existingTicket = await TicketGlpiModel.ticketExists(ticket.ticket_number);
if (existingTicket) {
logInfo(`⏭️ Ticket já existe no GLPI: ${existingTicket}`);
await TicketSnModel.updateSyncStatus(ticket.id, 'duplicate', existingTicket);
return;
2025-08-30 19:04:35 -03:00
}
// 2. Converter dados para formato GLPI (O MODEL vai fazer o mapeamento)
const glpiData = {
// Dados básicos do PostgreSQL
ticket_number: ticket.ticket_number,
short_description: ticket.short_description,
description: ticket.description,
// Dados do ServiceNow originais (se necessário para mapeamento)
state: ticket.status, // Já vem do ServiceNow
urgency: '2', // Default - O MODEL vai mapear
impact: '2', // Default - O MODEL vai mapear
priority: '3', // Default - O MODEL vai mapear
// Localização para de/para
location_name: ticket.location_name,
// Datas
opened_at: ticket.opened_at,
updated_at: ticket.updated_at
};
// 3. Inserir no GLPI (O MODEL faz INSERT e mapeamento)
const glpiTicketId = await TicketGlpiModel.createTicket(glpiData);
// 4. Atualizar status no PostgreSQL usando SEU MODEL
await TicketSnModel.updateSyncStatus(ticket.id, 'completed', glpiTicketId);
logInfo(`✅ Ticket ${ticket.ticket_number} sincronizado! GLPI ID: ${glpiTicketId}`);
} catch (error) {
logError(error, `❌ Erro no ticket ${ticket.ticket_number}`);
await TicketSnModel.updateSyncStatus(ticket.id, 'error');
}
2025-08-30 19:04:35 -03:00
}
}
const syncTicketsToGlpi = async () => {
await GlpiService.syncTicketsToGlpi();
2025-08-30 19:04:35 -03:00
};
module.exports = {
syncTicketsToGlpi,
GlpiService
2025-08-30 19:04:35 -03:00
};