public void CreaeteFromMealAndUserDataTest_ShouldCreateUserMealProfileObjectWithCorrectCalculatedCarbsDeviation_and_MealCarbsAmount_Properies()
        {
            Meal userMeal = new Meal()
            {
                Id = Guid.NewGuid(),
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170,
                CarbAmount = 85
            };
            string userName = "******";
            UserBaseInsulinCalcProfile insulineProfile = new RapidInsulinProfile()
            {
                UnitReductionValue = 40,
                InsulinCarbohydrateRatio = 12.5,
                MaxSugarRange = 150
            };
            SpontaneousUserModel userData = new SpontaneousUserModel()
            {
                BaseInsulinCalcProfile = insulineProfile,
            };

            //act
            UserMealProfileFactory mealFactory = new UserMealProfileFactory();
            UserMealProfile mealProfile = mealFactory.CreaeteFromMealAndUserData(userMeal, userName, userData);

            AlgorithmCalculations.AlgorithmResult algResult = AlgorithmCalculations.CalcMealCarbsDeviation(userMeal, mealProfile.UserInsulinProfile);

            //assert
            Assert.IsNotNull(mealProfile);
            Assert.AreEqual(mealProfile.CalculatedCarbsDeviation, algResult.Result);
            Assert.AreEqual(mealProfile.MealCarbsAmount, mealProfile.ExpectedCarbsAmount + algResult.Result);
        }
        public void CreaeteFromMealAndUserDataTest_ShouldCreateUserMealProfileObjectWithAllRelevantDataOfInputParameters()
        {
            Meal userMeal = new Meal()
            {
                Id = Guid.NewGuid(),
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170
            };
            string userName = "******";
            UserBaseInsulinCalcProfile insulineProfile = new RapidInsulinProfile()
            {
                UnitReductionValue = 40,
                InsulinCarbohydrateRatio = 12.5,
                MaxSugarRange = 150
            };
            SpontaneousUserModel userData = new SpontaneousUserModel()
            {
                BaseInsulinCalcProfile = insulineProfile,
            };

            //act
            UserMealProfileFactory mealFactory = new UserMealProfileFactory();
            UserMealProfile mealProfile = mealFactory.CreaeteFromMealAndUserData(userMeal, userName, userData);

            //assert
            Assert.IsNotNull(mealProfile);
            Assert.AreEqual(mealProfile.MealId, userMeal.Id);
            Assert.AreEqual(mealProfile.UserName, userName);
            Assert.AreEqual(mealProfile.UserInsulinProfile, insulineProfile);
        }
 public bool IfValidParameters(Meal userMeal, string userName, SpontaneousUserModel userData)
 {
     if (userMeal != null && userData != null && !string.IsNullOrEmpty(userName))
     {
         log.InfoFormat("[CarbohydratesVerification.IfValidParameters] Valid parameters: Meal.Id={0}, userName={1}.", userMeal.Id.ToString(), userName);
         return true;
     }
     else
     {
         log.ErrorFormat("[CarbohydratesVerification.IfValidParameters] Some of input parameters not valid.");
         return false;
     }
 }
 public static bool IfValidParameters(Meal meal, UserBaseInsulinCalcProfile insulinProfile)
 {
     if (meal != null && meal.CarbAmount > 0 && meal.PreMealSugarLevel > 0 && meal.PostMealSugarLevel > 0 &&
         insulinProfile != null && insulinProfile.MaxSugarRange > 0 && insulinProfile.UnitReductionValue > 0 && insulinProfile.InsulinCarbohydrateRatio > 0)
     {
         log.InfoFormat("[AlgorithmCalculations.IfValidParameters] Valid parameters: Meal.Id={0}.", meal.Id.ToString());
         return true;
     }
     else
     {
         log.ErrorFormat("[AlgorithmCalculations.IfValidParameters] Some of input parameters not valid.");
         return false;
     }
 }
        public void SaveDataInUserMealProfile(Meal userMeal, string userName, SpontaneousUserModel userData)
        {
            UserMealProfile mealProfile = null;
            if (IfValidParameters(userMeal, userName, userData))
            {
                mealProfile = CreaeteFromMealAndUserData(userMeal, userName, userData);
            }

            if (mealProfile != null)
            {
                UserMealProfileUtilities.AddUserMealProfileToDB(mealProfile);
                log.InfoFormat("[SaveDataInUserMealProfile] Saved UserMealProfile Id={0}, userMeal.Id={1}, userName={2}.",
                    mealProfile.Id.ToString(), userMeal.Id.ToString(), userName);
            }
            else log.ErrorFormat("[SaveDataInUserMealProfile] Error: Created mealProfile was null.");
        }
        public void VerifyMealCarbsTest_ShouldConvertUnitsToMgDlIfMmolL()
        {
            Meal meal = new Meal()
            {
                CarbAmount = 30,
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170
            };
            UserBaseInsulinCalcProfile insulinCalcProfile = new RapidInsulinProfile()
            {
                UnitReductionValue = 2.4975,
                UnitReductionUnits = UnitReductionUnits.mmolL,
                InsulinCarbohydrateRatio = 12.5,
                DosageUnits = DosageUnits.IU,
                MaxSugarRange = 150
            };

            var carbsDeviation = AlgorithmCalculations.CalcMealCarbsDeviation(meal, insulinCalcProfile);

            //Assert
            Assert.AreEqual(Convert.ToInt32(carbsDeviation.Result), 33);
        }
        public UserMealProfile CreaeteFromMealAndUserData(Meal userMeal, string userName, SpontaneousUserModel userData)
        {
            log.InfoFormat("[CreaeteFromMealAndUserData] userMeal.Id={0}, userName={1}.", userMeal.Id.ToString(), userName);
            UserMealProfile mealProfile = new UserMealProfile()
            {
                MealId = userMeal.Id,
                UserName = userName,
                ExpectedCarbsAmount = userMeal.CarbAmount
            };

            if (userData.BaseInsulinCalcProfile != null)
            {
                mealProfile.UserInsulinProfile = userData.BaseInsulinCalcProfile;
                AlgorithmCalculations.AlgorithmResult algResult =  AlgorithmCalculations.CalcMealCarbsDeviation(userMeal, mealProfile.UserInsulinProfile);
                if (algResult.Status == "Success")
                {
                    mealProfile.CalculatedCarbsDeviation = algResult.Result;
                    mealProfile.MealCarbsAmount = mealProfile.ExpectedCarbsAmount + mealProfile.CalculatedCarbsDeviation;
                }
            }
            return mealProfile;
        }
        public static AlgorithmResult CalcMealCarbsDeviation(Meal meal, UserBaseInsulinCalcProfile insulinProfile)
        {
            AlgorithmResult result = new AlgorithmResult() { Status = "Unsuccess"};

            if (IfValidParameters(meal, insulinProfile))
            {
                log.InfoFormat("[CalcMealCarbsDeviation] meal.Id={0}, meal.PreMealSugarLevel={1}, meal.PostMealSugarLevel={2}.", meal.Id.ToString(), meal.PreMealSugarLevel, meal.PostMealSugarLevel);
                double unitReductionValue = (insulinProfile.UnitReductionUnits == UnitReductionUnits.mmolL) ?
                    UnitsConverter.MmolLToMgDl(insulinProfile.UnitReductionValue) : insulinProfile.UnitReductionValue;

                double insulinDosage = BaseInsulineFormulas.CalculatingInsulinDose(insulinProfile.MaxSugarRange, meal.PreMealSugarLevel,
                                           insulinProfile.UnitReductionUnits, unitReductionValue, insulinProfile.InsulinCarbohydrateRatio, insulinProfile.DosageUnits, meal.CarbAmount);
                double calculatedCarbsAmount = BaseInsulineFormulas.CalculateMealCarbs(insulinProfile.MaxSugarRange, meal.PostMealSugarLevel,
                                           insulinProfile.UnitReductionUnits, unitReductionValue, insulinProfile.InsulinCarbohydrateRatio, insulinProfile.DosageUnits, insulinDosage);

                result.Status = "Success";
                result.Result = Math.Round(calculatedCarbsAmount - meal.CarbAmount, 2);
            }
            else
            {
                log.ErrorFormat("[CalcMealCarbsDeviation] Error: Some input parameters was invalid.");
            }
            return result;
        }
        public void Test_Meal_BSONSerialization()
        {
            List<Meal> meals = new List<Meal>();

            var meal = new Meal()
            {
                Id = Guid.NewGuid(),

            };
            meals.Add(meal);
            SpontaneousUserModel userModel = new SpontaneousUserModel()
            {
                UserMeals = meals,
            };
            m_Testdb.GetCollection<SpontaneousUserModel>(typeof(SpontaneousUserModel).Name).Insert(userModel);
        }
        public void VerifyMealCarbsTest_ShouldReturnExtreamNegativeDoubleIfNoNecesseryParameters()
        {
            Meal correctMeal = new Meal()
            {
                CarbAmount = 30,
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170
            };
            Meal meal1 = new Meal()
            {
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170
            };
            Meal meal2 = new Meal()
            {
                CarbAmount = 30,
                PostMealSugarLevel = 170
            };
            Meal meal3 = new Meal()
            {
                CarbAmount = 30,
                PreMealSugarLevel = 290
            };
            UserBaseInsulinCalcProfile correctInsulinCalcProfile = new RapidInsulinProfile()
            {
                UnitReductionValue = 45,
                UnitReductionUnits = UnitReductionUnits.mgDL,
                InsulinCarbohydrateRatio = 12.5,
                DosageUnits = DosageUnits.IU,
                MaxSugarRange = 150
            };
            UserBaseInsulinCalcProfile insulinCalcProfile1 = new RapidInsulinProfile()
            {
                UnitReductionUnits = UnitReductionUnits.mgDL,
                InsulinCarbohydrateRatio = 12.5,
                DosageUnits = DosageUnits.IU,
                MaxSugarRange = 150
            };
            UserBaseInsulinCalcProfile insulinCalcProfile2 = new RapidInsulinProfile()
            {
                UnitReductionValue = 45,
                UnitReductionUnits = UnitReductionUnits.mgDL,
                DosageUnits = DosageUnits.IU,
                MaxSugarRange = 150
            };
            UserBaseInsulinCalcProfile insulinCalcProfile3 = new RapidInsulinProfile()
            {
                UnitReductionValue = 45,
                UnitReductionUnits = UnitReductionUnits.mgDL,
                InsulinCarbohydrateRatio = 12.5,
                DosageUnits = DosageUnits.IU,
            };

            var carbsDeviation1 = AlgorithmCalculations.CalcMealCarbsDeviation(meal1, correctInsulinCalcProfile);
            var carbsDeviation2 = AlgorithmCalculations.CalcMealCarbsDeviation(meal2, correctInsulinCalcProfile);
            var carbsDeviation3 = AlgorithmCalculations.CalcMealCarbsDeviation(meal3, correctInsulinCalcProfile);
            var carbsDeviation4 = AlgorithmCalculations.CalcMealCarbsDeviation(correctMeal, insulinCalcProfile1);
            var carbsDeviation5 = AlgorithmCalculations.CalcMealCarbsDeviation(correctMeal, insulinCalcProfile2);
            var carbsDeviation6 = AlgorithmCalculations.CalcMealCarbsDeviation(correctMeal, insulinCalcProfile3);

            //Assert
            Assert.AreEqual(carbsDeviation1.Status, "Unsuccess");
            Assert.AreEqual(carbsDeviation2.Status, "Unsuccess");
            Assert.AreEqual(carbsDeviation3.Status, "Unsuccess");
            Assert.AreEqual(carbsDeviation4.Status, "Unsuccess");
            Assert.AreEqual(carbsDeviation5.Status, "Unsuccess");
            Assert.AreEqual(carbsDeviation6.Status, "Unsuccess");
        }
        /// <summary>
        ///     Creates new instance of meal.
        /// </summary>
        /// <param name="meal"></param>
        /// <returns></returns>
        public static Meal ToMeal(this IEnumerable<DishModel> meal)
        {
            double carbAmount =0;
            if(meal != null)
            {
                foreach (var dish in meal)
                {
                    if (dish.NutritionFacts != null)
                        carbAmount = carbAmount + dish.NutritionFacts.TotalCarbohydrate;
                }
            }

            List<Portion> portions = new List<Portion>();
            string restaurantId = string.Empty;
            foreach (var dish in meal)
            {
                Portion portion = new Portion();
                portion.CarbAmount = dish.NutritionFacts.TotalCarbohydrate;
                portion.PrtionFrom = dish.ToDish();
                portions.Add(portion);
                restaurantId = dish.RestaurantId;
            }

            Meal returnValue = new Meal()
            {
                CreatedAt = DateTime.UtcNow,
                Id = Guid.NewGuid(),
                CarbAmount = carbAmount,
                //Currently can be taken from the history of the locations in suggest option.
                //MealLocation
                //Very important to care this value.
                //Suspicious
                Portions = portions,
                RestaurantId = restaurantId,

            };
            return returnValue;
        }
        internal void UpdatePreMealSugar(int sugarLevel)
        {
            var userProfile = GetUserProfile();
            var userData = userProfile.GetUserData();
            if (userData.UserMeals == null)
            {
                log.WarnFormat("[UpdatePremealSugar] User={0} tried to update premeal sugar, but meal doesn't exists sugarLevel={1}.", userProfile.UserName, sugarLevel);
                userData.UserMeals = new List<Meal>();
                userData.UserMeals.Add(new Meal());
            }

            var userMeal = userData.UserMeals.OrderByDescending(c => c.CreatedAt).ToList().FirstOrDefault();
            var timeDiff = (DateTime.UtcNow - userMeal.CreatedAt);
            if (timeDiff.Hours > 2)
            {
                log.WarnFormat("[UpdatePremealSugar] last meal was created for more then 2 hours. Created new one");
                userMeal = new Meal();
                userData.UserMeals.Add(userMeal);
            }

            userMeal.PreMealSugarLevel = sugarLevel;
            userProfile.SetUserData(userData);
            userProfile.Save();
            log.InfoFormat("[UpdatePremealSugar] user={0}, meal={1}, sugarLevel={2}.", userProfile.UserName, userMeal, sugarLevel);
        }
        internal void UpdatePreMealSugar(int sugarLevel, int targetSugar)
        {
            var userProfile = GetUserProfile();
            var userData = userProfile.GetUserData();
            if (userData.UserMeals == null)
            {
                log.WarnFormat("[UpdatePremealSugar] User={0} tried to update premeal sugar, but meal doesn't exists sugarLevel={1}, targetSugar={2}.", userProfile.UserName, sugarLevel, targetSugar);
                userData.UserMeals = new List<Meal>();
                userData.UserMeals.Add(new Meal());
            }

            var userMeal = userData.UserMeals.OrderByDescending(c => c.CreatedAt).ToList().FirstOrDefault();
            var timeDiff = (DateTime.UtcNow - userMeal.CreatedAt);
            if (timeDiff.Hours > 2)
            {
                log.WarnFormat("[UpdatePremealSugar] last meal was created for more then 2 hours. Created new one");
                userMeal = new Meal();
                userData.UserMeals.Add(userMeal);
            }

            userMeal.PreMealSugarLevel = sugarLevel;
            userMeal.PreMealSugarUpdatedAt = DateTime.UtcNow;

            if (targetSugar >= 0)
            {
                if (userData.BaseInsulinCalcProfile == null)
                {
                    userData.BaseInsulinCalcProfile = new RapidInsulinProfile()
                    {
                        MaxSugarRange = targetSugar
                    };
                }
                else userData.BaseInsulinCalcProfile.MaxSugarRange = targetSugar;
            }

            userProfile.SetUserData(userData);
            userProfile.Save();
            log.InfoFormat("[UpdatePremealSugar] user={0}, meal={1}, sugarLevel={2}, targetSugar={3}.", userProfile.UserName, userMeal, sugarLevel, targetSugar);
        }
 internal void TraceBasicRestMeal(Meal meal)
 {
     var userProfile = GetUserProfile();
     var userData = userProfile.GetUserData();
     if (userData.UserMeals == null)
         userData.UserMeals = new List<Meal>();
     userData.UserMeals.Add(meal);
     userProfile.SetUserData(userData);
     userProfile.Save();
 }
        public void CreaeteFromMealAndUserDataTest_ShouldReturnNullIfOneOfInputParametersIsNullOrEmpty()
        {
            Meal userMeal = new Meal()
            {
                Id = Guid.NewGuid(),
                PreMealSugarLevel = 290,
                PostMealSugarLevel = 170
            };
            string userName = "******";
            UserBaseInsulinCalcProfile insulineProfile = new RapidInsulinProfile()
            {
                UnitReductionValue = 40,
                InsulinCarbohydrateRatio = 12.5,
                MaxSugarRange = 150
            };
            SpontaneousUserModel userData = new SpontaneousUserModel()
            {
                BaseInsulinCalcProfile = insulineProfile,
            };

            //act
            UserMealProfileFactory mealFactory = new UserMealProfileFactory();
            UserMealProfile mealProfile1 = mealFactory.CreaeteFromMealAndUserData(null, userName, userData);
            UserMealProfile mealProfile2 = mealFactory.CreaeteFromMealAndUserData(userMeal, null, userData);
            UserMealProfile mealProfile3 = mealFactory.CreaeteFromMealAndUserData(userMeal, userName, null);

            //assert
            Assert.IsNull(mealProfile1);
            Assert.IsNull(mealProfile2);
            Assert.IsNull(mealProfile3);
        }
        public static Meal ToMeal(this List<PortionModel> portionsModel)
        {
            Meal returnvalue = null;
            if (portionsModel != null)
            {
                IServicesLayer m_serviceLayer = new ServiceLayerImpl();
                var restaurnat = m_serviceLayer.GetRestaurantById(portionsModel[0].PortionFrom.RestaurantId);
                if (restaurnat != null)
                {
                    double totalCarbs = 0;
                    List<Portion> portions = new List<Portion>();
                    foreach (var portionModel in portionsModel)
                    {
                        Portion portion = portionModel.ToPortion();
                        portions.Add(portion);
                        totalCarbs += portionModel.CarbAmount;
                    }

                    returnvalue = new Meal()
                    {
                        CreatedAt = DateTime.UtcNow,
                        RestaurantId = restaurnat.Id,
                        Name = restaurnat.Name,
                        Portions = portions,
                        CarbAmount = totalCarbs
                    };
                }
            }
            return returnvalue;
        }