/// <summary> /// Start an async task to calculate steak data and then copy it to the enrollment model /// </summary> /// <param name="streakId">The streak identifier.</param> public static void RefreshStreakDenormalizedProperties(int streakId) { var rockContext = new RockContext(); var streakService = new StreakService(rockContext); var streakTypeService = new StreakTypeService(rockContext); // Get the streak data and validate it var streakData = streakTypeService.GetStreakData(streakId, out var errorMessage); if (!errorMessage.IsNullOrWhiteSpace()) { ExceptionLogService.LogException(errorMessage); return; } if (streakData == null) { ExceptionLogService.LogException("Streak Data was null, but no error was specified"); return; } // Get the streak and apply updated information to it var streak = streakService.Get(streakId); if (streak == null) { ExceptionLogService.LogException($"The streak with id {streakId} was not found (it may have been deleted)"); return; } CopyStreakDataToStreakModel(streakData, streak); rockContext.SaveChanges(true); }
/// <summary> /// Processes attempts for the specified streak type achievement type identifier. This adds new attempts and updates existing attempts. /// </summary> /// <param name="streakTypeAchievementTypeId">The streak type achievement type identifier.</param> public static void Process(int streakTypeAchievementTypeId) { var achievementTypeCache = StreakTypeAchievementTypeCache.Get(streakTypeAchievementTypeId); if (achievementTypeCache == null) { throw new ArgumentException($"The StreakTypeAchievementTypeCache did not resolve for record id {streakTypeAchievementTypeId}"); } var achievementComponent = achievementTypeCache.AchievementComponent; if (achievementComponent == null) { throw new ArgumentException($"The AchievementComponent did not resolve for record id {streakTypeAchievementTypeId}"); } var streakTypeId = achievementTypeCache.StreakTypeId; var streakService = new StreakService(new RockContext()); var streaks = streakService.Queryable().AsNoTracking() .Where(s => s.StreakTypeId == streakTypeId); foreach (var streak in streaks) { // Process each streak in it's own data context to avoid the data context changes getting too big and slow var rockContext = new RockContext(); achievementComponent.Process(rockContext, achievementTypeCache, streak); rockContext.SaveChanges(); } }
/// <summary> /// Check for achievements that may have been earned /// </summary> /// <param name="streakId">The streak identifier.</param> private static void ProcessAchievements(int streakId) { var rockContext = new RockContext(); var streakService = new StreakService(rockContext); var streak = streakService.Get(streakId); if (streak == null) { ExceptionLogService.LogException($"The streak with id {streakId} was not found (it may have been deleted)"); return; } var streakTypeCache = StreakTypeCache.Get(streak.StreakTypeId); /* * 2019-01-13 BJW * * Achievements need to be processed in order according to dependencies (prerequisites). Prerequisites should be processed first so that, * if the prerequisite becomes completed, the dependent achievement will be processed at this time as well. Furthermore, each achievement * needs to be processed and changes saved to the database so that subsequent achievements will see the changes (for example: now met * prerequisites). */ var sortedAchievementTypes = StreakTypeAchievementTypeService.SortAccordingToPrerequisites(streakTypeCache.StreakTypeAchievementTypes); foreach (var streakTypeAchievementTypeCache in sortedAchievementTypes) { var loopRockContext = new RockContext(); var component = streakTypeAchievementTypeCache.AchievementComponent; component.Process(loopRockContext, streakTypeAchievementTypeCache, streak); loopRockContext.SaveChanges(); } }
/// <summary> /// Called after the save operation is executed. /// </summary> protected override void PostSave() { base.PostSave(); if (PreSaveState != EntityContextState.Deleted) { // Running this as a task allows possibly changed streak type properties to be // propagated to the streak type cache. Also there isn't really a reason that // the data context save operation needs to wait while this is done. Task.Run(() => StreakService.HandlePostSaveChanges(Entity.Id)); } }
/// <summary> /// Check for achievements that may have been earned /// </summary> /// <param name="streakId">The streak identifier.</param> private static void ProcessAchievements(int streakId) { var rockContext = new RockContext(); var streakService = new StreakService(rockContext); var streak = streakService.Get(streakId); if (streak == null) { ExceptionLogService.LogException($"The streak with id {streakId} was not found (it may have been deleted)"); return; } var streakTypeCache = StreakTypeCache.Get(streak.StreakTypeId); foreach (var streakTypeAchievementTypeCache in streakTypeCache.StreakTypeAchievementTypes) { var component = streakTypeAchievementTypeCache.AchievementComponent; component.Process(rockContext, streakTypeAchievementTypeCache, streak); } rockContext.SaveChanges(); }