import { PrismaClient, Decimal } from '@prisma/client'; import { v4 as uuidv4 } from 'uuid'; // Importar uuid para gerar IDs const prisma = new PrismaClient(); export class CalculoJudicialService { /** * Cria um novo cálculo judicial */ async criarCalculo(data: { titulo: string; descricao?: string; dataBase: Date; valorBase: number; processoId?: string; clienteId?: string; usuarioId: string; }) { try { // Validar dados de entrada if (!data.titulo || !data.dataBase || data.valorBase === undefined) { throw new Error('Dados incompletos para criar cálculo'); } // Criar cálculo no banco de dados com ID UUID explícito const calculo = await prisma.calculoJudicial.create({ data: { id: uuidv4(), // Gerar UUID válido titulo: data.titulo, descricao: data.descricao, dataBase: data.dataBase, dataCalculo: new Date(), valorBase: new Decimal(data.valorBase), valorCorrigido: new Decimal(data.valorBase), valorFinal: new Decimal(data.valorBase), ...(data.processoId && { processo: { connect: { id: data.processoId } } }), ...(data.clienteId && { cliente: { connect: { id: data.clienteId } } }), ...(data.usuarioId && { usuario: { connect: { id: data.usuarioId } } }) } }); // Registrar o evento de criação no histórico await this.registrarHistorico({ calculoId: calculo.id, usuarioId: data.usuarioId, acao: 'CRIACAO', descricao: 'Cálculo criado', valorNovo: data.valorBase }); return calculo; } catch (error) { console.error('Erro ao criar cálculo judicial:', error); throw new Error(`Falha ao criar cálculo: ${error.message}`); } } /** * Busca um cálculo judicial pelo ID */ async buscarCalculo(id: string) { try { const calculo = await prisma.calculoJudicial.findUnique({ where: { id }, include: { usuario: true, processo: true, cliente: true, correcoes: true, juros: true, multas: true, honorarios: true, parcelas: true, descontos: true, historico: { include: { usuario: true }, orderBy: { criadoEm: 'desc' } } } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } return calculo; } catch (error) { console.error('Erro ao buscar cálculo:', error); throw new Error(`Falha ao buscar cálculo: ${error.message}`); } } /** * Adiciona correção monetária ao cálculo */ async adicionarCorrecaoMonetaria(data: { calculoId: string; indice: string; dataInicial: Date; dataFinal?: Date; valorOriginal: number; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.indice || !data.dataInicial || data.valorOriginal === undefined) { throw new Error('Dados incompletos para adicionar correção monetária'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Calcular o fator de correção const fatorCorrecao = await this.calcularFatorCorrecao({ indice: data.indice, dataInicial: data.dataInicial, dataFinal: data.dataFinal || new Date() }); // Calcular valor corrigido const valorCorrigido = new Decimal(data.valorOriginal).mul(fatorCorrecao); // Criar registro de correção monetária const correcao = await prisma.correcaoMonetaria.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, indice: data.indice, dataInicial: data.dataInicial, dataFinal: data.dataFinal || new Date(), valorOriginal: new Decimal(data.valorOriginal), valorCorrigido, fatorCorrecao } }); // Atualizar o valor corrigido do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Correção monetária adicionada: ${data.indice}`, valorNovo: valorCorrigido.toNumber(), metadados: { correcaoId: correcao.id, indice: data.indice, dataInicial: data.dataInicial, dataFinal: data.dataFinal || new Date(), fatorCorrecao: fatorCorrecao.toNumber() } }); return correcao; } catch (error) { console.error('Erro ao adicionar correção monetária:', error); throw new Error(`Falha ao adicionar correção monetária: ${error.message}`); } } /** * Adiciona juros ao cálculo */ async adicionarJuros(data: { calculoId: string; tipo: string; taxa: number; periodicidade: string; natureza: string; dataInicial: Date; dataFinal?: Date; valorBase: number; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.tipo || data.taxa === undefined || !data.dataInicial) { throw new Error('Dados incompletos para adicionar juros'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Calcular valor dos juros const valorJuros = this.calcularJuros( data.valorBase, data.taxa, data.tipo, data.dataInicial, data.dataFinal || new Date() ); // Criar registro de juros const juros = await prisma.juroCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, tipo: data.tipo, taxa: new Decimal(data.taxa), periodicidade: data.periodicidade, natureza: data.natureza, dataInicial: data.dataInicial, dataFinal: data.dataFinal || new Date(), valorBase: new Decimal(data.valorBase), valorJuros: new Decimal(valorJuros) } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Juros adicionados: ${data.tipo} ${data.taxa * 100}% ${data.periodicidade}`, valorNovo: valorJuros, metadados: { juroId: juros.id, tipo: data.tipo, taxa: data.taxa, dataInicial: data.dataInicial, dataFinal: data.dataFinal || new Date() } }); return juros; } catch (error) { console.error('Erro ao adicionar juros:', error); throw new Error(`Falha ao adicionar juros: ${error.message}`); } } /** * Adiciona multa ao cálculo */ async adicionarMulta(data: { calculoId: string; tipo: string; percentual: number; valorBase: number; fundamento?: string; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.tipo || data.percentual === undefined) { throw new Error('Dados incompletos para adicionar multa'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Calcular valor da multa const valorMulta = new Decimal(data.valorBase).mul(data.percentual); // Criar registro de multa const multa = await prisma.multaCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, tipo: data.tipo, percentual: new Decimal(data.percentual), valorBase: new Decimal(data.valorBase), valorMulta, fundamento: data.fundamento } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Multa adicionada: ${data.tipo} ${data.percentual * 100}%`, valorNovo: valorMulta.toNumber(), metadados: { multaId: multa.id, tipo: data.tipo, percentual: data.percentual } }); return multa; } catch (error) { console.error('Erro ao adicionar multa:', error); throw new Error(`Falha ao adicionar multa: ${error.message}`); } } /** * Adiciona honorários ao cálculo */ async adicionarHonorarios(data: { calculoId: string; tipo: string; percentual: number; valorBase: number; fundamento?: string; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.tipo || data.percentual === undefined) { throw new Error('Dados incompletos para adicionar honorários'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Calcular valor dos honorários const valorHonorario = new Decimal(data.valorBase).mul(data.percentual); // Criar registro de honorários const honorario = await prisma.honorarioCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, tipo: data.tipo, percentual: new Decimal(data.percentual), valorBase: new Decimal(data.valorBase), valorHonorario, fundamento: data.fundamento } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Honorários adicionados: ${data.tipo} ${data.percentual * 100}%`, valorNovo: valorHonorario.toNumber(), metadados: { honorarioId: honorario.id, tipo: data.tipo, percentual: data.percentual } }); return honorario; } catch (error) { console.error('Erro ao adicionar honorários:', error); throw new Error(`Falha ao adicionar honorários: ${error.message}`); } } /** * Adiciona parcela ao cálculo */ async adicionarParcela(data: { calculoId: string; numero: number; dataVencimento: Date; valorOriginal: number; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || data.numero === undefined || !data.dataVencimento) { throw new Error('Dados incompletos para adicionar parcela'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Verificar se já existe uma parcela com este número const existente = await prisma.parcelaCalculo.findFirst({ where: { calculoId: data.calculoId, numero: data.numero } }); if (existente) { throw new Error(`Já existe uma parcela ${data.numero} para este cálculo`); } // Calcular valores corrigidos se a data de vencimento já passou let valorCorrigido = new Decimal(data.valorOriginal); let valorJuros = new Decimal(0); let valorMulta = new Decimal(0); const hoje = new Date(); if (data.dataVencimento < hoje) { // Calcular correção monetária (usando INPC como padrão) const fatorCorrecao = await this.calcularFatorCorrecao({ indice: 'INPC', dataInicial: data.dataVencimento, dataFinal: hoje }); valorCorrigido = valorCorrigido.mul(fatorCorrecao); // Calcular juros de 1% ao mês const meses = this.calcularMesesAtraso(data.dataVencimento, hoje); valorJuros = valorCorrigido.mul(0.01).mul(meses); // Multa padrão de 2% valorMulta = valorCorrigido.mul(0.02); } const valorTotal = valorCorrigido.add(valorJuros).add(valorMulta); // Criar parcela const parcela = await prisma.parcelaCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, numero: data.numero, dataVencimento: data.dataVencimento, valorOriginal: new Decimal(data.valorOriginal), valorCorrigido, valorJuros, valorMulta, valorTotal, pago: false } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Parcela ${data.numero} adicionada`, valorNovo: valorTotal.toNumber(), metadados: { parcelaId: parcela.id, numero: data.numero, dataVencimento: data.dataVencimento, valorOriginal: data.valorOriginal } }); return parcela; } catch (error) { console.error('Erro ao adicionar parcela:', error); throw new Error(`Falha ao adicionar parcela: ${error.message}`); } } /** * Registra pagamento de uma parcela */ async registrarPagamentoParcela(data: { calculoId: string; parcelaId: string; dataPagamento: Date; valorPago?: number; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.parcelaId || !data.dataPagamento) { throw new Error('Dados incompletos para registrar pagamento'); } // Buscar a parcela const parcela = await prisma.parcelaCalculo.findUnique({ where: { id: data.parcelaId } }); if (!parcela) { throw new Error('Parcela não encontrada'); } if (parcela.calculoId !== data.calculoId) { throw new Error('Parcela não pertence ao cálculo informado'); } // Atualizar parcela como paga const parcelaAtualizada = await prisma.parcelaCalculo.update({ where: { id: data.parcelaId }, data: { pago: true, dataPagamento: data.dataPagamento } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Pagamento da parcela ${parcela.numero} registrado`, valorNovo: data.valorPago || parcela.valorTotal.toNumber(), metadados: { parcelaId: data.parcelaId, valorPago: data.valorPago || parcela.valorTotal.toNumber(), dataPagamento: data.dataPagamento } }); return parcelaAtualizada; } catch (error) { console.error('Erro ao registrar pagamento de parcela:', error); throw new Error(`Falha ao registrar pagamento: ${error.message}`); } } /** * Adiciona desconto ao cálculo */ async adicionarDesconto(data: { calculoId: string; tipo: string; descricao?: string; percentual?: number; valorFixo?: number; valorBase: number; usuarioId: string; }) { try { // Validar dados if (!data.calculoId || !data.tipo || (data.percentual === undefined && data.valorFixo === undefined)) { throw new Error('Dados incompletos para adicionar desconto'); } // Verificar se o cálculo existe e não está finalizado const calculo = await prisma.calculoJudicial.findUnique({ where: { id: data.calculoId } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Não é possível modificar um cálculo finalizado'); } // Calcular valor do desconto let valorDesconto = new Decimal(0); if (data.valorFixo !== undefined) { valorDesconto = new Decimal(data.valorFixo); } else if (data.percentual !== undefined) { valorDesconto = new Decimal(data.valorBase).mul(data.percentual); } // Criar registro de desconto const desconto = await prisma.descontoCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, tipo: data.tipo, descricao: data.descricao, percentual: data.percentual ? new Decimal(data.percentual) : null, valorFixo: data.valorFixo ? new Decimal(data.valorFixo) : null, valorBase: new Decimal(data.valorBase), valorDesconto } }); // Atualizar o valor final do cálculo await this.atualizarValorCalculo(data.calculoId); // Registrar no histórico await this.registrarHistorico({ calculoId: data.calculoId, usuarioId: data.usuarioId, acao: 'ATUALIZACAO', descricao: `Desconto adicionado: ${data.tipo}`, valorNovo: valorDesconto.toNumber() * -1, // Valor negativo para desconto metadados: { descontoId: desconto.id, tipo: data.tipo, percentual: data.percentual, valorFixo: data.valorFixo } }); return desconto; } catch (error) { console.error('Erro ao adicionar desconto:', error); throw new Error(`Falha ao adicionar desconto: ${error.message}`); } } /** * Finaliza um cálculo judicial */ async finalizarCalculo(id: string, usuarioId: string) { try { // Verificar se o cálculo existe const calculo = await prisma.calculoJudicial.findUnique({ where: { id } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } if (calculo.status === 'FINALIZADO') { throw new Error('Cálculo já está finalizado'); } // Finalizar o cálculo const calculoFinalizado = await prisma.calculoJudicial.update({ where: { id }, data: { status: 'FINALIZADO', atualizadoEm: new Date() } }); // Registrar no histórico await this.registrarHistorico({ calculoId: id, usuarioId, acao: 'FINALIZACAO', descricao: 'Cálculo finalizado', valorNovo: calculo.valorFinal.toNumber() }); return calculoFinalizado; } catch (error) { console.error('Erro ao finalizar cálculo:', error); throw new Error(`Falha ao finalizar cálculo: ${error.message}`); } } /** * Lista cálculos judiciais com filtros */ async listarCalculos(filtros: { titulo?: string; status?: string; processoId?: string; clienteId?: string; usuarioId?: string; }) { try { const where: any = {}; if (filtros.titulo) { where.titulo = { contains: filtros.titulo, mode: 'insensitive' }; } if (filtros.status) { where.status = filtros.status; } if (filtros.processoId) { where.processoId = filtros.processoId; } if (filtros.clienteId) { where.clienteId = filtros.clienteId; } if (filtros.usuarioId) { where.usuarioId = filtros.usuarioId; } const calculos = await prisma.calculoJudicial.findMany({ where, include: { usuario: true, processo: true, cliente: true }, orderBy: { criadoEm: 'desc' } }); return calculos; } catch (error) { console.error('Erro ao listar cálculos:', error); throw new Error(`Falha ao listar cálculos: ${error.message}`); } } /** * Gera relatório do cálculo em PDF */ async gerarRelatorio(id: string) { try { // Implementar geração de PDF const calculo = await this.buscarCalculo(id); if (!calculo) { throw new Error('Cálculo não encontrado'); } // Aqui seria implementada a lógica de geração de PDF // Por enquanto, retornaremos apenas um buffer vazio return Buffer.from('Relatório PDF placeholder'); } catch (error) { console.error('Erro ao gerar relatório:', error); throw new Error(`Falha ao gerar relatório: ${error.message}`); } } /** * Exporta cálculo para Excel */ async exportarExcel(id: string) { try { // Implementar exportação para Excel const calculo = await this.buscarCalculo(id); if (!calculo) { throw new Error('Cálculo não encontrado'); } // Aqui seria implementada a lógica de exportação para Excel // Por enquanto, retornaremos apenas um buffer vazio return Buffer.from('Excel placeholder'); } catch (error) { console.error('Erro ao exportar para Excel:', error); throw new Error(`Falha ao exportar para Excel: ${error.message}`); } } /** * Calcula o fator de correção entre duas datas para um índice */ async calcularFatorCorrecao(data: { indice: string; dataInicial: Date; dataFinal: Date; }) { try { const { indice, dataInicial, dataFinal } = data; // Obter o mês/ano das datas const mesInicial = dataInicial.getMonth() + 1; // getMonth retorna 0-11 const anoInicial = dataInicial.getFullYear(); const mesFinal = dataFinal.getMonth() + 1; const anoFinal = dataFinal.getFullYear(); // Buscar todos os índices necessários para o período const indices = await prisma.indiceMonetario.findMany({ where: { nome: indice, OR: [ // Índices do ano inicial { anoReferencia: anoInicial, mesReferencia: { gte: mesInicial } }, // Anos intermediários (se houver) { anoReferencia: { gt: anoInicial, lt: anoFinal } }, // Índices do ano final { anoReferencia: anoFinal, mesReferencia: { lte: mesFinal } } ] }, orderBy: [ { anoReferencia: 'asc' }, { mesReferencia: 'asc' } ] }); // Se não houver índices suficientes, usar uma estimativa if (indices.length === 0) { const mesesDiferenca = (anoFinal - anoInicial) * 12 + (mesFinal - mesInicial); // Taxa média mensal estimada (usar 0.5% ao mês como estimativa conservadora) const taxaMediaMensal = 0.005; return new Decimal(Math.pow(1 + taxaMediaMensal, mesesDiferenca)); } // Calcular o fator de correção acumulado let fatorAcumulado = new Decimal(1); for (const indice of indices) { // Somar 1 ao valor do índice (ex: índice de 0.0082 vira fator de 1.0082) const fator = new Decimal(1).add(indice.valor); fatorAcumulado = fatorAcumulado.mul(fator); } return fatorAcumulado; } catch (error) { console.error('Erro ao calcular fator de correção:', error); throw new Error(`Falha ao calcular fator de correção: ${error.message}`); } } /** * Calcula juros entre duas datas */ private calcularJuros( valorBase: number, taxa: number, tipo: string, dataInicial: Date, dataFinal: Date ): number { // Calcular tempo entre as datas (em meses) const meses = this.calcularMesesAtraso(dataInicial, dataFinal); // Juros simples: valorBase * taxa * tempo if (tipo === 'SIMPLES') { return valorBase * taxa * meses; } // Juros compostos: valorBase * ((1 + taxa) ^ tempo - 1) if (tipo === 'COMPOSTO') { return valorBase * (Math.pow(1 + taxa, meses) - 1); } return 0; // Tipo de juros não reconhecido } /** * Calcula meses de atraso entre duas datas */ private calcularMesesAtraso(dataInicial: Date, dataFinal: Date): number { const diferencaAnos = dataFinal.getFullYear() - dataInicial.getFullYear(); const diferencaMeses = dataFinal.getMonth() - dataInicial.getMonth(); let meses = diferencaAnos * 12 + diferencaMeses; // Ajustar para dias (se a diferença for menos de um mês completo) const diaInicial = dataInicial.getDate(); const diaFinal = dataFinal.getDate(); if (diaFinal < diaInicial) { meses -= 1; } // Adicionar fração do mês se necessário const diasNoMes = new Date(dataInicial.getFullYear(), dataInicial.getMonth() + 1, 0).getDate(); const fracaoDias = (diasNoMes - diaInicial + diaFinal) / diasNoMes; return Math.max(0, meses + fracaoDias); } /** * Atualiza o valor final do cálculo somando todos os componentes */ private async atualizarValorCalculo(calculoId: string) { try { // Buscar o cálculo const calculo = await prisma.calculoJudicial.findUnique({ where: { id: calculoId }, include: { correcoes: true, juros: true, multas: true, honorarios: true, parcelas: true, descontos: true } }); if (!calculo) { throw new Error('Cálculo não encontrado'); } // Valor base corrigido (usar o valor da última correção ou o valor base original) let valorCorrigido = calculo.valorBase; if (calculo.correcoes.length > 0) { // Ordenar correções por data const correcoes = [...calculo.correcoes].sort((a, b) => new Date(b.dataFinal).getTime() - new Date(a.dataFinal).getTime() ); // Usar o valor da correção mais recente valorCorrigido = correcoes[0].valorCorrigido; } // Somar juros let valorJuros = new Decimal(0); for (const juro of calculo.juros) { valorJuros = valorJuros.add(juro.valorJuros); } // Somar multas let valorMultas = new Decimal(0); for (const multa of calculo.multas) { valorMultas = valorMultas.add(multa.valorMulta); } // Somar honorários let valorHonorarios = new Decimal(0); for (const honorario of calculo.honorarios) { valorHonorarios = valorHonorarios.add(honorario.valorHonorario); } // Calcular valor das parcelas não pagas let valorParcelas = new Decimal(0); for (const parcela of calculo.parcelas) { if (!parcela.pago) { valorParcelas = valorParcelas.add(parcela.valorTotal); } } // Subtrair descontos let valorDescontos = new Decimal(0); for (const desconto of calculo.descontos) { valorDescontos = valorDescontos.add(desconto.valorDesconto); } // Calcular valor final: Valor Corrigido + Juros + Multas + Honorários + Parcelas - Descontos const valorFinal = valorCorrigido.add(valorJuros).add(valorMultas).add(valorHonorarios).add(valorParcelas).sub(valorDescontos); // Atualizar o cálculo await prisma.calculoJudicial.update({ where: { id: calculoId }, data: { valorCorrigido, valorFinal, atualizadoEm: new Date() } }); return valorFinal; } catch (error) { console.error('Erro ao atualizar valor do cálculo:', error); throw new Error(`Falha ao atualizar valor: ${error.message}`); } } /** * Registra uma entrada no histórico do cálculo */ async registrarHistorico(data: { calculoId: string; usuarioId?: string; acao: string; descricao: string; valorAnterior?: number; valorNovo?: number; metadados?: any; }) { try { return await prisma.historicoCalculo.create({ data: { id: uuidv4(), // Gerar UUID válido calculoId: data.calculoId, usuarioId: data.usuarioId, acao: data.acao, descricao: data.descricao, valorAnterior: data.valorAnterior !== undefined ? new Decimal(data.valorAnterior) : null, valorNovo: data.valorNovo !== undefined ? new Decimal(data.valorNovo) : null, metadados: data.metadados || {} } }); } catch (error) { console.error('Erro ao registrar histórico:', error); // Apenas logar o erro, não interrompe o fluxo return null; } } }