2025-10-07 17:57:23 -03:00
// controller/processController.js
const hubsoftModel = require ( '../model/hubsoftModel.js' ) ;
const hubglpiModel = require ( '../model/hubglpiModel.js' ) ;
2025-10-08 18:55:29 -03:00
const glpiModel = require ( '../model/glpiModel.js' ) ;
const { logError , logInfo } = require ( '../utils/logger' ) ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
// ================================================================================
// Constantes e Configurações
// ================================================================================
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
const statusAtendimentoHubGlpi = {
1 : 'Pendente' ,
2 : 'Em atendimento' ,
3 : 'Resolvido' ,
31 : 'Pendente' ,
32 : 'Pendente' ,
33 : 'Novo'
} ;
const statusAtendimentoGLPI = {
'Novo' : 1 ,
'Pendente' : 4 ,
'Em atendimento' : 2 ,
'Resolvido' : 5
} ;
2025-10-13 16:20:11 -03:00
const categoriaGLPI = {
'Lan-to-Lan 100 Mbps' : 5708 ,
'Link de Internet Dedicado 2 Gbps Full Duplex' : 5707 ,
'Lan-to-Lan' : 5707 ,
'Lan-to-Lan 500 Mbps' : 5708 ,
'Link de internet - Banda Larga' : 5708 ,
'Lan-to-Lan 700 Mbps' : 5708 ,
'Link de Internet Dedicado 20 Mbps Full Duplex' : 5707 ,
'Lan-to-Lan 300 Mbps' : 5708 ,
'Link de Internet Dedicado 5Gbs + Burst 5Gbs Burs Full Duplex Anti DDOS' : 5707 ,
'Link de Internet - Banda Larga - 500 Mbps' : 5708 ,
'Link de Internet Dedicado 600Mbps Full Duplex' : 5707 ,
'Link de Internet - Banda Larga - 1Gbps' : 5707 ,
'Link de Internet Dedicado 1Gbps Full Duplex' : 5707 ,
'Link de Internet Dedicado Full Duplex' : 5707 ,
'Fibra Apagada' : 5706 ,
'Link de Internet - Banda Larga - 100 Mbps' : 5708 ,
'Canal de Voz IP' : 5715 ,
'Link de Internet Dedicado 500Mbps Full Duplex' : 5707 ,
'Lan-to-Lan 200 Mbps' : 5708 ,
'Lan-to-Lan 50 Mbps' : 5708 ,
'Linha IP - Limitado' : 5715 ,
'PABX IP Cloud' : 5717 ,
'Link de Internet Dedicado 100 Mbps Full Duplex' : 5707 ,
'Link de Internet Dedicado 200 Mbps Full Duplex' : 5707 ,
'Link de Internet - Banda Larga - 200 Mbps' : 5708 ,
'Link de Internet - Banda Larga - 300 Mbps' : 5708 ,
'Link de Internet - Banda Larga - 700 Mbps' : 5708 ,
'Link de Internet Dedicado 300 Mbps Full Duplex' : 5707 ,
'Link de Internet Dedicado 50Mbps Full Duplex' : 5707 ,
'Link de Internet Dedicado 10 Mbps Full Duplex' : 5707 ,
'Link de Internet Dedicado 30 Mbps Full Duplex' : 5707 ,
'PABX IP - Até 30 ramais com telefones IPs (CAOA ESTADO DE SP)' : 5717 ,
'Lan-to-Lan 1GB' : 5707 ,
'PABX IP - Até 30 ramais com telefones IPs (CAOA OUTROS ESTADOS)' : 5717 ,
'Link de Internet Dedicado 700MB Full Duplex' : 5707 ,
'Link de Internet Dedicado - Temporário' : 5707
}
2025-10-08 18:55:29 -03:00
// ================================================================================
// Funções Utilitárias
// ================================================================================
// Formata a descrição do ticket em HTML
const formatDescription = ( ticketData ) => {
2025-10-10 09:06:44 -03:00
let htmlDescription = `
< table style = "width:100%; border-collapse: collapse;" >
< tr style = "background-color:#f2f2f2;" >
< th style = "padding: 8px; border: 1px solid #ddd; text-align: left;" > Campo < / t h >
< th style = "padding: 8px; border: 1px solid #ddd; text-align: left;" > Valor < / t h >
< / t r >
< tr >
< td style = "padding: 8px; border: 1px solid #ddd;" > < strong > Nome : < / s t r o n g > < / t d >
< td style = "padding: 8px; border: 1px solid #ddd;" > $ { ticketData . cliente _nome } < / t d >
< / t r >
< tr >
< td style = "padding: 8px; border: 1px solid #ddd;" > < strong > Codigo : < / s t r o n g > < / t d >
< td style = "padding: 8px; border: 1px solid #ddd;" > $ { ticketData . codigo _cliente } < / t d >
< / t r >
< tr >
< td style = "padding: 8px; border: 1px solid #ddd;" > < strong > Serviço : < / s t r o n g > < / t d >
< td style = "padding: 8px; border: 1px solid #ddd;" > $ { ticketData . servico _nome } < / t d >
< / t r >
< tr >
< td style = "padding: 8px; border: 1px solid #ddd;" > < strong > Ticket Mundiale < / s t r o n g > < / t d >
< td style = "padding: 8px; border: 1px solid #ddd;" > $ { ticketData . ticket _mundiale } < / t d >
< / t r >
< tr >
2025-10-10 15:05:05 -03:00
< td style = "padding: 8px; border: 1px solid #ddd;" > < strong > Protocolo Hub : < / s t r o n g > < / t d >
2025-10-10 09:06:44 -03:00
< td style = "padding: 8px; border: 1px solid #ddd;" > $ { ticketData . protocolo _hub || 'N/A' } < / t d >
< / t r >
< / t a b l e >
` ;
2025-10-08 18:55:29 -03:00
return htmlDescription ;
} ;
// Formata os dados do ticket para o GLPI
const formatTicketDataForGlpi = async ( ticketData ) => {
const formattedData = {
... ticketData ,
status _atendimento : statusAtendimentoGLPI [ ticketData . status _atendimento ] || 1 ,
date _mod : new Date ( ) ,
2025-10-14 15:38:16 -03:00
user _id _recipient : 1100 ,
2025-10-10 09:06:44 -03:00
descricao _abertura : formatDescription ( ticketData ) ,
2025-10-08 18:55:29 -03:00
urgency : 3 ,
impact : 3 ,
priority : 3 ,
type : 1 ,
2025-10-13 16:20:11 -03:00
itilcategories _id : categoriaGLPI [ ticketData . servico _nome ] || 1 ,
2025-10-08 18:55:29 -03:00
date _creation : new Date ( ) ,
2025-10-10 09:06:44 -03:00
// entidades_id: 0 //await glpiModel.selectEntityId() //TODO: Implementar a busca da entidade
2025-10-08 18:55:29 -03:00
} ;
return formattedData ;
} ;
// ================================================================================
// Funções de Integração
// ================================================================================
const createGlpiTicket = async ( ticketData ) => {
2025-10-07 17:57:23 -03:00
try {
2025-10-08 18:55:29 -03:00
2025-10-13 00:42:38 -03:00
const formattedTicketData = await formatTicketDataForGlpi ( ticketData ) ;
2025-10-10 09:06:44 -03:00
const glpiTicket = await glpiModel . insertTicket ( formattedTicketData ) ;
2025-10-13 00:42:38 -03:00
logInfo ( ` Ticket criado no GLPI: ${ glpiTicket . insertId } ` ) ;
2025-10-10 15:05:05 -03:00
2025-10-08 18:55:29 -03:00
2025-10-13 00:42:38 -03:00
//Atualiza que ticket foi criado
2025-10-10 16:28:06 -03:00
ticketData . status _sync = 'created_glpi' ;
2025-10-13 00:42:38 -03:00
ticketData . glpi _ticket _id = glpiTicket . insertId ;
ticketData . created _at = new Date ( ) ;
ticketData . updated _at = new Date ( ) ;
2025-10-10 10:28:32 -03:00
2025-10-10 16:28:06 -03:00
const updateSyncData = await hubglpiModel . update _syncData ( ticketData ) ;
2025-10-13 00:42:38 -03:00
logInfo ( ` Sync Data atualizado com o ID do ticket do GLPI: ${ updateSyncData . glpi _ticket _id } ` ) ;
try {
2025-10-14 15:47:51 -03:00
//Insetindo ao grupo Operacao NOC
2025-10-13 00:42:38 -03:00
await glpiModel . insertGroupTickets ( glpiTicket . insertId ) ;
logInfo ( ` Atribuido grupo Operação NOC ao ticket no GLPI: ${ glpiTicket . insertId } ` )
} catch ( error ) {
const updateSyncDataError = await hubglpiModel . update _syncaDataError ( error . message , ticketData . id _atendimento )
logError ( ` Erro ao criar ticket no GLPI. Sync Data atualizado com a mensagem de erro: ${ error } ` ) ;
}
2025-10-08 18:55:29 -03:00
} catch ( error ) {
2025-10-13 00:42:38 -03:00
const updateSyncDataError = await hubglpiModel . update _syncaDataError ( error . message , ticketData . id _atendimento )
logError ( ` Erro ao criar ticket no GLPI. Sync Data atualizado com a mensagem de erro: ${ error } ` ) ;
2025-10-08 18:55:29 -03:00
}
} ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
const processTicketFromHubSoft = async ( atendimento ) => {
const ticketData = {
id _atendimento : atendimento . id _atendimento ,
id _atendimento _status : atendimento . id _atendimento _status ,
codigo _servico : String ( atendimento . id _cliente _servico || '' ) , // Garante que seja uma string
protocolo _hub : atendimento . protocolo ,
servico _nome : atendimento . descricao ,
descricao _abertura : atendimento . descricao _abertura ,
data _cadastro : atendimento . data _cadastro ,
cliente _nome : atendimento . nome _contato ,
codigo _cliente : atendimento . codigo _cliente ,
descricao : atendimento . descricao
} ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
ticketData . status _atendimento = statusAtendimentoHubGlpi [ ticketData . id _atendimento _status ] || ticketData . id _atendimento _status ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
ticketData . descricao _abertura = ticketData . descricao _abertura . replace ( /[^0-9]/g , '' ) ;
ticketData . ticket _mundiale = parseInt ( ticketData . descricao _abertura ) || null ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
return ticketData ;
} ;
const saveTicketToHubGlpi = async ( ticketData ) => {
try {
const insertedTicket = await hubglpiModel . insertTicket ( ticketData ) ;
2025-10-13 00:42:38 -03:00
logInfo ( ` Ticket inserido/atualizado na tabela hubsoft_tickets: ${ insertedTicket . protocolo _hub } ` ) ;
2025-10-08 18:55:29 -03:00
2025-10-13 00:42:38 -03:00
await hubglpiModel . insertSyncData ( ticketData . id _atendimento ) ;
logInfo ( 'Dados inseridos/atualizados na tabela sync_data' ) ;
2025-10-08 18:55:29 -03:00
return insertedTicket ;
} catch ( error ) {
2025-10-13 00:42:38 -03:00
logError ( ` Erro ao salvar ticket no hubglpi: ${ error } ` ) ;
2025-10-08 18:55:29 -03:00
throw error ; // Rejeita a promise para que o erro seja tratado no nível superior
}
} ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
const processAtendimento = async ( ticketData ) => {
2025-10-13 00:42:38 -03:00
2025-10-08 18:55:29 -03:00
try {
2025-10-13 00:42:38 -03:00
const glpiTicketId = await hubglpiModel . getGlpiTicketIdByAtendimentoId ( ticketData . id _atendimento ) ;
if ( glpiTicketId ) {
logInfo ( ` Ticket já inserido no GLPI para id_atendimento ${ ticketData . id _atendimento } , pulando criação. ` ) ;
ticketData . status _sync = 'created_glpi' ;
ticketData . glpi _ticket _id = glpiTicketId ;
await hubglpiModel . update _syncData ( ticketData ) ;
return ;
}
2025-10-08 18:55:29 -03:00
2025-10-10 09:06:44 -03:00
const titulo = ` Mundiale - Protocolo: ${ ticketData . ticket _mundiale } - ${ ticketData . cliente _nome } ` ;
ticketData . titulo = titulo ;
const selectedEntityCodServico = await glpiModel . selectEntityId ( ticketData . codigo _servico ) ;
2025-10-14 15:47:51 -03:00
// Prioriza a entidade do serviço; se não existir tenta pelo cliente; fallback para 0
2025-10-15 08:41:24 -03:00
if ( selectedEntityCodServico . name . include ( ticketData . codigo _cliente ) ) {
ticketData . entidades _id = selectedEntityCodServico . id ;
logInfo ( ` Entidade encontrada por serviço: ${ selectedEntityCodServico . name } ` ) ;
2025-10-10 09:06:44 -03:00
} else {
2025-10-14 15:47:51 -03:00
const selectedEntityCodCliente = await glpiModel . selectEntityId ( ticketData . codigo _cliente ) ;
if ( selectedEntityCodCliente ) {
2025-10-15 08:41:24 -03:00
ticketData . entidades _id = selectedEntityCodCliente . id ;
logInfo ( ` Entidade encontrada por cliente: ${ selectedEntityCodCliente . name } ` ) ;
2025-10-14 15:47:51 -03:00
} else {
ticketData . entidades _id = 0 ;
2025-10-15 08:41:24 -03:00
logInfo ( ` Nenhuma entidade encontrada para serviço=" ${ ticketData . codigo _servico } " ou cliente=" ${ ticketData . codigo _cliente } ", atribuindo contratos ativos ` ) ;
2025-10-14 15:47:51 -03:00
}
}
2025-10-08 18:55:29 -03:00
await createGlpiTicket ( ticketData ) ;
2025-10-07 17:57:23 -03:00
2025-10-08 18:55:29 -03:00
} catch ( error ) {
2025-10-13 00:42:38 -03:00
console . error ( ` Erro ao processar atendimento ${ ticketData . id _atendimento } : ` , error ) ;
2025-10-08 18:55:29 -03:00
}
} ;
// ================================================================================
// Função Principal (com opção de pular a etapa do HubSoft)
// ================================================================================
const processaAtendimentos = async ( skipHubSoft = false ) => {
try {
let atendimentosDB = [ ] ;
if ( ! skipHubSoft ) {
// Esta parte depende da VPN
2025-10-13 00:42:38 -03:00
logInfo ( 'Buscando atendimentos do HubSoft...' ) ;
2025-10-08 18:55:29 -03:00
atendimentosDB = await hubsoftModel . getAtendimentosFromDB ( ) ;
2025-10-13 00:42:38 -03:00
logInfo ( ` Total de atendimentos obtidos do HubSoft: ${ atendimentosDB . length } ` ) ;
2025-10-08 18:55:29 -03:00
for ( const atendimento of atendimentosDB ) {
try {
// Processa o ticket do HubSoft
const ticketData = await processTicketFromHubSoft ( atendimento ) ;
// Salva no banco intermediário (hubglpi)
await saveTicketToHubGlpi ( ticketData ) ;
}
catch ( error ) {
2025-10-13 00:42:38 -03:00
logError ( ` Erro ao processar atendimento ${ atendimento . id _atendimento } : ` , error ) ;
2025-10-08 18:55:29 -03:00
}
}
} else {
2025-10-13 00:42:38 -03:00
logInfo ( 'Pulando a busca de atendimentos do HubSoft (skipHubSoft = true)' ) ;
2025-10-07 17:57:23 -03:00
}
2025-10-08 18:55:29 -03:00
// Coletando atendimentos do banco intermediário (hubglpi)
atendimentosDB = await hubglpiModel . getTicketDataPending ( ) ;
for ( const atendimento of atendimentosDB ) {
try {
// Processa o atendimento para o GLPI
await processAtendimento ( atendimento ) ;
2025-10-13 00:42:38 -03:00
2025-10-08 18:55:29 -03:00
} catch ( error ) {
2025-10-13 00:42:38 -03:00
logError ( ` Erro ao processar atendimento ${ atendimento . id _atendimento } :, ${ error } ` ) ;
2025-10-08 18:55:29 -03:00
}
}
2025-10-07 17:57:23 -03:00
} catch ( error ) {
2025-10-13 00:42:38 -03:00
logError ( ` Erro ao processar atendimentos: ${ error } ` ) ;
2025-10-08 18:55:29 -03:00
}
} ;
2025-10-07 17:57:23 -03:00
module . exports = {
2025-10-08 18:55:29 -03:00
processaAtendimentos ,
processAtendimento ,
formatTicketDataForGlpi ,
formatDescription
} ;