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