UNPKG

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
"use strict"; 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;