btcpayserver/BTCPayServer/Services/DisplayFormatter.cs
d11n 0c16492d1c
Payment details: Re-add unit for displayed amount (#5541)
* Payment details: Re-add unit for displayed amount

Fixes #5540.

* Ensure we are not using the symbol for BTC
2023-12-07 20:40:13 +09:00

75 lines
2.7 KiB
C#

using System;
using System.Globalization;
using BTCPayServer.Rating;
using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Reporting;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Services;
public class DisplayFormatter
{
private readonly CurrencyNameTable _currencyNameTable;
public DisplayFormatter(CurrencyNameTable currencyNameTable)
{
_currencyNameTable = currencyNameTable;
}
public enum CurrencyFormat
{
Code,
Symbol,
CodeAndSymbol,
None
}
/// <summary>
/// Format a currency, rounded to significant divisibility
/// </summary>
/// <param name="value">The value</param>
/// <param name="currency">Currency code</param>
/// <param name="format">The format, defaults to amount + code, e.g. 1.234,56 USD</param>
/// <returns>Formatted amount and currency string</returns>
public string Currency(decimal value, string currency, CurrencyFormat format = CurrencyFormat.Code)
{
var provider = _currencyNameTable.GetNumberFormatInfo(currency, true);
var currencyData = _currencyNameTable.GetCurrencyData(currency, true);
var divisibility = currencyData.Divisibility;
value = value.RoundToSignificant(ref divisibility);
if (divisibility != provider.CurrencyDecimalDigits)
{
provider = (NumberFormatInfo)provider.Clone();
provider.CurrencyDecimalDigits = divisibility;
}
var formatted = value.ToString("C", provider);
// Ensure we are not using the symbol for BTC — we made that design choice consciously.
if (format == CurrencyFormat.Symbol && currencyData.Code == "BTC")
{
format = CurrencyFormat.Code;
}
return format switch
{
CurrencyFormat.None => formatted.Replace(provider.CurrencySymbol, "").Trim(),
CurrencyFormat.Code => $"{formatted.Replace(provider.CurrencySymbol, "").Trim()} {currency}",
CurrencyFormat.Symbol => formatted,
CurrencyFormat.CodeAndSymbol => $"{formatted} ({currency})",
_ => throw new ArgumentOutOfRangeException(nameof(format), format, null)
};
}
public string Currency(string value, string currency, CurrencyFormat format = CurrencyFormat.Code)
{
return Currency(decimal.Parse(value, CultureInfo.InvariantCulture), currency, format);
}
public JObject ToFormattedAmount(decimal value, string currency)
{
var currencyData = _currencyNameTable.GetCurrencyData(currency, true);
var divisibility = currencyData.Divisibility;
return new FormattedAmount(value, divisibility).ToJObject();
}
}