public async Task <DataTablesResponse> GetCurrencyInfo(DataTablesModel model)
        {
            var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.CurrencyInfo(), TimeSpan.FromMinutes(5), async() =>
            {
                using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                {
                    var query = context.Currency
                                .AsNoTracking()
                                .Where(c => c.IsEnabled)
                                .Select(currency => new
                    {
                        Id            = currency.Id,
                        Name          = currency.Name,
                        Symbol        = currency.Symbol,
                        Rating        = currency.Info.StarRating,
                        Algo          = currency.Info.AlgoType,
                        Network       = currency.Info.NetworkType,
                        Connections   = currency.Connections,
                        BlockHeight   = currency.Block,
                        Status        = currency.Status,
                        StatusMessage = currency.StatusMessage,
                        ListingStatus = currency.ListingStatus,
                        Version       = currency.Version,
                    }).OrderBy(x => x.Name);

                    return(await query.GetDataTableResultNoLockAsync(model).ConfigureAwait(false));
                }
            }).ConfigureAwait(false);

            return(cacheResult);
        }
        public async Task <IWriterResult> DelistCurrency(string adminUserId, UpdateListingStatusModel model)
        {
            model.ListingStatus = CurrencyListingStatus.Delisted;
            var writerResult = await UpdateListingStatus(adminUserId, model);

            if (!writerResult.Success)
            {
                return(writerResult);
            }

            using (var context = ExchangeDataContextFactory.CreateContext())
            {
                // Checks for closing trade pairs only as it's expected to be in 'delisting' before it's delisted.
                var tradePairs = await context.TradePair.Where(t => t.Status == TradePairStatus.Closing && (t.CurrencyId1 == model.CurrencyId || t.CurrencyId2 == model.CurrencyId)).ToListNoLockAsync();

                foreach (var tradePair in tradePairs)
                {
                    tradePair.Status = TradePairStatus.Closed;
                }

                using (var adminContext = DataContextFactory.CreateContext())
                {
                    adminContext.LogActivity(adminUserId, $"Delisted Currency: {model.Name}");
                    await adminContext.SaveChangesAsync().ConfigureAwait(false);
                }

                await context.SaveChangesAsync().ConfigureAwait(false);

                await CacheService.InvalidateAsync(CacheKey.Currencies(), CacheKey.CurrencyInfo(), CacheKey.CurrencyDataTable(), CacheKey.CurrencySummary(model.CurrencyId)).ConfigureAwait(false);
            }

            writerResult.Message = "Successfully delisted currency.";

            return(writerResult);
        }
        public async Task <IWriterResult> UpdateCurrencyInfo(UpdateCurrencyInfoModel model)
        {
            try
            {
                using (var context = ExchangeDataContextFactory.CreateContext())
                {
                    var currencyInfo =
                        await context.CurrencyInfo.Where(c => c.Id == model.Id).FirstOrDefaultNoLockAsync().ConfigureAwait(false);

                    if (currencyInfo == null)
                    {
                        return(new WriterResult(false, "Currency not found"));
                    }

                    currencyInfo.AlgoType       = model.AlgoType;
                    currencyInfo.BlockExplorer  = model.BlockExplorer;
                    currencyInfo.BlockReward    = model.BlockReward;
                    currencyInfo.BlockTime      = model.BlockTime;
                    currencyInfo.CryptopiaForum = model.CryptopiaForum;
                    currencyInfo.Description    = model.Summary;
                    currencyInfo.DiffRetarget   = model.DiffRetarget;
                    currencyInfo.LaunchForum    = model.LaunchForum;
                    currencyInfo.MaxStakeAge    = model.MaxStakeAge;
                    currencyInfo.MinStakeAge    = model.MinStakeAge;
                    currencyInfo.NetworkType    = model.NetworkType;
                    currencyInfo.PosRate        = model.PosRate;
                    currencyInfo.Source         = model.Source;
                    currencyInfo.TotalCoin      = model.TotalCoin;
                    currencyInfo.TotalPremine   = model.TotalPremine;
                    currencyInfo.WalletLinux    = model.WalletLinux;
                    currencyInfo.WalletMac      = model.WalletMac;
                    currencyInfo.WalletMobile   = model.WalletMobile;
                    currencyInfo.WalletWeb      = model.WalletWeb;
                    currencyInfo.WalletWindows  = model.WalletWindows;
                    currencyInfo.Website        = model.Website;
                    currencyInfo.LastUpdated    = DateTime.UtcNow;

                    var ratingInfo = CalulateRating(model, currencyInfo.MaxRating);
                    currencyInfo.TotalRating = ratingInfo.TotalRating;
                    currencyInfo.StarRating  = ratingInfo.StarRating;

                    await context.SaveChangesAsync().ConfigureAwait(false);

                    await
                    CacheService.InvalidateAsync(CacheKey.CurrencyInfo(), CacheKey.CurrencyDataTable(),
                                                 CacheKey.CurrencySummary(model.Id)).ConfigureAwait(false);

                    return(new WriterResult(true, "Succesfully updated currency details."));
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
        public async Task <IWriterResult> UpdateCurrency(string adminUserId, UpdateCurrencyModel model)
        {
            try
            {
                using (var context = ExchangeDataContextFactory.CreateContext())
                {
                    var currency =
                        await context.Currency.Where(c => c.Id == model.Id).FirstOrDefaultNoLockAsync().ConfigureAwait(false);

                    if (currency == null)
                    {
                        return(new WriterResult(false, "Currency not found"));
                    }

                    currency.PoolFee          = model.PoolFee;
                    currency.TradeFee         = model.TradeFee;
                    currency.WithdrawFee      = model.WithdrawFee;
                    currency.WithdrawFeeType  = model.WithdrawFeeType;
                    currency.MinWithdraw      = model.WithdrawMin;
                    currency.MaxWithdraw      = model.WithdrawMax;
                    currency.MinTip           = model.TipMin;
                    currency.MinBaseTrade     = model.MinBaseTrade;
                    currency.MinConfirmations = model.MinConfirmations;
                    currency.Status           = model.Status;
                    currency.StatusMessage    = model.StatusMessage;
                    currency.ListingStatus    = model.ListingStatus;

                    using (var adminContext = DataContextFactory.CreateContext())
                    {
                        adminContext.LogActivity(adminUserId, $"Updated Currency: {currency.Symbol}");
                    }

                    await context.SaveChangesAsync().ConfigureAwait(false);

                    await CacheService.InvalidateAsync(CacheKey.Currencies(), CacheKey.CurrencyInfo(), CacheKey.CurrencyDataTable(), CacheKey.CurrencySummary(model.Id)).ConfigureAwait(false);

                    return(new WriterResult(true, "Succesfully updated currency settings."));
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
        private async Task <IWriterResult> UpdateListingStatus(string adminUserId, UpdateListingStatusModel model)
        {
            try
            {
                using (var context = ExchangeDataContextFactory.CreateContext())
                {
                    var currency =
                        await context.Currency.Where(c => c.Id == model.CurrencyId).FirstOrDefaultNoLockAsync().ConfigureAwait(false);

                    if (currency == null)
                    {
                        return(new WriterResult(false, "Currency not found"));
                    }

                    var oldStatus = currency.ListingStatus;
                    currency.StatusMessage     = model.StatusMessage;
                    currency.ListingStatus     = model.ListingStatus;
                    currency.Settings.DelistOn = model.DelistOn;

                    using (var adminContext = DataContextFactory.CreateContext())
                    {
                        adminContext.LogActivity(adminUserId, $"Updated Currency listing status from : {oldStatus} to: {model.ListingStatus}");
                        await adminContext.SaveChangesAsync().ConfigureAwait(false);
                    }

                    await context.SaveChangesAsync().ConfigureAwait(false);

                    await CacheService.InvalidateAsync(CacheKey.Currencies(), CacheKey.CurrencyInfo(), CacheKey.CurrencyDataTable(), CacheKey.CurrencySummary(model.CurrencyId)).ConfigureAwait(false);

                    return(new WriterResult(true, "Succesfully updated listing status."));
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }