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 }
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 }