// src/models/ticketGlpiModel.js const glpiPool = require('../data/glpiDataBase'); const { logInfo, logError } = require('../utils/logger'); class TicketGlpiModel { // Mapeamento de status ServiceNow → GLPI static mapStatus(snState) { const statusMap = { '1': 1, // Aguardando Atendimento → Novo '2': 2, // Em Andamento → Em andamento '3': 3, // Pendente → Pendente '6': 5, // Resolvido → Resolvido '7': 6 // Fechado → Fechado }; return statusMap[snState] || 1; } // Mapeamento de prioridade static mapPriority(snPriority) { const priorityMap = { '1': 5, // Crítico → Muito alta '2': 4, // Alto → Alta '3': 3, // Moderado → Média '4': 2, // Baixo → Baixa '5': 1 // Planejamento → Muito baixa }; return priorityMap[snPriority] || 3; } // Mapeamento de categoria static mapCategory(shortDescription) { const categoryMap = { 'Problemas com Telefonia Fixa': 5717, // PABX IP Nuvem 'Problemas com Internet': 5720, // Link Dedicado 'Problemas com Wi-Fi/Rede Corporativa': 5722, // Wifi 'Wi-fi Clientes': 5722 // Wifi }; return categoryMap[shortDescription] || 5717; } // Criar ticket no GLPI static async createTicket(snTicket, mapping) { const connection = await glpiPool.getConnection(); try { await connection.beginTransaction(); // 1. Preparar dados para o GLPI const glpiTicketData = { entities_id: mapping.entityId || 1371, name: snTicket.short_description?.value || 'Sem título', date: snTicket.sys_created_on?.value ? new Date(snTicket.sys_created_on.value) : new Date(), date_mod: snTicket.sys_updated_on?.value ? new Date(snTicket.sys_updated_on.value) : new Date(), status: this.mapStatus(snTicket.state?.value), users_id_recipient: mapping.userId || 917, requesttypes_id: 1, content: snTicket.description?.value || '', urgency: this.mapUrgency(snTicket.urgency?.value), impact: this.mapImpact(snTicket.impact?.value), priority: this.mapPriority(snTicket.priority?.value), type: 1, // Incidente itilcategories_id: this.mapCategory(snTicket.short_description?.value), global_validation: 1, date_creation: snTicket.sys_created_on?.value ? new Date(snTicket.sys_created_on.value) : new Date() }; // 2. Inserir ticket principal const ticketQuery = ` INSERT INTO glpi_tickets SET ? `; const [ticketResult] = await connection.execute(ticketQuery, [glpiTicketData]); const ticketId = ticketResult.insertId; // 3. Adicionar requerente const requesterQuery = ` INSERT INTO glpi_tickets_users (tickets_id, users_id, type, use_notification, alternative_email) VALUES (?, ?, 1, 1, '') `; await connection.execute(requesterQuery, [ticketId, mapping.userId || 917]); // 4. Adicionar grupo const groupQuery = ` INSERT INTO glpi_groups_tickets (tickets_id, groups_id, type) VALUES (?, ?, 2) `; await connection.execute(groupQuery, [ticketId, mapping.groupId || 30]); await connection.commit(); logInfo(`✅ Ticket GLPI criado: ${ticketId}`, { glpi_ticket_id: ticketId, sn_ticket_number: snTicket.number?.value, location: snTicket.location?.display_value }); return ticketId; } catch (error) { await connection.rollback(); logError(error, `❌ Erro ao criar ticket GLPI para ${snTicket.number?.value}`); throw error; } finally { connection.release(); } } // Verificar se ticket já existe no GLPI static async ticketExists(snTicketNumber) { try { const query = ` SELECT id FROM glpi_tickets WHERE name LIKE ? OR content LIKE ? LIMIT 1 `; const [rows] = await glpiPool.execute(query, [ `%${snTicketNumber}%`, `%${snTicketNumber}%` ]); return rows.length > 0 ? rows[0].id : null; } catch (error) { logError(error, 'Erro ao verificar ticket existente'); return null; } } } module.exports = TicketGlpiModel;