Skip to content

Commit 833c14c

Browse files
component now uses isJurosVisible to control the rendering of the installment interest fields and passes the formInputs and onInputChange to DynamicInputs
1 parent 27516c9 commit 833c14c

1 file changed

Lines changed: 85 additions & 70 deletions

File tree

taxcalcreact/src/components/CalculatorForm.js

Lines changed: 85 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import React, { useState, useEffect } from 'react';
22
import DynamicInputs from './DynamicInputs';
3-
import * as Calc from '../utils/financialCalculation'; // Importa todas as funções de cálculo
3+
import * as Calc from '../utils/financialCalculations'; // Importa todas as funções de cálculo
44

55
const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, setResults }) => {
66
// Estado interno para os inputs do formulário
77
const [formInputs, setFormInputs] = useState({});
8-
const [isJurosVisible, setIsJurosVisible] = useState(false);
8+
const [isJurosVisible, setIsJurosVisible] = useState(false); // Para controlar a visibilidade dos juros na Opção 1
99

1010
// Limpa o estado dos inputs quando a opção principal muda
1111
useEffect(() => {
1212
setFormInputs({});
13+
setIsJurosVisible(false); // Reseta a visibilidade dos juros
1314
}, [selectedOption]);
1415

16+
// Lida com a mudança em qualquer input do formulário
1517
const handleInputChange = (event) => {
1618
const { id, value, type, checked } = event.target;
1719
setFormInputs(prevInputs => ({
@@ -72,29 +74,21 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
7274
// Elas leem do estado do formulário e usam as funções do módulo `financialCalculations`.
7375

7476
function calculateOption1(inputs, selicRate, ipcaRate) {
75-
const valorTotal = parseFloat(inputs.valorTotal);
76-
const parcelas = parseInt(inputs.parcelas);
77-
const descontoVista = parseFloat(inputs.descontoVista) / 100 || 0;
77+
const valorTotal = Calc.getNumericInputValue(inputs, "valorTotal");
78+
const parcelas = Calc.getIntInputValue(inputs, "parcelas");
79+
const descontoVista = Calc.getNumericInputValue(inputs, "descontoVista") / 100 || 0;
7880
const temJurosParcelado = inputs.temJurosParcelado === 'S';
79-
const tipoTaxa = inputs.rendimentoTipoTaxa;
80-
const valorTaxa = parseFloat(inputs.rendimentoValorTaxa);
81-
const considerarIR = inputs.rendimentoConsiderarIR === 'S';
8281

8382
let valorVista = valorTotal * (1 - descontoVista);
8483
let valorParceladoComJuros = valorTotal;
8584

8685
if (temJurosParcelado) {
8786
const tipoJurosParcelado = inputs.tipoJurosParcelado;
88-
const taxaJurosParcelado = parseFloat(inputs.taxaJurosParcelado) / 100;
87+
const taxaJurosParcelado = Calc.getNumericInputValue(inputs, "taxaJurosParcelado") / 100;
8988
valorParceladoComJuros = Calc.calcularValorParceladoComJuros(valorTotal, parcelas, taxaJurosParcelado, tipoJurosParcelado);
9089
}
9190

92-
const valorParcela = valorParceladoComJuros / parcelas;
93-
const taxaRendimentoAjustada = Calc.ajustarTaxaParaIR(
94-
Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, inputs.rendimentoIndiceBase),
95-
parcelas,
96-
considerarIR ? 'S' : 'N'
97-
);
91+
const { taxaMensal: taxaRendimentoAjustada, considerarIR: irConsiderado } = getAdjustedYieldRateFromInputs('rendimento', inputs, parcelas, selicRate, ipcaRate);
9892

9993
const { ganho: rendimentosAcumulados, simulacaoDetalhada } = Calc.simularRendimento(parcelas, valorParcela, taxaRendimentoAjustada);
10094
const valorEfetivoParcelado = valorParceladoComJuros - rendimentosAcumulados;
@@ -104,7 +98,7 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
10498
<p>Valor total da compra: R$ ${valorTotal.toFixed(2)}</p>
10599
<p>Valor pagando à vista (com desconto): R$ ${valorVista.toFixed(2)}</p>
106100
<p>Valor pagando parcelado (com juros, se houver): R$ ${valorParceladoComJuros.toFixed(2)}</p>
107-
<p>Taxa de rendimento utilizada (após IR${considerarIR ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
101+
<p>Taxa de rendimento utilizada (após IR${irConsiderado === 'S' ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
108102
<p>Rendimentos acumulados (se investir o que não foi gasto à vista): R$ ${rendimentosAcumulados.toFixed(2)}</p>
109103
<p>Valor efetivo pago parcelando (descontando rendimentos): R$ ${valorEfetivoParcelado.toFixed(2)}</p>
110104
${simulacaoDetalhada}
@@ -113,27 +107,21 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
113107
}
114108

115109
function calculateOption2(inputs, selicRate, ipcaRate) {
116-
const valorVista = parseFloat(inputs.valorVista);
117-
const parcelas = parseInt(inputs.parcelas);
118-
const valorParcela = parseFloat(inputs.valorParcela);
119-
const tipoTaxa = inputs.rendimentoTipoTaxa;
120-
const valorTaxa = parseFloat(inputs.rendimentoValorTaxa);
121-
const considerarIR = inputs.rendimentoConsiderarIR === 'S';
110+
const valorVista = Calc.getNumericInputValue(inputs, "valorVista");
111+
const parcelas = Calc.getIntInputValue(inputs, "parcelas");
112+
const valorParcela = Calc.getNumericInputValue(inputs, "valorParcela");
122113

123114
const totalParcelado = parcelas * valorParcela;
124-
const taxaRendimentoAjustada = Calc.ajustarTaxaParaIR(
125-
Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, inputs.rendimentoIndiceBase),
126-
parcelas,
127-
considerarIR ? 'S' : 'N'
128-
);
115+
const { taxaMensal: taxaRendimentoAjustada, considerarIR: irConsiderado } = getAdjustedYieldRateFromInputs('rendimento', inputs, parcelas, selicRate, ipcaRate);
116+
129117
const { ganho: rendimentosAcumulados, simulacaoDetalhada } = Calc.simularRendimento(parcelas, valorParcela, taxaRendimentoAjustada);
130118
const valorEfetivoParcelado = totalParcelado - rendimentosAcumulados;
131119

132120
return `
133121
<h3>[2] À Vista vs. Parcelas:</h3>
134122
<p>Valor pagando à vista: R$ ${valorVista.toFixed(2)}</p>
135123
<p>Valor pagando parcelado: R$ ${totalParcelado.toFixed(2)}</p>
136-
<p>Taxa de rendimento utilizada (após IR${considerarIR ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
124+
<p>Taxa de rendimento utilizada (após IR${irConsiderado === 'S' ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
137125
<p>Rendimentos acumulados (se investir o que não foi gasto à vista): R$ ${rendimentosAcumulados.toFixed(2)}</p>
138126
<p>Valor efetivo pago parcelando (descontando rendimentos): R$ ${valorEfetivoParcelado.toFixed(2)}</p>
139127
${simulacaoDetalhada}
@@ -142,20 +130,13 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
142130
}
143131

144132
function calculateOption3(inputs, selicRate, ipcaRate) {
145-
const entrada = parseFloat(inputs.entrada);
146-
const parcelas = parseInt(inputs.parcelas);
147-
const valorParcela = parseFloat(inputs.valorParcela);
148-
const valorVista = parseFloat(inputs.valorVista);
133+
const entrada = Calc.getNumericInputValue(inputs, "entrada");
134+
const parcelas = Calc.getIntInputValue(inputs, "parcelas");
135+
const valorParcela = Calc.getNumericInputValue(inputs, "valorParcela");
136+
const valorVista = Calc.getNumericInputValue(inputs, "valorVista");
149137
const totalParcelado = entrada + parcelas * valorParcela;
150-
const tipoTaxa = inputs.rendimentoTipoTaxa;
151-
const valorTaxa = parseFloat(inputs.rendimentoValorTaxa);
152-
const considerarIR = inputs.rendimentoConsiderarIR === 'S';
153-
154-
const taxaRendimentoAjustada = Calc.ajustarTaxaParaIR(
155-
Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, inputs.rendimentoIndiceBase),
156-
parcelas,
157-
considerarIR ? 'S' : 'N'
158-
);
138+
139+
const { taxaMensal: taxaRendimentoAjustada, considerarIR: irConsiderado } = getAdjustedYieldRateFromInputs('rendimento', inputs, parcelas, selicRate, ipcaRate);
159140

160141
let saldoInvestimento = valorVista;
161142
let rendimentoTotalAcumulado = 0;
@@ -169,7 +150,7 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
169150
rendimentoTotalAcumulado += rendimentoMes;
170151

171152
let valorPagoNoMes = valorParcela;
172-
if (i === 1) {
153+
if (i === 1) { // A entrada é paga no mês 1
173154
valorPagoNoMes += entrada;
174155
}
175156
saldoInvestimento -= valorPagoNoMes;
@@ -187,7 +168,7 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
187168
<p>Número de parcelas: ${parcelas}</p>
188169
<p>Total nominal parcelado (entrada + parcelas): R$ ${totalParcelado.toFixed(2)}</p>
189170
<p>Valor da compra à vista: R$ ${valorVista.toFixed(2)}</p>
190-
<p>Taxa de rendimento utilizada (após IR${considerarIR ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
171+
<p>Taxa de rendimento utilizada (após IR${irConsiderado === 'S' ? ' SIM' : ' NÃO'}): ${(taxaRendimentoAjustada * 100).toFixed(4)}% ao mês</p>
191172
<p>Rendimento total gerado pelo investimento do valor à vista: R$ ${rendimentoTotalAcumulado.toFixed(2)}</p>
192173
<p>Saldo final do investimento (após pagar entrada e parcelas): R$ ${saldoInvestimento.toFixed(2)}</p>
193174
<p>Custo efetivo do parcelamento com entrada (considerando rendimentos): R$ ${valorEfetivoParceladoComEntrada.toFixed(2)}</p>
@@ -197,12 +178,14 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
197178
}
198179

199180
function calculateOption4(inputs) {
200-
const parcelas1 = parseInt(inputs.parcelas1);
201-
const valorParcela1 = parseFloat(inputs.valorParcela1);
202-
const parcelas2 = parseInt(inputs.parcelas2);
203-
const valorParcela2 = parseFloat(inputs.valorParcela2);
181+
const parcelas1 = Calc.getIntInputValue(inputs, "parcelas1");
182+
const valorParcela1 = Calc.getNumericInputValue(inputs, "valorParcela1");
183+
const parcelas2 = Calc.getIntInputValue(inputs, "parcelas2");
184+
const valorParcela2 = Calc.getNumericInputValue(inputs, "valorParcela2");
185+
204186
const total1 = parcelas1 * valorParcela1;
205187
const total2 = parcelas2 * valorParcela2;
188+
206189
return `
207190
<h3>[4] Comparar Duas Opções de Parcelamento:</h3>
208191
<p>Total da primeira opção: R$ ${total1.toFixed(2)}</p>
@@ -212,29 +195,32 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
212195
}
213196

214197
function calculateOption5(inputs) {
215-
const valorParcelaOriginal = parseFloat(inputs.valorParcelaOriginal);
216-
const diasAtraso = parseInt(inputs.diasAtraso);
217-
const multa = parseFloat(inputs.multa) / 100;
218-
const jurosDiarios = parseFloat(inputs.jurosDiarios) / 100;
198+
const valorParcelaOriginal = Calc.getNumericInputValue(inputs, "valorParcelaOriginal");
199+
const diasAtraso = Calc.getIntInputValue(inputs, "diasAtraso");
200+
const multa = Calc.getNumericInputValue(inputs, "multa") / 100;
201+
const jurosDiarios = Calc.getNumericInputValue(inputs, "jurosDiarios") / 100;
202+
219203
const valorCorrigido = valorParcelaOriginal * (1 + multa + jurosDiarios * diasAtraso);
204+
220205
return `
221206
<h3>[5] Impacto de Atrasos em Parcelas:</h3>
222207
<p>Valor com atraso: R$ ${valorCorrigido.toFixed(2)}</p>
223208
`;
224209
}
225210

226211
function calculateOption6(inputs, selicRate, ipcaRate) {
227-
const parcelas = parseInt(inputs.parcelas);
228-
const valorParcela = parseFloat(inputs.valorParcela);
229-
const tipoTaxa = inputs.inflacaoTipoTaxa;
230-
const valorTaxa = parseFloat(inputs.inflacaoValorTaxa);
231-
232-
const inflacaoMensalAjustada = Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, inputs.inflacaoIndiceBase);
212+
const parcelas = Calc.getIntInputValue(inputs, "parcelas");
213+
const valorParcela = Calc.getNumericInputValue(inputs, "valorParcela");
233214

215+
// Para inflação, a função getAdjustedYieldRate com prefixo 'inflacao'
216+
// já retorna a taxa mensal que queremos usar como taxa de desconto/inflação.
217+
const { taxaMensal: inflacaoMensalAjustada } = getAdjustedYieldRateFromInputs('inflacao', inputs, parcelas, selicRate, ipcaRate);
218+
234219
let valorTotalInflacao = 0;
235220
for (let i = 1; i <= parcelas; i++) {
236221
valorTotalInflacao += valorParcela / Math.pow(1 + inflacaoMensalAjustada, i);
237222
}
223+
238224
return `
239225
<h3>[6] Simulação com Inflação:</h3>
240226
<p>Valor de cada parcela: R$ ${valorParcela.toFixed(2)}</p>
@@ -245,28 +231,30 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
245231
}
246232

247233
function calculateOption7(inputs, selicRate, ipcaRate) {
248-
const valorVista = parseFloat(inputs.valorVista);
249-
const parcelas = parseInt(inputs.parcelas);
250-
const valorParcela = parseFloat(inputs.valorParcela);
251-
const tipoTaxa = inputs.investimentoTipoTaxa;
252-
const valorTaxa = parseFloat(inputs.investimentoValorTaxa);
253-
const considerarIR = inputs.investimentoConsiderarIR === 'S';
234+
const valorVista = Calc.getNumericInputValue(inputs, "valorVista");
235+
const parcelas = Calc.getIntInputValue(inputs, "parcelas");
236+
const valorParcela = Calc.getNumericInputValue(inputs, "valorParcela");
254237

255-
const taxaInvestimentoAjustada = Calc.ajustarTaxaParaIR(
256-
Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, inputs.investimentoIndiceBase),
257-
parcelas,
258-
considerarIR ? 'S' : 'N'
259-
);
238+
const { taxaMensal: taxaInvestimentoAjustada, considerarIR: irConsiderado } = getAdjustedYieldRateFromInputs('investimento', inputs, parcelas, selicRate, ipcaRate);
260239

261240
let saldoInvestimento = valorVista;
241+
262242
let tabelaDetalhada = '<p>Detalhes do Investimento:</p><table><thead><tr><th>Mês</th><th>Saldo Inicial (R$)</th><th>Rendimento (R$)</th><th>Parcela Paga (R$)</th><th>Saldo Final (R$)</th></tr></thead><tbody>';
263243

264244
for (let i = 1; i <= parcelas; i++) {
265245
const rendimento = saldoInvestimento * taxaInvestimentoAjustada;
266246
const saldoInicialMes = saldoInvestimento;
247+
267248
saldoInvestimento += rendimento;
268249
saldoInvestimento -= valorParcela;
269-
tabelaDetalhada += `<tr><td>${i}</td><td>${saldoInicialMes.toFixed(2)}</td><td>${rendimento.toFixed(2)}</td><td>${valorParcela.toFixed(2)}</td><td>${saldoInvestimento.toFixed(2)}</td></tr>`;
250+
251+
tabelaDetalhada += `<tr>
252+
<td>${i}</td>
253+
<td>${saldoInicialMes.toFixed(2)}</td>
254+
<td>${rendimento.toFixed(2)}</td>
255+
<td>${valorParcela.toFixed(2)}</td>
256+
<td>${saldoInvestimento.toFixed(2)}</td>
257+
</tr>`;
270258
}
271259
tabelaDetalhada += '</tbody></table>';
272260

@@ -275,13 +263,40 @@ const CalculatorForm = ({ selectedOption, onOptionChange, selicRate, ipcaRate, s
275263
<p>Valor da compra à vista: R$ ${valorVista.toFixed(2)}</p>
276264
<p>Valor de cada parcela: R$ ${valorParcela.toFixed(2)}</p>
277265
<p>Número de parcelas: ${parcelas}</p>
278-
<p>Taxa de investimento utilizada (após IR${considerarIR ? ' SIM' : ' NÃO'}): ${(taxaInvestimentoAjustada * 100).toFixed(4)}% ao mês</p>
266+
<p>Taxa de investimento utilizada (após IR${irConsiderado === 'S' ? ' SIM' : ' NÃO'}): ${(taxaInvestimentoAjustada * 100).toFixed(4)}% ao mês</p>
279267
<p>Saldo final se você investir o valor à vista e pagar em parcelas: R$ ${saldoInvestimento.toFixed(2)}</p>
280268
${tabelaDetalhada}
281269
<strong>${saldoInvestimento > 0 ? "Investir e parcelar é vantajoso (você termina com dinheiro extra)." : "Pagar à vista é mais seguro (evita dívidas ou perdas)."}</strong>
282270
`;
283271
}
284272

273+
/**
274+
* Helper para obter a taxa de rendimento convertida e ajustada para IR,
275+
* lendo os valores do objeto `inputs` do formulário.
276+
* @param {string} prefix - O prefixo dos IDs dos campos de taxa ('rendimento', 'inflacao', 'investimento').
277+
* @param {object} inputs - O objeto `formInputs` do estado do componente.
278+
* @param {number} numMeses - O número total de meses/parcelas.
279+
* @param {number} selicRate - A taxa SELIC atual.
280+
* @param {number} ipcaRate - A taxa IPCA atual.
281+
* @returns {{taxaMensal: number, considerarIR: string}} Objeto com a taxa mensal ajustada e se IR foi considerado ('S' ou 'N').
282+
*/
283+
function getAdjustedYieldRateFromInputs(prefix, inputs, numMeses, selicRate, ipcaRate) {
284+
const tipoTaxa = inputs[`${prefix}TipoTaxa`];
285+
const valorTaxa = inputs[`${prefix}ValorTaxa`];
286+
const considerarIR = inputs[`${prefix}ConsiderarIR`] || 'N'; // Default 'N' se não houver ou não for selecionado
287+
288+
let indiceBase = '';
289+
if (tipoTaxa === 'indice-percentual') {
290+
indiceBase = inputs[`${prefix}IndiceBase`];
291+
}
292+
293+
let taxaMensalDecimal = Calc.getConvertedMonthlyRate(tipoTaxa, valorTaxa, selicRate, ipcaRate, indiceBase);
294+
taxaMensalDecimal = Calc.ajustarTaxaParaIR(taxaMensalDecimal, numMeses, considerarIR);
295+
296+
return { taxaMensal: taxaMensalDecimal, considerarIR: considerarIR };
297+
}
298+
299+
285300
return (
286301
<form id="form-simulador">
287302
<fieldset className="form-section">

0 commit comments

Comments
 (0)