/// <summary> /// Evaluates whether the user is entitled to any new badges, as a result of submitting an observation. /// </summary> /// <param name="observation">The observation that has just been approved for the user.</param> public async Task EvaluateBadges(Observation observation) { var userId = observation.UserId; Log.Info($"Evaluating badges for user id={userId} name={observation.User.UserName}"); try { var challenge = observation.Challenge; var track = challenge.MissionTrack; var badgeForTrack = track.Badge; var alreadyHasBadge = badgeForTrack.Users.Any(p => p.Id == userId); if (alreadyHasBadge) { return; } var eligibleObservationsSpec = new EligibleObservationsForChallenges(track.Challenges, userId); var eligibleObservations = unitOfWork.Observations.AllSatisfying(eligibleObservationsSpec); var percentComplete = ComputePercentComplete(track.Challenges, eligibleObservations); if (percentComplete < 100) { return; } AwardBadge(badgeForTrack.Id, userId); await notifier.BadgeAwarded(badgeForTrack, observation.User, track); } finally { Log.Info($"Completed evaluating badges for user id={userId} name={observation.User.UserName}"); } }
// GET: UserProfile public ActionResult Index(int showBadges = 4, int showObservations = 10) { var specification = new SingleUserWithProfileInformation(user.UniqueId); var maybeUser = uow.Users.GetMaybe(specification); if (maybeUser.None) { return(HttpNotFound("User not found in the database")); } var appUser = maybeUser.Single(); var badges = appUser.Badges.Take(showBadges).Select(p => p.ImageIdentifier); var missionSpec = new MissionProgressSummary(); var missions = uow.Missions.AllSatisfying(missionSpec); var missionViewModel = missions.Select(p => mapper.Map <Mission, MissionProgressViewModel>(p)).ToList(); var model = new UserProfileViewModel { UserId = user.UniqueId, UserName = user.DisplayName, EmailAddress = user.LoginName, Titles = Enumerable.Empty <string>(), //ToDo: coming soon... Badges = badges, Observations = appUser.Observations .Take(showObservations) .Select(p => new ObservationSummaryViewModel { DateTimeUtc = p.ObservationDateTimeUtc, ChallengeTitle = p.Challenge.Name }), Missions = missionViewModel }; var allChallenges = uow.Challenges.GetAll(); foreach (var mission in model.Missions) { foreach (var level in mission.Levels) { var challengesForLevel = allChallenges.Where(p => p.MissionTrack.MissionLevelId == level.Id); var observationSpec = new EligibleObservationsForChallenges(challengesForLevel, user.UniqueId); var eligibleObservations = uow.Observations.AllSatisfying(observationSpec); level.OverallProgressPercent = gameEngine.ComputePercentComplete(challengesForLevel, eligibleObservations); } } return(View(model)); }
// GET Mission/Progress/1 public ActionResult Progress(int id) { //ToDo - this is not very 'clean' and really needs some TLC // Validate the parameters and fetch the Mission from the database var query = new MissionLevelProgress(id); var maybeMission = uow.Missions.GetMaybe(query); if (maybeMission.None) { return(HttpNotFound("The specified Mission ID was not found")); } var mission = maybeMission.Single(); var missionModel = mapper.Map <Mission, MissionProgressViewModel>(mission); // Compute the % complete for each level overall and its individual tracks foreach (var missionLevel in missionModel.Levels) { var challengeSpecification = new ChallengesInMissionLevel(missionLevel.Id); var challengesInLevel = uow.Challenges.AllSatisfying(challengeSpecification); missionLevel.Unlocked = gameEngine.IsLevelUnlockedForUser(missionLevel, requestingUser.UniqueId); // Only count one observation towards each challenge, for the purposes of computing progress. var eligibleObservationsForLevel = new EligibleObservationsForChallenges(challengesInLevel, requestingUser.UniqueId); var observationsForLevel = uow.Observations.AllSatisfying(eligibleObservationsForLevel); missionLevel.OverallProgressPercent = gameEngine.ComputePercentComplete(challengesInLevel, observationsForLevel); // Compute individual track progress foreach (var track in missionLevel.Tracks) { var challengesInTrack = challengesInLevel.Where(p => p.MissionTrackId == track.Id).ToList(); var trackObservationsSpec = new EligibleObservationsForChallenges(challengesInTrack, requestingUser.UniqueId); var observationsForTrack = uow.Observations.AllSatisfying(trackObservationsSpec); track.PercentComplete = gameEngine.ComputePercentComplete(challengesInTrack, observationsForTrack); // Iterate through the challenges to determine whether or not each one is "complete" foreach (var challenge in track.Challenges) { challenge.HasObservation = observationsForTrack.Any(p => p.ChallengeId == challenge.Id); } } } return(View(missionModel)); }