From 35f386d6816939ba932b834ec7394423430b9f79 Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Sun, 24 Jan 2021 15:23:18 -0800 Subject: [PATCH] Add backend support for multiple dates/meals in journal entry --- .../Controllers/JournalEntryController.php | 83 +++++++++++-------- app/Support/ArrayFormat.php | 55 ++++++++++++ .../views/journal-entries/create.blade.php | 4 +- resources/views/layouts/navigation.blade.php | 2 +- 4 files changed, 104 insertions(+), 40 deletions(-) create mode 100644 app/Support/ArrayFormat.php diff --git a/app/Http/Controllers/JournalEntryController.php b/app/Http/Controllers/JournalEntryController.php index 3937935..5106a3a 100644 --- a/app/Http/Controllers/JournalEntryController.php +++ b/app/Http/Controllers/JournalEntryController.php @@ -12,6 +12,7 @@ use App\Rules\ArrayNotEmpty; use App\Rules\InArray; use App\Rules\StringIsDecimalOrFraction; use App\Rules\UsesIngredientTrait; +use App\Support\ArrayFormat; use App\Support\Number; use App\Support\Nutrients; use Illuminate\Contracts\View\View; @@ -99,52 +100,62 @@ class JournalEntryController extends Controller 'ingredients.type.*' => ['required_with:ingredients.id.*', 'nullable', new UsesIngredientTrait()], ]); - $summary = []; - $nutrients = array_fill_keys(Nutrients::$all, 0); + $ingredients = ArrayFormat::flipTwoDimensionalKeys($input['ingredients']); + /** @var \App\Models\JournalEntry[] $entries */ + $entries = []; // TODO: Improve efficiency? Potential for lots of queries here... - foreach ($input['ingredients']['id'] as $key => $id) { - if ($input['ingredients']['type'][$key] == Food::class) { - $food = Food::whereId($id)->first(); - $nutrient_multiplier = Nutrients::calculateFoodNutrientMultiplier( - $food, - Number::floatFromString($input['ingredients']['amount'][$key]), - $input['ingredients']['unit'][$key], - ); - foreach ($nutrients as $nutrient => $amount) { - $nutrients[$nutrient] += $food->{$nutrient} * $nutrient_multiplier; + foreach ($ingredients as $ingredient) { + // Prepare entry values. + /** + * @var string $date + * @var string $meal + * @var float $amount + * @var string $unit + * @var int $id + * @var string $type + */ + extract($ingredient, EXTR_OVERWRITE); + $entry_key = "{$date}{$meal}"; + $entries[$entry_key] = $entries[$entry_key] ?? JournalEntry::make([ + 'date' => $date, + 'meal' => $meal, + ])->user()->associate(Auth::user()); + + // Calculate amounts based on ingredient type. + if ($type == Food::class) { + $item = Food::whereId($id)->first(); + $nutrient_multiplier = Nutrients::calculateFoodNutrientMultiplier($item, Number::floatFromString($amount), $unit,); + foreach (Nutrients::$all as $nutrient) { + $entries[$entry_key]->{$nutrient} =+ $item->{$nutrient} * $nutrient_multiplier; } - $summary[] = "{$input['ingredients']['amount'][$key]} {$input['ingredients']['unit'][$key]} {$food->name}"; + $entries[$entry_key]->foods->add($item); } - elseif ($input['ingredients']['type'][$key] == Recipe::class) { - $recipe = Recipe::whereId($id)->first(); - foreach ($nutrients as $nutrient => $amount) { - $nutrients[$nutrient] += $recipe->{"{$nutrient}PerServing"}() * Number::floatFromString($input['ingredients']['amount'][$key]); + elseif ($type == Recipe::class) { + $item = Recipe::whereId($id)->first(); + foreach (Nutrients::$all as $nutrient) { + $entries[$entry_key]->{$nutrient} += $item->{"{$nutrient}PerServing"}() * Number::floatFromString($amount); } - $summary[] = "{$input['ingredients']['amount'][$key]} {$input['ingredients']['unit'][$key]} {$recipe->name}"; + $entries[$entry_key]->recipes->add($item); } + else { + return back()->withInput()->withErrors("Invalid ingredient type {$type}."); + } + + // Update summary + $entries[$entry_key]->summary .= (!empty($entries[$entry_key]->summary) ? ', ' : null) . "{$amount} {$unit} {$item->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); - } + foreach ($entries as $entry) { + $entry->save(); + $entry->user->save(); + $entry->foods()->saveMany($entry->foods); + $entry->recipes()->saveMany($entry->recipes); } - session()->flash('message', "Journal entry added!"); - return redirect()->route( - 'journal-entries.index', - ['date' => $entry->date->format('Y-m-d')] - ); + $count = count($entries); + session()->flash('message', "Added {$count} journal entries!"); + return redirect()->route('journal-entries.index'); } /** diff --git a/app/Support/ArrayFormat.php b/app/Support/ArrayFormat.php new file mode 100644 index 0000000..b33a2da --- /dev/null +++ b/app/Support/ArrayFormat.php @@ -0,0 +1,55 @@ + [ + * 0 => 'ingredient-0', + * 1 => 'ingredient-1', + * 2 => 'ingredient-2', + * 3 => 'ingredient-3', + * ], + * 'amount' => [ + * 0 => 'amount-0', + * 1 => 'amount-1', + * 2 => 'amount-2', + * 3 => 'amount-3', + * ] + * ] + * + * becomes: + * + * $to = [ + * 0 => ['ingredient' => 'ingredient-0', 'amount' => 'amount-0'], + * 1 => ['ingredient' => 'ingredient-1', 'amount' => 'amount-1'], + * 2 => ['ingredient' => 'ingredient-2', 'amount' => 'amount-2'], + * 3 => ['ingredient' => 'ingredient-3', 'amount' => 'amount-3'], + * ] + * + * @param array $array + * Two dimensional array to be "flipped". + * + * @return array + * The flipped array. + */ + public static function flipTwoDimensionalKeys(array $array): array { + $flipped = []; + foreach ($array as $parent_key => $parent_values) { + foreach ($parent_values as $child_key => $child_value) { + $flipped[$child_key][$parent_key] = $child_value; + } + } + return $flipped; + } +} diff --git a/resources/views/journal-entries/create.blade.php b/resources/views/journal-entries/create.blade.php index d12174b..7a01f0c 100644 --- a/resources/views/journal-entries/create.blade.php +++ b/resources/views/journal-entries/create.blade.php @@ -34,9 +34,7 @@
- - {{ __('Add') }} - + Add entries
diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index c392a76..2472acb 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -37,7 +37,7 @@ {{ __('View Journal') }} - {{ __('Add Entry') }} + {{ __('Add Entries') }}