--- name: Sessão 2026-04-01 - Correções massivas financeiro + Bling + NFSe + Logs description: Resumo completo de tudo que foi feito na sessão de 01/04/2026 - Bling produtos, cobrança, NFSe, cancelamento SEFIN, logs, proteções type: project --- ## Bling ERP - Produtos - Implementado `produtosApi()` no controller + rota + view com tabela de produtos - Produtos carregam em tempo real da API Bling ao abrir aba da empresa - Páginas públicas criadas no site GotechBr: `/integracao-bling` e `/manual-bling` ## Logger - Threshold corrigido - Threshold alterado de 4 (só ERROR) para 9 (tudo) - Handler do FileHandler: removido 'info' e 'debug' para evitar spam de "Session: Class initialized" - Todos os `log_message('info',...)` dos crons alterados para `log_message('notice',...)` - Collation fix: `whatsapp_group_user_reads` e `whatsapp_lid_names` convertidas para utf8mb4_unicode_ci ## Log Viewer (`/logs-sistema`) - Controller `LogViewer.php` com `tail` + `grep` shell (suporta arquivos de 300MB+) - Estatísticas via `grep -c` (rápido) - Botões Limpar/Excluir/Limpar Antigos com SweetAlert2 - CSRF exception adicionada em Filters.php - Rotas `match(['GET','POST'])` (maiúsculas obrigatórias no CI4) ## NFSe - Cancelamento via API SEFIN - **Endpoint correto**: `POST /SefinNacional/nfse/{chaveAcesso}/eventos` - **Campo JSON correto**: `pedidoRegistroEventoXmlGZipB64` (NÃO `pedRegEvtXmlGZipB64`) - XML segue XSD pedRegEvento_v1.01: tag raiz ``, inner `` - ID formato: `PRE` + chaveNFSe(50) + tipoEvento(6) = `PRE[0-9]{56}` - Cancelamento funciona! Notas 30-35 canceladas com sucesso na SEFIN ## NFSe - Emissão corrigida - Campo `` obrigatório: quando cliente não tem número, usa "S/N" - Query anti-duplicata: `NOT IN ('erro')` em vez de `NOT IN ('erro','cancelada')` - nota cancelada bloqueia re-emissão - Competência usa `data_pagamento` (não data atual) - Limite de boletos: `DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01')` (não 90 dias) - 16 notas vinculadas a boletos por `boleto_id` (previne duplicatas) - `proximo_num_dps` avançado para 50 (evitar conflito com notas de erro) ## NFSe - Mensagens corrigidas - WhatsApp: "Olá", "Serviço Eletrônica", "Código", "confiança" - Email: "Serviço Eletrônica", "serviços", "Número" ## Cobrança - Proteções anti-duplicata - Agradecimento: UPDATE atômico `SET agradecimento_enviado=1 WHERE agradecimento_enviado=0` ANTES de enviar - Log cobrança: registrado ANTES do envio (não depois) - Ambos CronBoletos e CronCobrancaAutomatica usam UPDATE atômico ## Cobrança - Validação centralizada `clienteContratoAtivo()` - Verifica `cliente.status = 'ativo'` + `cliente.gerar_boleto = 1` + `contrato.status IN ('ativo','prorrogado')` - Chamada em: gerarBoleto, enviarCobrancaOtimizada, enviarCobrancaConsolidadaCompleta, enviarNotificacaoPagamentoRecebido, executarProtestoAutomaticoSicoob - NFSe: verifica `cliente.status !== 'ativo'` antes de emitir ## Cobrança - Acentos corrigidos - "restricoes" → "restrições", "cartorarias" → "cartoriais" - "titulo(s)" → "título(s)", "cobranca" → "cobrança" - "cartorio" → "cartório", "duvida" → "dúvida", "disposicao" → "disposição" - "regularizacao" → "regularização", "negociacao" → "negociação" - "condicao" → "condição", "confirmacao" → "confirmação", "possivel" → "possível" ## Telefone WhatsApp - DDD corrigido - CronBoletos: agora adiciona 55 para telefones de 10 E 11 dígitos (antes só 11) - CronNfseAutomatica: DDD > 30 → corrigido para DDD 31-38 (só MG) - WhatsApp.php enviarArquivo(): mesmo fix DDD 31-38 - Mensagem texto E arquivo PDF agora vão para o MESMO número em qualquer DDD ## Protesto - Segurança extra - Verificação `diasAtraso >= 10` adicionada dentro de `executarProtestoAutomaticoSicoob()` ## O.S. - Envio ao cliente - `notificarCliente()` corrigido: acentos ("Serviço", "Técnico", "número") - PDF da O.S. gerado via dompdf e enviado por WhatsApp junto com texto - Usa sessão principal GotechBr para envio