private async Task <ViewCrowdfundViewModel> GetInfo(AppData appData) { var settings = appData.GetSettings <CrowdfundSettings>(); var resetEvery = settings.StartDate.HasValue ? settings.ResetEvery : CrowdfundResetEvery.Never; DateTime?lastResetDate = null; DateTime?nextResetDate = null; if (resetEvery != CrowdfundResetEvery.Never) { lastResetDate = settings.StartDate.Value; nextResetDate = lastResetDate.Value; while (DateTime.UtcNow >= nextResetDate) { lastResetDate = nextResetDate; switch (resetEvery) { case CrowdfundResetEvery.Hour: nextResetDate = lastResetDate.Value.AddHours(settings.ResetEveryAmount); break; case CrowdfundResetEvery.Day: nextResetDate = lastResetDate.Value.AddDays(settings.ResetEveryAmount); break; case CrowdfundResetEvery.Month: nextResetDate = lastResetDate.Value.AddMonths(settings.ResetEveryAmount); break; case CrowdfundResetEvery.Year: nextResetDate = lastResetDate.Value.AddYears(settings.ResetEveryAmount); break; } } } var invoices = await GetInvoicesForApp(appData, lastResetDate); var completeInvoices = invoices.Where(IsComplete).ToArray(); var pendingInvoices = invoices.Where(IsPending).ToArray(); var paidInvoices = invoices.Where(IsPaid).ToArray(); var pendingPayments = GetContributionsByPaymentMethodId(settings.TargetCurrency, pendingInvoices, !settings.EnforceTargetAmount); var currentPayments = GetContributionsByPaymentMethodId(settings.TargetCurrency, completeInvoices, !settings.EnforceTargetAmount); var perkCount = paidInvoices .Where(entity => !string.IsNullOrEmpty(entity.Metadata.ItemCode)) .GroupBy(entity => entity.Metadata.ItemCode) .ToDictionary(entities => entities.Key, entities => entities.Count()); Dictionary <string, decimal> perkValue = new(); if (settings.DisplayPerksValue) { perkValue = paidInvoices .Where(entity => entity.Currency.Equals(settings.TargetCurrency, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(entity.Metadata.ItemCode)) .GroupBy(entity => entity.Metadata.ItemCode) .ToDictionary(entities => entities.Key, entities => entities.Sum(entity => entity.GetPayments(true).Sum(pay => { var paymentMethodId = pay.GetPaymentMethodId(); var value = pay.GetCryptoPaymentData().GetValue() - pay.NetworkFee; var rate = entity.GetPaymentMethod(paymentMethodId).Rate; return(rate * value); }))); } var perks = Parse(settings.PerksTemplate, settings.TargetCurrency); if (settings.SortPerksByPopularity) { var ordered = perkCount.OrderByDescending(pair => pair.Value); var newPerksOrder = ordered .Select(keyValuePair => perks.SingleOrDefault(item => item.Id == keyValuePair.Key)) .Where(matchingPerk => matchingPerk != null) .ToList(); var remainingPerks = perks.Where(item => !newPerksOrder.Contains(item)); newPerksOrder.AddRange(remainingPerks); perks = newPerksOrder.ToArray(); } return(new ViewCrowdfundViewModel { Title = settings.Title, Tagline = settings.Tagline, Description = settings.Description, CustomCSSLink = settings.CustomCSSLink, MainImageUrl = settings.MainImageUrl, EmbeddedCSS = settings.EmbeddedCSS, StoreId = appData.StoreDataId, AppId = appData.Id, StartDate = settings.StartDate?.ToUniversalTime(), EndDate = settings.EndDate?.ToUniversalTime(), TargetAmount = settings.TargetAmount, TargetCurrency = settings.TargetCurrency, EnforceTargetAmount = settings.EnforceTargetAmount, Perks = perks, Enabled = settings.Enabled, DisqusEnabled = settings.DisqusEnabled, SoundsEnabled = settings.SoundsEnabled, DisqusShortname = settings.DisqusShortname, AnimationsEnabled = settings.AnimationsEnabled, ResetEveryAmount = settings.ResetEveryAmount, ResetEvery = Enum.GetName(typeof(CrowdfundResetEvery), settings.ResetEvery), DisplayPerksRanking = settings.DisplayPerksRanking, PerkCount = perkCount, PerkValue = perkValue, NeverReset = settings.ResetEvery == CrowdfundResetEvery.Never, Sounds = settings.Sounds, AnimationColors = settings.AnimationColors, CurrencyData = _Currencies.GetCurrencyData(settings.TargetCurrency, true), CurrencyDataPayments = Enumerable.DistinctBy(currentPayments.Select(pair => pair.Key) .Concat(pendingPayments.Select(pair => pair.Key)) .Select(id => _Currencies.GetCurrencyData(id.CryptoCode, true)), data => data.Code) .ToDictionary(data => data.Code, data => data), Info = new CrowdfundInfo { TotalContributors = paidInvoices.Length, ProgressPercentage = (currentPayments.TotalCurrency / settings.TargetAmount) * 100, PendingProgressPercentage = (pendingPayments.TotalCurrency / settings.TargetAmount) * 100, LastUpdated = DateTime.UtcNow, PaymentStats = currentPayments.ToDictionary(c => c.Key.ToString(), c => c.Value.Value), PendingPaymentStats = pendingPayments.ToDictionary(c => c.Key.ToString(), c => c.Value.Value), LastResetDate = lastResetDate, NextResetDate = nextResetDate, CurrentPendingAmount = pendingPayments.TotalCurrency, CurrentAmount = currentPayments.TotalCurrency } }); }