FEATURE/FIX: Ajusta encerramento SN->GLPI e direção do bastão da verdade
- Adiciona comentário estilizado no GLPI quando SN marca Resolvido, Encerrado ou Encerrado - Omitido - Marca Sync como "closed" para remover o chamado da fila de sincronização - Corrige a direção do bastão da verdade para preservar SNOW -> GLPI quando SN foi a última origem
This commit is contained in:
parent
a4f6797c8f
commit
eda8f558fd
@ -4,7 +4,7 @@ const TicketGlpiModel = require('../models/ticketGlpiModel');
|
|||||||
const { logInfo, logError, logWarning } = require('../utils/logger');
|
const { logInfo, logError, logWarning } = require('../utils/logger');
|
||||||
const { stripHTML } = require('../utils/commentSanitizer');
|
const { stripHTML } = require('../utils/commentSanitizer');
|
||||||
const { closeTicketInServiceNow, updateStatusInServiceNow, addWorkNoteToServiceNow } = require('../services/servicenowService');
|
const { closeTicketInServiceNow, updateStatusInServiceNow, addWorkNoteToServiceNow } = require('../services/servicenowService');
|
||||||
const { closeTicketInGlpi } = require('../services/glpiTicketService');
|
const { addServiceNowClosureNoteToGlpi } = require('../services/glpiTicketService');
|
||||||
|
|
||||||
const processStatusAndClosureController = async () => {
|
const processStatusAndClosureController = async () => {
|
||||||
logInfo('Iniciando processamento de status e fechamento de tickets...');
|
logInfo('Iniciando processamento de status e fechamento de tickets...');
|
||||||
@ -40,9 +40,12 @@ const processStatusAndClosureController = async () => {
|
|||||||
|
|
||||||
// Compara o status real do GLPI com o status que temos do ServiceNow
|
// Compara o status real do GLPI com o status que temos do ServiceNow
|
||||||
if (glpiLiveStatus !== null && glpiLiveStatusAsString !== snCurrentStatus) {
|
if (glpiLiveStatus !== null && glpiLiveStatusAsString !== snCurrentStatus) {
|
||||||
logInfo(`Mudança de status detectada no GLPI para o ticket ${ticket.glpi_ticket_id}. GLPI está como '${glpiLiveStatusAsString}', SN está como '${snCurrentStatus}'.`);
|
logInfo(`Mudanca de status detectada no GLPI para o ticket ${ticket.glpi_ticket_id}. GLPI esta como '${glpiLiveStatusAsString}', SN esta como '${snCurrentStatus}'.`);
|
||||||
// Se uma mudança foi detectada no GLPI, forçamos o "bastão" para ele.
|
if (ticket.source_last !== 'SNOW') {
|
||||||
ticket.source_last = 'GLPI';
|
ticket.source_last = 'GLPI';
|
||||||
|
} else {
|
||||||
|
logInfo(`Direcao mantida como SNOW -> GLPI para o ticket ${ticketSnDetails.ticket_number}.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= LÓGICA SNOW -> GLPI =================
|
// ================= LÓGICA SNOW -> GLPI =================
|
||||||
@ -56,17 +59,22 @@ const processStatusAndClosureController = async () => {
|
|||||||
// Se o ticket no GLPI está permanentemente Fechado (6), não fazemos nada.
|
// Se o ticket no GLPI está permanentemente Fechado (6), não fazemos nada.
|
||||||
if (glpiCurrentStatus === 6) {
|
if (glpiCurrentStatus === 6) {
|
||||||
logWarning(`Ticket GLPI ${ticket.glpi_ticket_id} está permanentemente Fechado (6). Ação de reabertura pelo SN ('${snCurrentStatus}') foi bloqueada.`);
|
logWarning(`Ticket GLPI ${ticket.glpi_ticket_id} está permanentemente Fechado (6). Ação de reabertura pelo SN ('${snCurrentStatus}') foi bloqueada.`);
|
||||||
} else if (snCurrentStatus === 'Resolvido' && glpiCurrentStatus !== 5) { // SN foi para 'Resolved' e GLPI ainda não está 'Solucionado'
|
} else if (snCurrentStatus === 'Resolvido') {
|
||||||
logInfo(`SN ${ticketSnDetails.ticket_number} foi Resolvido. Sincronizando para GLPI...`);
|
logInfo(`SN ${ticketSnDetails.ticket_number} foi Resolvido. Enviando nota para GLPI sem fechar o chamado...`);
|
||||||
await closeTicketInGlpi(ticket);
|
|
||||||
await TicketSyncModel.updateStatus(ticket.sn_ticket_id, 'solved', 'solved');
|
// Regra de negocio: resolucao vinda do SN nao fecha no GLPI.
|
||||||
} else if (snCurrentStatus === 'Resolvido' && glpiCurrentStatus === 5) {
|
// Apenas registra uma nota e remove o ticket do monitoramento da integracao.
|
||||||
// Ambos já estão resolvidos, nenhuma ação necessária.
|
const collaboratorName = ticketSnDetails.updated_by || ticketSnDetails.closed_by || null;
|
||||||
logInfo(`SN ${ticketSnDetails.ticket_number} e GLPI ${ticket.glpi_ticket_id} já estão no estado Resolvido/Solucionado. Nenhuma ação necessária.`);
|
await addServiceNowClosureNoteToGlpi(ticket, collaboratorName, 'solucionado');
|
||||||
|
await TicketSyncModel.updateStatusAndSourceLast(ticket.sn_ticket_id, 'closed', 'closed', 'SNOW');
|
||||||
} else if (snCurrentStatus === 'Encerrado - Omitido' || snCurrentStatus === 'Encerrado') { // SN foi para 'Closed'
|
} else if (snCurrentStatus === 'Encerrado - Omitido' || snCurrentStatus === 'Encerrado') { // SN foi para 'Closed'
|
||||||
logInfo(`SN ${ticketSnDetails.ticket_number} foi Fechado. Sincronizando para GLPI...`);
|
logInfo(`SN ${ticketSnDetails.ticket_number} foi Fechado. Enviando nota para GLPI sem fechar o chamado...`);
|
||||||
await TicketGlpiModel.forceCloseTicket(ticket.glpi_ticket_id);
|
|
||||||
await TicketSyncModel.updateStatus(ticket.sn_ticket_id, 'closed', 'closed');
|
// Regra de negocio: encerramento vindo do SN nao fecha no GLPI.
|
||||||
|
// Apenas registra uma nota e remove o ticket do monitoramento da integracao.
|
||||||
|
const collaboratorName = ticketSnDetails.updated_by || ticketSnDetails.closed_by || null;
|
||||||
|
await addServiceNowClosureNoteToGlpi(ticket, collaboratorName, 'encerrado');
|
||||||
|
await TicketSyncModel.updateStatusAndSourceLast(ticket.sn_ticket_id, 'closed', 'closed', 'SNOW');
|
||||||
} else {
|
} else {
|
||||||
// Se estiver Solucionado (5) ou em qualquer outro estado, permite a atualização (reabertura).
|
// Se estiver Solucionado (5) ou em qualquer outro estado, permite a atualização (reabertura).
|
||||||
await TicketGlpiModel.updateStatus(ticket.glpi_ticket_id, snCurrentStatus);
|
await TicketGlpiModel.updateStatus(ticket.glpi_ticket_id, snCurrentStatus);
|
||||||
|
|||||||
@ -147,6 +147,36 @@ const checkGlpiStatusChanges = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addServiceNowClosureNoteToGlpi = async (ticket, collaboratorName, finalStatus = 'encerrado') => {
|
||||||
|
try {
|
||||||
|
const resolvedBy = collaboratorName && collaboratorName.trim()
|
||||||
|
? collaboratorName.trim()
|
||||||
|
: 'colaborador CAOA';
|
||||||
|
const statusText = finalStatus === 'solucionado'
|
||||||
|
? 'Chamado solucionado no Service Now pela CAOA.'
|
||||||
|
: 'Chamado encerrado no Service Now pela CAOA.';
|
||||||
|
|
||||||
|
const styledMessage = `
|
||||||
|
<div style="border:1px solid #d6e9ff; border-left:4px solid #2b6cb0; background:#f7fbff; padding:12px; border-radius:4px;">
|
||||||
|
<div style="font-weight:700; color:#1a365d; margin-bottom:6px;">Atualizacao automatica de encerramento</div>
|
||||||
|
<div style="color:#2d3748;">
|
||||||
|
${statusText}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:8px; color:#4a5568; font-size:12px;">
|
||||||
|
Responsavel informado: ${resolvedBy}
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
await TicketGlpiModel.insertComment({ content: styledMessage }, ticket.glpi_ticket_id);
|
||||||
|
await TicketSyncModel.updateLastSync(ticket.sn_ticket_id, 'glpi');
|
||||||
|
logInfo(`Nota de encerramento do ServiceNow adicionada ao GLPI ${ticket.glpi_ticket_id}.`);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
logError(error, `Falha ao adicionar nota de encerramento do SN no GLPI ${ticket.glpi_ticket_id}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const closeTicketInGlpi = async (ticket) => {
|
const closeTicketInGlpi = async (ticket) => {
|
||||||
try {
|
try {
|
||||||
logInfo(`🔒 Iniciando fechamento do chamado GLPI ${ticket.glpi_ticket_id}...`);
|
logInfo(`🔒 Iniciando fechamento do chamado GLPI ${ticket.glpi_ticket_id}...`);
|
||||||
@ -167,7 +197,8 @@ const closeTicketInGlpi = async (ticket) => {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
syncTicketsToGlpi,
|
syncTicketsToGlpi,
|
||||||
checkGlpiStatusChanges,
|
checkGlpiStatusChanges,
|
||||||
closeTicketInGlpi
|
closeTicketInGlpi,
|
||||||
|
addServiceNowClosureNoteToGlpi
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user