287 lines
10 KiB
C#
287 lines
10 KiB
C#
using Nop.Core;
|
|
using Nop.Core.Domain.Directory;
|
|
using Nop.Data;
|
|
using Nop.Services.Stores;
|
|
|
|
namespace Nop.Services.Directory;
|
|
|
|
/// <summary>
|
|
/// Currency service
|
|
/// </summary>
|
|
public partial class CurrencyService : ICurrencyService
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly CurrencySettings _currencySettings;
|
|
protected readonly IExchangeRatePluginManager _exchangeRatePluginManager;
|
|
protected readonly IRepository<Currency> _currencyRepository;
|
|
protected readonly IStoreMappingService _storeMappingService;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public CurrencyService(CurrencySettings currencySettings,
|
|
IExchangeRatePluginManager exchangeRatePluginManager,
|
|
IRepository<Currency> currencyRepository,
|
|
IStoreMappingService storeMappingService)
|
|
{
|
|
_currencySettings = currencySettings;
|
|
_exchangeRatePluginManager = exchangeRatePluginManager;
|
|
_currencyRepository = currencyRepository;
|
|
_storeMappingService = storeMappingService;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
#region Currency
|
|
|
|
/// <summary>
|
|
/// Deletes currency
|
|
/// </summary>
|
|
/// <param name="currency">Currency</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
public virtual async Task DeleteCurrencyAsync(Currency currency)
|
|
{
|
|
await _currencyRepository.DeleteAsync(currency);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a currency
|
|
/// </summary>
|
|
/// <param name="currencyId">Currency identifier</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the currency
|
|
/// </returns>
|
|
public virtual async Task<Currency> GetCurrencyByIdAsync(int currencyId)
|
|
{
|
|
return await _currencyRepository.GetByIdAsync(currencyId, cache => default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a currency by code
|
|
/// </summary>
|
|
/// <param name="currencyCode">Currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the currency
|
|
/// </returns>
|
|
public virtual async Task<Currency> GetCurrencyByCodeAsync(string currencyCode)
|
|
{
|
|
if (string.IsNullOrEmpty(currencyCode))
|
|
return null;
|
|
|
|
return (await GetAllCurrenciesAsync(true))
|
|
.FirstOrDefault(c => c.CurrencyCode.ToLowerInvariant() == currencyCode.ToLowerInvariant());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all currencies
|
|
/// </summary>
|
|
/// <param name="showHidden">A value indicating whether to show hidden records</param>
|
|
/// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the currencies
|
|
/// </returns>
|
|
public virtual async Task<IList<Currency>> GetAllCurrenciesAsync(bool showHidden = false, int storeId = 0)
|
|
{
|
|
var currencies = await _currencyRepository.GetAllAsync(query =>
|
|
{
|
|
if (!showHidden)
|
|
query = query.Where(c => c.Published);
|
|
|
|
query = query.OrderBy(c => c.DisplayOrder).ThenBy(c => c.Id);
|
|
|
|
return query;
|
|
}, cache => cache.PrepareKeyForDefaultCache(NopDirectoryDefaults.CurrenciesAllCacheKey, showHidden));
|
|
|
|
//store mapping
|
|
if (storeId > 0)
|
|
currencies = await currencies
|
|
.WhereAwait(async c => await _storeMappingService.AuthorizeAsync(c, storeId))
|
|
.ToListAsync();
|
|
|
|
return currencies;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inserts a currency
|
|
/// </summary>
|
|
/// <param name="currency">Currency</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
public virtual async Task InsertCurrencyAsync(Currency currency)
|
|
{
|
|
await _currencyRepository.InsertAsync(currency);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the currency
|
|
/// </summary>
|
|
/// <param name="currency">Currency</param>
|
|
/// <returns>A task that represents the asynchronous operation</returns>
|
|
public virtual async Task UpdateCurrencyAsync(Currency currency)
|
|
{
|
|
await _currencyRepository.UpdateAsync(currency);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Conversions
|
|
|
|
/// <summary>
|
|
/// Gets live rates regarding the passed currency
|
|
/// </summary>
|
|
/// <param name="currencyCode">Currency code; pass null to use primary exchange rate currency</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the exchange rates
|
|
/// </returns>
|
|
public virtual async Task<IList<ExchangeRate>> GetCurrencyLiveRatesAsync(string currencyCode = null)
|
|
{
|
|
var exchangeRateProvider = await _exchangeRatePluginManager.LoadPrimaryPluginAsync()
|
|
?? throw new Exception("Active exchange rate provider cannot be loaded");
|
|
|
|
currencyCode ??= (await GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId))?.CurrencyCode
|
|
?? throw new NopException("Primary exchange rate currency is not set");
|
|
|
|
return await exchangeRateProvider.GetCurrencyLiveRatesAsync(currencyCode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="exchangeRate">Currency exchange rate</param>
|
|
/// <returns>Converted value</returns>
|
|
public virtual decimal ConvertCurrency(decimal amount, decimal exchangeRate)
|
|
{
|
|
if (amount != decimal.Zero && exchangeRate != decimal.Zero)
|
|
return amount * exchangeRate;
|
|
|
|
return decimal.Zero;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to primary store currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="sourceCurrencyCode">Source currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the converted value
|
|
/// </returns>
|
|
public virtual async Task<decimal> ConvertToPrimaryStoreCurrencyAsync(decimal amount, Currency sourceCurrencyCode)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(sourceCurrencyCode);
|
|
|
|
var primaryStoreCurrency = await GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
|
|
var result = await ConvertCurrencyAsync(amount, sourceCurrencyCode, primaryStoreCurrency);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts from primary store currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="targetCurrencyCode">Target currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the converted value
|
|
/// </returns>
|
|
public virtual async Task<decimal> ConvertFromPrimaryStoreCurrencyAsync(decimal amount, Currency targetCurrencyCode)
|
|
{
|
|
var primaryStoreCurrency = await GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
|
|
var result = await ConvertCurrencyAsync(amount, primaryStoreCurrency, targetCurrencyCode);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="sourceCurrencyCode">Source currency code</param>
|
|
/// <param name="targetCurrencyCode">Target currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the converted value
|
|
/// </returns>
|
|
public virtual async Task<decimal> ConvertCurrencyAsync(decimal amount, Currency sourceCurrencyCode, Currency targetCurrencyCode)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(sourceCurrencyCode);
|
|
|
|
ArgumentNullException.ThrowIfNull(targetCurrencyCode);
|
|
|
|
var result = amount;
|
|
|
|
if (result == decimal.Zero || sourceCurrencyCode.Id == targetCurrencyCode.Id)
|
|
return result;
|
|
|
|
result = await ConvertToPrimaryExchangeRateCurrencyAsync(result, sourceCurrencyCode);
|
|
result = await ConvertFromPrimaryExchangeRateCurrencyAsync(result, targetCurrencyCode);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to primary exchange rate currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="sourceCurrencyCode">Source currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the converted value
|
|
/// </returns>
|
|
public virtual async Task<decimal> ConvertToPrimaryExchangeRateCurrencyAsync(decimal amount, Currency sourceCurrencyCode)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(sourceCurrencyCode);
|
|
|
|
var primaryExchangeRateCurrency = await GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId) ?? throw new Exception("Primary exchange rate currency cannot be loaded");
|
|
|
|
var result = amount;
|
|
if (result == decimal.Zero || sourceCurrencyCode.Id == primaryExchangeRateCurrency.Id)
|
|
return result;
|
|
|
|
var exchangeRate = sourceCurrencyCode.Rate;
|
|
if (exchangeRate == decimal.Zero)
|
|
throw new NopException($"Exchange rate not found for currency [{sourceCurrencyCode.Name}]");
|
|
result /= exchangeRate;
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts from primary exchange rate currency
|
|
/// </summary>
|
|
/// <param name="amount">Amount</param>
|
|
/// <param name="targetCurrencyCode">Target currency code</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the converted value
|
|
/// </returns>
|
|
public virtual async Task<decimal> ConvertFromPrimaryExchangeRateCurrencyAsync(decimal amount, Currency targetCurrencyCode)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(targetCurrencyCode);
|
|
|
|
var primaryExchangeRateCurrency = await GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId) ?? throw new Exception("Primary exchange rate currency cannot be loaded");
|
|
|
|
var result = amount;
|
|
if (result == decimal.Zero || targetCurrencyCode.Id == primaryExchangeRateCurrency.Id)
|
|
return result;
|
|
|
|
var exchangeRate = targetCurrencyCode.Rate;
|
|
if (exchangeRate == decimal.Zero)
|
|
throw new NopException($"Exchange rate not found for currency [{targetCurrencyCode.Name}]");
|
|
result *= exchangeRate;
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
} |