Add recipe nutrient calculation to journal entry store

This commit is contained in:
Christopher C. Wells 2021-01-03 06:11:00 -08:00
parent dbb752d73c
commit 187c1a0e4a
3 changed files with 61 additions and 6 deletions

View File

@ -9,6 +9,7 @@ use App\Models\Food;
use App\Models\JournalEntry;
use App\Models\Recipe;
use App\Rules\ArrayNotEmpty;
use App\Support\Nutrients;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
@ -90,14 +91,56 @@ class JournalEntryController extends Controller
'recipes.*' => 'nullable|exists:App\Models\Recipe,id',
]);
$summary = [];
$nutrients = array_fill_keys(Nutrients::$list, 0);
$foods_selected = array_filter($input['foods']);
if (!empty($foods_selected)) {
/** @var \App\Models\Food $foods */
$foods = Food::findMany($foods_selected);
$foods = Food::findMany($foods_selected)->keyBy('id');
foreach ($foods_selected as $key => $id) {
// TODO: Calculate totals with NutrientCalculator.
$food = $foods->get($id);
$nutrient_multiplier = Nutrients::calculateFoodNutrientMultiplier(
$food,
$input['amounts'][$key],
$input['units'][$key],
);
foreach ($nutrients as $nutrient => $amount) {
$nutrients[$nutrient] += $food->{$nutrient} * $nutrient_multiplier;
}
$summary[] = "{$input['amounts'][$key]} {$input['units'][$key]} {$food->name}";
}
}
// TODO: Add support and/or error handling for non-servings.
$recipes_selected = array_filter($input['recipes']);
if (!empty($recipes_selected)) {
// TODO: Check out barryvdh/laravel-ide-helper.
$recipes = Recipe::findMany($recipes_selected)->keyBy('id');
foreach ($recipes_selected as $key => $id) {
$recipe = $recipes->get($id);
foreach ($nutrients as $nutrient => $amount) {
$nutrients[$nutrient] += $recipe->{"{$nutrient}PerServing"}() * $input['amounts'][$key];
}
$summary[] = "{$input['amounts'][$key]} {$input['units'][$key]} {$recipe->name}";
}
}
$entry = new JournalEntry([
'summary' => implode(', ', $summary),
'date' => $input['date'],
'meal' => $input['meal'],
] + $nutrients);
$entry->user()->associate(Auth::user());
if ($entry->save()) {
if (isset($foods)) {
$entry->foods()->saveMany($foods);
}
if (isset($recipes)) {
$entry->recipes()->saveMany($recipes);
}
}
return back()->with('message', "Journal entry added!");
}
/**

View File

@ -2,7 +2,7 @@
namespace App\Models;
use App\Support\NutrientCalculator;
use App\Support\Nutrients;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -87,7 +87,7 @@ class FoodAmount extends Model
*/
public function __call($method, $parameters): mixed {
if (in_array($method, $this->nutrientMethods)) {
return $this->food->{$method} * NutrientCalculator::calculateFoodNutrientMultiplier(
return $this->food->{$method} * Nutrients::calculateFoodNutrientMultiplier(
$this->food,
$this->amount,
$this->unit

View File

@ -7,8 +7,17 @@ use App\Models\Food;
/**
* TODO: Refactor for more general use.
*/
class NutrientCalculator
class Nutrients
{
public static array $list = [
'calories',
'fat',
'cholesterol',
'sodium',
'carbohydrates',
'protein',
];
public static function calculateFoodNutrientMultiplier(
Food $food,
float $amount,
@ -17,6 +26,9 @@ class NutrientCalculator
if ($fromUnit === 'oz') {
return $amount * 28.349523125 / $food->serving_weight;
}
elseif ($fromUnit === 'servings') {
return $amount;
}
if ($food->serving_unit === $fromUnit) {
$multiplier = 1;