Do not roundup rates

This commit is contained in:
nicolas.dorier
2018-05-13 15:09:17 +09:00
parent 449738414b
commit f7fe855274
3 changed files with 47 additions and 23 deletions

View File

@@ -296,6 +296,22 @@ namespace BTCPayServer.Tests
}
}
[Fact]
public void RoundupCurrenciesCorrectly()
{
foreach(var test in new[]
{
(0.0005m, "$0.0005 (USD)"),
(0.001m, "$0.001 (USD)"),
(0.01m, "$0.01 (USD)"),
(0.1m, "$0.10 (USD)"),
})
{
var actual = InvoiceController.FormatCurrency(test.Item1, "USD", new CurrencyNameTable());
Assert.Equal(test.Item2, actual);
}
}
[Fact]
public void CanPayUsingBIP70()
{
@@ -1424,7 +1440,7 @@ namespace BTCPayServer.Tests
// This check if the currency pair is using right currency pair
Assert.Contains(exchangeRates.ByExchange[result.ExpectedName],
e => ( e.CurrencyPair == new CurrencyPair("BTC", "USD") ||
e => (e.CurrencyPair == new CurrencyPair("BTC", "USD") ||
e.CurrencyPair == new CurrencyPair("BTC", "EUR") ||
e.CurrencyPair == new CurrencyPair("BTC", "USDT"))
&& e.Value > 1.0m // 1BTC will always be more than 1USD
@@ -1454,7 +1470,7 @@ namespace BTCPayServer.Tests
private static BTCPayRateProviderFactory CreateBTCPayRateFactory(BTCPayNetworkProvider provider)
{
return new BTCPayRateProviderFactory(new MemoryCacheOptions() { ExpirationScanFrequency = TimeSpan.FromSeconds(1.0) }, provider, null, new CoinAverageSettings());
return new BTCPayRateProviderFactory(new MemoryCacheOptions() { ExpirationScanFrequency = TimeSpan.FromSeconds(1.0) }, provider, new CoinAverageSettings());
}
[Fact]

View File

@@ -61,7 +61,7 @@ namespace BTCPayServer.Controllers
MonitoringDate = invoice.MonitoringExpiration,
OrderId = invoice.OrderId,
BuyerInformation = invoice.BuyerInformation,
Fiat = FormatCurrency((decimal)dto.Price, dto.Currency),
Fiat = FormatCurrency((decimal)dto.Price, dto.Currency, _CurrencyNameTable),
NotificationUrl = invoice.NotificationURL,
RedirectUrl = invoice.RedirectURL,
ProductInformation = invoice.ProductInformation,
@@ -291,11 +291,29 @@ namespace BTCPayServer.Controllers
private string FormatCurrency(PaymentMethod paymentMethod)
{
string currency = paymentMethod.ParentEntity.ProductInformation.Currency;
return FormatCurrency(paymentMethod.Rate, currency);
return FormatCurrency(paymentMethod.Rate, currency, _CurrencyNameTable);
}
public string FormatCurrency(decimal price, string currency)
public static string FormatCurrency(decimal price, string currency, CurrencyNameTable currencies)
{
return price.ToString("C", _CurrencyNameTable.GetCurrencyProvider(currency)) + $" ({currency})";
var provider = ((CultureInfo)currencies.GetCurrencyProvider(currency)).NumberFormat;
var currencyData = currencies.GetCurrencyData(currency);
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;
}
return price.ToString("C", provider) + $" ({currency})";
}
[HttpGet]
@@ -430,7 +448,7 @@ namespace BTCPayServer.Controllers
var stores = await _StoreRepository.GetStoresByUserId(GetUserId());
model.Stores = new SelectList(stores, nameof(StoreData.Id), nameof(StoreData.StoreName), model.StoreId);
var store = stores.FirstOrDefault(s => s.Id == model.StoreId);
if(store == null)
if (store == null)
{
ModelState.AddModelError(nameof(model.StoreId), "Store not found");
}

View File

@@ -36,7 +36,6 @@ namespace BTCPayServer.Services.Rates
}
IMemoryCache _Cache;
private IOptions<MemoryCacheOptions> _CacheOptions;
CurrencyNameTable _CurrencyTable;
public IMemoryCache Cache
{
get
@@ -47,12 +46,10 @@ namespace BTCPayServer.Services.Rates
CoinAverageSettings _CoinAverageSettings;
public BTCPayRateProviderFactory(IOptions<MemoryCacheOptions> cacheOptions,
BTCPayNetworkProvider btcpayNetworkProvider,
CurrencyNameTable currencyTable,
CoinAverageSettings coinAverageSettings)
{
if (cacheOptions == null)
throw new ArgumentNullException(nameof(cacheOptions));
_CurrencyTable = currencyTable;
_CoinAverageSettings = coinAverageSettings;
_Cache = new MemoryCache(cacheOptions);
_CacheOptions = cacheOptions;
@@ -90,7 +87,7 @@ namespace BTCPayServer.Services.Rates
public CoinAverageExchanges GetSupportedExchanges()
{
CoinAverageExchanges exchanges = new CoinAverageExchanges();
foreach(var exchange in _CoinAverageSettings.AvailableExchanges)
foreach (var exchange in _CoinAverageSettings.AvailableExchanges)
{
exchanges.Add(exchange.Value);
}
@@ -180,13 +177,6 @@ namespace BTCPayServer.Services.Rates
}
rateRule.Reevaluate();
result.Value = rateRule.Value;
var currencyData = _CurrencyTable?.GetCurrencyData(rateRule.CurrencyPair.Right);
if(currencyData != null && result.Value.HasValue)
{
result.Value = decimal.Round(result.Value.Value, currencyData.Divisibility, MidpointRounding.AwayFromZero);
}
result.Errors = rateRule.Errors;
result.EvaluatedRule = rateRule.ToString(true);
result.Rule = rateRule.ToString(false);