financial-calc-br
Version:
Calculadora financeira brasileira com suporte a financiamentos, investimentos e cartão de crédito
276 lines (275 loc) • 11.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils/utils");
class FinancingCalc {
/**
* Calcula financiamento usando o Sistema de Amortização Constante (SAC)
* @param {number} valor - Valor total a ser financiado
* @param {number} taxaAnual - Taxa de juros anual (em percentual)
* @param {number} anos - Prazo do financiamento em anos
* @returns {ResultadoSAC} Objeto com detalhes completos do financiamento SAC
*/
financingSAC(valor, taxaAnual, anos) {
const validation = (0, utils_1.validateFinancialParams)(valor, taxaAnual, anos);
if (!validation.isValid) {
throw new Error(`Parâmetros inválidos: ${validation.errors.join(", ")}`);
}
const parcelas = anos * 12;
const taxaMensal = (0, utils_1.convertRate)(taxaAnual, "anual", "mensal") / 100;
const amortizacao = valor / parcelas;
let saldoDevedor = valor;
let totalJuros = 0;
const primeiros12 = [];
const ultimos12 = [];
for (let i = 1; i <= parcelas; i++) {
const juros = saldoDevedor * taxaMensal;
const prestacao = amortizacao + juros;
saldoDevedor = Math.max(0, saldoDevedor - amortizacao);
totalJuros += juros;
if (i <= 12) {
primeiros12.push({
parcela: i,
prestacao: prestacao,
juros: juros,
saldo: saldoDevedor,
});
}
if (i > parcelas - 12) {
ultimos12.push({
parcela: i,
prestacao: prestacao,
juros: juros,
saldo: saldoDevedor,
});
}
}
return {
sistema: "SAC",
valorFinanciado: valor,
prazo: parcelas,
taxa: taxaAnual / 100,
totalJuros: totalJuros,
totalPago: valor + totalJuros,
primeiraParcela: amortizacao + valor * taxaMensal,
ultimaParcela: amortizacao + amortizacao * taxaMensal,
resumo: {
primeiros12,
ultimos12,
},
formatted: {
sistema: "SAC",
valorFinanciado: (0, utils_1.formatMoney)(valor),
prazo: `${(0, utils_1.formatPeriod)(parcelas)} (${parcelas}x)`,
taxa: `${taxaAnual}% a.a.`,
totalJuros: (0, utils_1.formatMoney)(totalJuros),
totalPago: (0, utils_1.formatMoney)(valor + totalJuros),
primeiraParcela: (0, utils_1.formatMoney)(amortizacao + valor * taxaMensal),
ultimaParcela: (0, utils_1.formatMoney)(amortizacao + amortizacao * taxaMensal),
},
};
}
/**
* Calcula financiamento usando o Sistema Price (Tabela Price)
* @param {number} valor - Valor total a ser financiado
* @param {number} taxaAnual - Taxa de juros anual (em percentual)
* @param {number} anos - Prazo do financiamento em anos
* @returns {ResultadoPRICE} Objeto com detalhes completos do financiamento Price
*/
financingPrice(valor, taxaAnual, anos) {
const validation = (0, utils_1.validateFinancialParams)(valor, taxaAnual, anos);
if (!validation.isValid) {
throw new Error(`Parâmetros inválidos: ${validation.errors.join(", ")}`);
}
const parcelas = anos * 12;
const taxaMensal = (0, utils_1.convertRate)(taxaAnual, "anual", "mensal") / 100;
const prestacao = (valor * (taxaMensal * Math.pow(1 + taxaMensal, parcelas))) /
(Math.pow(1 + taxaMensal, parcelas) - 1);
let saldoDevedor = valor;
let totalJuros = 0;
const primeiros12 = [];
const ultimos12 = [];
for (let i = 1; i <= parcelas; i++) {
const juros = saldoDevedor * taxaMensal;
const amortizacao = prestacao - juros;
saldoDevedor = Math.max(0, saldoDevedor - amortizacao);
totalJuros += juros;
if (i <= 12) {
primeiros12.push({
parcela: i,
prestacao: prestacao,
juros: juros,
amortizacao: amortizacao,
saldo: saldoDevedor,
});
}
if (i > parcelas - 12) {
ultimos12.push({
parcela: i,
prestacao: prestacao,
juros: juros,
amortizacao: amortizacao,
saldo: saldoDevedor,
});
}
}
return {
sistema: "Price",
valorFinanciado: valor,
prazo: parcelas,
taxa: taxaAnual / 100,
totalJuros: totalJuros,
totalPago: valor + totalJuros,
prestacaoFixa: prestacao,
resumo: {
primeiros12,
ultimos12,
},
formatted: {
sistema: "Price",
valorFinanciado: (0, utils_1.formatMoney)(valor),
prazo: `${(0, utils_1.formatPeriod)(parcelas)} (${parcelas}x)`,
taxa: `${taxaAnual}% a.a.`,
totalJuros: (0, utils_1.formatMoney)(totalJuros),
totalPago: (0, utils_1.formatMoney)(valor + totalJuros),
prestacaoFixa: (0, utils_1.formatMoney)(prestacao),
},
};
}
/**
* Compara os sistemas de financiamento SAC e Price
* @param {number} valor - Valor total a ser financiado
* @param {number} taxaAnual - Taxa de juros anual (em percentual)
* @param {number} anos - Prazo do financiamento em anos
* @returns {ResultadoComparacao} Objeto com comparação detalhada entre SAC e Price
*/
compareFinancing(valor, taxaAnual, anos) {
const validation = (0, utils_1.validateFinancialParams)(valor, taxaAnual, anos);
if (!validation.isValid) {
throw new Error(`Parâmetros inválidos: ${validation.errors.join(", ")}`);
}
const sac = this.financingSAC(valor, taxaAnual, anos);
const price = this.financingPrice(valor, taxaAnual, anos);
const sacJuros = sac.totalJuros;
const priceJuros = price.totalJuros;
const economia = priceJuros - sacJuros;
return {
cenario: {
valor: valor,
prazo: `${anos} anos`,
taxa: `${taxaAnual}% ao ano`,
},
sac: {
totalJuros: sac.totalJuros,
primeira: sac.primeiraParcela,
ultima: sac.ultimaParcela,
caracteristicas: [
"Parcelas decrescentes",
"Menor custo total",
"Maior parcela inicial",
],
},
price: {
totalJuros: price.totalJuros,
parcelaFixa: price.prestacaoFixa,
caracteristicas: [
"Parcelas fixas",
"Fácil planejamento",
"Maior custo total",
],
},
comparacao: {
economia: economia,
economiaPercentual: economia / priceJuros,
recomendacao: this.getRecommendation(sacJuros, priceJuros, sac.primeiraParcela, price.prestacaoFixa),
formatted: {
economia: (0, utils_1.formatMoney)(economia),
economiaPercentual: `${((economia / priceJuros) * 100).toFixed(1)}%`,
},
},
};
}
/**
* Determina qual sistema de financiamento é mais recomendado
* @param {number} sacJuros - Total de juros do sistema SAC
* @param {number} priceJuros - Total de juros do sistema Price
* @param {number} primeiraSAC - Valor da primeira parcela SAC
* @param {number} parcelaPrice - Valor da parcela fixa Price
* @returns {Recomendacao} Objeto com recomendação do melhor sistema
*/
getRecommendation(sacJuros, priceJuros, primeiraSAC, parcelaPrice) {
const economiaPercentual = ((priceJuros - sacJuros) / priceJuros) * 100;
const diferencaParcela = ((primeiraSAC - parcelaPrice) / parcelaPrice) * 100;
if (economiaPercentual < 5) {
return {
sistema: "Price",
motivo: "Diferença de custo pequena, parcelas fixas facilitam planejamento",
};
}
else if (diferencaParcela > 30) {
return {
sistema: "Price",
motivo: "Primeira parcela SAC muito alta, pode comprometer orçamento",
};
}
else {
return {
sistema: "SAC",
motivo: `Economia significativa de ${(0, utils_1.formatMoney)(priceJuros - sacJuros)}`,
};
}
}
/**
* Simula um financiamento com entrada (down payment)
* @param {number} valorImovel - Valor total do imóvel
* @param {number} entrada - Valor da entrada
* @param {number} taxaAnual - Taxa de juros anual (em percentual)
* @param {number} anos - Prazo do financiamento em anos
* @returns {SimulacaoEntrada} Objeto com simulação completa incluindo entrada
*/
simulateDownPayment(valorImovel, entrada, taxaAnual, anos) {
if (valorImovel <= 0) {
throw new Error("Valor do imóvel deve ser positivo");
}
if (entrada < 0) {
throw new Error("Entrada não pode ser negativa");
}
if (entrada >= valorImovel) {
throw new Error("Entrada não pode ser maior ou igual ao valor do imóvel");
}
const validation = (0, utils_1.validateFinancialParams)(valorImovel - entrada, taxaAnual, anos);
if (!validation.isValid) {
throw new Error(`Parâmetros inválidos: ${validation.errors.join(", ")}`);
}
const valorFinanciado = valorImovel - entrada;
const result = this.compareFinancing(valorFinanciado, taxaAnual, anos);
return {
entrada: entrada,
entradaPercentual: entrada / valorImovel,
valorFinanciado: valorFinanciado,
sac: {
primeira: result.sac.primeira,
ultima: result.sac.ultima,
totalJuros: result.sac.totalJuros,
},
price: {
parcela: result.price.parcelaFixa,
totalJuros: result.price.totalJuros,
},
formatted: {
entrada: (0, utils_1.formatMoney)(entrada),
entradaPercentual: `${((entrada / valorImovel) * 100).toFixed(0)}%`,
valorFinanciado: (0, utils_1.formatMoney)(valorFinanciado),
sac: {
primeira: (0, utils_1.formatMoney)(result.sac.primeira),
ultima: (0, utils_1.formatMoney)(result.sac.ultima),
totalJuros: (0, utils_1.formatMoney)(result.sac.totalJuros),
},
price: {
parcela: (0, utils_1.formatMoney)(result.price.parcelaFixa),
totalJuros: (0, utils_1.formatMoney)(result.price.totalJuros),
},
},
};
}
}
exports.default = FinancingCalc;