Example #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 GetCriterionAsync(request);

            var report = new StoredReport
            {
                Title = ReportAttribute?.Name,
                AsOf  = _serviceFacade.DateTimeProvider.Now
            };

            var reportData = new List <object[]>();
            #endregion Reporting initialization

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

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

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

            var system = await _systemRepository.GetByIdAsync((int)criterion.SystemId);

            var programDictionary = (await _programRepository.GetAllAsync((int)criterion.SiteId))
                                    .ToDictionary(_ => _.Id, _ => _.Name);

            foreach (var programId in programDictionary.Keys)
            {
                var pointTranslation = await _pointTranslationRepository
                                       .GetByProgramIdAsync(programId);

                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[0]
                                      .ToString()
                                      .ToUpper(System.Globalization.CultureInfo.InvariantCulture)
                                      + description[1..]);
        public async Task <PointTranslation> GetByProgramIdAsync(int id, bool titleCase = false)
        {
            var pointTranslation = await _pointTranslationRepository.GetByProgramIdAsync(id);

            if (titleCase)
            {
                if (!string.IsNullOrWhiteSpace(pointTranslation.ActivityDescription))
                {
                    pointTranslation.ActivityDescription = pointTranslation.ActivityDescription
                                                           .First()
                                                           .ToString()
                                                           .ToUpper()
                                                           + pointTranslation.ActivityDescription.Substring(1);
                }
                if (!string.IsNullOrWhiteSpace(pointTranslation.ActivityDescriptionPlural))
                {
                    pointTranslation.ActivityDescriptionPlural =
                        pointTranslation.ActivityDescriptionPlural
                        .First()
                        .ToString()
                        .ToUpper()
                        + pointTranslation.ActivityDescriptionPlural.Substring(1);
                }
                if (!string.IsNullOrWhiteSpace(pointTranslation.TranslationDescriptionPastTense))
                {
                    pointTranslation.TranslationDescriptionPastTense =
                        pointTranslation.TranslationDescriptionPastTense
                        .First()
                        .ToString()
                        .ToUpper()
                        + pointTranslation.TranslationDescriptionPastTense.Substring(1);
                }
                if (!string.IsNullOrWhiteSpace(pointTranslation.TranslationDescriptionPresentTense))
                {
                    pointTranslation.TranslationDescriptionPresentTense =
                        pointTranslation.TranslationDescriptionPresentTense
                        .First()
                        .ToString()
                        .ToUpper()
                        + pointTranslation.TranslationDescriptionPresentTense.Substring(1);
                }
            }
            return(pointTranslation);
        }
        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 async override 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 GetCriterionAsync(request);

            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",
                "Program Name",
                "Registered Users",
            };

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

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

            var programDictionary = (await _programRepository.GetAllAsync((int)criterion.SiteId))
                                    .ToDictionary(_ => _.Id, _ => _.Name);

            foreach (var programId in programDictionary.Keys)
            {
                var pointTranslation = await _pointTranslationRepository
                                       .GetByProgramIdAsync(programId);

                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);
                }
            }
            report.HeaderRow = headerRow.ToArray();

            int count = 0;

            // running totals
            long totalRegistered = 0;
            long totalFirstTime  = 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);

            int totalItems = branches.Count() * programDictionary.Count();

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

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

                    foreach (var programId in programDictionary.Keys)
                    {
                        UpdateProgress(progress,
                                       ++count * 100 / totalItems,
                                       $"Processing: {branch.SystemName} - {branch.Name}",
                                       request.Name);

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

                        int users = await _userRepository.GetCountAsync(criterion);

                        totalRegistered += users;

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

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

                            totalFirstTime += firstTime;

                            row.Add(firstTime);
                        }

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

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

                        reportData.Add(row.ToArray());

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

            report.Data = reportData.ToArray();

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

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

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

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

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

            #endregion Finish up reporting
        }
Example #5
0
        public async Task <ActivityLogResult> LogActivityAsync(int userIdToLog,
                                                               int activityAmountEarned,
                                                               Book book = null)
        {
            VerifyCanLog();

            if (activityAmountEarned < 0)
            {
                throw new GraException($"Cannot log negative activity amounts!");
            }

            if (book != null)
            {
                if (string.IsNullOrWhiteSpace(book.Title) &&
                    !string.IsNullOrWhiteSpace(book.Author))
                {
                    throw new GraException("When providing an author you must also provide a title.");
                }
            }

            int activeUserId = GetActiveUserId();
            int authUserId   = GetClaimId(ClaimType.UserId);
            var userToLog    = await _userRepository.GetByIdAsync(userIdToLog);

            bool loggingAsAdminUser = HasPermission(Permission.LogActivityForAny);

            if (activeUserId != userIdToLog &&
                authUserId != userToLog.HouseholdHeadUserId &&
                !loggingAsAdminUser)
            {
                string error = $"User id {activeUserId} cannot log activity for user id {userIdToLog}";
                _logger.LogError(error);
                throw new GraException(error);
            }

            var translation
                = await _pointTranslationRepository.GetByProgramIdAsync(userToLog.ProgramId);

            int pointsEarned
                = (activityAmountEarned / translation.ActivityAmount) * translation.PointsEarned;

            // add the row to the user's point log
            var userLog = new UserLog
            {
                ActivityEarned     = activityAmountEarned,
                IsDeleted          = false,
                PointsEarned       = pointsEarned,
                UserId             = userToLog.Id,
                PointTranslationId = translation.Id
            };

            if (activeUserId != userToLog.Id)
            {
                userLog.AwardedBy = activeUserId;
            }
            userLog = await _userLogRepository.AddSaveAsync(activeUserId, userLog);

            // update the score in the user record
            userToLog = await AddPointsSaveAsync(authUserId,
                                                 activeUserId,
                                                 userToLog.Id,
                                                 pointsEarned);

            // prepare the notification text
            string activityDescription = "for <strong>";

            if (translation.TranslationDescriptionPresentTense.Contains("{0}"))
            {
                activityDescription += string.Format(
                    translation.TranslationDescriptionPresentTense,
                    userLog.ActivityEarned);
                if (userLog.ActivityEarned == 1)
                {
                    activityDescription += $" {translation.ActivityDescription}";
                }
                else
                {
                    activityDescription += $" {translation.ActivityDescriptionPlural}";
                }
            }
            else
            {
                activityDescription = $"{translation.TranslationDescriptionPresentTense} {translation.ActivityDescription}";
            }
            activityDescription += "</strong>";

            // create the notification record
            var notification = new Notification
            {
                PointsEarned = pointsEarned,
                Text         = $"<span class=\"fa fa-star\"></span> You earned <strong>{pointsEarned} points</strong> {activityDescription}!",
                UserId       = userToLog.Id
            };

            int?bookId = null;

            // add the book if one was supplied
            if (book != null && !string.IsNullOrWhiteSpace(book.Title))
            {
                bookId = await AddBookAsync(GetActiveUserId(), book);

                notification.Text += $" The book <strong><em>{book.Title}</em></strong> by <strong>{book.Author}</strong> was added to your book list.";
            }

            await _notificationRepository.AddSaveAsync(authUserId, notification);

            return(new ActivityLogResult
            {
                UserLogId = userLog.Id,
                BookId = bookId
            });
        }
Example #6
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[]>();

            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[0]
                                      .ToString()
                                      .ToUpper(CultureInfo.InvariantCulture)
                                      + description[1..]);