mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 17:45:39 +00:00
This commit is contained in:
parent
45db9ff90c
commit
2d8ad24887
@ -17,40 +17,27 @@ class RecipesController extends BaseController
|
||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
$recipes = $this->Database->recipes()->orderBy('name');
|
||||
$recipesResolved = $this->RecipesService->GetRecipesResolved();
|
||||
|
||||
$selectedRecipe = null;
|
||||
$selectedRecipePositions = null;
|
||||
$selectedRecipePositionsResolved = null;
|
||||
if (isset($request->getQueryParams()['recipe']))
|
||||
{
|
||||
$selectedRecipe = $this->Database->recipes($request->getQueryParams()['recipe']);
|
||||
$selectedRecipePositions = $this->Database->recipes_pos()->where('recipe_id', $request->getQueryParams()['recipe'])->orderBy('ingredient_group');
|
||||
$selectedRecipePositionsResolved = $this->Database->recipes_pos_resolved()->where('recipe_id', $request->getQueryParams()['recipe'])->orderBy('ingredient_group');
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($recipes as $recipe)
|
||||
{
|
||||
$selectedRecipe = $recipe;
|
||||
$selectedRecipePositions = $this->Database->recipes_pos()->where('recipe_id', $recipe->id)->orderBy('ingredient_group');
|
||||
$selectedRecipePositionsResolved = $this->Database->recipes_pos_resolved()->where('recipe_id', $recipe->id)->orderBy('ingredient_group');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$selectedRecipeSubRecipes = $this->Database->recipes()->where('id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('name')->fetchAll();
|
||||
$selectedRecipeSubRecipesPositions = $this->Database->recipes_pos()->where('recipe_id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('ingredient_group')->fetchAll();
|
||||
|
||||
// Scale ingredients amount based on desired servings & calculate total costs
|
||||
$recipesFulfillment = $this->RecipesService->GetRecipesFulfillment();
|
||||
$totalRecipeCosts = 0;
|
||||
foreach ($selectedRecipePositions as $selectedRecipePosition)
|
||||
{
|
||||
$selectedRecipePosition->amount = $selectedRecipePosition->amount * ($selectedRecipe->desired_servings / $selectedRecipe->base_servings);
|
||||
$totalRecipeCosts += FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->costs;
|
||||
}
|
||||
foreach ($selectedRecipeSubRecipesPositions as $selectedSubRecipePosition)
|
||||
{
|
||||
$selectedSubRecipePosition->amount = $selectedSubRecipePosition->amount * ($selectedRecipe->desired_servings / $selectedRecipe->base_servings);
|
||||
$totalRecipeCosts += FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedSubRecipePosition->id)->costs;
|
||||
}
|
||||
$selectedRecipeSubRecipesPositions = $this->Database->recipes_pos_resolved()->where('recipe_id = :1', $selectedRecipe->id)->orderBy('ingredient_group')->fetchAll();
|
||||
|
||||
$includedRecipeIdsAbsolute = array();
|
||||
$includedRecipeIdsAbsolute[] = $selectedRecipe->id;
|
||||
@ -61,16 +48,16 @@ class RecipesController extends BaseController
|
||||
|
||||
return $this->AppContainer->view->render($response, 'recipes', [
|
||||
'recipes' => $recipes,
|
||||
'recipesFulfillment' => $recipesFulfillment,
|
||||
'recipesSumFulfillment' => $this->RecipesService->GetRecipesSumFulfillment(),
|
||||
'recipesResolved' => $recipesResolved,
|
||||
'recipePositionsResolved' => $this->Database->recipes_pos_resolved(),
|
||||
'selectedRecipe' => $selectedRecipe,
|
||||
'selectedRecipePositions' => $selectedRecipePositions,
|
||||
'selectedRecipePositionsResolved' => $selectedRecipePositionsResolved,
|
||||
'products' => $this->Database->products(),
|
||||
'quantityunits' => $this->Database->quantity_units(),
|
||||
'selectedRecipeSubRecipes' => $selectedRecipeSubRecipes,
|
||||
'selectedRecipeSubRecipesPositions' => $selectedRecipeSubRecipesPositions,
|
||||
'includedRecipeIdsAbsolute' => $includedRecipeIdsAbsolute,
|
||||
'totalRecipeCosts' => $totalRecipeCosts
|
||||
'selectedRecipeTotalCosts' => FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $selectedRecipe->id)->costs
|
||||
]);
|
||||
}
|
||||
|
||||
@ -93,8 +80,8 @@ class RecipesController extends BaseController
|
||||
'mode' => 'edit',
|
||||
'products' => $this->Database->products(),
|
||||
'quantityunits' => $this->Database->quantity_units(),
|
||||
'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(),
|
||||
'recipesSumFulfillment' => $this->RecipesService->GetRecipesSumFulfillment(),
|
||||
'recipePositionsResolved' => $this->RecipesService->GetRecipesPosResolved(),
|
||||
'recipesResolved' => $this->RecipesService->GetRecipesResolved(),
|
||||
'recipes' => $this->Database->recipes()->orderBy('name'),
|
||||
'recipeNestings' => $this->Database->recipes_nestings()->where('recipe_id', $recipeId)
|
||||
]);
|
||||
|
@ -344,5 +344,6 @@ return array(
|
||||
'Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated' => 'Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated',
|
||||
'You have to select a location' => 'You have to select a location',
|
||||
'List' => 'List',
|
||||
'Gallery' => 'Gallery'
|
||||
'Gallery' => 'Gallery',
|
||||
'The current picture will be deleted when you save the recipe' => 'The current picture will be deleted when you save the recipe'
|
||||
);
|
||||
|
109
migrations/0058.sql
Normal file
109
migrations/0058.sql
Normal file
@ -0,0 +1,109 @@
|
||||
ALTER TABLE recipes_nestings
|
||||
ADD servings INTEGER DEFAULT 1;
|
||||
|
||||
DROP VIEW recipes_nestings_resolved;
|
||||
CREATE VIEW recipes_nestings_resolved
|
||||
AS
|
||||
WITH RECURSIVE r1(recipe_id, includes_recipe_id, includes_servings)
|
||||
AS (
|
||||
SELECT id, id, 1
|
||||
FROM recipes
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT rn.recipe_id, r1.includes_recipe_id, rn.servings
|
||||
FROM recipes_nestings rn, r1 r1
|
||||
WHERE rn.includes_recipe_id = r1.recipe_id
|
||||
LIMIT 100 -- This is just a safety limit to prevent infinite loops due to infinite nested recipes
|
||||
)
|
||||
SELECT *
|
||||
FROM r1;
|
||||
|
||||
DROP VIEW recipes_fulfillment;
|
||||
CREATE VIEW recipes_pos_resolved
|
||||
AS
|
||||
SELECT
|
||||
r.id AS recipe_id,
|
||||
rp.id AS recipe_pos_id,
|
||||
rp.product_id AS product_id,
|
||||
rp.amount * (r.desired_servings / r.base_servings) * rnr.includes_servings AS recipe_amount,
|
||||
IFNULL(sc.amount, 0) AS stock_amount,
|
||||
CASE WHEN IFNULL(sc.amount, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) * (r.desired_servings / r.base_servings) * rnr.includes_servings END THEN 1 ELSE 0 END AS need_fulfilled,
|
||||
CASE WHEN IFNULL(sc.amount, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) * (r.desired_servings / r.base_servings) * rnr.includes_servings END < 0 THEN ABS(IFNULL(sc.amount, 0) - (CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) * (r.desired_servings / r.base_servings) * rnr.includes_servings END)) ELSE 0 END AS missing_amount,
|
||||
IFNULL(sl.amount, 0) * p.qu_factor_purchase_to_stock AS amount_on_shopping_list,
|
||||
CASE WHEN IFNULL(sc.amount, 0) + (CASE WHEN r.not_check_shoppinglist = 1 THEN 0 ELSE IFNULL(sl.amount, 0) END * p.qu_factor_purchase_to_stock) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) * (r.desired_servings / r.base_servings) * rnr.includes_servings END THEN 1 ELSE 0 END AS need_fulfilled_with_shopping_list,
|
||||
rp.qu_id,
|
||||
(CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE rp.amount * (r.desired_servings / r.base_servings) * rnr.includes_servings END / p.qu_factor_purchase_to_stock) * pcp.last_price AS costs,
|
||||
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN 0 ELSE 1 END AS is_nested_recipe_pos,
|
||||
rp.ingredient_group,
|
||||
rp.id, -- Just a dummy id column
|
||||
rnr.includes_recipe_id as child_recipe_id
|
||||
FROM recipes r
|
||||
JOIN recipes_nestings_resolved rnr
|
||||
ON r.id = rnr.recipe_id
|
||||
JOIN recipes_pos rp
|
||||
ON rnr.includes_recipe_id = rp.recipe_id
|
||||
JOIN products p
|
||||
ON rp.product_id = p.id
|
||||
LEFT JOIN (
|
||||
SELECT product_id, SUM(amount) AS amount
|
||||
FROM shopping_list
|
||||
GROUP BY product_id) sl
|
||||
ON rp.product_id = sl.product_id
|
||||
LEFT JOIN stock_current sc
|
||||
ON rp.product_id = sc.product_id
|
||||
LEFT JOIN products_current_price pcp
|
||||
ON rp.product_id = pcp.product_id
|
||||
WHERE rp.not_check_stock_fulfillment = 0
|
||||
|
||||
UNION
|
||||
|
||||
-- Just add all recipe positions which should not be checked against stock with fulfilled need
|
||||
|
||||
SELECT
|
||||
r.id AS recipe_id,
|
||||
rp.id AS recipe_pos_id,
|
||||
rp.product_id AS product_id,
|
||||
rp.amount * (r.desired_servings / r.base_servings) * rnr.includes_servings AS recipe_amount,
|
||||
IFNULL(sc.amount, 0) AS stock_amount,
|
||||
1 AS need_fulfilled,
|
||||
0 AS missing_amount,
|
||||
IFNULL(sl.amount, 0) * p.qu_factor_purchase_to_stock AS amount_on_shopping_list,
|
||||
1 AS need_fulfilled_with_shopping_list,
|
||||
rp.qu_id,
|
||||
(CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE rp.amount * (r.desired_servings / r.base_servings) * rnr.includes_servings END / p.qu_factor_purchase_to_stock) * pcp.last_price AS costs,
|
||||
CASE WHEN rnr.recipe_id = rnr.includes_recipe_id THEN 0 ELSE 1 END AS is_nested_recipe_pos,
|
||||
rp.ingredient_group,
|
||||
rp.id, -- Just a dummy id column
|
||||
rnr.includes_recipe_id as child_recipe_id
|
||||
FROM recipes r
|
||||
JOIN recipes_nestings_resolved rnr
|
||||
ON r.id = rnr.recipe_id
|
||||
JOIN recipes_pos rp
|
||||
ON rnr.includes_recipe_id = rp.recipe_id
|
||||
JOIN products p
|
||||
ON rp.product_id = p.id
|
||||
LEFT JOIN (
|
||||
SELECT product_id, SUM(amount) AS amount
|
||||
FROM shopping_list
|
||||
GROUP BY product_id) sl
|
||||
ON rp.product_id = sl.product_id
|
||||
LEFT JOIN stock_current sc
|
||||
ON rp.product_id = sc.product_id
|
||||
LEFT JOIN products_current_price pcp
|
||||
ON rp.product_id = pcp.product_id
|
||||
WHERE rp.not_check_stock_fulfillment = 1;
|
||||
|
||||
DROP VIEW recipes_fulfillment_sum;
|
||||
CREATE VIEW recipes_resolved
|
||||
AS
|
||||
SELECT
|
||||
r.id AS recipe_id,
|
||||
IFNULL(MIN(rpr.need_fulfilled), 1) AS need_fulfilled,
|
||||
IFNULL(MIN(rpr.need_fulfilled_with_shopping_list), 1) AS need_fulfilled_with_shopping_list,
|
||||
(SELECT COUNT(*) FROM recipes_pos_resolved WHERE recipe_id = r.id AND need_fulfilled = 0) AS missing_products_count,
|
||||
SUM(rpr.costs) AS costs
|
||||
FROM recipes r
|
||||
LEFT JOIN recipes_pos_resolved rpr
|
||||
ON r.id = rpr.recipe_id
|
||||
GROUP BY r.id;
|
@ -235,14 +235,16 @@ $(document).on('click', '.recipe-include-edit-button', function (e)
|
||||
{
|
||||
var id = $(e.currentTarget).attr('data-recipe-include-id');
|
||||
var recipeId = $(e.currentTarget).attr('data-recipe-included-recipe-id');
|
||||
console.log(recipeId);
|
||||
var recipeServings = $(e.currentTarget).attr('data-recipe-included-recipe-servings');
|
||||
|
||||
Grocy.Api.Put('objects/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
$("#recipe-include-editform-title").text(L("Edit included recipe"));
|
||||
$("#recipe-include-form").data("edit-mode", "edit");
|
||||
$("#recipe-include-form").data("recipe-nesting-id", id);
|
||||
$("#includes_recipe_id").val(recipeId);
|
||||
Grocy.Components.RecipePicker.SetId(recipeId);
|
||||
$("#includes_servings").val(recipeServings);
|
||||
$("#recipe-include-editform-modal").modal("show");
|
||||
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
|
||||
},
|
||||
@ -274,7 +276,7 @@ $("#recipe-include-add-button").on("click", function(e)
|
||||
{
|
||||
$("#recipe-include-editform-title").text(L("Add included recipe"));
|
||||
$("#recipe-include-form").data("edit-mode", "create");
|
||||
$("#includes_recipe_id").val("");
|
||||
Grocy.Components.RecipePicker.Clear();
|
||||
$("#recipe-include-editform-modal").modal("show");
|
||||
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
|
||||
},
|
||||
@ -289,10 +291,17 @@ $('#save-recipe-include-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
if (document.getElementById("recipe-include-form").checkValidity() === false) //There is at least one validation error
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var nestingId = $("#recipe-include-form").data("recipe-nesting-id");
|
||||
var editMode = $("#recipe-include-form").data("edit-mode");
|
||||
|
||||
var jsonData = $('#recipe-include-form').serializeJSON();
|
||||
var jsonData = {};
|
||||
jsonData.includes_recipe_id = Grocy.Components.RecipePicker.GetValue();
|
||||
jsonData.servings = $("#includes_servings").val();
|
||||
jsonData.recipe_id = Grocy.EditObjectId;
|
||||
|
||||
if (editMode === 'create')
|
||||
|
@ -14,15 +14,15 @@ class RecipesService extends BaseService
|
||||
|
||||
protected $StockService;
|
||||
|
||||
public function GetRecipesFulfillment()
|
||||
public function GetRecipesPosResolved()
|
||||
{
|
||||
$sql = 'SELECT * from recipes_fulfillment';
|
||||
$sql = 'SELECT * FROM recipes_pos_resolved';
|
||||
return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function GetRecipesSumFulfillment()
|
||||
public function GetRecipesResolved()
|
||||
{
|
||||
$sql = 'SELECT * from recipes_fulfillment_sum';
|
||||
$sql = 'SELECT * FROM recipes_resolved';
|
||||
return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ class RecipesService extends BaseService
|
||||
{
|
||||
$recipe = $this->Database->recipes($recipeId);
|
||||
|
||||
$recipePositions = $this->GetRecipesFulfillment();
|
||||
$recipePositions = $this->GetRecipesPosResolved();
|
||||
foreach ($recipePositions as $recipePosition)
|
||||
{
|
||||
if($recipePosition->recipe_id == $recipeId && !in_array($recipePosition->product_id, $excludedProductIds))
|
||||
|
@ -154,6 +154,7 @@
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{{ $L('Recipe') }}</th>
|
||||
<th>{{ $L('Servings') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="d-none">
|
||||
@ -161,7 +162,7 @@
|
||||
@foreach($recipeNestings as $recipeNesting)
|
||||
<tr>
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-sm btn-info recipe-include-edit-button" href="#" data-recipe-include-id="{{ $recipeNesting->id }}" data-recipe-included-recipe-id="{{ $recipeNesting->includes_recipe_id }}">
|
||||
<a class="btn btn-sm btn-info recipe-include-edit-button" href="#" data-recipe-include-id="{{ $recipeNesting->id }}" data-recipe-included-recipe-id="{{ $recipeNesting->includes_recipe_id }}" data-recipe-included-recipe-servings="{{ $recipeNesting->servings }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger recipe-include-delete-button" href="#" data-recipe-include-id="{{ $recipeNesting->id }}" data-recipe-include-name="{{ FindObjectInArrayByPropertyValue($recipes, 'id', $recipeNesting->includes_recipe_id)->name }}">
|
||||
@ -171,6 +172,9 @@
|
||||
<td>
|
||||
{{ FindObjectInArrayByPropertyValue($recipes, 'id', $recipeNesting->includes_recipe_id)->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $recipeNesting->servings }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@endif
|
||||
@ -202,18 +206,20 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="recipe-include-form" novalidate>
|
||||
<div class="form-group">
|
||||
<label for="includes_recipe_id">{{ $L('Recipe') }}</label>
|
||||
<select required class="form-control" id="includes_recipe_id" name="includes_recipe_id">
|
||||
<option></option>
|
||||
@foreach($recipes as $recipeForList)
|
||||
@if($recipeForList->id !== $recipe->id)
|
||||
<option data-already-included="{{ BoolToString(FindObjectInArrayByPropertyValue($recipeNestings, 'includes_recipe_id', $recipeForList->id) === null) }}" value="{{ $recipeForList->id }}">{{ $recipeForList->name }}</option>
|
||||
@endif
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="invalid-feedback">{{ $L('A recipe is required') }}</div>
|
||||
</div>
|
||||
|
||||
@include('components.recipepicker', array(
|
||||
'recipes' => $recipes,
|
||||
'isRequired' => true
|
||||
))
|
||||
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'includes_servings',
|
||||
'label' => 'Servings',
|
||||
'min' => 1,
|
||||
'value' => '1',
|
||||
'invalidFeedback' => $L('This cannot be lower than #1', '1')
|
||||
))
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -49,11 +49,11 @@
|
||||
{{ $recipe->desired_servings }}
|
||||
</td>
|
||||
<td>
|
||||
@if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $L('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $L('Not enough in stock, #1 ingredients missing but already on the shopping list', FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->missing_products_count) }}@else{{ $L('Not enough in stock, #1 ingredients missing', FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->missing_products_count) }}@endif</span>
|
||||
@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $L('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $L('Not enough in stock, #1 ingredients missing but already on the shopping list', FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count) }}@else{{ $L('Not enough in stock, #1 ingredients missing', FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count) }}@endif</span>
|
||||
</td>
|
||||
<td class="d-none">
|
||||
{{ FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->missing_products_count }}
|
||||
{{ FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@ -73,8 +73,8 @@
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title mb-1">{{ $recipe->name }}</h5>
|
||||
<p class="card-text">
|
||||
@if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $L('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $L('Not enough in stock, #1 ingredients missing but already on the shopping list', FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->missing_products_count) }}@else{{ $L('Not enough in stock, #1 ingredients missing', FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $recipe->id)->missing_products_count) }}@endif</span>
|
||||
@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $L('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $L('Not enough in stock, #1 ingredients missing but already on the shopping list', FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count) }}@else{{ $L('Not enough in stock, #1 ingredients missing', FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count) }}@endif</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -95,7 +95,7 @@
|
||||
<a id="selectedRecipeConsumeButton" class="btn btn-sm btn-outline-success py-0" href="#" data-toggle="tooltip" title="{{ $L('Consume all ingredients needed by this recipe') }}" data-recipe-id="{{ $selectedRecipe->id }}" data-recipe-name="{{ $selectedRecipe->name }}">
|
||||
<i class="fas fa-utensils"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-outline-primary py-0 recipe-order-missing-button @if(FindObjectInArrayByPropertyValue($recipesSumFulfillment, 'recipe_id', $selectedRecipe->id)->need_fulfilled_with_shopping_list == 1){{ disabled }}@endif" href="#" data-toggle="tooltip" title="{{ $L('Put missing products on shopping list') }}" data-recipe-id="{{ $selectedRecipe->id }}" data-recipe-name="{{ $selectedRecipe->name }}">
|
||||
<a class="btn btn-sm btn-outline-primary py-0 recipe-order-missing-button @if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $selectedRecipe->id)->need_fulfilled_with_shopping_list == 1){{ disabled }}@endif" href="#" data-toggle="tooltip" title="{{ $L('Put missing products on shopping list') }}" data-recipe-id="{{ $selectedRecipe->id }}" data-recipe-name="{{ $selectedRecipe->name }}">
|
||||
<i class="fas fa-cart-plus"></i>
|
||||
</a>
|
||||
<a id="selectedRecipeEditButton" class="btn btn-sm btn-outline-info py-0" href="{{ $U('/recipe/') }}{{ $selectedRecipe->id }}">
|
||||
@ -126,7 +126,7 @@
|
||||
<span class="small text-muted">{{ $L('Based on the prices of the last purchase per product') }}</span>
|
||||
</label>
|
||||
<p class="font-weight-bold font-italic">
|
||||
<span class="locale-number-format" data-format="currency">{{ $totalRecipeCosts }}</span>
|
||||
<span class="locale-number-format" data-format="currency">{{ $selectedRecipeTotalCosts }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -142,7 +142,7 @@
|
||||
<p class="w-75 mx-auto"><img src="{{ $U('/api/files/recipepictures/' . base64_encode($selectedRecipeSubRecipe->picture_file_name)) }}" class="img-fluid img-thumbnail"></p>
|
||||
@endif
|
||||
|
||||
@php $selectedRecipeSubRecipePositionsFiltered = FindAllObjectsInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_id', $selectedRecipeSubRecipe->id); @endphp
|
||||
@php $selectedRecipeSubRecipePositionsFiltered = FindAllObjectsInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'child_recipe_id', $selectedRecipeSubRecipe->id); @endphp
|
||||
@if(count($selectedRecipeSubRecipePositionsFiltered) > 0)
|
||||
<div class="card-body">
|
||||
<h5 class="mb-0">{{ $L('Ingredients') }}</h5>
|
||||
@ -154,8 +154,8 @@
|
||||
<h5 class="mb-2 mt-2 ml-4"><strong>{{ $selectedRecipePosition->ingredient_group }}</strong></h5>
|
||||
@endif
|
||||
<li class="list-group-item">
|
||||
@if($selectedRecipePosition->amount == round($selectedRecipePosition->amount)){{ round($selectedRecipePosition->amount) }}@else{{ $selectedRecipePosition->amount }}@endif {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', round($selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif</span>
|
||||
@if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount)){{ round($selectedRecipePosition->recipe_amount) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif {{ Pluralize($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', round(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif</span>
|
||||
|
||||
@if(!empty($selectedRecipePosition->note))
|
||||
<div class="text-muted">{!! nl2br($selectedRecipePosition->note) !!}</div>
|
||||
@ -178,19 +178,19 @@
|
||||
<p class="w-75 mx-auto"><img src="{{ $U('/api/files/recipepictures/' . base64_encode($selectedRecipe->picture_file_name)) }}" class="img-fluid img-thumbnail"></p>
|
||||
@endif
|
||||
|
||||
@if($selectedRecipePositions->count() > 0)
|
||||
@if($selectedRecipePositionsResolved->count() > 0)
|
||||
<div class="card-body">
|
||||
<h5 class="mb-0">{{ $L('Ingredients') }}</h5>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
@php $lastGroup = 'undefined'; @endphp
|
||||
@foreach($selectedRecipePositions as $selectedRecipePosition)
|
||||
@foreach($selectedRecipePositionsResolved as $selectedRecipePosition)
|
||||
@if($lastGroup != $selectedRecipePosition->ingredient_group)
|
||||
<h5 class="mb-2 mt-2 ml-4"><strong>{{ $selectedRecipePosition->ingredient_group }}</strong></h5>
|
||||
@endif
|
||||
<li class="list-group-item">
|
||||
@if($selectedRecipePosition->amount == round($selectedRecipePosition->amount)){{ round($selectedRecipePosition->amount) }}@else{{ $selectedRecipePosition->amount }}@endif {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif</span>
|
||||
@if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount)){{ round($selectedRecipePosition->recipe_amount) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif {{ Pluralize($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif</span>
|
||||
|
||||
@if(!empty($selectedRecipePosition->note))
|
||||
<div class="text-muted">{!! nl2br($selectedRecipePosition->note) !!}</div>
|
||||
@ -212,7 +212,7 @@
|
||||
</div>
|
||||
|
||||
<div id="missing-recipe-pos-list" class="list-group d-none mt-3">
|
||||
@foreach($recipesFulfillment as $recipePos)
|
||||
@foreach($recipePositionsResolved as $recipePos)
|
||||
@if(in_array($recipePos->recipe_id, $includedRecipeIdsAbsolute) && $recipePos->missing_amount > 0)
|
||||
<a href="#" class="list-group-item list-group-item-action list-group-item-primary missing-recipe-pos-select-button">
|
||||
<div class="form-check form-check-inline">
|
||||
|
Loading…
x
Reference in New Issue
Block a user