/// <summary> /// Here we generate a week depending on some rules: /// - Avoid having multiple times the same meal /// - Avoid having a meal that we already ate before the Minimum Weeks to wait /// - Get only meals for the selected moments of the days /// </summary> /// <param name="user"></param> /// <param name="maxFailuresCount"></param> public bool Generate(Users user, int maxFailuresCount) { // Get the number of recipes we need. DateTime minimumWeeksPassed = DateTime.Now.AddDays(-user.TimeBetweenMeals); int countMeals = user.DailyMeals.Sum(x => x.Meals.Count(y => y.Value)); List <Recipes> recipes = MongoManager.Where <Recipes>(x => x.UserId == user._id && x.Type == Recipes.RecipeTypes.Dish && (!x.LastCooked.HasValue || (x.LastCooked.Value < minimumWeeksPassed)), 0, countMeals) .OrderBy(_ => Guid.NewGuid()).ToList(); int failuresCount = 0; while (failuresCount <= maxFailuresCount && recipes.Count < countMeals) { int diffMealsCount = countMeals - recipes.Count; Recipes recipe = MongoManager.Where <Recipes>(x => x.UserId == user._id && x.Type == Recipes.RecipeTypes.Dish && (!x.LastCooked.HasValue || (x.LastCooked.Value < minimumWeeksPassed)), 0, diffMealsCount).OrderBy(_ => Guid.NewGuid()).FirstOrDefault(); if (recipe != null) { recipes.Add(recipe); } else { ++failuresCount; } } if (recipes == null || recipes.Count < countMeals) { return(false); } countMeals = 0; Days = new List <Day>(); int countDays = 0; for (int i = 0; i < 7; ++i) { Days.Add(new Day { Position = countDays, Date = DateTime.Now.AddDays(++countDays), Meals = new List <Meals>() }); } foreach (var i in user.DailyMeals) { int index = Days.FindIndex(x => x.Date.DayOfWeek == i.Day); foreach (var j in i.Meals) { if (!j.Value) { continue; } Days[index].Meals.Add(new Meals { _id = recipes.First()._id, NumberOfPeople = 2, Type = j.Key }); recipes.RemoveAt(0); } } return(true); }