As stated in the comments the best way to work with currency in trade is to remove non-numeric characters (grouping points and decimal comma) operationalize and readjust the result by dividing by 100.
The result of these operations results in an object Number
which does not have mile grouping symbols and the decimal separator is the point. What makes it necessary to format that result for your needs.
To obtain culturally specific formatting you must use the method Number.prototype.toLocaleString() returns a string with a crop-sensitive representation for that number.
The first argument of toLocaleString()
is local
which informs the culture in which the number will be formatted. The value for this location is a string in the format BCP 74/RFC 5646
the values valid for local
are listed in http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry. Here I used as local pt-BR
.
The second argument is an object opção
which are the formatting options, act as a more refined setting.
For your case I created two examples of formatting.
One formatting directly in currency which includes the monetary symbol for Reais (R$) which can be specified in the object opções
setting the properties style: 'currency'
to indicate the formatting in local currency and currency: 'BRL'
to indicate the monetary symbol to be inserted in the case BRL
which means Brazilian Real. Here is a list of the values for monetary symbols: ISO 4217 Current currency & funds code list.
The other example formatting as a decimal number, which I find the most appropriate to your question. I have set the properties of the object opções
in style: 'decimal'
to indicate the format in a decimal number, useGrouping: 'true'
(default value, would not need to be used) to display the thousand character(. ) grouper, minimumFractionDigits: '2'
to display a minimum of two decimal places and maximumFractionDigits: '2' (default value would not need to be used) to restrict formatting to a maximum of two decimal places.
//Não sabia do se tratava o seu estoque, criei um fictício.
const produtos = [{
'name': 'perucas fio de prata',
'price': '2.222,57'
},
{
'name': 'perucas fio de ouro',
'price': '5.000.326,90'
},
{
'name': 'perucas fio de barbante',
'price': '1.326,00'
}
];
produtos.forEach((currentValue) => {
// Remoção do caracteres não numéricos.
let rawPrice = parseInt(currentValue.price.replace(/[.,]/g, ''));
let quantity = parseInt(prompt(`Deseja comprar quantas ${currentValue.name} ?`));
// Operacionalização e reajuste do resultado.
let total = (rawPrice * quantity / 100);
//Caso queira o valor formatado como moeda(incluio simbolo ISO 4217 para moeda).
alert(`${currentValue.name}(resultado em moeda): ${quantity} X ${currentValue.price} = ${total.toLocaleString('pt-BR',{ style: 'currency', currency: 'BRL' })}`);
//Caso queira o valor formatdo apenas como decimal com duas casas.
alert(`${currentValue.name}(resultado em decimal): ${quantity} X ${currentValue.price} = ${total.toLocaleString('pt-BR',{ style: 'decimal', useGrouping: 'true', minimumFractionDigits: '2', maximumFractionDigits: '2' })}`);
});
Remove all non-numeric characters from the string to then perform the calculation, then divide by 10 and put the dots and the string back
– Costamilam
I did so, but I lose the value of the two decimal places when I go to float: et valor = this.products[i]. price value.replace('.', ') value.replace(',', ') value = parseFloat(value) value = value * this.products[i]. amount
– veroneseComS
Mathematical operation has no relationship with monetary format (internally numbers have no formatting). Monetary format should only be applied in the display phase. It has to fix the data origin. With what was posted on the question will be a gambiarras show in the area of answers.
– Bacco
@veroneseComS so you divide by 100 at the end of the calculation (not by 10, I was wrong in the previous comment), makes the calculation as integer then goes back to decimal
– Costamilam
@Bacco my frontend brings me the values with dots and commas, but I believe it has already given a clear
– veroneseComS
no sign thousands numbers, and the decimal separator is the point, not comma. Use
replace
stop solving this before converting tofloat
– Ricardo Pontual
@veroneseComS ideally it would be good to already convert into numerical once you capture the data. Preferably the front already send right, if using ajax (even to be able to fix the locale, if the front is internationalizable)
– Bacco