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