diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index dcc5b9c1d..058383ac5 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -332,7 +332,7 @@ namespace BTCPayServer.Tests (0.1m, "$0.10 (USD)"), }) { - var actual = InvoiceController.FormatCurrency(test.Item1, "USD", new CurrencyNameTable()); + var actual = new CurrencyNameTable().DisplayFormatCurrency(test.Item1, "USD"); Assert.Equal(test.Item2, actual); } } diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 48d39969c..340643b1f 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -57,7 +57,7 @@ namespace BTCPayServer.Controllers MonitoringDate = invoice.MonitoringExpiration, OrderId = invoice.OrderId, BuyerInformation = invoice.BuyerInformation, - Fiat = FormatCurrency((decimal)dto.Price, dto.Currency, _CurrencyNameTable), + Fiat = _CurrencyNameTable.DisplayFormatCurrency((decimal)dto.Price, dto.Currency), NotificationUrl = invoice.NotificationURL, RedirectUrl = invoice.RedirectURL, ProductInformation = invoice.ProductInformation, @@ -323,39 +323,12 @@ namespace BTCPayServer.Controllers if (cryptoCode == productInformation.Currency) return null; - return FormatCurrency(productInformation.Price, productInformation.Currency, _CurrencyNameTable); + return _CurrencyNameTable.DisplayFormatCurrency(productInformation.Price, productInformation.Currency); } private string ExchangeRate(PaymentMethod paymentMethod) { string currency = paymentMethod.ParentEntity.ProductInformation.Currency; - return FormatCurrency(paymentMethod.Rate, currency, _CurrencyNameTable); - } - - public static string FormatCurrency(decimal price, string currency, CurrencyNameTable currencies) - { - var provider = currencies.GetNumberFormatInfo(currency, true); - var currencyData = currencies.GetCurrencyData(currency, true); - var divisibility = currencyData.Divisibility; - while (true) - { - var rounded = decimal.Round(price, divisibility, MidpointRounding.AwayFromZero); - if ((Math.Abs(rounded - price) / price) < 0.001m) - { - price = rounded; - break; - } - divisibility++; - } - if (divisibility != provider.CurrencyDecimalDigits) - { - provider = (NumberFormatInfo)provider.Clone(); - provider.CurrencyDecimalDigits = divisibility; - } - - if (currencyData.Crypto) - return price.ToString("C", provider); - else - return price.ToString("C", provider) + $" ({currency})"; + return _CurrencyNameTable.DisplayFormatCurrency(paymentMethod.Rate, currency); } [HttpGet] diff --git a/BTCPayServer/Services/Rates/CurrencyNameTable.cs b/BTCPayServer/Services/Rates/CurrencyNameTable.cs index a709890e0..9773cb711 100644 --- a/BTCPayServer/Services/Rates/CurrencyNameTable.cs +++ b/BTCPayServer/Services/Rates/CurrencyNameTable.cs @@ -101,6 +101,40 @@ namespace BTCPayServer.Services.Rates currencyProviders.TryAdd(code, number); } + /// + /// Format a currency like "0.004 $ (USD)", round to significant divisibility + /// + /// The value + /// Currency code + /// Add three letter suffix (like USD) + /// + public string DisplayFormatCurrency(decimal value, string currency, bool threeLetterSuffix = true) + { + var provider = GetNumberFormatInfo(currency, true); + var currencyData = GetCurrencyData(currency, true); + var divisibility = currencyData.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) + { + provider = (NumberFormatInfo)provider.Clone(); + provider.CurrencyDecimalDigits = divisibility; + } + + if (currencyData.Crypto) + return value.ToString("C", provider); + else + return value.ToString("C", provider) + $" ({currency})"; + } + Dictionary _Currencies; static CurrencyData[] LoadCurrency() @@ -135,13 +169,16 @@ namespace BTCPayServer.Services.Rates foreach (var network in new BTCPayNetworkProvider(NetworkType.Mainnet).GetAll()) { - dico.TryAdd(network.CryptoCode, new CurrencyData() + if (!dico.TryAdd(network.CryptoCode, new CurrencyData() { Code = network.CryptoCode, Divisibility = 8, Name = network.CryptoCode, Crypto = true - }); + })) + { + dico[network.CryptoCode].Crypto = true; + } } return dico.Values.ToArray(); @@ -150,9 +187,9 @@ namespace BTCPayServer.Services.Rates public CurrencyData GetCurrencyData(string currency, bool useFallback) { CurrencyData result; - if(!_Currencies.TryGetValue(currency.ToUpperInvariant(), out result)) + if (!_Currencies.TryGetValue(currency.ToUpperInvariant(), out result)) { - if(useFallback) + if (useFallback) { var usd = GetCurrencyData("USD", false); result = new CurrencyData()