Esempio n. 1
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
        }