FEATURE: Novo Cammpo adicionado!
- Campo de Justificativa adicionado para as requisições
This commit is contained in:
parent
e84647a2ba
commit
a4f6797c8f
@ -39,6 +39,8 @@ GLPI_DB_CHARSET=utf8mb4
|
|||||||
|
|
||||||
# ID do usuario padrao do GLPI para criacao de tickets e comentarios
|
# ID do usuario padrao do GLPI para criacao de tickets e comentarios
|
||||||
GLPI_DEFAULT_USER_ID=11111
|
GLPI_DEFAULT_USER_ID=11111
|
||||||
|
GLPI_REQ_DEFAULT_JUSTIFICATIVA=Chamado aberto por colaborador CAOA sem Justificativa
|
||||||
|
GLPI_REQ_DEFAULT_DESCRIPTION=Chamado aberto por colaborador CAOA sem Descricao
|
||||||
|
|
||||||
# Banco intermediario (PostgreSQL)
|
# Banco intermediario (PostgreSQL)
|
||||||
SNGLPI_DB_HOST=10.0.120.75
|
SNGLPI_DB_HOST=10.0.120.75
|
||||||
|
|||||||
@ -44,6 +44,8 @@ GLPI_DB_CHARSET=utf8mb4
|
|||||||
|
|
||||||
# ID do usuario padrao do GLPI para criacao de tickets e comentarios
|
# ID do usuario padrao do GLPI para criacao de tickets e comentarios
|
||||||
GLPI_DEFAULT_USER_ID=1118
|
GLPI_DEFAULT_USER_ID=1118
|
||||||
|
GLPI_REQ_DEFAULT_JUSTIFICATIVA=Chamado aberto por colaborador CAOA sem Justificativa
|
||||||
|
GLPI_REQ_DEFAULT_DESCRIPTION=Chamado aberto por colaborador CAOA sem Descricao
|
||||||
|
|
||||||
# --- Configuracao do Banco de Dados Intermediario (PostgreSQL) ---
|
# --- Configuracao do Banco de Dados Intermediario (PostgreSQL) ---
|
||||||
SNGLPI_DB_HOST=localhost
|
SNGLPI_DB_HOST=localhost
|
||||||
|
|||||||
@ -30,28 +30,28 @@ const processAndSaveTickets = async (tickets, type) => {
|
|||||||
let latestUpdateTimestamp = new Date(0);
|
let latestUpdateTimestamp = new Date(0);
|
||||||
for (const ticket of tickets) {
|
for (const ticket of tickets) {
|
||||||
try {
|
try {
|
||||||
if (type === 'requisicao' && (!ticket.description || ticket.description.trim() === '')) {
|
if (type === 'requisicao') {
|
||||||
logInfo(`Descricao vazia para requisicao ${ticket.number}. Buscando em sc_item_option...`);
|
const ticketNumber = typeof ticket.number === 'object' ? ticket.number?.value : ticket.number;
|
||||||
|
logInfo(`Buscando variaveis de catalogo para requisicao ${ticketNumber}.`);
|
||||||
const extraData = await fetchScItemOptionValue(ticket.sys_id, 'justificativa');
|
const extraData = await fetchScItemOptionValue(ticket.sys_id, 'justificativa');
|
||||||
const vars = {};
|
const vars = {};
|
||||||
(extraData || []).forEach(item => {
|
|
||||||
const question = item['sc_item_option.item_option_new.question_text'];
|
|
||||||
const value = item['sc_item_option.value'];
|
|
||||||
|
|
||||||
if (question === 'Select what you want') vars.whatYouWant = value;
|
(extraData || []).forEach((item) => {
|
||||||
if (question === 'Please justify the need') vars.justification = value;
|
const question = item.question_text;
|
||||||
if (question === 'Telephone') vars.telephone = value;
|
const name = item.variable_name;
|
||||||
|
const value = item.value;
|
||||||
|
|
||||||
|
if (name === 'select_what_you_want' || question === 'Select what you want') vars.whatYouWant = value;
|
||||||
|
if (name === 'please_justify_the_need' || question === 'Please justify the need') vars.justification = value;
|
||||||
|
if (name === 'telephone_favorecido_ti' || question === 'Telephone') vars.telephone = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ticket.justificativa = vars.justification || null;
|
||||||
if (vars.justification) {
|
if (vars.telephone) {
|
||||||
ticket.description = vars.justification;
|
|
||||||
logInfo(`Descricao da requisicao ${ticket.number} atualizada com valor de sc_item_option.`);
|
|
||||||
}
|
|
||||||
if (vars.telephone){
|
|
||||||
ticket.telefone = vars.telephone;
|
ticket.telefone = vars.telephone;
|
||||||
logInfo(`Telefone da requisicao ${ticket.number} atualizado com valor de sc_item_option.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logInfo(`Variaveis da requisicao ${ticketNumber}: justificativa=${ticket.justificativa ? 'ok' : 'vazia'}, telefone=${ticket.telefone ? 'ok' : 'vazio'}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id: idTableTicketSn, wasInserted } = await TicketSnModel.saveTicket(ticket, type);
|
const { id: idTableTicketSn, wasInserted } = await TicketSnModel.saveTicket(ticket, type);
|
||||||
|
|||||||
@ -4,6 +4,8 @@ const LocationMappingModel = require('./locationMappingModel');
|
|||||||
|
|
||||||
// Carrega o ID do usuário padrão do GLPI a partir das variáveis de ambiente
|
// Carrega o ID do usuário padrão do GLPI a partir das variáveis de ambiente
|
||||||
const GLPI_DEFAULT_USER_ID = parseInt(process.env.GLPI_DEFAULT_USER_ID, 10) || 1118;
|
const GLPI_DEFAULT_USER_ID = parseInt(process.env.GLPI_DEFAULT_USER_ID, 10) || 1118;
|
||||||
|
const GLPI_REQ_DEFAULT_JUSTIFICATIVA = process.env.GLPI_REQ_DEFAULT_JUSTIFICATIVA || 'Chamado aberto por colaborador CAOA sem Justificativa';
|
||||||
|
const GLPI_REQ_DEFAULT_DESCRIPTION = process.env.GLPI_REQ_DEFAULT_DESCRIPTION || 'Chamado aberto por colaborador CAOA sem Descricao';
|
||||||
|
|
||||||
class TicketGlpiModel {
|
class TicketGlpiModel {
|
||||||
|
|
||||||
@ -118,9 +120,31 @@ class TicketGlpiModel {
|
|||||||
return extractInfo(/(\d{3,4})/i, description);
|
return extractInfo(/(\d{3,4})/i, description);
|
||||||
};
|
};
|
||||||
|
|
||||||
const email = ticketData.caller_email || extractEmailFromDescription(ticketData.description) || 'N/A';
|
const rawDescription = ticketData.description;
|
||||||
const phone = ticketData.caller_phone || extractPhoneFromDescription(ticketData.description) || 'N/A';
|
const isRequest = ticketData.type === 'requisicao';
|
||||||
const ramal = ticketData.caller_ramal || extractRamalFromDescription(ticketData.description) || 'N/A';
|
const justificationForDisplay = isRequest
|
||||||
|
? (ticketData.justificativa && ticketData.justificativa.trim()
|
||||||
|
? ticketData.justificativa
|
||||||
|
: GLPI_REQ_DEFAULT_JUSTIFICATIVA)
|
||||||
|
: null;
|
||||||
|
const descriptionForDisplay = isRequest
|
||||||
|
? (rawDescription && rawDescription.trim()
|
||||||
|
? rawDescription
|
||||||
|
: GLPI_REQ_DEFAULT_DESCRIPTION)
|
||||||
|
: (rawDescription || 'N/A');
|
||||||
|
|
||||||
|
const email = ticketData.caller_email || extractEmailFromDescription(rawDescription) || 'N/A';
|
||||||
|
const phone = ticketData.caller_phone || extractPhoneFromDescription(rawDescription) || 'N/A';
|
||||||
|
const ramal = ticketData.caller_ramal || extractRamalFromDescription(rawDescription) || 'N/A';
|
||||||
|
|
||||||
|
const requestExtraHtml = isRequest
|
||||||
|
? `
|
||||||
|
<div style="margin-top: 12px; padding: 12px; border: 1px solid #d9e2ec; border-left: 4px solid #2b6cb0; background-color: #f8fbff;">
|
||||||
|
<div style="font-weight: 700; margin-bottom: 8px;">Justificativa</div>
|
||||||
|
<div style="white-space: pre-wrap;">${justificationForDisplay}</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: '';
|
||||||
|
|
||||||
let htmlDescription = `
|
let htmlDescription = `
|
||||||
<table style="width:100%; border-collapse: collapse;">
|
<table style="width:100%; border-collapse: collapse;">
|
||||||
@ -149,10 +173,11 @@ class TicketGlpiModel {
|
|||||||
<td style="padding: 8px; border: 1px solid #ddd;">${ticketData.ticket_number || 'N/A'}</td>
|
<td style="padding: 8px; border: 1px solid #ddd;">${ticketData.ticket_number || 'N/A'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<br>
|
${requestExtraHtml}
|
||||||
<strong>Descrição:</strong>
|
<div style="margin-top: 12px; padding: 12px; border: 1px solid #e2e8f0; border-left: 4px solid #4a5568; background-color: #fcfcfc;">
|
||||||
<hr>
|
<div style="font-weight: 700; margin-bottom: 8px;">Descricao</div>
|
||||||
${ticketData.description || 'N/A'}
|
<div style="white-space: pre-wrap;">${descriptionForDisplay}</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
return htmlDescription;
|
return htmlDescription;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
const pool = require('../data/database');
|
const pool = require('../data/database');
|
||||||
const { logInfo, logError, logWarning } = require('../utils/logger');
|
const { logInfo, logError } = require('../utils/logger');
|
||||||
|
|
||||||
class TicketSnModel {
|
class TicketSnModel {
|
||||||
|
|
||||||
@ -7,8 +7,8 @@ class TicketSnModel {
|
|||||||
const query = `
|
const query = `
|
||||||
INSERT INTO tickets_sn
|
INSERT INTO tickets_sn
|
||||||
(ticket_number, sys_id, short_description, status, description, caller_id, caller_email,
|
(ticket_number, sys_id, short_description, status, description, caller_id, caller_email,
|
||||||
location_id, location_name, ramal, telefone, opened_at, tipo)
|
location_id, location_name, ramal, telefone, justificativa, opened_at, tipo)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||||
ON CONFLICT (ticket_number)
|
ON CONFLICT (ticket_number)
|
||||||
DO UPDATE SET
|
DO UPDATE SET
|
||||||
sys_id = EXCLUDED.sys_id,
|
sys_id = EXCLUDED.sys_id,
|
||||||
@ -21,12 +21,13 @@ class TicketSnModel {
|
|||||||
location_name = EXCLUDED.location_name,
|
location_name = EXCLUDED.location_name,
|
||||||
ramal = EXCLUDED.ramal,
|
ramal = EXCLUDED.ramal,
|
||||||
telefone = EXCLUDED.telefone,
|
telefone = EXCLUDED.telefone,
|
||||||
|
justificativa = EXCLUDED.justificativa,
|
||||||
opened_at = EXCLUDED.opened_at,
|
opened_at = EXCLUDED.opened_at,
|
||||||
tipo = EXCLUDED.tipo
|
tipo = EXCLUDED.tipo
|
||||||
RETURNING id, (xmax = 0) AS "wasInserted"`;
|
RETURNING id, (xmax = 0) AS "wasInserted"`;
|
||||||
|
|
||||||
const ticketNumber = typeof ticketData.number === 'object' ? ticketData.number?.value : ticketData.number;
|
const ticketNumber = typeof ticketData.number === 'object' ? ticketData.number?.value : ticketData.number;
|
||||||
let callerName, callerEmail, ramal, telefone, sysId, shortDescription, state, description, locationId, locationName, openedAt;
|
let callerName, callerEmail, ramal, telefone, justificativa, sysId, shortDescription, state, description, locationId, locationName, openedAt;
|
||||||
|
|
||||||
|
|
||||||
if (typeTicket === 'incidente') {
|
if (typeTicket === 'incidente') {
|
||||||
@ -39,6 +40,7 @@ class TicketSnModel {
|
|||||||
shortDescription = ticketData.short_description || null;
|
shortDescription = ticketData.short_description || null;
|
||||||
state = ticketData.state || null;
|
state = ticketData.state || null;
|
||||||
description = ticketData.description || null;
|
description = ticketData.description || null;
|
||||||
|
justificativa = null;
|
||||||
const locationLink = ticketData.location?.link;
|
const locationLink = ticketData.location?.link;
|
||||||
locationId = locationLink ? locationLink.substring(locationLink.lastIndexOf('/') + 1) : null;
|
locationId = locationLink ? locationLink.substring(locationLink.lastIndexOf('/') + 1) : null;
|
||||||
locationName = ticketData.location?.display_value || null;
|
locationName = ticketData.location?.display_value || null;
|
||||||
@ -47,11 +49,12 @@ class TicketSnModel {
|
|||||||
callerName = ticketData.opened_by?.display_value || null;
|
callerName = ticketData.opened_by?.display_value || null;
|
||||||
callerEmail = ticketData['opened_by.email'] || null;
|
callerEmail = ticketData['opened_by.email'] || null;
|
||||||
ramal = ticketData['variables.numero_ramal'] || null;
|
ramal = ticketData['variables.numero_ramal'] || null;
|
||||||
telefone = ticketData['variables.telephone_favorecido_rh'] || ticketData.telefone || null;
|
telefone = ticketData['variables.telephone_favorecido_rh'] || ticketData['variables.telephone_favorecido_ti'] || ticketData.telefone || null;
|
||||||
sysId = ticketData.sys_id || null;
|
sysId = ticketData.sys_id || null;
|
||||||
shortDescription = ticketData.short_description || null;
|
shortDescription = ticketData.short_description || null;
|
||||||
state = ticketData.state || null;
|
state = ticketData.state || null;
|
||||||
description = ticketData.description || null;
|
description = ticketData.description || null;
|
||||||
|
justificativa = ticketData.justificativa || null;
|
||||||
const locationLink = ticketData.location?.link;
|
const locationLink = ticketData.location?.link;
|
||||||
locationId = locationLink ? locationLink.substring(locationLink.lastIndexOf('/') + 1) : null;
|
locationId = locationLink ? locationLink.substring(locationLink.lastIndexOf('/') + 1) : null;
|
||||||
locationName = ticketData.location?.display_value || null;
|
locationName = ticketData.location?.display_value || null;
|
||||||
@ -70,6 +73,7 @@ class TicketSnModel {
|
|||||||
locationName,
|
locationName,
|
||||||
ramal,
|
ramal,
|
||||||
telefone,
|
telefone,
|
||||||
|
justificativa,
|
||||||
openedAt
|
openedAt
|
||||||
? (typeof openedAt === 'string' && openedAt.includes('/')
|
? (typeof openedAt === 'string' && openedAt.includes('/')
|
||||||
? new Date(openedAt.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$2-$1'))
|
? new Date(openedAt.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$2-$1'))
|
||||||
@ -119,6 +123,7 @@ class TicketSnModel {
|
|||||||
ts.location_name,
|
ts.location_name,
|
||||||
ts.ramal,
|
ts.ramal,
|
||||||
ts.telefone,
|
ts.telefone,
|
||||||
|
ts.justificativa,
|
||||||
ts.opened_at,
|
ts.opened_at,
|
||||||
ts.tipo,
|
ts.tipo,
|
||||||
ts.created_at,
|
ts.created_at,
|
||||||
|
|||||||
@ -34,6 +34,7 @@ CREATE TABLE tickets_sn (
|
|||||||
location_name VARCHAR(255), -- Nome da localização no ServiceNow
|
location_name VARCHAR(255), -- Nome da localização no ServiceNow
|
||||||
ramal VARCHAR(100), -- Ramal do solicitante
|
ramal VARCHAR(100), -- Ramal do solicitante
|
||||||
telefone VARCHAR(100), -- Telefone do solicitante
|
telefone VARCHAR(100), -- Telefone do solicitante
|
||||||
|
justificativa TEXT, -- Justificativa da requisicao (catalog variable)
|
||||||
opened_at TIMESTAMP, -- Data e hora de abertura no ServiceNow
|
opened_at TIMESTAMP, -- Data e hora de abertura no ServiceNow
|
||||||
created_at TIMESTAMP DEFAULT NOW(), -- Data e hora de criação do registro
|
created_at TIMESTAMP DEFAULT NOW(), -- Data e hora de criação do registro
|
||||||
updated_at TIMESTAMP DEFAULT NOW() -- Data e hora da última atualização do registro
|
updated_at TIMESTAMP DEFAULT NOW() -- Data e hora da última atualização do registro
|
||||||
@ -225,6 +226,7 @@ COMMENT ON COLUMN tickets_sn.location_id IS 'ID da localização no ServiceNow';
|
|||||||
COMMENT ON COLUMN tickets_sn.location_name IS 'Nome da localização no ServiceNow';
|
COMMENT ON COLUMN tickets_sn.location_name IS 'Nome da localização no ServiceNow';
|
||||||
COMMENT ON COLUMN tickets_sn.ramal IS 'Ramal do solicitante';
|
COMMENT ON COLUMN tickets_sn.ramal IS 'Ramal do solicitante';
|
||||||
COMMENT ON COLUMN tickets_sn.telefone IS 'Telefone do solicitante';
|
COMMENT ON COLUMN tickets_sn.telefone IS 'Telefone do solicitante';
|
||||||
|
COMMENT ON COLUMN tickets_sn.justificativa IS 'Justificativa da requisicao vinda das variaveis de catalogo';
|
||||||
COMMENT ON COLUMN tickets_sn.opened_at IS 'Data e hora de abertura no ServiceNow';
|
COMMENT ON COLUMN tickets_sn.opened_at IS 'Data e hora de abertura no ServiceNow';
|
||||||
COMMENT ON COLUMN tickets_sn.created_at IS 'Data e hora de criação do registro';
|
COMMENT ON COLUMN tickets_sn.created_at IS 'Data e hora de criação do registro';
|
||||||
COMMENT ON COLUMN tickets_sn.updated_at IS 'Data e hora da última atualização do registro';
|
COMMENT ON COLUMN tickets_sn.updated_at IS 'Data e hora da última atualização do registro';
|
||||||
@ -293,3 +295,8 @@ DELETE FROM tickets_sn WHERE status != 'Encerrado' AND status != 'Encerrado - Om
|
|||||||
|
|
||||||
UPDATE sync_control
|
UPDATE sync_control
|
||||||
SET last_watermark = '1970-01-01 00:00:00+00';
|
SET last_watermark = '1970-01-01 00:00:00+00';
|
||||||
|
|
||||||
|
-- Migracao para bases existentes:
|
||||||
|
ALTER TABLE tickets_sn ADD COLUMN IF NOT EXISTS justificativa TEXT;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ const TicketSnModel = require('../models/ticketSnModel');
|
|||||||
const TicketGlpiModel = require('../models/ticketGlpiModel');
|
const TicketGlpiModel = require('../models/ticketGlpiModel');
|
||||||
const TicketUpdateModel = require('../models/ticketUpdateModel');
|
const TicketUpdateModel = require('../models/ticketUpdateModel');
|
||||||
const TicketSyncModel = require('../models/ticketSyncModel');
|
const TicketSyncModel = require('../models/ticketSyncModel');
|
||||||
const { logInfo, logError, logWarning } = require('../utils/logger');
|
const { logInfo, logError } = require('../utils/logger');
|
||||||
const { addWorkNoteToServiceNow } = require('./servicenowService');
|
const { addWorkNoteToServiceNow } = require('./servicenowService');
|
||||||
|
|
||||||
const syncTicketsToGlpi = async () => {
|
const syncTicketsToGlpi = async () => {
|
||||||
@ -61,6 +61,7 @@ const processSingleTicket = async (ticket) => {
|
|||||||
ticket_number: ticket.ticket_number,
|
ticket_number: ticket.ticket_number,
|
||||||
short_description: ticket.short_description,
|
short_description: ticket.short_description,
|
||||||
description: ticket.description,
|
description: ticket.description,
|
||||||
|
justificativa: ticket.justificativa,
|
||||||
caller_id: ticket.caller_id,
|
caller_id: ticket.caller_id,
|
||||||
caller_email: ticket.caller_email,
|
caller_email: ticket.caller_email,
|
||||||
caller_phone: ticket.telefone,
|
caller_phone: ticket.telefone,
|
||||||
@ -73,18 +74,6 @@ const processSingleTicket = async (ticket) => {
|
|||||||
opened_at: ticket.opened_at,
|
opened_at: ticket.opened_at,
|
||||||
updated_at: ticket.updated_at
|
updated_at: ticket.updated_at
|
||||||
};
|
};
|
||||||
|
|
||||||
if (glpiData.type === 'requisicao' && (!glpiData.description || glpiData.description.trim() === '')) {
|
|
||||||
logInfo(`Descrição vazia para requisição ${ticket.ticket_number}. Tentando buscar de sc_item_option.`);
|
|
||||||
const scItemOptionDescription = await require('./servicenowService').fetchScItemOptionValue(ticket.sys_id, 'justificativa');
|
|
||||||
if (scItemOptionDescription) {
|
|
||||||
glpiData.description = scItemOptionDescription;
|
|
||||||
logInfo(`Descrição atualizada para requisição ${ticket.ticket_number} a partir de sc_item_option.`);
|
|
||||||
} else {
|
|
||||||
logWarning(`Não foi possível obter descrição de sc_item_option para requisição ${ticket.ticket_number}.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const glpiTicketId = await TicketGlpiModel.createTicket(glpiData);
|
const glpiTicketId = await TicketGlpiModel.createTicket(glpiData);
|
||||||
await TicketSyncModel.updateLastSync(ticket.id, 'glpi');
|
await TicketSyncModel.updateLastSync(ticket.id, 'glpi');
|
||||||
await TicketSyncModel.updateStatusAndGlpiTicket(ticket.id, 'synced', 'synced', glpiTicketId);
|
await TicketSyncModel.updateStatusAndGlpiTicket(ticket.id, 'synced', 'synced', glpiTicketId);
|
||||||
|
|||||||
@ -495,14 +495,29 @@ const fetchScItemOptionValue = async (ritmSysId, variableName) => {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
const baseUrl = apiConfig.snScItemOptionConfig.baseUrl.replace(/\/$/, "");
|
const baseUrl = apiConfig.snScItemOptionConfig.baseUrl.replace(/\/$/, "");
|
||||||
const url = `${baseUrl}?sysparm_query=request_item=${ritmSysId}^sc_item_option.item_option_new.question_textINPlease justify the need,Telephone,Select what you want&sysparm_fields=sc_item_option.item_option_new.question_text,sc_item_option.value`;
|
const url = `${baseUrl}?sysparm_query=request_item=${ritmSysId}^sc_item_option.item_option_new.question_textINPlease justify the need,Telephone,Select what you want&sysparm_fields=sc_item_option.item_option_new.question_text,sc_item_option.item_option_new.name,sc_item_option.value`;
|
||||||
|
|
||||||
const response = await axios.get(url, {
|
const response = await axios.get(url, {
|
||||||
auth: apiConfig.servicenowAuthentication.auth
|
auth: apiConfig.servicenowAuthentication.auth
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = response.data.result;
|
const result = response.data.result || [];
|
||||||
return (result && result.length > 0) ? result : null;
|
if (result.length === 0) return null;
|
||||||
|
|
||||||
|
const normalize = (value) => {
|
||||||
|
if (value === null || value === undefined) return '';
|
||||||
|
if (typeof value === 'string') return value;
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
return value.value || value.display_value || '';
|
||||||
|
}
|
||||||
|
return String(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return result.map((item) => ({
|
||||||
|
question_text: normalize(item['sc_item_option.item_option_new.question_text']),
|
||||||
|
variable_name: normalize(item['sc_item_option.item_option_new.name']),
|
||||||
|
value: normalize(item['sc_item_option.value'])
|
||||||
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logError(error, `ERRO: Falha ao buscar valor da variavel '${variableName}' para RITM ${ritmSysId}`);
|
logError(error, `ERRO: Falha ao buscar valor da variavel '${variableName}' para RITM ${ritmSysId}`);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user