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.");

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

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

            #region Adjust report criteria as needed
            int?badgeId     = null;
            int?challengeId = null;

            if (!string.IsNullOrEmpty(criterion.BadgeRequiredList))
            {
                try
                {
                    badgeId = Convert.ToInt32(criterion.BadgeRequiredList);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to convert badge id to number: {ex.Message}");
                    _logger.LogError($"Badge id: {criterion.BadgeRequiredList}");
                }
            }

            if (!string.IsNullOrEmpty(criterion.ChallengeRequiredList))
            {
                try
                {
                    challengeId = Convert.ToInt32(criterion.ChallengeRequiredList);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to convert challenge id to number: {ex.Message}");
                    _logger.LogError($"Challenge id: {criterion.BadgeRequiredList}");
                }
            }

            if (criterion.StartDate == null)
            {
                criterion.StartDate = DateTime.MinValue;
            }

            if (criterion.EndDate == null)
            {
                criterion.EndDate = DateTime.MaxValue;
            }

            #endregion Adjust report criteria as needed

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

            // header row
            report.HeaderRow = new object[] {
                "Rank",
                "Participant",
                "System Name",
                "Branch Name",
                "Program",
                "Points Earned"
            };

            ICollection <int> usersWhoEarned = null;

            if (badgeId != null && !token.IsCancellationRequested)
            {
                UpdateProgress(progress, 1, "Looking up users who earned the badge...", request.Name);

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

                usersWhoEarned = earned;
            }

            if (challengeId != null && !token.IsCancellationRequested)
            {
                UpdateProgress(progress, 1, "Looking up users who completed the challenge...", request.Name);

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

                if (usersWhoEarned == null || usersWhoEarned.Count == 0)
                {
                    usersWhoEarned = earned;
                }
                else
                {
                    usersWhoEarned = usersWhoEarned.Union(earned).ToList();
                }
            }

            int  count       = 0;
            long totalPoints = 0;

            foreach (int userId in usersWhoEarned)
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }

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

                long pointsEarned = await _userLogRepository.GetEarningsOverPeriodAsync(userId, criterion);

                var user = await _userRepository.GetByIdAsync(userId);

                var name = new StringBuilder(user.FirstName);
                if (!string.IsNullOrEmpty(user.LastName))
                {
                    name.Append(' ').Append(user.LastName);
                }
                if (!string.IsNullOrEmpty(user.Username))
                {
                    name.Append(" (").Append(user.Username).Append(')');
                }

                reportData.Add(new object[]
                {
                    0,
                    name.ToString(),
                    user.SystemName,
                    user.BranchName,
                    user.ProgramName,
                    pointsEarned
                });

                totalPoints += pointsEarned;
            }

            int rank = 1;
            report.Data = reportData
                          .OrderByDescending(_ => _[5])
                          .Select(_ => new object[] {
                rank++,
                _[1],
                _[2],
                _[3],
                _[4],
                _[5],
            });

            report.FooterRow = new object[]
            {
                "Total",
                string.Empty,
                string.Empty,
                string.Empty,
                string.Empty,
                totalPoints
            };
            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
        }
Esempio n. 2
0
        public override async Task ExecuteAsync(ReportRequest request,
                                                CancellationToken token,
                                                IProgress <OperationStatus> progress = null)
        {
            var pointValues = new long[] { 250, 500, 750, 1000 };

            #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[]>();
            #endregion Reporting initialization

            #region Adjust report criteria as needed
            if (criterion.StartDate == null)
            {
                criterion.StartDate = DateTime.MinValue;
            }
            if (criterion.EndDate == null)
            {
                criterion.EndDate = DateTime.MaxValue;
            }
            #endregion Adjust report criteria as needed

            #region Collect data
            UpdateProgress(progress, 1, "Getting total user count...", request.Name);

            var totalCheck = new Dictionary <long, long>();

            // header row
            var row = new List <object> {
                "System Name",
                "Branch Name",
                "Program",
                "Registered Users"
            };
            foreach (var pointValue in pointValues)
            {
                row.Add($"Achieved {pointValue} points");
                totalCheck.Add(pointValue, 0);
            }
            report.HeaderRow = row.ToArray();

            long totalRegistered = 0;
            long count           = 0;

            var programIds = await _programRepository.GetAllAsync((int)criterion.SiteId);

            long reportUserCount = 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)
            {
                var userCriterion = new ReportCriterion
                {
                    SiteId   = criterion.SiteId,
                    SystemId = systemId
                };
                reportUserCount += await _userRepository.GetCountAsync(userCriterion);
            }

            UpdateProgress(progress,
                           $"Beginning processing of {reportUserCount} users...",
                           request.Name);

            foreach (var systemId in systemIds)
            {
                foreach (var branch in branches.Where(_ => _.SystemId == systemId))
                {
                    foreach (var program in programIds)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        string processing = systemIds.Count() == 1
                            ? $"Processing: {branch.Name} - {program.Name} -"
                            : $"Processing: {branch.SystemName} - {branch.Name} -";

                        // clear counters of participants that achieved point values
                        var programCheck = new Dictionary <long, long>();
                        foreach (var pointValue in pointValues)
                        {
                            programCheck.Add(pointValue, 0);
                        }

                        // get users for this program, branch, system
                        criterion.ProgramId = program.Id;
                        criterion.BranchId  = branch.Id;
                        criterion.SystemId  = systemId;

                        var userIds = await _userRepository
                                      .GetUserIdsByBranchProgram(criterion);

                        foreach (var userId in userIds)
                        {
                            if (++count % 10 == 0)
                            {
                                UpdateProgress(progress,
                                               Math.Max((int)((count * 100) / reportUserCount), 1),
                                               $"{processing} {count}/{reportUserCount}",
                                               request.Name);
                            }
                            var pointsUntilPeriod = await _userLogRepository
                                                    .GetEarningsUpToDateAsync(userId,
                                                                              criterion.StartDate ?? DateTime.MinValue);

                            var pointsDuringPeriod = await _userLogRepository
                                                     .GetEarningsOverPeriodAsync(userId, criterion);

                            var pointsUntilPeriodEnd = pointsUntilPeriod + pointsDuringPeriod;

                            foreach (var pointValue in pointValues)
                            {
                                if (pointsUntilPeriod < pointValue &&
                                    pointValue <= pointsUntilPeriodEnd)
                                {
                                    programCheck[pointValue] += 1;
                                }
                            }
                        }

                        int userCount = await _userRepository.GetCountAsync(criterion);

                        // add row
                        row = new List <object> {
                            branch.SystemName,
                            branch.Name,
                            program.Name,
                            userCount
                        };
                        foreach (var pointValue in pointValues)
                        {
                            row.Add(programCheck[pointValue]);
                            totalCheck[pointValue] += programCheck[pointValue];
                        }
                        reportData.Add(row.ToArray());

                        totalRegistered += userCount;
                    }

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

            report.Data = reportData.ToArray();

            // total row
            row = new List <object>
            {
                "Total",
                string.Empty,
                string.Empty,
                totalRegistered
            };
            foreach (var pointValue in pointValues)
            {
                row.Add(totalCheck[pointValue]);
            }
            report.FooterRow = row.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. 3
0
        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[]>();
            #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}");
                }
            }

            if (criterion.StartDate == null)
            {
                criterion.StartDate = DateTime.MinValue;
            }

            if (criterion.EndDate == null)
            {
                criterion.EndDate = DateTime.MaxValue;
            }

            #endregion Adjust report criteria as needed

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

            // header row
            report.HeaderRow = new object[] {
                "Rank",
                "Participant",
                "System Name",
                "Branch Name",
                "Program",
                "Points Earned"
            };

            ICollection <int> usersWhoEarned = null;

            if (badgeIds != null && !token.IsCancellationRequested)
            {
                UpdateProgress(progress, 1, "Looking up users who earned badges...", request.Name);

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

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

                    usersWhoEarned = earned;
                }
            }

            if (challengeIds != null && !token.IsCancellationRequested)
            {
                UpdateProgress(progress, 1, "Looking up users who completed challenges...", request.Name);

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

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

                    if (usersWhoEarned == null || usersWhoEarned.Count == 0)
                    {
                        usersWhoEarned = earned;
                    }
                    else
                    {
                        usersWhoEarned = usersWhoEarned.Union(earned).ToList();
                    }
                }
            }

            int  totalCount  = usersWhoEarned.Count;
            int  count       = 0;
            long totalPoints = 0;

            foreach (int userId in usersWhoEarned)
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }

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

                long pointsEarned = await _userLogRepository.GetEarningsOverPeriodAsync(userId, criterion);

                var user = await _userRepository.GetByIdAsync(userId);

                var name = new StringBuilder(user.FirstName);
                if (!string.IsNullOrEmpty(user.LastName))
                {
                    name.Append($" {user.LastName}");
                }
                if (!string.IsNullOrEmpty(user.Username))
                {
                    name.Append($" ({user.Username})");
                }

                reportData.Add(new object[]
                {
                    0,
                    name.ToString(),
                    user.SystemName,
                    user.BranchName,
                    user.ProgramName,
                    pointsEarned
                });

                totalPoints += pointsEarned;
            }

            int rank = 1;
            report.Data = reportData
                          .OrderByDescending(_ => _.ElementAt(5))
                          .Select(_ => new object[] {
                rank++,
                _.ElementAt(1),
                _.ElementAt(2),
                _.ElementAt(3),
                _.ElementAt(4),
                _.ElementAt(5),
            });

            report.FooterRow = new object[]
            {
                "Total",
                string.Empty,
                string.Empty,
                string.Empty,
                string.Empty,
                totalPoints
            };
            report.AsOf = _serviceFacade.DateTimeProvider.Now;
            #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
        }