diff --git a/app/Http/Controllers/JournalEntryController.php b/app/Http/Controllers/JournalEntryController.php index e469f5d..bff0597 100644 --- a/app/Http/Controllers/JournalEntryController.php +++ b/app/Http/Controllers/JournalEntryController.php @@ -135,7 +135,12 @@ class JournalEntryController extends Controller elseif ($ingredient['type'] == Recipe::class) { $item = Recipe::whereId($ingredient['id'])->first(); foreach (Nutrients::$all as $nutrient) { - $entries[$entry_key]->{$nutrient['value']} += $item->{"{$nutrient['value']}PerServing"}() * Number::floatFromString($ingredient['amount']); + $entries[$entry_key]->{$nutrient['value']} += Nutrients::calculateRecipeNutrientAmount( + $item, + $nutrient['value'], + Number::floatFromString($ingredient['amount']), + $ingredient['unit'] + ); } $entries[$entry_key]->recipes->add($item); } @@ -144,14 +149,14 @@ class JournalEntryController extends Controller } // Update summary - if (empty($item->serving_unit) && empty($item->serving_unit_name)) { - $unit = null; - } - elseif (!empty($item->serving_unit_name)) { - $unit = $item->serving_unit_formatted; - } - else { - $unit = $ingredient['unit']; + $unit = $ingredient['unit']; + if ($item instanceof Food) { + if (empty($item->serving_unit) && empty($item->serving_unit_name)) { + $unit = null; + } + elseif (!empty($item->serving_unit_name)) { + $unit = $item->serving_unit_formatted; + } } $entries[$entry_key]->summary .= (!empty($entries[$entry_key]->summary) ? ', ' : null); $entries[$entry_key]->summary .= "{$ingredient['amount']} {$unit} {$item->name}"; diff --git a/app/Models/IngredientAmount.php b/app/Models/IngredientAmount.php index 72711fe..a5ff8ec 100644 --- a/app/Models/IngredientAmount.php +++ b/app/Models/IngredientAmount.php @@ -146,7 +146,12 @@ final class IngredientAmount extends Model $this->amount, $this->unit ), - Recipe::class => $this->ingredient->{"{$method}PerServing"}() * $this->amount, + Recipe::class => Nutrients::calculateRecipeNutrientAmount( + $this->ingredient, + $method, + $this->amount, + $this->unit + ), default => 0 }; } diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index f4e35ac..4d11ed4 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -53,6 +53,9 @@ use Spatie\Tags\HasTags; * @method static \Illuminate\Database\Eloquent\Builder|Recipe withAllTagsOfAnyType($tags) * @method static \Illuminate\Database\Eloquent\Builder|Recipe withAnyTags($tags, ?string $type = null) * @method static \Illuminate\Database\Eloquent\Builder|Recipe withAnyTagsOfAnyType($tags) + * @property float|null $weight + * @property-read float|null $serving_weight + * @method static \Illuminate\Database\Eloquent\Builder|Recipe whereWeight($value) */ final class Recipe extends Model { diff --git a/app/Support/Nutrients.php b/app/Support/Nutrients.php index afef205..1b030d4 100644 --- a/app/Support/Nutrients.php +++ b/app/Support/Nutrients.php @@ -3,12 +3,12 @@ namespace App\Support; use App\Models\Food; +use App\Models\Recipe; -/** - * TODO: Refactor for more general use. - */ class Nutrients { + public static float $gramsPerOunce = 28.349523125; + public static array $all = [ ['value' => 'calories', 'unit' => null], ['value' => 'fat', 'unit' => 'g'], @@ -27,13 +27,22 @@ class Nutrients ['value' => 'serving', 'label' => 'servings'], ]; + /** + * Calculate a nutrient multiplier for a Food. + * + * @param \App\Models\Food $food + * @param float $amount + * @param string|null $fromUnit + * + * @return float + */ public static function calculateFoodNutrientMultiplier( Food $food, float $amount, string|null $fromUnit ): float { if ($fromUnit === 'oz') { - return $amount * 28.349523125 / $food->serving_weight; + return $amount * self::$gramsPerOunce / $food->serving_weight; } elseif ($fromUnit === 'serving') { return $amount; @@ -76,4 +85,34 @@ class Nutrients return $multiplier / $food->serving_size * $amount; } + + /** + * Calculate a nutrient amount for a recipe. + * + * @param \App\Models\Recipe $recipe + * @param string $nutrient + * @param float $amount + * @param string $fromUnit + * + * @return float + */ + public static function calculateRecipeNutrientAmount( + Recipe $recipe, + string $nutrient, + float $amount, + string $fromUnit + ): float { + if ($fromUnit === 'oz') { + return $amount * self::$gramsPerOunce / $recipe->weight * $recipe->{"{$nutrient}Total"}(); + } + elseif ($fromUnit === 'serving') { + return $recipe->{"{$nutrient}PerServing"}() * $amount; + } + elseif ($fromUnit === 'gram') { + return $amount / $recipe->weight * $recipe->{"{$nutrient}Total"}(); + } + else { + throw new \DomainException("Unsupported recipe unit: {$fromUnit}"); + } + } } diff --git a/resources/views/components/ingredient-picker.blade.php b/resources/views/components/ingredient-picker.blade.php index db42ab8..e78a9a0 100644 --- a/resources/views/components/ingredient-picker.blade.php +++ b/resources/views/components/ingredient-picker.blade.php @@ -29,12 +29,17 @@ x-bind:data-detail="result.detail">
- +
-
-
Servings:
+
+
+
Serving weight g
+
+
+
Servings:
+
-
+
Serving size