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_')) {
|
} 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,40 +3103,37 @@ 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`;
|
||||||
|
message += `🆔 **ID**: ${servicoInfo.servico.id}\n\n`;
|
||||||
|
|
||||||
|
servicoInfo.faturas.forEach((fatura, fIndex) => {
|
||||||
|
const isPago = fatura.status === 'Pago';
|
||||||
const statusEmoji = isPago ? '✅' : '🔴';
|
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) {
|
if (fatura.valor) {
|
||||||
const valor = parseFloat(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 += ` 📅 Vencimento: ${fatura.vencimento}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
message += ` 📊 Status: ${statusTexto}\n`;
|
message += ` 📊 Status: ${fatura.status}\n`;
|
||||||
|
|
||||||
if (fatura.historico) {
|
if (fatura.descricao) {
|
||||||
message += ` 📝 Descrição: ${fatura.historico}\n`;
|
message += ` 📝 Descrição: ${fatura.descricao}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPago && fatura.datapagto) {
|
if (fatura.periodo) {
|
||||||
message += ` 💳 Pago em: ${fatura.datapagto}\n`;
|
message += ` 📆 Período: ${fatura.periodo}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
message += `\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) {
|
} 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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in new issue
Block a user