testes/src/services/boletosService.js

216 lines
7.0 KiB
JavaScript

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<Array>}
*/
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<Blob>}
*/
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<any>}
*/
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<Array>}
*/
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<any>}
*/
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 [];
}
})
};