TopSapp: fix API show blocked services from client

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2025-12-12 14:07:26 -03:00
1 parent cfbc730e70
commit d4bd364690
2 files changed
+243 -43

No files matched your search

+196 -43
View File
@@ -1146,6 +1146,12 @@ Digite /help para ver todos os comandos disponíveis!
} else if (data.startsWith('suporte_servico_')) { } else if (data.startsWith('suporte_servico_')) {
console.log(`🔍 Condição suporte_servico_ atendida`); console.log(`🔍 Condição suporte_servico_ atendida`);
await this.handleSuporteServicoCallback(callbackQuery, data); await this.handleSuporteServicoCallback(callbackQuery, data);
} else if (data.startsWith('linha_')) {
console.log(`🔍 Condição linha_ atendida`);
await this.handleLinhaDigitavelCallback(callbackQuery, data);
} else if (data.startsWith('pix_')) {
console.log(`🔍 Condição pix_ atendida`);
await this.handlePixCallback(callbackQuery, data);
} else { } else {
console.log(`❓ Callback não reconhecido: ${data}`); console.log(`❓ Callback não reconhecido: ${data}`);
await this.bot.answerCallbackQuery(callbackQuery.id, 'Comando não reconhecido'); await this.bot.answerCallbackQuery(callbackQuery.id, 'Comando não reconhecido');
@@ -3086,7 +3092,7 @@ Digite /help para ver todos os comandos disponíveis!
await this.bot.sendMessage(chatId, '📄 Buscando faturas...'); await this.bot.sendMessage(chatId, '📄 Buscando faturas...');
const resultado = await this.topsapp.obterFaturas(idCliente, location); const resultado = await this.topsapp.obterFaturasDetalhadas(idCliente, location);
if (!resultado.success) { if (!resultado.success) {
await this.bot.sendMessage(chatId, await this.bot.sendMessage(chatId,
@@ -3097,64 +3103,99 @@ Digite /help para ver todos os comandos disponíveis!
return; return;
} }
// Corrigir acesso aos dados: resultado.data é um objeto { resultado: true, dados: [...] } const faturasPorServico = resultado.faturasPorServico || [];
const faturas = resultado.data?.dados || resultado.data?.faturas || resultado.faturas || [];
// Verificar se é realmente um array if (faturasPorServico.length === 0) {
if (!Array.isArray(faturas)) {
console.error('❌ Faturas não é um array:', typeof faturas, faturas);
await this.bot.sendMessage(chatId, await this.bot.sendMessage(chatId,
`❌ **Erro ao processar faturas**\n\n` + `📄 **Nenhuma fatura encontrada**\n\n` +
`⚠️ Formato de resposta inválido`, `✅ O cliente não possui faturas cadastradas.`,
{ parse_mode: 'Markdown' } { parse_mode: 'Markdown' }
); );
return; return;
} }
if (faturas.length === 0) { // Contar total de faturas
await this.bot.sendMessage(chatId, let totalFaturas = 0;
`📄 **Nenhuma fatura em aberto**\n\n` + faturasPorServico.forEach(s => {
`✅ O cliente não possui faturas pendentes.`, totalFaturas += s.faturas.length;
{ parse_mode: 'Markdown' } });
);
return;
}
let message = `📄 **FATURAS DO CLIENTE**\n\n`; let message = `📄 **FATURAS DO CLIENTE**\n\n`;
message += `🆔 **ID Cliente**: ${idCliente}\n`; message += `🆔 **ID Cliente**: ${idCliente}\n`;
message += `📊 **Total de faturas**: ${faturas.length}\n\n`; message += `📊 **Total de faturas**: ${totalFaturas}\n\n`;
faturas.forEach((fatura, index) => { faturasPorServico.forEach((servicoInfo, sIndex) => {
// Verificar se está paga if (servicoInfo.faturas.length > 0) {
const isPago = fatura.pago && fatura.pago.toUpperCase() === 'SIM'; message += `📋 **Serviço**: ${servicoInfo.servico.descricao || 'Serviço'}\n`;
const statusEmoji = isPago ? '✅' : '🔴'; message += `🆔 **ID**: ${servicoInfo.servico.id}\n\n`;
const statusTexto = isPago ? 'PAGO' : 'EM ABERTO';
message += `${index + 1}. ${statusEmoji} **Fatura #${fatura.id || fatura.numero_fatura}**\n`; servicoInfo.faturas.forEach((fatura, fIndex) => {
const isPago = fatura.status === 'Pago';
const statusEmoji = isPago ? '✅' : '🔴';
if (fatura.valor) { message += `${fIndex + 1}. ${statusEmoji} **Fatura #${fatura.id}**\n`;
const valor = parseFloat(fatura.valor);
message += ` 💰 Valor: R$ ${valor.toFixed(2)}\n`; if (fatura.valor) {
const valor = parseFloat(fatura.valor);
message += ` 💰 Valor: R$ ${valor.toFixed(2)}\n`;
}
if (fatura.vencimento) {
message += ` 📅 Vencimento: ${fatura.vencimento}\n`;
}
message += ` 📊 Status: ${fatura.status}\n`;
if (fatura.descricao) {
message += ` 📝 Descrição: ${fatura.descricao}\n`;
}
if (fatura.periodo) {
message += ` 📆 Período: ${fatura.periodo}\n`;
}
message += `\n`;
});
message += `\n`;
} }
if (fatura.vencimento) {
message += ` 📅 Vencimento: ${fatura.vencimento}\n`;
}
message += ` 📊 Status: ${statusTexto}\n`;
if (fatura.historico) {
message += ` 📝 Descrição: ${fatura.historico}\n`;
}
if (isPago && fatura.datapagto) {
message += ` 💳 Pago em: ${fatura.datapagto}\n`;
}
message += `\n`;
}); });
await this.bot.sendMessage(chatId, message, { parse_mode: 'Markdown' }); // Criar botões para cada fatura com linha digitável/PIX
const keyboard = [];
faturasPorServico.forEach((servicoInfo) => {
servicoInfo.faturas.forEach((fatura) => {
if (fatura.status !== 'Pago') {
const row = [];
if (fatura.linhaDigitavel) {
row.push({
text: `📋 Linha Digitável #${fatura.id}`,
callback_data: `linha_${fatura.id}_${location}`
});
}
if (fatura.pixCopiaCola) {
row.push({
text: `💳 PIX #${fatura.id}`,
callback_data: `pix_${fatura.id}_${location}`
});
}
if (row.length > 0) {
keyboard.push(row);
}
}
});
});
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: keyboard.length > 0 ? {
inline_keyboard: keyboard
} : undefined
});
} catch (error) { } catch (error) {
console.error('❌ Erro ao buscar faturas:', error); console.error('❌ Erro ao buscar faturas:', error);
@@ -3488,6 +3529,118 @@ Digite /help para ver todos os comandos disponíveis!
await this.handleListarServicos(chatId, idCliente); await this.handleListarServicos(chatId, idCliente);
} }
/**
* Callback para exibir linha digitável
*/
async handleLinhaDigitavelCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('linha_', '').split('_');
const idFatura = parts[0];
const location = parts.slice(1).join('_');
try {
await this.bot.answerCallbackQuery(callbackQuery.id);
await this.bot.sendMessage(chatId, '⏳ Buscando linha digitável...');
// Buscar dados da fatura
const resultado = await this.topsapp.obterDadosFatura(idFatura, location);
if (!resultado.success) {
await this.bot.sendMessage(chatId,
`❌ **Erro ao buscar linha digitável**\n\n` +
`⚠️ ${resultado.error}`,
{ parse_mode: 'Markdown' }
);
return;
}
const dadosFatura = resultado.data?.fatura || resultado.data?.dados || resultado.data;
if (!dadosFatura || !dadosFatura.linha_digitavel) {
await this.bot.sendMessage(chatId,
`⚠️ **Linha digitável não disponível**\n\n` +
`A fatura #${idFatura} não possui linha digitável.`,
{ parse_mode: 'Markdown' }
);
return;
}
let message = `📋 **LINHA DIGITÁVEL**\n\n`;
message += `🆔 **Fatura**: #${idFatura}\n`;
message += `💰 **Valor**: R$ ${parseFloat(dadosFatura.valor || dadosFatura.valor_atualizado || 0).toFixed(2)}\n`;
message += `📅 **Vencimento**: ${dadosFatura.vencimento || dadosFatura.vencimento_atualizado || 'N/A'}\n\n`;
message += `📋 **Linha Digitável**:\n\`${dadosFatura.linha_digitavel}\`\n\n`;
message += `💡 _Copie a linha digitável acima para pagar pelo app do banco_`;
await this.bot.sendMessage(chatId, message, { parse_mode: 'Markdown' });
} catch (error) {
console.error('❌ Erro ao buscar linha digitável:', error);
await this.bot.sendMessage(chatId,
`❌ **Erro ao buscar linha digitável**\n\n` +
`⚠️ ${error.message}`,
{ parse_mode: 'Markdown' }
);
}
}
/**
* Callback para exibir PIX copia e cola
*/
async handlePixCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('pix_', '').split('_');
const idFatura = parts[0];
const location = parts.slice(1).join('_');
try {
await this.bot.answerCallbackQuery(callbackQuery.id);
await this.bot.sendMessage(chatId, '⏳ Buscando código PIX...');
// Buscar dados da fatura
const resultado = await this.topsapp.obterDadosFatura(idFatura, location);
if (!resultado.success) {
await this.bot.sendMessage(chatId,
`❌ **Erro ao buscar código PIX**\n\n` +
`⚠️ ${resultado.error}`,
{ parse_mode: 'Markdown' }
);
return;
}
const dadosFatura = resultado.data?.fatura || resultado.data?.dados || resultado.data;
const pixCode = dadosFatura?.qrcode || dadosFatura?.pix_copia_cola || dadosFatura?.codigo_pix;
if (!dadosFatura || !pixCode) {
await this.bot.sendMessage(chatId,
`⚠️ **PIX não disponível**\n\n` +
`A fatura #${idFatura} não possui código PIX.`,
{ parse_mode: 'Markdown' }
);
return;
}
let message = `💳 **PIX COPIA E COLA**\n\n`;
message += `🆔 **Fatura**: #${idFatura}\n`;
message += `💰 **Valor**: R$ ${parseFloat(dadosFatura.valor || dadosFatura.valor_atualizado || 0).toFixed(2)}\n`;
message += `📅 **Vencimento**: ${dadosFatura.vencimento || dadosFatura.vencimento_atualizado || 'N/A'}\n\n`;
message += `💳 **PIX Copia e Cola**:\n\`${pixCode}\`\n\n`;
message += `💡 _Copie o código acima e cole no app do banco na opção PIX Copia e Cola_`;
await this.bot.sendMessage(chatId, message, { parse_mode: 'Markdown' });
} catch (error) {
console.error('❌ Erro ao buscar código PIX:', error);
await this.bot.sendMessage(chatId,
`❌ **Erro ao buscar código PIX**\n\n` +
`⚠️ ${error.message}`,
{ parse_mode: 'Markdown' }
);
}
}
/** /**
* Escapar caracteres problemáticos para Markdown do Telegram * Escapar caracteres problemáticos para Markdown do Telegram
*/ */
+47
View File
@@ -1214,6 +1214,53 @@ class TopSappManager {
}; };
} }
} }
/**
* Obter dados completos de uma fatura (linha digitável, PIX, etc)
*/
async obterDadosFatura(idFatura, location = '') {
if (!this.isReady()) {
return {
success: false,
error: 'TopSapp não está configurado'
};
}
try {
const credentials = this.config.getCredentialsByLocation(location);
// Primeiro obter a lista de faturas para pegar o idCliente
const faturas = await this.api.obterFaturas(null, location, credentials);
if (!faturas.success || !faturas.data || !faturas.data.dados) {
return {
success: false,
error: 'Erro ao buscar faturas'
};
}
// Encontrar a fatura específica
const fatura = faturas.data.dados.find(f => f.id == idFatura);
if (!fatura) {
return {
success: false,
error: 'Fatura não encontrada'
};
}
const idCliente = fatura.codigo_cliente || fatura.id_cliente;
// Obter dados completos da fatura
return await this.api.obterDadosFatura(idFatura, idCliente, location, credentials);
} catch (error) {
return {
success: false,
error: error.message
};
}
}
} }
module.exports = TopSappManager; module.exports = TopSappManager;