feat: sincronização ativa direta com a API do Asaas ao entrar no financeiro

This commit is contained in:
Sidney 2026-05-08 11:57:56 -03:00
parent 001e7a19aa
commit 84a55c2392
2 changed files with 70 additions and 3 deletions

View File

@ -183,12 +183,14 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
setIsSyncing(true); setIsSyncing(true);
try { try {
// 1. Solicita ao backend que sincronize o SQL para o JSON // 1. Realiza a sincronização PESADA: Busca no Asaas -> Salva no SQL -> Atualiza o JSON
const syncResp = await fetch('/api/admin/sync-finance-json', { method: 'POST' }); const syncResp = await fetch('/api/admin/sync-asaas-full', { method: 'POST' });
const syncResult = await syncResp.json(); const syncResult = await syncResp.json();
if (syncResult.success && syncResult.updatedCount > 0) { if (syncResult.success && syncResult.updatedCount > 0) {
showAlert('Sincronização', `${syncResult.updatedCount} pagamentos foram atualizados e salvos no sistema.`, 'success'); showAlert('Sincronização Ativa', `${syncResult.updatedCount} pagamentos foram atualizados diretamente do Asaas e salvos no sistema.`, 'success');
} else if (syncResult.success) {
console.log('[Sync] Tudo atualizado com o Asaas.');
} }
// 2. Busca os dados atualizados para exibir na tela // 2. Busca os dados atualizados para exibir na tela

View File

@ -1324,6 +1324,60 @@ function agendarRotina(tipo, hora, minuto) {
console.log(`[Cron:${label}] ✅ Rotina agendada para ${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')} (America/Sao_Paulo)`); console.log(`[Cron:${label}] ✅ Rotina agendada para ${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')} (America/Sao_Paulo)`);
} }
async function syncPaymentsWithAsaasAPI() {
try {
const response = await fetch(`${process.env.ASAAS_BASE_URL || 'https://api.asaas.com'}/v3/payments?limit=100`, {
headers: { 'access_token': process.env.ASAAS_API_KEY }
});
if (!response.ok) throw new Error(`Erro API Asaas: ${response.status}`);
const data = await response.json();
if (!data.data || !Array.isArray(data.data)) return 0;
const statusMap = {
'PENDING': 'PENDENTE',
'OVERDUE': 'ATRASADO',
'RECEIVED': 'PAGO',
'CONFIRMED': 'PAGO',
'RECEIVED_IN_CASH': 'PAGO',
'REFUNDED': 'CANCELADO',
'DELETED': 'CANCELADO'
};
console.log(`[Asaas:Sync] Processando ${data.data.length} cobranças da API...`);
for (const payment of data.data) {
const updateData = {
valor: payment.value,
vencimento: payment.dueDate,
status: statusMap[payment.status] || 'PENDENTE',
data_pagamento: payment.confirmedDate || payment.paymentDate || null,
link_boleto: payment.bankSlipUrl || payment.invoiceUrl || null
};
// Atualiza o SQL (updateCobranca já faz o UPSERT internamente se implementado via banco.js)
// Se não existir, a função deve tratar ou usamos pool.query diretamente aqui.
await pool.query(`
INSERT INTO alunos_cobrancas (asaas_payment_id, valor, vencimento, status, data_pagamento, link_boleto)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (asaas_payment_id) DO UPDATE SET
valor = EXCLUDED.valor,
vencimento = EXCLUDED.vencimento,
status = EXCLUDED.status,
data_pagamento = EXCLUDED.data_pagamento,
link_boleto = EXCLUDED.link_boleto
`, [payment.id, updateData.valor, updateData.vencimento, updateData.status, updateData.data_pagamento, updateData.link_boleto]);
}
// Após atualizar o SQL, sincroniza o status para o arquivo JSON legado
const jsonUpdated = await syncRelationalToJsonPayments();
return jsonUpdated;
} catch (err) {
console.error('[Asaas:Sync] ❌ Falha na sincronização ativa:', err.message);
throw err;
}
}
async function syncRelationalToJsonPayments() { async function syncRelationalToJsonPayments() {
try { try {
const { rows: cloudPayments } = await pool.query('SELECT * FROM alunos_cobrancas'); const { rows: cloudPayments } = await pool.query('SELECT * FROM alunos_cobrancas');
@ -1466,6 +1520,17 @@ async function startServer() {
} }
}); });
// Endpoint para forçar sincronização direta com a API do Asaas (Aba Financeiro)
app.post('/api/admin/sync-asaas-full', async (req, res) => {
try {
const updatedCount = await syncPaymentsWithAsaasAPI();
res.json({ success: true, updatedCount });
} catch (e) {
console.error('[Asaas:FullSync] Erro:', e.message);
res.status(500).json({ error: e.message });
}
});
// Endpoint para forçar sincronização SQL -> JSON (Aba Financeiro) // Endpoint para forçar sincronização SQL -> JSON (Aba Financeiro)
app.post('/api/admin/sync-finance-json', async (req, res) => { app.post('/api/admin/sync-finance-json', async (req, res) => {
try { try {