Round currency up to significant decimal

This commit is contained in:
nicolas.dorier
2019-02-22 22:15:25 +09:00
parent fbcb69f447
commit b4b4523193
3 changed files with 22 additions and 15 deletions

View File

@@ -108,8 +108,10 @@ namespace BTCPayServer.Controllers
var currencyInfo = _CurrencyNameTable.GetNumberFormatInfo(invoice.Currency, false); var currencyInfo = _CurrencyNameTable.GetNumberFormatInfo(invoice.Currency, false);
if (currencyInfo != null) if (currencyInfo != null)
{ {
invoice.Price = Math.Round(invoice.Price, currencyInfo.CurrencyDecimalDigits); int divisibility = currencyInfo.CurrencyDecimalDigits;
invoice.TaxIncluded = Math.Round(taxIncluded, currencyInfo.CurrencyDecimalDigits); invoice.Price = invoice.Price.RoundToSignificant(ref divisibility);
divisibility = currencyInfo.CurrencyDecimalDigits;
invoice.TaxIncluded = taxIncluded.RoundToSignificant(ref divisibility);
} }
invoice.Price = Math.Max(0.0m, invoice.Price); invoice.Price = Math.Max(0.0m, invoice.Price);
invoice.TaxIncluded = Math.Max(0.0m, taxIncluded); invoice.TaxIncluded = Math.Max(0.0m, taxIncluded);

View File

@@ -61,6 +61,23 @@ namespace BTCPayServer
} }
return value; return value;
} }
public static decimal RoundToSignificant(this decimal value, ref int divisibility)
{
if (value != 0m)
{
while (true)
{
var rounded = decimal.Round(value, divisibility, MidpointRounding.AwayFromZero);
if ((Math.Abs(rounded - value) / value) < 0.001m)
{
value = rounded;
break;
}
divisibility++;
}
}
return value;
}
public static PaymentMethodId GetpaymentMethodId(this InvoiceCryptoInfo info) public static PaymentMethodId GetpaymentMethodId(this InvoiceCryptoInfo info)
{ {
return new PaymentMethodId(info.CryptoCode, Enum.Parse<PaymentTypes>(info.PaymentType)); return new PaymentMethodId(info.CryptoCode, Enum.Parse<PaymentTypes>(info.PaymentType));

View File

@@ -130,19 +130,7 @@ namespace BTCPayServer.Services.Rates
var provider = GetNumberFormatInfo(currency, true); var provider = GetNumberFormatInfo(currency, true);
var currencyData = GetCurrencyData(currency, true); var currencyData = GetCurrencyData(currency, true);
var divisibility = currencyData.Divisibility; var divisibility = currencyData.Divisibility;
if (value != 0m) value = value.RoundToSignificant(ref divisibility);
{
while (true)
{
var rounded = decimal.Round(value, divisibility, MidpointRounding.AwayFromZero);
if ((Math.Abs(rounded - value) / value) < 0.001m)
{
value = rounded;
break;
}
divisibility++;
}
}
if (divisibility != provider.CurrencyDecimalDigits) if (divisibility != provider.CurrencyDecimalDigits)
{ {
provider = (NumberFormatInfo)provider.Clone(); provider = (NumberFormatInfo)provider.Clone();