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) {
|
elseif ($ingredient['type'] == Recipe::class) {
|
||||||
$item = Recipe::whereId($ingredient['id'])->first();
|
$item = Recipe::whereId($ingredient['id'])->first();
|
||||||
foreach (Nutrients::$all as $nutrient) {
|
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);
|
$entries[$entry_key]->recipes->add($item);
|
||||||
}
|
}
|
||||||
|
@ -144,14 +149,14 @@ class JournalEntryController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update summary
|
// Update summary
|
||||||
if (empty($item->serving_unit) && empty($item->serving_unit_name)) {
|
$unit = $ingredient['unit'];
|
||||||
$unit = null;
|
if ($item instanceof Food) {
|
||||||
}
|
if (empty($item->serving_unit) && empty($item->serving_unit_name)) {
|
||||||
elseif (!empty($item->serving_unit_name)) {
|
$unit = null;
|
||||||
$unit = $item->serving_unit_formatted;
|
}
|
||||||
}
|
elseif (!empty($item->serving_unit_name)) {
|
||||||
else {
|
$unit = $item->serving_unit_formatted;
|
||||||
$unit = $ingredient['unit'];
|
}
|
||||||
}
|
}
|
||||||
$entries[$entry_key]->summary .= (!empty($entries[$entry_key]->summary) ? ', ' : null);
|
$entries[$entry_key]->summary .= (!empty($entries[$entry_key]->summary) ? ', ' : null);
|
||||||
$entries[$entry_key]->summary .= "{$ingredient['amount']} {$unit} {$item->name}";
|
$entries[$entry_key]->summary .= "{$ingredient['amount']} {$unit} {$item->name}";
|
||||||
|
|
|
@ -146,7 +146,12 @@ final class IngredientAmount extends Model
|
||||||
$this->amount,
|
$this->amount,
|
||||||
$this->unit
|
$this->unit
|
||||||
),
|
),
|
||||||
Recipe::class => $this->ingredient->{"{$method}PerServing"}() * $this->amount,
|
Recipe::class => Nutrients::calculateRecipeNutrientAmount(
|
||||||
|
$this->ingredient,
|
||||||
|
$method,
|
||||||
|
$this->amount,
|
||||||
|
$this->unit
|
||||||
|
),
|
||||||
default => 0
|
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 withAllTagsOfAnyType($tags)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withAnyTags($tags, ?string $type = null)
|
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withAnyTags($tags, ?string $type = null)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withAnyTagsOfAnyType($tags)
|
* @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
|
final class Recipe extends Model
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
namespace App\Support;
|
namespace App\Support;
|
||||||
|
|
||||||
use App\Models\Food;
|
use App\Models\Food;
|
||||||
|
use App\Models\Recipe;
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Refactor for more general use.
|
|
||||||
*/
|
|
||||||
class Nutrients
|
class Nutrients
|
||||||
{
|
{
|
||||||
|
public static float $gramsPerOunce = 28.349523125;
|
||||||
|
|
||||||
public static array $all = [
|
public static array $all = [
|
||||||
['value' => 'calories', 'unit' => null],
|
['value' => 'calories', 'unit' => null],
|
||||||
['value' => 'fat', 'unit' => 'g'],
|
['value' => 'fat', 'unit' => 'g'],
|
||||||
|
@ -27,13 +27,22 @@ class Nutrients
|
||||||
['value' => 'serving', 'label' => 'servings'],
|
['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(
|
public static function calculateFoodNutrientMultiplier(
|
||||||
Food $food,
|
Food $food,
|
||||||
float $amount,
|
float $amount,
|
||||||
string|null $fromUnit
|
string|null $fromUnit
|
||||||
): float {
|
): float {
|
||||||
if ($fromUnit === 'oz') {
|
if ($fromUnit === 'oz') {
|
||||||
return $amount * 28.349523125 / $food->serving_weight;
|
return $amount * self::$gramsPerOunce / $food->serving_weight;
|
||||||
}
|
}
|
||||||
elseif ($fromUnit === 'serving') {
|
elseif ($fromUnit === 'serving') {
|
||||||
return $amount;
|
return $amount;
|
||||||
|
@ -76,4 +85,34 @@ class Nutrients
|
||||||
|
|
||||||
return $multiplier / $food->serving_size * $amount;
|
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">
|
x-bind:data-detail="result.detail">
|
||||||
<div class="pointer-events-none">
|
<div class="pointer-events-none">
|
||||||
<div>
|
<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>
|
||||||
<div x-show="result.servings">
|
<div x-show="result.type === 'App\\Models\\Recipe'">
|
||||||
<div class="text-sm">Servings: <span x-text="result.servings"></span></div>
|
<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>
|
||||||
<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 text-gray-600" x-text="result.brand" x-show="result.brand"></div>
|
||||||
<div class="text-sm">
|
<div class="text-sm">
|
||||||
Serving size <span x-text="result.serving_size_formatted"></span>
|
Serving size <span x-text="result.serving_size_formatted"></span>
|
||||||
|
|
Loading…
Reference in New Issue