mirror of https://github.com/kcal-app/kcal.git
Add handling for recipes by weight in ingredient amounts and journal entries
This commit is contained in:
parent
836c40abf2
commit
33a8591c72
|
@ -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}";
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,17 @@
|
|||
x-bind:data-detail="result.detail">
|
||||
<div class="pointer-events-none">
|
||||
<div>
|
||||
<span x-text="result.name"></span><span class="text-gray-600" x-text="', ' + result.detail" x-show="result.detail"></span>
|
||||
<span class="font-bold" x-text="result.name"></span><span class="text-gray-600" x-text="', ' + result.detail" x-show="result.detail"></span>
|
||||
</div>
|
||||
<div x-show="result.servings">
|
||||
<div class="text-sm">Servings: <span x-text="result.servings"></span></div>
|
||||
<div x-show="result.type === 'App\\Models\\Recipe'">
|
||||
<div x-show="result.serving_weight">
|
||||
<div class="text-sm">Serving weight <span x-text="result.serving_weight"></span>g</div>
|
||||
</div>
|
||||
<div x-show="result.servings">
|
||||
<div class="text-sm">Servings: <span x-text="result.servings"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div x-show="result.serving_size">
|
||||
<div x-show="result.type === 'App\\Models\\Food'">
|
||||
<div class="text-sm text-gray-600" x-text="result.brand" x-show="result.brand"></div>
|
||||
<div class="text-sm">
|
||||
Serving size <span x-text="result.serving_size_formatted"></span>
|
||||
|
|
Loading…
Reference in New Issue