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:
1 parent
cfbc730e70
commit
d4bd364690
2 files changed
+228
-28
No files matched your search
+181
-28
@@ -1146,6 +1146,12 @@ Digite /help para ver todos os comandos disponíveis!
|
||||
} else if (data.startsWith('suporte_servico_')) {
|
||||
console.log(`🔍 Condição suporte_servico_ atendida`);
|
||||
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 {
|
||||
console.log(`❓ Callback não reconhecido: ${data}`);
|
||||
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...');
|
||||
|
||||
const resultado = await this.topsapp.obterFaturas(idCliente, location);
|
||||
const resultado = await this.topsapp.obterFaturasDetalhadas(idCliente, location);
|
||||
|
||||
if (!resultado.success) {
|
||||
await this.bot.sendMessage(chatId,
|
||||
@@ -3097,40 +3103,37 @@ Digite /help para ver todos os comandos disponíveis!
|
||||
return;
|
||||
}
|
||||
|
||||
// Corrigir acesso aos dados: resultado.data é um objeto { resultado: true, dados: [...] }
|
||||
const faturas = resultado.data?.dados || resultado.data?.faturas || resultado.faturas || [];
|
||||
const faturasPorServico = resultado.faturasPorServico || [];
|
||||
|
||||
// Verificar se é realmente um array
|
||||
if (!Array.isArray(faturas)) {
|
||||
console.error('❌ Faturas não é um array:', typeof faturas, faturas);
|
||||
if (faturasPorServico.length === 0) {
|
||||
await this.bot.sendMessage(chatId,
|
||||
`❌ **Erro ao processar faturas**\n\n` +
|
||||
`⚠️ Formato de resposta inválido`,
|
||||
`📄 **Nenhuma fatura encontrada**\n\n` +
|
||||
`✅ O cliente não possui faturas cadastradas.`,
|
||||
{ parse_mode: 'Markdown' }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (faturas.length === 0) {
|
||||
await this.bot.sendMessage(chatId,
|
||||
`📄 **Nenhuma fatura em aberto**\n\n` +
|
||||
`✅ O cliente não possui faturas pendentes.`,
|
||||
{ parse_mode: 'Markdown' }
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Contar total de faturas
|
||||
let totalFaturas = 0;
|
||||
faturasPorServico.forEach(s => {
|
||||
totalFaturas += s.faturas.length;
|
||||
});
|
||||
|
||||
let message = `📄 **FATURAS DO CLIENTE**\n\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) => {
|
||||
// Verificar se está paga
|
||||
const isPago = fatura.pago && fatura.pago.toUpperCase() === 'SIM';
|
||||
faturasPorServico.forEach((servicoInfo, sIndex) => {
|
||||
if (servicoInfo.faturas.length > 0) {
|
||||
message += `📋 **Serviço**: ${servicoInfo.servico.descricao || 'Serviço'}\n`;
|
||||
message += `🆔 **ID**: ${servicoInfo.servico.id}\n\n`;
|
||||
|
||||
servicoInfo.faturas.forEach((fatura, fIndex) => {
|
||||
const isPago = fatura.status === 'Pago';
|
||||
const statusEmoji = isPago ? '✅' : '🔴';
|
||||
const statusTexto = isPago ? 'PAGO' : 'EM ABERTO';
|
||||
|
||||
message += `${index + 1}. ${statusEmoji} **Fatura #${fatura.id || fatura.numero_fatura}**\n`;
|
||||
message += `${fIndex + 1}. ${statusEmoji} **Fatura #${fatura.id}**\n`;
|
||||
|
||||
if (fatura.valor) {
|
||||
const valor = parseFloat(fatura.valor);
|
||||
@@ -3141,20 +3144,58 @@ Digite /help para ver todos os comandos disponíveis!
|
||||
message += ` 📅 Vencimento: ${fatura.vencimento}\n`;
|
||||
}
|
||||
|
||||
message += ` 📊 Status: ${statusTexto}\n`;
|
||||
message += ` 📊 Status: ${fatura.status}\n`;
|
||||
|
||||
if (fatura.historico) {
|
||||
message += ` 📝 Descrição: ${fatura.historico}\n`;
|
||||
if (fatura.descricao) {
|
||||
message += ` 📝 Descrição: ${fatura.descricao}\n`;
|
||||
}
|
||||
|
||||
if (isPago && fatura.datapagto) {
|
||||
message += ` 💳 Pago em: ${fatura.datapagto}\n`;
|
||||
if (fatura.periodo) {
|
||||
message += ` 📆 Período: ${fatura.periodo}\n`;
|
||||
}
|
||||
|
||||
message += `\n`;
|
||||
});
|
||||
|
||||
await this.bot.sendMessage(chatId, message, { parse_mode: 'Markdown' });
|
||||
message += `\n`;
|
||||
}
|
||||
});
|
||||
|
||||
// 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
Reference in new issue
Block a user