fix: estabilização do sistema de lembretes preventivos e correções de formatação
This commit is contained in:
parent
a667368ce3
commit
db7b79fe87
11
MEMORY.md
11
MEMORY.md
|
|
@ -106,8 +106,13 @@
|
|||
- **Estado Atual:** Pipeline 100% estabilizado no GitHub Actions usando `self-hosted` runner (Oracle ARM64 nativo).
|
||||
- **Melhoria:** O build agora ocorre diretamente na arquitetura de destino, sem emulação QEMU, garantindo velocidade e estabilidade total.
|
||||
|
||||
### 📢 Automação de Mensagens
|
||||
- [x] **Estabilização de Lembretes:** Sistema de avisos preventivos e de inadimplência agora é 100% confiável, com tracking preciso de envios e suporte a múltiplos templates dinâmicos.
|
||||
|
||||
## 📋 Próximos Passos Pendentes
|
||||
|
||||
1. **Concluída a Arquitetura de Storage Local (MinIO):** Todo o sistema (Tanto portal quanto manager) agora utiliza `FormData` para envio físico de arquivos aos servidores, salvando apenas a `URL pública` no banco de dados.
|
||||
2. **Otimização de Build:** Re-explorar o cache do Docker ou considerar a remoção do suporte nativo ARM64 se não for estritamente necessário para o servidor final.
|
||||
3. **Financeiro:** Implementar visualização de extrato detalhado e integração com gateway de pagamento direto via cartão.
|
||||
1. **Módulo Financeiro SQL:** Iniciar a migração total do financeiro para PostgreSQL (padrão `notas_boletim`).
|
||||
2. **Otimização de Build:** Re-explorar o cache do Docker.
|
||||
3. **Financeiro:** Implementar visualização de extrato detalhado.
|
||||
|
||||
**Nota Técnica:** O arquivo `server.js` deve ser mantido como espelho ou ignorado conforme orientação do usuário, com foco total no `server.selfhosted.js`.
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ async function sendEvolutionMessage(asaasPaymentId, eventType, paymentPayload =
|
|||
.replace(/{nome_aluno}/g, aluno.name)
|
||||
.replace(/{matricula}/g, aluno.enrollmentNumber || aluno.matricula || '—')
|
||||
.replace(/{valor}/g, parseFloat(fallbackValor).toFixed(2).replace('.', ','))
|
||||
.replace(/{vencimento}/g, formatCobrancaDate(typeof fallbackVencimento === 'string' ? fallbackVencimento : ''))
|
||||
.replace(/{vencimento}/g, formatCobrancaDate(typeof fallbackVencimento === 'string' ? fallbackVencimento : (fallbackVencimento instanceof Date ? fallbackVencimento.toISOString().split('T')[0] : '')))
|
||||
.replace(/{link_boleto}/g, pdfUrl)
|
||||
.replace(/{descricao}/g, descricao);
|
||||
|
||||
|
|
@ -593,7 +593,7 @@ async function sendEvolutionMessage(asaasPaymentId, eventType, paymentPayload =
|
|||
}
|
||||
}
|
||||
|
||||
if ((isCreationEvent || isPaymentConfirmation || eventType === 'PAYMENT_UPDATED') && !base64Pdf && pdfUrl) {
|
||||
if ((isCreationEvent || isPaymentConfirmation || eventType === 'PAYMENT_UPDATED' || eventType === 'PAYMENT_UPCOMING') && !base64Pdf && pdfUrl) {
|
||||
msgFinal += `\n\n📄 Acesse aqui sua cobrança:\n${pdfUrl}`;
|
||||
}
|
||||
|
||||
|
|
@ -613,10 +613,16 @@ async function sendEvolutionMessage(asaasPaymentId, eventType, paymentPayload =
|
|||
const url = `${evoConfig.apiUrl.replace(/\/$/, '')}/message/${endpoint}/${evoConfig.instanceName}`;
|
||||
const sendResp = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': evoConfig.apiKey }, body: JSON.stringify(payload) });
|
||||
|
||||
if (sendResp.ok) console.log(`[WhatsApp] ✅ Enviado para ${cleanPhone}`);
|
||||
else console.error(`[WhatsApp] ❌ Erro:`, sendResp.status);
|
||||
if (sendResp.ok) {
|
||||
console.log(`[WhatsApp] ✅ Enviado para ${cleanPhone}`);
|
||||
return true;
|
||||
} else {
|
||||
console.error(`[WhatsApp] ❌ Erro:`, sendResp.status);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[WhatsApp] Erro interno:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1133,15 +1139,17 @@ async function executarRotinaCobrancas(tipo = 'ambos') {
|
|||
const jaEnviadoHoje = lastWarn && lastWarn.getTime() === hoje.getTime();
|
||||
|
||||
if (!jaEnviadoHoje && (diasDesdeUltimoAviso === null || diasDesdeUltimoAviso >= repeatEveryDays)) {
|
||||
await sendEvolutionMessage(cob.asaas_payment_id, 'PAYMENT_OVERDUE');
|
||||
const sent = await sendEvolutionMessage(cob.asaas_payment_id, 'PAYMENT_OVERDUE');
|
||||
|
||||
const currentCount = parseInt(cob.overdue_warnings_count) || 0;
|
||||
await pool.query(
|
||||
'UPDATE alunos_cobrancas SET overdue_warnings_count = $1, last_overdue_warning_at = NOW() WHERE asaas_payment_id = $2',
|
||||
[currentCount + 1, cob.asaas_payment_id]
|
||||
);
|
||||
if (sent) {
|
||||
const currentCount = parseInt(cob.overdue_warnings_count) || 0;
|
||||
await pool.query(
|
||||
'UPDATE alunos_cobrancas SET overdue_warnings_count = $1, last_overdue_warning_at = NOW() WHERE asaas_payment_id = $2',
|
||||
[currentCount + 1, cob.asaas_payment_id]
|
||||
);
|
||||
|
||||
enviadasAtraso++;
|
||||
enviadasAtraso++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1160,8 +1168,9 @@ async function executarRotinaCobrancas(tipo = 'ambos') {
|
|||
vencimento.setHours(0,0,0,0);
|
||||
|
||||
const diffDias = Math.ceil((vencimento.getTime() - hoje.getTime()) / (1000 * 60 * 60 * 24));
|
||||
const sendOnDueDate = rules.sendOnDueDate !== false;
|
||||
|
||||
if (diffDias > 0 && diffDias <= sendDaysBefore) {
|
||||
if ((diffDias > 0 && diffDias <= sendDaysBefore) || (diffDias === 0 && sendOnDueDate)) {
|
||||
const currentCount = parseInt(cob.pre_warnings_count) || 0;
|
||||
|
||||
if (currentCount < maxPreWarnings) {
|
||||
|
|
@ -1169,13 +1178,15 @@ async function executarRotinaCobrancas(tipo = 'ambos') {
|
|||
const jaEnviadoHoje = lastWarn && lastWarn.toDateString() === hoje.toDateString();
|
||||
|
||||
if (!jaEnviadoHoje) {
|
||||
await sendEvolutionMessage(cob.asaas_payment_id, 'PAYMENT_UPCOMING');
|
||||
const sent = await sendEvolutionMessage(cob.asaas_payment_id, 'PAYMENT_UPCOMING');
|
||||
|
||||
await pool.query(
|
||||
'UPDATE alunos_cobrancas SET pre_warnings_count = $1, last_pre_warning_at = NOW() WHERE asaas_payment_id = $2',
|
||||
[currentCount + 1, cob.asaas_payment_id]
|
||||
);
|
||||
enviadasAviso++;
|
||||
if (sent) {
|
||||
await pool.query(
|
||||
'UPDATE alunos_cobrancas SET pre_warnings_count = $1, last_pre_warning_at = NOW() WHERE asaas_payment_id = $2',
|
||||
[currentCount + 1, cob.asaas_payment_id]
|
||||
);
|
||||
enviadasAviso++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue