import api from './api'; import { handleRequest, simulateLatency } from './serviceUtils'; /** * Service de Boletos do Inter * Gerencia comunicação com as rotas de boletos e extrato para cruzamento * Baseado na lógica antiga do sistema */ export const boletosService = { /** * Busca dados de apresentação dos boletos (Lista e Resumo) * Rota: GET /boletos/status * API retorna: { cobrancas: [...], resumoValorPorSituacaoMesAno: [...] } */ fetchBoletosStatus: () => handleRequest({ mockFn: () => simulateLatency({ cobrancas: [], resumoValorPorSituacaoMesAno: [] }), apiFn: async () => { // O usuário solicitou OPTIONS seguido de GET para apresentação try { await api.options('/boletos/status'); } catch (err) { console.warn('[boletosService] OPTIONS /boletos/status failed', err); } const response = await api.get('/boletos/status'); return response.data; } }), /** * Busca extrato bancário * Rota: GET /extrato/apresentar * Usado para fazer cruzamento com boletos e identificar PIX recebidos sem boleto correspondente * @returns {Promise} */ fetchExtrato: () => handleRequest({ mockFn: () => simulateLatency([]), apiFn: async () => { const response = await api.get('/extrato/apresentar'); // Retorna array de itens do extrato const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || []); return data; } }), /** * Baixa PDF do boleto * Rota: GET /boletos/pdf/{codigoSolicitacao} * @param {string} codigoSolicitacao * @returns {Promise} */ downloadBoletoPDF: (codigoSolicitacao) => handleRequest({ mockFn: () => simulateLatency(new Blob(['PDF mock'], { type: 'application/pdf' })), apiFn: async () => { const response = await api.get(`/boletos/pdf/${codigoSolicitacao}`, { responseType: 'blob' }); return response.data; } }), /** * Envia boleto por email * Rota: POST /boletos/enviar_email * @param {Object} payload - { codigo_solicitacao, idempresa } * @returns {Promise} */ enviarBoletoEmail: (payload) => handleRequest({ mockFn: () => simulateLatency({ success: true, message: 'Email enviado com sucesso' }), apiFn: async () => { const response = await api.post('/boletos/enviar_email', payload); return response.data; } }), /** * Busca empresas/clientes para envio de email * Rota: GET /empresas_financeiro * @returns {Promise} */ fetchEmpresas: () => handleRequest({ mockFn: () => simulateLatency([]), apiFn: async () => { const response = await api.get('/empresas_financeiro'); const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || Object.values(response.data || {})); return data; } }), /** * Cria um novo serviço financeiro (preâmbulo para boleto avulso) * Rota: POST /servicos_financeiro/create */ createServicoFinanceiro: (payload) => handleRequest({ mockFn: () => simulateLatency({ success: true }), apiFn: async () => { const response = await api.post('/servicos_financeiro/create', payload); return response.data; } }), /** * Busca lista de serviços financeiros * Rota: GET /servicos_financeiro */ fetchServicosFinanceiro: () => handleRequest({ mockFn: () => simulateLatency([]), apiFn: async () => { const response = await api.get('/servicos_financeiro'); const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || []); return data; } }), /** * Gera o PDF de um boleto avulso * Rota: POST /boletos/avulsos (com OPTIONS prévio) */ generateBoletoAvulsoPDF: (objeto) => handleRequest({ mockFn: () => simulateLatency(new Blob(['PDF mock'], { type: 'application/pdf' })), apiFn: async () => { try { await api.options('/boletos/avulsos', objeto); } catch (err) { console.warn('[boletosService] OPTIONS /boletos/avulsos failed', err); } const response = await api.post('/boletos/avulsos', objeto, { responseType: 'blob' }); return response.data; } }), /** * Cria um novo boleto (Mensal ou outros tipos que usam a rota padrão) * Realiza OPTIONS seguido de POST na rota /boletos * @param {Object} payload * @returns {Promise} */ createBoleto: (payload) => handleRequest({ mockFn: () => simulateLatency({ success: true, message: 'Boleto gerado com sucesso' }), apiFn: async () => { // Primeiro faz OPTIONS try { await api.options('/boletos', payload); } catch (err) { console.warn('[boletosService] createBoleto OPTIONS failed:', err); } // Depois faz POST const response = await api.post('/boletos', payload); return response.data; } }), /** * Cancela um boleto * Rota: POST /boletos/cancelar * @param {Object} payload - { codigo_solicitacao, motivo } */ cancelarBoleto: (payload) => handleRequest({ mockFn: () => simulateLatency({ success: true, message: 'Boleto cancelado com sucesso' }), apiFn: async () => { const response = await api.post('/boletos/cancelar', payload); return response.data; } }), /** * Agenda um boleto individual * Rota: POST /boletos/agendar/individual */ scheduleBoleto: (payload) => handleRequest({ mockFn: () => simulateLatency({ success: true }), apiFn: async () => { const response = await api.post('/boletos/agendar/individual', payload); return response.data; } }), /** * Busca detalhes de juros de um cliente específico * Rota: GET /financeiro/cliente/boletos * Resposta esperada: { cliente, dias_atraso, juros, multa, seuNumero, situacao, total_atualizado, valor_original, vencimento } * @param {number|string} idempresa * @param {Object} filters - { situacao, mes, ano } */ fetchJurosCliente: (idempresa, filters = {}) => handleRequest({ mockFn: () => simulateLatency([]), apiFn: async () => { // Filtra parâmetros vazios para não enviá-los na URL const cleanFilters = Object.fromEntries( Object.entries(filters).filter(([_, v]) => v !== null && v !== undefined && v !== '') ); const response = await api.get('/financeiro/cliente/boletos', { params: { idempresa, ...cleanFilters } }); const raw = response?.data ?? response; const data = raw?.dados ?? raw?.Base_Dados_API ?? raw; // A API pode retornar um objeto único ou um array if (Array.isArray(data)) return data; // Se for objeto válido com campos conhecidos, envolve em array if (data && typeof data === 'object' && !Array.isArray(data)) { const items = Object.values(data); // Se o próprio objeto tem campos de juros é um registro único const hasBoletoFields = 'vencimento' in data || 'juros' in data || 'situacao' in data; return hasBoletoFields ? [data] : items.filter(i => typeof i === 'object' && i !== null); } return []; } }) };