From fb3fa3dd1db3d9e0d0f608ca441ecabf71b46e1e Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Sun, 18 Apr 2021 13:46:20 -0700 Subject: [PATCH] Add nutrient calculation for recipe volumes --- app/Models/Recipe.php | 3 +++ app/Models/Traits/Ingredient.php | 3 +++ app/Support/Nutrients.php | 23 +++++++++++++---------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index e31e271..b856e4e 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -80,6 +80,9 @@ use Spatie\MediaLibrary\MediaCollections\Models\Media; * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\RecipeSeparator[] $separators * @property-read int|null $separators_count * @property-read Collection $units_supported + * @property float|null $volume + * @property-read string|null $volume_formatted + * @method static \Illuminate\Database\Eloquent\Builder|Recipe whereVolume($value) */ final class Recipe extends Model implements HasMedia { diff --git a/app/Models/Traits/Ingredient.php b/app/Models/Traits/Ingredient.php index a81c339..81f5c2c 100644 --- a/app/Models/Traits/Ingredient.php +++ b/app/Models/Traits/Ingredient.php @@ -65,6 +65,9 @@ trait Ingredient if (!empty($this->serving_weight)) { $supported = $supported->merge($units->where('type', 'weight')); } + if (isset($this->volume) && !empty($this->volume)) { + $supported = $supported->merge($units->where('type', 'volume')); + } return $supported->sortBy('label'); } } diff --git a/app/Support/Nutrients.php b/app/Support/Nutrients.php index 4daa135..24ec687 100644 --- a/app/Support/Nutrients.php +++ b/app/Support/Nutrients.php @@ -175,6 +175,8 @@ class Nutrients /** * Calculate a nutrient amount for a recipe. + * + * Weight base unit is grams, volume base unit is cups. */ public static function calculateRecipeNutrientAmount( Recipe $recipe, @@ -182,18 +184,19 @@ class Nutrients float $amount, string $fromUnit ): float { - if ($fromUnit === 'oz') { - return $amount * self::$gramsPerOunce / $recipe->weight * $recipe->{"{$nutrient}Total"}(); - } - elseif ($fromUnit === 'serving') { + if ($fromUnit === 'serving') { + // Use "per serving" methods directly. return $recipe->{"{$nutrient}PerServing"}() * $amount; } - elseif ($fromUnit === 'gram') { - return $amount / $recipe->weight * $recipe->{"{$nutrient}Total"}(); - } - else { - throw new \DomainException("Unsupported recipe unit: {$fromUnit}"); - } + $multiplier = match ($fromUnit) { + 'oz' => $amount * self::$gramsPerOunce / $recipe->weight, + 'gram' => $amount / $recipe->weight, + 'tsp' => $amount / 48 / $recipe->volume, + 'tbsp' => $amount / 16 / $recipe->volume, + 'cup' => $amount / $recipe->volume, + default => throw new \DomainException("Unsupported recipe unit: {$fromUnit}"), + }; + return $multiplier * $recipe->{"{$nutrient}Total"}(); } /**