Esempio n. 1
0
        public async Task <StatusSummary> GetCurrentStatsAsync(StatusSummary request)
        {
            if (request.SiteId == null ||
                request.SiteId != GetCurrentSiteId())
            {
                request.SiteId = GetCurrentSiteId();
            }
            string cacheKey = $"{CacheKey.CurrentStats}s{request.SiteId}p{request.ProgramId}sys{request.SystemId}b{request.BranchId}";
            var    summary  = _memoryCache.Get <StatusSummary>(cacheKey);

            if (summary == null)
            {
                summary = request;
                summary.RegisteredUsers = await _userRepository.GetCountAsync(request);

                summary.PointsEarned = await _userLogRepository.PointsEarnedTotalAsync(request);

                summary.ActivityEarnings = await _userLogRepository
                                           .ActivityEarningsTotalAsync(request);

                summary.CompletedChallenges = await _userLogRepository
                                              .CompletedChallengeCountAsync(request);

                summary.BadgesEarned = await _userLogRepository.EarnedBadgeCountAsync(request);

                summary.DaysUntilEnd = await GetDaysUntilEnd();

                _memoryCache.Set(cacheKey,
                                 summary,
                                 new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(5)));
            }
            return(summary);
        }
        public async Task <StatusSummary> GetCurrentStatsAsync(ReportCriterion request)
        {
            if (request.SiteId == null ||
                request.SiteId != GetCurrentSiteId())
            {
                request.SiteId = GetCurrentSiteId();
            }
            string cacheKey    = $"s{request.SiteId}.p{request.ProgramId}.sys{request.SystemId}.b{request.BranchId}.{CacheKey.CurrentStats}";
            var    summaryJson = _cache.GetString(cacheKey);

            if (string.IsNullOrEmpty(summaryJson))
            {
                var summary = new StatusSummary
                {
                    RegisteredUsers     = await _userRepository.GetCountAsync(request),
                    Achievers           = await _userRepository.GetAchieverCountAsync(request),
                    PointsEarned        = await _userLogRepository.PointsEarnedTotalAsync(request),
                    CompletedChallenges = await _userLogRepository
                                          .CompletedChallengeCountAsync(request),
                    BadgesEarned = await _userLogRepository.EarnedBadgeCountAsync(request),
                    DaysUntilEnd = await GetDaysUntilEnd()
                };
                _cache.SetString(cacheKey, JsonConvert.SerializeObject(summary), ExpireIn());
                return(summary);
            }
            else
            {
                return(JsonConvert.DeserializeObject <StatusSummary>(summaryJson));
            }
        }
        public override async Task ExecuteAsync(ReportRequest request,
                                                CancellationToken token,
                                                IProgress <OperationStatus> progress = null)
        {
            #region Reporting initialization
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            request = await StartRequestAsync(request);

            var criterion
                = await _serviceFacade.ReportCriterionRepository.GetByIdAsync(request.ReportCriteriaId)
                  ?? throw new GraException($"Report criteria {request.ReportCriteriaId} for report request id {request.Id} could not be found.");

            if (criterion.SiteId == null)
            {
                throw new ArgumentNullException(nameof(criterion.SiteId));
            }

            var report = new StoredReport
            {
                Title = ReportAttribute?.Name,
                AsOf  = _serviceFacade.DateTimeProvider.Now
            };
            var reportData = new List <object[]>();

            var askIfFirstTime
                = await GetSiteSettingBoolAsync(criterion, SiteSettingKey.Users.AskIfFirstTime);

            #endregion Reporting initialization

            #region Collect data
            UpdateProgress(progress, 1, "Starting report...", request.Name);

            // header row
            var headerRow = new List <object>()
            {
                "System Name",
                "Branch Name",
                "Registered Users"
            };

            if (askIfFirstTime)
            {
                headerRow.Add("First time Participants");
            }

            headerRow.Add("Achievers");
            headerRow.Add("Challenges Completed");
            headerRow.Add("Badges Earned");

            var translations      = new Dictionary <string, ICollection <int?> >();
            var translationTotals = new Dictionary <string, long>();

            foreach (var program in await _programRepository.GetAllAsync((int)criterion.SiteId))
            {
                var pointTranslation = await _pointTranslationRepository
                                       .GetByProgramIdAsync(program.Id);

                string description = pointTranslation.ActivityDescriptionPlural;

                if (!translations.ContainsKey(description))
                {
                    translations.Add(description, new List <int?> {
                        pointTranslation.Id
                    });
                    translationTotals.Add(description, 0);
                    if (description.Length > 2)
                    {
                        headerRow.Add(description.First().ToString().ToUpper()
                                      + description.Substring(1));
                    }
                    else
                    {
                        headerRow.Add(description);
                    }
                }
                else
                {
                    translations[description].Add(pointTranslation.Id);
                }
            }

            headerRow.Add("Points Earned");
            report.HeaderRow = headerRow.ToArray();

            int count = 0;

            // running totals
            long totalRegistered = 0;
            long totalFirstTime  = 0;
            long totalAchiever   = 0;
            long totalChallenges = 0;
            long totalBadges     = 0;
            long totalPoints     = 0;

            var branches = criterion.SystemId != null
                ? await _branchRepository.GetBySystemAsync((int)criterion.SystemId)
                : await _branchRepository.GetAllAsync((int)criterion.SiteId);

            var systemIds = branches
                            .OrderBy(_ => _.SystemName)
                            .GroupBy(_ => _.SystemId)
                            .Select(_ => _.First().SystemId);

            foreach (var systemId in systemIds)
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }

                foreach (var branch in branches.Where(_ => _.SystemId == systemId))
                {
                    UpdateProgress(progress,
                                   ++count * 100 / branches.Count(),
                                   $"Processing: {branch.SystemName} - {branch.Name}",
                                   request.Name);

                    criterion.SystemId = systemId;
                    criterion.BranchId = branch.Id;

                    int users = await _userRepository.GetCountAsync(criterion);

                    int achievers = await _userRepository.GetAchieverCountAsync(criterion);

                    long challenge = await _userLogRepository
                                     .CompletedChallengeCountAsync(criterion);

                    long badge = await _userLogRepository.EarnedBadgeCountAsync(criterion);

                    long points = await _userLogRepository.PointsEarnedTotalAsync(criterion);

                    totalRegistered += users;
                    totalAchiever   += achievers;
                    totalChallenges += challenge;
                    totalBadges     += badge;
                    totalPoints     += points;

                    var row = new List <object>()
                    {
                        branch.SystemName,
                        branch.Name,
                        users
                    };

                    if (askIfFirstTime)
                    {
                        int firstTime = await _userRepository.GetFirstTimeCountAsync(criterion);

                        totalFirstTime += firstTime;

                        row.Add(firstTime);
                    }

                    row.Add(achievers);
                    row.Add(challenge);
                    row.Add(badge);

                    foreach (var translationName in translations.Keys)
                    {
                        long total = await _userLogRepository.TranslationEarningsAsync(criterion,
                                                                                       translations[translationName]);

                        row.Add(total);
                        translationTotals[translationName] += total;
                    }

                    row.Add(points);
                    reportData.Add(row.ToArray());

                    if (token.IsCancellationRequested)
                    {
                        break;
                    }
                }
            }

            report.Data = reportData.ToArray();

            // total row
            var footerRow = new List <object>()
            {
                "Total",
                string.Empty,
                totalRegistered
            };

            if (askIfFirstTime)
            {
                footerRow.Add(totalFirstTime);
            }

            footerRow.Add(totalAchiever);
            footerRow.Add(totalChallenges);
            footerRow.Add(totalBadges);

            foreach (var total in translationTotals.Values)
            {
                footerRow.Add(total);
            }

            footerRow.Add(totalPoints);

            report.FooterRow = footerRow.ToArray();
            #endregion Collect data

            #region Finish up reporting
            _logger.LogInformation($"Report {GetType().Name} with criterion {criterion.Id} ran in {StopTimer()}");

            request.Success = !token.IsCancellationRequested;

            if (request.Success == true)
            {
                ReportSet.Reports.Add(report);
                request.Finished   = _serviceFacade.DateTimeProvider.Now;
                request.ResultJson = Newtonsoft.Json.JsonConvert.SerializeObject(ReportSet);
            }
            await _serviceFacade.ReportRequestRepository.UpdateSaveNoAuditAsync(request);

            #endregion Finish up reporting
        }
Esempio n. 4
0
        public override async Task ExecuteAsync(ReportRequest request,
                                                CancellationToken token,
                                                IProgress <JobStatus> progress = null)
        {
            #region Reporting initialization
            request = await StartRequestAsync(request);

            var criterion
                = await _serviceFacade.ReportCriterionRepository.GetByIdAsync(request.ReportCriteriaId)
                  ?? throw new GraException($"Report criteria {request.ReportCriteriaId} for report request id {request.Id} could not be found.");

            var report     = new StoredReport();
            var reportData = new List <object[]>();

            int count = 0;
            #endregion Reporting initialization

            #region Adjust report criteria as needed
            IEnumerable <int> badgeIds     = null;
            IEnumerable <int> challengeIds = null;

            if (!string.IsNullOrEmpty(criterion.BadgeRequiredList))
            {
                try
                {
                    badgeIds = criterion.BadgeRequiredList.Split(',').Select(int.Parse);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to convert badge id list to numbers: {ex.Message}");
                    _logger.LogError($"Badge id list: {criterion.BadgeRequiredList}");
                }
            }

            if (!string.IsNullOrEmpty(criterion.ChallengeRequiredList))
            {
                try
                {
                    challengeIds = criterion.ChallengeRequiredList.Split(',').Select(int.Parse);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to convert challenge id list to numbers: {ex.Message}");
                    _logger.LogError($"Challenge id list: {criterion.BadgeRequiredList}");
                }
            }

            int totalCount = challengeIds?.Count() ?? 0;
            totalCount += badgeIds?.Count() ?? 0;
            #endregion Adjust report criteria as needed

            #region Collect data
            UpdateProgress(progress, 1, "Starting report...", request.Name);

            // header row
            report.HeaderRow = new object[] {
                "Earned Item",
                "Participants"
            };

            // running totals
            long totalEarnedItems = 0;

            if (badgeIds != null)
            {
                foreach (var badgeId in badgeIds)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    var badgeName = await _badgeRepository.GetBadgeNameAsync(badgeId);

                    var earned = await _userLogRepository.EarnedBadgeCountAsync(criterion, badgeId);

                    UpdateProgress(progress,
                                   ++count * 100 / totalCount,
                                   $"Processing badge: {badgeName}...",
                                   request.Name);

                    reportData.Add(new object[]
                    {
                        badgeName,
                        earned
                    });

                    totalEarnedItems += earned;
                }
            }

            if (challengeIds != null)
            {
                foreach (var challengeId in challengeIds)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    var challenge = await _challengeRepository.GetByIdAsync(challengeId);

                    var earned = await _userLogRepository.CompletedChallengeCountAsync(criterion, challengeId);

                    UpdateProgress(progress,
                                   ++count * 100 / totalCount,
                                   $"Processing challenge: {challenge.Name}...",
                                   request.Name);

                    reportData.Add(new object[]
                    {
                        challenge.Name,
                        earned
                    });

                    totalEarnedItems += earned;
                }
            }

            report.Data = reportData.OrderByDescending(_ => _[1]);

            report.FooterRow = new object[]
            {
                "Total",
                totalEarnedItems
            };
            report.AsOf = _serviceFacade.DateTimeProvider.Now;
            #endregion Collect data

            #region Finish up reporting
            if (!token.IsCancellationRequested)
            {
                ReportSet.Reports.Add(report);
            }
            await FinishRequestAsync(request, !token.IsCancellationRequested);

            #endregion Finish up reporting
        }