package mi.hdm.recipes; import mi.hdm.mealPlan.MealPlan; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Map; public class NutritionCalculator { private static final Logger log = LogManager.getLogger(NutritionCalculator.class); /** * Method to calculate the nutrition table for a recipe out of its ingredients. * * @return the nutrition table for this recipe based on its ingredients. All nutrition values are added up. */ public static NutritionTable calculateNutritionTable(Map<RecipeComponent, Integer> ingredients) { if (ingredients == null || ingredients.isEmpty()) { log.info("Map ingredients is null or empty. Therefore new nutritionTable() was generated."); return NutritionTable.empty(); } BigDecimal totalCals = BigDecimal.ZERO, totalCarbs = BigDecimal.ZERO, totalFats = BigDecimal.ZERO, totalProteins = BigDecimal.ZERO, totalFibers = BigDecimal.ZERO, totalSalt = BigDecimal.ZERO; for (RecipeComponent entry : ingredients.keySet()) { final Map<Nutrition, BigDecimal> nutritionTable = entry.getNutritionTable().getTable(); int divisor; if (entry.getMeasurement() == Measurement.PIECE || entry.getMeasurement() == Measurement.PINCH) { divisor = 1; } else { divisor = 100; } totalCals = totalCals.add(nutritionTable.get(Nutrition.CALORIES).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); totalCarbs = totalCarbs.add(nutritionTable.get(Nutrition.CARBS).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); totalFats = totalFats.add(nutritionTable.get(Nutrition.FAT).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); totalProteins = totalProteins.add(nutritionTable.get(Nutrition.PROTEINS).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); totalFibers = totalFibers.add(nutritionTable.get(Nutrition.FIBERS).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); totalSalt = totalSalt.add(nutritionTable.get(Nutrition.SALT).multiply(BigDecimal.valueOf(ingredients.get(entry))).divide(BigDecimal.valueOf(divisor))); } log.info("NutritionTable calculated successfully."); return new NutritionTable(totalCals.doubleValue(), totalCarbs.doubleValue(), totalFats.doubleValue(), totalProteins.doubleValue(), totalFibers.doubleValue(), totalSalt.doubleValue()); } public static NutritionTable calculateNutritionTable(MealPlan mealPlan) { Map<LocalDate, Recipe> plan = mealPlan.getAllRecipesFromPlan(); double totalCals = 0, totalCarbs = 0, totalFats = 0, totalProteins = 0, totalFibers = 0, totalSalt = 0; //we calculate with double -> still rounding errors! that's why testCalculateNutritionTableFromIngredients failes for (Recipe r : plan.values()) { final Map<Nutrition, BigDecimal> nutritionTable = r.getNutritionTable().getTable(); totalCals += nutritionTable.get(Nutrition.CALORIES).doubleValue(); totalCarbs += nutritionTable.get(Nutrition.CARBS).doubleValue(); totalFats += nutritionTable.get(Nutrition.FAT).doubleValue(); totalProteins += nutritionTable.get(Nutrition.PROTEINS).doubleValue(); totalFibers += nutritionTable.get(Nutrition.FIBERS).doubleValue(); totalSalt += nutritionTable.get(Nutrition.SALT).doubleValue(); } log.info("NutritionTable calculated successfully."); return new NutritionTable(totalCals, totalCarbs, totalFats, totalProteins, totalFibers, totalSalt); } }