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(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;

                    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);
            }
        }
        public async Task <CurrencySummaryModel> GetCurrencySummary(int currencyId)
        {
            var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.CurrencySummary(currencyId), TimeSpan.FromMinutes(10), async() =>
            {
                using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                {
                    var summary = await context.CurrencyInfo
                                  .AsNoTracking()
                                  .Where(c => c.Id == currencyId)
                                  .Select(currency => new CurrencySummaryModel
                    {
                        Id          = currency.Id,
                        Name        = currency.Currency.Name,
                        Symbol      = currency.Currency.Symbol,
                        LastUpdated = currency.LastUpdated,
                        StarRating  = currency.StarRating,

                        // Info
                        AlgoType     = currency.AlgoType,
                        NetworkType  = currency.NetworkType,
                        CurrentBlock = currency.Currency.Block,
                        BlockTime    = currency.BlockTime,
                        BlockReward  = currency.BlockReward,
                        TotalCoin    = currency.TotalCoin,
                        PosRate      = currency.PosRate,
                        MaxStakeAge  = currency.MaxStakeAge,
                        MinStakeAge  = currency.MinStakeAge,
                        DiffRetarget = currency.DiffRetarget,

                        // Links
                        Website        = currency.Website,
                        CryptopiaForum = currency.CryptopiaForum,
                        LaunchForum    = currency.LaunchForum,
                        BlockExplorer  = currency.BlockExplorer,
                        Source         = currency.Source,

                        // Rating
                        TotalRating   = currency.TotalRating,
                        MaxRating     = currency.MaxRating,
                        TotalPremine  = currency.TotalPremine,
                        WalletLinux   = currency.WalletLinux,
                        WalletMac     = currency.WalletMac,
                        WalletMobile  = currency.WalletMobile,
                        WalletWeb     = currency.WalletWeb,
                        WalletWindows = currency.WalletWindows,

                        // Settings
                        PoolFee          = currency.Currency.PoolFee,
                        TradeFee         = currency.Currency.TradeFee,
                        WithdrawFee      = currency.Currency.WithdrawFee,
                        WithdrawMin      = currency.Currency.MinWithdraw,
                        WithdrawMax      = currency.Currency.MaxWithdraw,
                        TipMin           = currency.Currency.MinTip,
                        MinConfirmations = currency.Currency.MinConfirmations,
                        TippingExpires   = currency.Currency.TippingExpires,
                        RewardsExpires   = currency.Currency.RewardsExpires,


                        // Other
                        WithdrawFeeType = currency.Currency.WithdrawFeeType,
                        MinBaseTrade    = currency.Currency.MinBaseTrade,
                        Status          = currency.Currency.Status,
                        StatusMessage   = currency.Currency.StatusMessage,
                        ListingStatus   = currency.Currency.ListingStatus,
                        FeaturedExpires = currency.Currency.FeaturedExpires,
                        Summary         = currency.Description,
                    }).FirstOrDefaultNoLockAsync().ConfigureAwait(false);

                    return(summary);
                }
            }).ConfigureAwait(false);

            return(cacheResult);
        }
        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);
            }
        }
        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);
        }