Esempio n. 1
0
 public bool HasChanges(Achievement achievement)
 {
     return Distance != achievement.Distance ||
            Duration != achievement.Duration ||
            Speed != achievement.Speed ||
            Repetitions != achievement.Repetitions ||
            Weight != achievement.Weight ||
            CommentText != achievement.CommentText ||
            IsPropped != achievement.IsPropped;
 }
        public async Task<IEnumerable<Achievement>> Execute(Workout workout)
        {
            var achievements = new List<Achievement>();

            foreach (var activity in workout.Activities
                                            .Where(activity => activity.Group != null)
                                            .GroupBy(activity => new {activity.Group, activity.Name})
                                            .Select(group => new {group.Key.Group, group.Key.Name, Sets = group.SelectMany(activity => activity.Sets).ToList()})
                                            .Where(activity => !activity.Sets.Any(set => set.IsPr)))
            {
                var category = _grouping.GetGroupCategory(activity.Group);
                if (category == null)
                {
                    continue;
                }

                if (category == ActivityCategory.Weights)
                {
                    var max = activity.Sets
                                      .OrderByDescending(set => set.Weight)
                                      .ThenByDescending(set => set.Repetitions)
                                      .FirstOrDefault();
                    if (max == null || (max.Weight == null && max.Repetitions == null))
                    {
                        continue;
                    }

                    var fromDate = workout.Date.AddYears(-1);
                    var lastYearMax = await _database.Single<dynamic>(
                        "select top 1 s.[Weight], s.[Repetitions] " +
                        "from [Workout] w, [Activity] a, [Set] s " +
                        "where w.[Id] = a.[WorkoutId] " +
                        "and a.[Id] = s.[ActivityId] " +
                        "and w.[UserId] = @UserId " +
                        "and w.[Date] < @fromDate " +
                        "and a.[Name] = @Name " +
                        "order by s.[Weight] desc, s.[Repetitions] desc", new {workout.UserId, fromDate, activity.Name});
                    if (lastYearMax == null ||
                        max.Weight > lastYearMax.Weight ||
                        (max.Weight == lastYearMax.Weight && max.Repetitions > lastYearMax.Repetitions) ||
                        max.Weight*2 <= lastYearMax.Weight)
                    {
                        continue;
                    }

                    var thisYearMax = await _database.Single<dynamic>(
                        "select top 1 s.[Weight], s.[Repetitions] " +
                        "from [Workout] w, [Activity] a, [Set] s " +
                        "where w.[Id] = a.[WorkoutId] " +
                        "and a.[Id] = s.[ActivityId] " +
                        "and w.[UserId] = @UserId " +
                        "and w.[Date] >= @fromDate " +
                        "and w.[Date] < @Date " +
                        "and a.[Name] = @Name " +
                        "and s.[Weight] " + (max.Weight != null ? ">= @Weight" : "is null") + " " +
                        "order by s.[Weight] desc, s.[Repetitions] desc", new {workout.UserId, fromDate, workout.Date, activity.Name, max.Weight});
                    if (thisYearMax != null && (max.Weight < thisYearMax.Weight || max.Repetitions <= thisYearMax.Repetitions))
                    {
                        continue;
                    }

                    var achievement = new Achievement
                        {
                            Type = "ComebackRecord",
                            Activity = activity.Name,
                            CommentText = $"1 year {activity.Name} comeback record: "
                        };
                    if (max.Weight == null)
                    {
                        achievement.Repetitions = max.Repetitions;
                        achievement.CommentText += max.Repetitions.FormatRepetitions();
                    }
                    else
                    {
                        achievement.Weight = max.Weight;
                        achievement.CommentText += max.Weight.FormatWeight(max.IsImperial);
                        if (thisYearMax != null && max.Weight == thisYearMax.Weight)
                        {
                            achievement.Repetitions = max.Repetitions;
                            achievement.CommentText += " for " + max.Repetitions.FormatRepetitions();
                        }
                    }
                    achievements.Add(achievement);
                }
                else
                {
                    string column;
                    switch (category)
                    {
                        case ActivityCategory.Cardio:
                            column = "Distance";
                            break;
                        case ActivityCategory.Bodyweight:
                            column = "Repetitions";
                            break;
                        case ActivityCategory.Sports:
                            column = "Duration";
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }

                    var max = activity.Sets
                                      .Select(set =>
                                          {
                                              switch (category)
                                              {
                                                  case ActivityCategory.Cardio:
                                                      return new {Value = set.Distance, set.IsImperial};
                                                  case ActivityCategory.Bodyweight:
                                                      return new {Value = set.Repetitions, set.IsImperial};
                                                  case ActivityCategory.Sports:
                                                      return new {Value = set.Duration, set.IsImperial};
                                                  default:
                                                      throw new ArgumentOutOfRangeException();
                                              }
                                          })
                                      .OrderByDescending(set => set.Value)
                                      .FirstOrDefault();
                    if (max?.Value == null)
                    {
                        continue;
                    }

                    var fromDate = workout.Date.AddYears(-1);
                    var lastYearMax = await _database.Single<decimal?>(
                        "select max(s.[" + column + "]) " +
                        "from [Workout] w, [Activity] a, [Set] s " +
                        "where w.[Id] = a.[WorkoutId] " +
                        "and a.[Id] = s.[ActivityId] " +
                        "and w.[UserId] = @UserId " +
                        "and w.[Date] < @fromDate " +
                        "and a.[Name] = @Name", new {workout.UserId, fromDate, activity.Name});
                    if (lastYearMax == null || max.Value > lastYearMax || max.Value*2 <= lastYearMax)
                    {
                        continue;
                    }

                    var thisYearCount = await _database.Single<int>(
                        "select count(*) " +
                        "from [Workout] w, [Activity] a, [Set] s " +
                        "where w.[Id] = a.[WorkoutId] " +
                        "and a.[Id] = s.[ActivityId] " +
                        "and w.[UserId] = @UserId " +
                        "and w.[Date] >= @fromDate " +
                        "and w.[Date] < @Date " +
                        "and a.[Name] = @Name " +
                        "and s.[" + column + "] >= @Value", new {workout.UserId, fromDate, workout.Date, activity.Name, max.Value});
                    if (thisYearCount > 0)
                    {
                        continue;
                    }

                    var achievement = new Achievement
                        {
                            Type = "ComebackRecord",
                            Activity = activity.Name
                        };
                    string formattedValue;
                    switch (category)
                    {
                        case ActivityCategory.Cardio:
                            achievement.Distance = max.Value;
                            formattedValue = max.Value.FormatDistance(max.IsImperial);
                            break;
                        case ActivityCategory.Bodyweight:
                            achievement.Repetitions = max.Value;
                            formattedValue = max.Value.FormatRepetitions();
                            break;
                        case ActivityCategory.Sports:
                            achievement.Duration = max.Value;
                            formattedValue = max.Value.FormatDuration();
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                    achievement.CommentText = $"1 year {activity.Name} comeback record: {formattedValue}";
                    achievements.Add(achievement);
                }
            }

            return achievements;
        }
        public async Task<IEnumerable<Achievement>> Execute(Workout workout)
        {
            var achievements = new List<Achievement>();

            foreach (var group in workout.Activities.GroupBy(activity => activity.Group).Where(group => group.Key != null))
            {
                var category = _grouping.GetGroupCategory(group.Key);
                if (category == null)
                {
                    continue;
                }

                int threshold;
                if (!Thresholds.TryGetValue(group.Key, out threshold))
                {
                    switch (category)
                    {
                        case ActivityCategory.Cardio:
                            threshold = 500;
                            break;
                        case ActivityCategory.Sports:
                            threshold = 100;
                            break;
                        default:
                            threshold = 2000;
                            break;
                    }
                }

                string column;
                switch (category)
                {
                    case ActivityCategory.Cardio:
                        column = "Distance";
                        threshold *= 1000;
                        break;
                    case ActivityCategory.Sports:
                        column = "Duration";
                        threshold *= 3600;
                        break;
                    default:
                        column = "Repetitions";
                        break;
                }

                var previousSum = await _database.Single<decimal?>(
                    "select sum([" + column + "]) " +
                    "from [Workout] w, [Activity] a, [Set] s " +
                    "where w.[Id] = a.[WorkoutId] " +
                    "and a.[Id] = s.[ActivityId] " +
                    "and w.[UserId] = @UserId " +
                    "and w.[Date] < @Date " +
                    "and a.[Group] = @Key", new {workout.UserId, workout.Date, group.Key});
                if (previousSum == null)
                {
                    continue;
                }

                var sum = group.SelectMany(activity => activity.Sets)
                               .Sum(set =>
                                   {
                                       switch (category)
                                       {
                                           case ActivityCategory.Cardio:
                                               return set.Distance;
                                           case ActivityCategory.Sports:
                                               return set.Duration;
                                           default:
                                               return set.Repetitions;
                                       }
                                   }) + previousSum;
                if (sum < threshold)
                {
                    continue;
                }

                previousSum = Math.Floor(previousSum.Value/threshold)*threshold;
                sum = Math.Floor(sum.Value/threshold)*threshold;
                if (sum == previousSum)
                {
                    continue;
                }

                var achievement = new Achievement
                    {
                        Type = "LifetimeMilestone",
                        Group = group.Key
                    };
                string formattedValue;
                switch (category)
                {
                    case ActivityCategory.Cardio:
                        achievement.Distance = sum;
                        formattedValue = sum.FormatDistance();
                        break;
                    case ActivityCategory.Sports:
                        achievement.Duration = sum;
                        formattedValue = sum.FormatDuration();
                        break;
                    default:
                        achievement.Repetitions = sum;
                        formattedValue = sum.FormatRepetitions();
                        break;
                }
                achievement.CommentText = $"Lifetime {group.Key} milestone: {formattedValue}";
                achievements.Add(achievement);
            }

            return achievements;
        }
Esempio n. 4
0
        public async Task<IEnumerable<Achievement>> Execute(Workout workout)
        {
            var achievements = new List<Achievement>();

            foreach (var group in workout.Activities.GroupBy(activity => activity.Group).Where(group => group.Key != null))
            {
                var category = _grouping.GetGroupCategory(group.Key);
                if (category == null)
                {
                    continue;
                }

                var sets = group.SelectMany(activity => activity.Sets).ToList();
                if (sets.Count <= 1)
                {
                    continue;
                }

                var sum = sets.Sum(set =>
                    {
                        switch (category)
                        {
                            case ActivityCategory.Cardio:
                                return set.Distance;
                            case ActivityCategory.Sports:
                                return set.Duration;
                            default:
                                return set.Repetitions;
                        }
                    });
                if (sum == 0 || (category == ActivityCategory.Cardio && sum < 1000))
                {
                    continue;
                }

                string column;
                switch (category)
                {
                    case ActivityCategory.Cardio:
                        column = "Distance";
                        break;
                    case ActivityCategory.Sports:
                        column = "Duration";
                        break;
                    default:
                        column = "Repetitions";
                        break;
                }

                var previousMax = await _database.Single<decimal?>(
                    "select max([Value]) " +
                    "from ( " +
                    "  select sum(s.[" + column + "]) [Value] " +
                    "  from [Workout] w, [Activity] a, [Set] s " +
                    "  where w.[Id] = a.[WorkoutId] " +
                    "  and a.[Id] = s.[ActivityId] " +
                    "  and w.[UserId] = @UserId " +
                    "  and w.[Date] < @Date " +
                    "  and a.[Group] = @Key " +
                    "  group by w.[Id] " +
                    ") [x]", new {workout.UserId, workout.Date, group.Key});
                if ((previousMax ?? 0) == 0 || sum <= previousMax)
                {
                    continue;
                }

                var achievement = new Achievement
                    {
                        Type = "DailyRecord",
                        Group = group.Key
                    };
                string formattedValue;
                switch (category)
                {
                    case ActivityCategory.Cardio:
                        achievement.Distance = sum;
                        var lookup = sets.ToLookup(set => set.IsImperial);
                        formattedValue = sum.FormatDistance(lookup[true].Count() > lookup[false].Count());
                        break;
                    case ActivityCategory.Sports:
                        achievement.Duration = sum;
                        formattedValue = sum.FormatDuration();
                        break;
                    default:
                        achievement.Repetitions = sum;
                        formattedValue = sum.FormatRepetitions();
                        break;
                }
                achievement.CommentText = $"Daily {group.Key} record: {formattedValue}";
                achievements.Add(achievement);
            }

            return achievements;
        }