Reputation: 1487
I have the following inputs:
cost
, where I type in a currency value, like 6,23
, profit
, where I type in a percentage value like 29,21
and value
where the sum of the both values is show.
JavaScript does the math and returns me in value
the value from cost
+ the currency value of the percentage typed in profit
, in which case the result is 8,05
(6,23 + 29,21%
).
But if try to do the same, but informing the value
instead of profit
, as the same 8,05
, so JavaScript would return me the profit
of 29,21
, but it returns me 36,44
.
Does anyone know what it can be?
Here is my code:
$(document).ready(function () {
$(".valor").on("input", function () {
// Margem
var valor = $(this).val();
var valorCorrigido = parseFloat(adicionarPontos(valor));
var valorFloat = parseFloat(valorCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Calculo
var calculo = (parseFloat(valorFloat) - parseFloat(valorCustoFloat)) / parseFloat(valorCustoFloat) * 100;
var inputMargem = $(this).attr("margem");
$("#" + inputMargem).val(calculo.toFixed(2)).trigger('blur');
});
// Faz o calculo do valor com base na margem
$(".margem").on("input", function () {
// Margem
var valorMargem = $(this).val();
var valorMargemCorrigido = parseFloat(adicionarPontos(valorMargem));
var valorMargemFloat = parseFloat(valorMargemCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Cálculo
var calculo = (parseFloat(valorCustoFloat) * parseFloat(valorMargemFloat) / 100) + parseFloat(valorCustoFloat);
var inputValor = $(this).attr("valor");
var resultadoMonetario = calculo.toFixed(2).toString();
resultadoMonetario = resultadoMonetario.replace(".", ",");
$("#" + inputValor).val(resultadoMonetario).trigger('blur');
});
function removerPontos(valor){
valor = valor.replace(".","");
valor = valor.replace(",",".");
return valor;
}
function adicionarPontos(valor){
if(valor.length == 1){
return valor;
}
else{
if(valor.length == 2){
return valor;
}
else{
// The problem was here
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
}
}
}
});
$('input').mask('00.000.000,00', {
reverse: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.13.4/jquery.mask.js"></script>
Custo:
<input type='text' id='custo' class='custo valores' name='custo'>
<br>
<br> Valor:
<input type='text' id='valor1' class='valor valores' name='valor1' margem='margem1'> Margem:
<input type='text' id='margem1' class='margem valores' name='margem1' valor="valor1">
<br> Valor:
<input type='text' id='valor2' class='valor valores' name='valor2' margem='margem2'> Margem:
<input type='text' id='margem2' class='margem valores' name='margem2' valor="valor2">
Upvotes: 0
Views: 474
Reputation: 1487
So seems that the problem was in this part of the code:
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
After changing it to this worked fine:
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substring(valor.length - 2, valor.length);
Upvotes: 0
Reputation: 53576
If your total profit equation is total = cost + (cost * profit)
.
Then your profit % equation should be profit = (total - cost) / cost
.
Here are two functions that provide you with what you need. You might be interested to use them instead of calculating in line like how you do in your question.
function getProfitTotal(cost, profit) {
cost = parseFloat(cost, 10);
profit = parseFloat(profit, 10) / 100;
return cost + (cost * profit);
}
function getProfitMargin(cost, total) {
cost = parseFloat(cost, 10);
total = parseFloat(total, 10);
return (total - cost) / cost * 100;
}
Thus getProfitMargin(6.23, getProfitTotal(6.23, 21.23) );
will output 21.23
. Just use .toFixed(2)
before setting the value in your text field.
On a side note, you should only reset your field's value if the value is NaN
. As of now, I am personally unable to write decimals in the example you provided because of this.
Also, all numbers have to be dot-separated. Just parse and format your numbers with a globalization library, as your current functions are not working correctly as described earlier.
Upvotes: 0
Reputation: 20601
The calculations appear to be incorrect because decimal separators in JavaScript are not localized.
6,23 * 29,21 // 21
6.23 * 29.21 // 181.97830000000002
parseFloat(6,23); // 6
parseFloat(6.23); // 6.23
You can use Number.prototype.toLocaleString()
or a currency formatting plugin to format the values for display, but your custo
, valor
, and margem
values should be formatted with a .
decimal separator when you do your calculations.
Upvotes: 1