Files
advx/src/server/services/CalculoJudicialService.ts
T
2025-04-10 23:07:21 -03:00

1024 lines
29 KiB
TypeScript

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;
}
}
}