mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 17:45:39 +00:00
Finish first version of nested recipes feature (references #77)
This commit is contained in:
parent
12a2cb0bdf
commit
fc3a4c6899
@ -35,6 +35,9 @@ class RecipesController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$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)->fetchAll();
|
||||||
|
|
||||||
return $this->AppContainer->view->render($response, 'recipes', [
|
return $this->AppContainer->view->render($response, 'recipes', [
|
||||||
'recipes' => $recipes,
|
'recipes' => $recipes,
|
||||||
'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(),
|
'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(),
|
||||||
@ -42,7 +45,9 @@ class RecipesController extends BaseController
|
|||||||
'selectedRecipe' => $selectedRecipe,
|
'selectedRecipe' => $selectedRecipe,
|
||||||
'selectedRecipePositions' => $selectedRecipePositions,
|
'selectedRecipePositions' => $selectedRecipePositions,
|
||||||
'products' => $this->Database->products(),
|
'products' => $this->Database->products(),
|
||||||
'quantityunits' => $this->Database->quantity_units()
|
'quantityunits' => $this->Database->quantity_units(),
|
||||||
|
'selectedRecipeSubRecipes' => $selectedRecipeSubRecipes,
|
||||||
|
'selectedRecipeSubRecipesPositions' => $selectedRecipeSubRecipesPositions
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ class RecipesController extends BaseController
|
|||||||
'quantityunits' => $this->Database->quantity_units(),
|
'quantityunits' => $this->Database->quantity_units(),
|
||||||
'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(),
|
'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(),
|
||||||
'recipesSumFulfillment' => $this->RecipesService->GetRecipesSumFulfillment(),
|
'recipesSumFulfillment' => $this->RecipesService->GetRecipesSumFulfillment(),
|
||||||
'recipes' => $this->Database->recipes(),
|
'recipes' => $this->Database->recipes()->orderBy('name'),
|
||||||
'recipeNestings' => $this->Database->recipes_nestings()->where('recipe_id', $recipeId)
|
'recipeNestings' => $this->Database->recipes_nestings()->where('recipe_id', $recipeId)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -94,25 +99,4 @@ class RecipesController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RecipeIncludeEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['recipeIncludeId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->AppContainer->view->render($response, 'recipeincludeform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'recipe' => $this->Database->recipes($args['recipeId']),
|
|
||||||
'recipes' => $this->Database->recipes()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->AppContainer->view->render($response, 'recipeincludeform', [
|
|
||||||
'mode' => 'edit',
|
|
||||||
'recipe' => $this->Database->recipes($args['recipeId']),
|
|
||||||
'recipeInclude' => $this->Database->recipes_nestings($args['recipeIncludeId']),
|
|
||||||
'recipes' => $this->Database->recipes()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -280,6 +280,10 @@ return array(
|
|||||||
'No picture available' => 'Kein Bild vorhanden',
|
'No picture available' => 'Kein Bild vorhanden',
|
||||||
'Filter by product group' => 'Nach Produktgruppe filtern',
|
'Filter by product group' => 'Nach Produktgruppe filtern',
|
||||||
'Presets for new products' => 'Vorgaben für neue Produkte',
|
'Presets for new products' => 'Vorgaben für neue Produkte',
|
||||||
|
'Included recipes' => 'Enthaltene Rezepte',
|
||||||
|
'A recipe is required' => 'Ein Rezept ist erforderlich',
|
||||||
|
'Add included recipe' => 'Enthaltenes Rezept hinzufügen',
|
||||||
|
'Edit included recipe' => 'Enthaltenes Rezept bearbeiten',
|
||||||
|
|
||||||
//Constants
|
//Constants
|
||||||
'manually' => 'Manuell',
|
'manually' => 'Manuell',
|
||||||
@ -364,5 +368,13 @@ return array(
|
|||||||
'Vegetables/Fruits' => 'Obst/Gemüse',
|
'Vegetables/Fruits' => 'Obst/Gemüse',
|
||||||
'Refrigerated products' => 'Kühlregal',
|
'Refrigerated products' => 'Kühlregal',
|
||||||
'Coffee machine' => 'Kaffeemaschine',
|
'Coffee machine' => 'Kaffeemaschine',
|
||||||
'Dishwasher' => 'Spülmaschine'
|
'Dishwasher' => 'Spülmaschine',
|
||||||
|
'Liter' => 'Liter',
|
||||||
|
'Liters' => 'Liter',
|
||||||
|
'Bottle' => 'Flasche',
|
||||||
|
'Bottles' => 'Flaschen',
|
||||||
|
'Milk' => 'Milch',
|
||||||
|
'Chocolate sauce' => 'Schokoladensoße',
|
||||||
|
'Milliliters' => 'Milliliter',
|
||||||
|
'Milliliter' => 'Milliliter'
|
||||||
);
|
);
|
||||||
|
@ -23,3 +23,18 @@ AS (
|
|||||||
)
|
)
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM r1;
|
FROM r1;
|
||||||
|
|
||||||
|
DROP VIEW recipes_fulfillment_sum;
|
||||||
|
CREATE VIEW recipes_fulfillment_sum
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
r.id AS recipe_id,
|
||||||
|
IFNULL(MIN(rf.need_fulfilled), 1) AS need_fulfilled,
|
||||||
|
IFNULL(MIN(rf.need_fulfilled_with_shopping_list), 1) AS need_fulfilled_with_shopping_list,
|
||||||
|
(SELECT COUNT(*) FROM recipes_fulfillment WHERE recipe_id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved rnr2 WHERE rnr2.recipe_id = r.id) AND need_fulfilled = 0 AND recipe_pos_id IS NOT NULL) AS missing_products_count
|
||||||
|
FROM recipes r
|
||||||
|
LEFT JOIN recipes_nestings_resolved rnr
|
||||||
|
ON r.id = rnr.recipe_id
|
||||||
|
LEFT JOIN recipes_fulfillment rf
|
||||||
|
ON rnr.includes_recipe_id = rf.recipe_id
|
||||||
|
GROUP BY r.id;
|
||||||
|
@ -118,7 +118,7 @@ $(document).on('click', '.recipe-pos-delete-button', function(e)
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('click', '.recipe-inlcude-delete-button', function(e)
|
$(document).on('click', '.recipe-include-delete-button', function(e)
|
||||||
{
|
{
|
||||||
var objectName = $(e.currentTarget).attr('data-recipe-include-name');
|
var objectName = $(e.currentTarget).attr('data-recipe-include-name');
|
||||||
var objectId = $(e.currentTarget).attr('data-recipe-include-id');
|
var objectId = $(e.currentTarget).attr('data-recipe-include-id');
|
||||||
@ -206,11 +206,17 @@ $(document).on('click', '.recipe-pos-edit-button', function (e)
|
|||||||
$(document).on('click', '.recipe-include-edit-button', function (e)
|
$(document).on('click', '.recipe-include-edit-button', function (e)
|
||||||
{
|
{
|
||||||
var id = $(e.currentTarget).attr('data-recipe-include-id');
|
var id = $(e.currentTarget).attr('data-recipe-include-id');
|
||||||
|
var recipeId = $(e.currentTarget).attr('data-recipe-included-recipe-id');
|
||||||
|
console.log(recipeId);
|
||||||
Grocy.Api.Post('edit-object/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(),
|
Grocy.Api.Post('edit-object/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(),
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/recipe/' + Grocy.EditObjectId + '/included_recipe/' + id);
|
$("#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);
|
||||||
|
$("#recipe-include-editform-modal").modal("show");
|
||||||
|
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@ -238,7 +244,11 @@ $("#recipe-include-add-button").on("click", function(e)
|
|||||||
Grocy.Api.Post('edit-object/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(),
|
Grocy.Api.Post('edit-object/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(),
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/recipe/' + Grocy.EditObjectId + '/included_recipe/new');
|
$("#recipe-include-editform-title").text(L("Add included recipe"));
|
||||||
|
$("#recipe-include-form").data("edit-mode", "create");
|
||||||
|
$("#includes_recipe_id").val("");
|
||||||
|
$("#recipe-include-editform-modal").modal("show");
|
||||||
|
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@ -247,6 +257,44 @@ $("#recipe-include-add-button").on("click", function(e)
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#save-recipe-include-button').on('click', function(e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var nestingId = $("#recipe-include-form").data("recipe-nesting-id");
|
||||||
|
var editMode = $("#recipe-include-form").data("edit-mode");
|
||||||
|
|
||||||
|
var jsonData = $('#recipe-include-form').serializeJSON();
|
||||||
|
jsonData.recipe_id = Grocy.EditObjectId;
|
||||||
|
|
||||||
|
if (editMode === 'create')
|
||||||
|
{
|
||||||
|
Grocy.Api.Post('add-object/recipes_nestings', jsonData,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
window.location.href = U('/recipe/' + Grocy.EditObjectId);
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Grocy.Api.Post('edit-object/recipes_nestings/' + nestingId, jsonData,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
window.location.href = U('/recipe/' + Grocy.EditObjectId);
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('#description').summernote({
|
$('#description').summernote({
|
||||||
minHeight: '300px',
|
minHeight: '300px',
|
||||||
lang: L('summernote_locale')
|
lang: L('summernote_locale')
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
$('#save-recipe-include-button').on('click', function(e)
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var jsonData = $('#recipe-include-form').serializeJSON();
|
|
||||||
jsonData.recipe_id = Grocy.EditObjectParentId;
|
|
||||||
if (Grocy.EditMode === 'create')
|
|
||||||
{
|
|
||||||
Grocy.Api.Post('add-object/recipes_nestings', jsonData,
|
|
||||||
function(result)
|
|
||||||
{
|
|
||||||
window.location.href = U('/recipe/' + Grocy.EditObjectParentId);
|
|
||||||
},
|
|
||||||
function(xhr)
|
|
||||||
{
|
|
||||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Grocy.Api.Post('edit-object/recipes_nestings/' + Grocy.EditObjectId, jsonData,
|
|
||||||
function(result)
|
|
||||||
{
|
|
||||||
window.location.href = U('/recipe/' + Grocy.EditObjectParentId);
|
|
||||||
},
|
|
||||||
function(xhr)
|
|
||||||
{
|
|
||||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Grocy.FrontendHelpers.ValidateForm('recipe-include-form');
|
|
||||||
|
|
||||||
$('#recipe-include-form input').keyup(function(event)
|
|
||||||
{
|
|
||||||
Grocy.FrontendHelpers.ValidateForm('recipe-include-form');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#recipe-include-form select').change(function(event)
|
|
||||||
{
|
|
||||||
Grocy.FrontendHelpers.ValidateForm('recipe-include-form');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#recipe-include-form input').keydown(function(event)
|
|
||||||
{
|
|
||||||
if (event.keyCode === 13) //Enter
|
|
||||||
{
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
if (document.getElementById('recipe-include-form').checkValidity() === false) //There is at least one validation error
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$('#save-include-include-button').click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@ -40,7 +40,6 @@ $app->group('', function()
|
|||||||
$this->get('/recipes', '\Grocy\Controllers\RecipesController:Overview');
|
$this->get('/recipes', '\Grocy\Controllers\RecipesController:Overview');
|
||||||
$this->get('/recipe/{recipeId}', '\Grocy\Controllers\RecipesController:RecipeEditForm');
|
$this->get('/recipe/{recipeId}', '\Grocy\Controllers\RecipesController:RecipeEditForm');
|
||||||
$this->get('/recipe/{recipeId}/pos/{recipePosId}', '\Grocy\Controllers\RecipesController:RecipePosEditForm');
|
$this->get('/recipe/{recipeId}/pos/{recipePosId}', '\Grocy\Controllers\RecipesController:RecipePosEditForm');
|
||||||
$this->get('/recipe/{recipeId}/included_recipe/{recipeIncludeId}', '\Grocy\Controllers\RecipesController:RecipeIncludeEditForm');
|
|
||||||
|
|
||||||
// Chore routes
|
// Chore routes
|
||||||
$this->get('/choresoverview', '\Grocy\Controllers\ChoresController:Overview');
|
$this->get('/choresoverview', '\Grocy\Controllers\ChoresController:Overview');
|
||||||
|
@ -31,6 +31,9 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Can')}', '{$localizationService->Localize('Cans')}'); --6
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Can')}', '{$localizationService->Localize('Cans')}'); --6
|
||||||
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Bunch')}', '{$localizationService->Localize('Bunches')}'); --7
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Bunch')}', '{$localizationService->Localize('Bunches')}'); --7
|
||||||
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Gram')}', '{$localizationService->Localize('Grams')}'); --8
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Gram')}', '{$localizationService->Localize('Grams')}'); --8
|
||||||
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Liter')}', '{$localizationService->Localize('Liters')}'); --9
|
||||||
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Bottle')}', '{$localizationService->Localize('Bottles')}'); --10
|
||||||
|
INSERT INTO quantity_units (name, name_plural) VALUES ('{$localizationService->Localize('Milliliter')}', '{$localizationService->Localize('Milliliters')}'); --11
|
||||||
|
|
||||||
INSERT INTO product_groups(name) VALUES ('01 {$localizationService->Localize('Sweets')}'); --1
|
INSERT INTO product_groups(name) VALUES ('01 {$localizationService->Localize('Sweets')}'); --1
|
||||||
INSERT INTO product_groups(name) VALUES ('02 {$localizationService->Localize('Bakery products')}'); --2
|
INSERT INTO product_groups(name) VALUES ('02 {$localizationService->Localize('Bakery products')}'); --2
|
||||||
@ -62,6 +65,7 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Minced meat')}', 2, 3, 3, 1, 4); --20
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Minced meat')}', 2, 3, 3, 1, 4); --20
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Flour')}', 2, 3, 3, 1, 3); --21
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Flour')}', 2, 3, 3, 1, 3); --21
|
||||||
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Sugar')}', 3, 3, 3, 1, 3); --22
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, product_group_id) VALUES ('{$localizationService->Localize('Sugar')}', 3, 3, 3, 1, 3); --22
|
||||||
|
INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Milk')}', 2, 10, 10, 1); --23
|
||||||
|
|
||||||
INSERT INTO shopping_list (note, amount) VALUES ('{$localizationService->Localize('Some good snacks')}', 1);
|
INSERT INTO shopping_list (note, amount) VALUES ('{$localizationService->Localize('Some good snacks')}', 1);
|
||||||
INSERT INTO shopping_list (product_id, amount) VALUES (20, 1);
|
INSERT INTO shopping_list (product_id, amount) VALUES (20, 1);
|
||||||
@ -71,6 +75,8 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Spaghetti bolognese')}', '{$loremIpsumWithHtmlFormattings}'); --2
|
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Spaghetti bolognese')}', '{$loremIpsumWithHtmlFormattings}'); --2
|
||||||
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Sandwiches')}', '{$loremIpsumWithHtmlFormattings}'); --3
|
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Sandwiches')}', '{$loremIpsumWithHtmlFormattings}'); --3
|
||||||
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pancakes')}', '{$loremIpsumWithHtmlFormattings}'); --4
|
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pancakes')}', '{$loremIpsumWithHtmlFormattings}'); --4
|
||||||
|
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Chocolate sauce')}', '{$loremIpsumWithHtmlFormattings}'); --5
|
||||||
|
INSERT INTO recipes (name, description) VALUES ('{$localizationService->Localize('Pancakes')} / {$localizationService->Localize('Chocolate sauce')}', '{$loremIpsumWithHtmlFormattings}'); --6
|
||||||
|
|
||||||
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 16, 1);
|
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 16, 1);
|
||||||
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 17, 1);
|
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (1, 17, 1);
|
||||||
@ -85,6 +91,11 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (4, 5, 4);
|
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (4, 5, 4);
|
||||||
INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 21, 200, 8, 1);
|
INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 21, 200, 8, 1);
|
||||||
INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 22, 200, 8, 1);
|
INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (4, 22, 200, 8, 1);
|
||||||
|
INSERT INTO recipes_pos (recipe_id, product_id, amount) VALUES (5, 2, 1);
|
||||||
|
INSERT INTO recipes_pos (recipe_id, product_id, amount, qu_id, only_check_single_unit_in_stock) VALUES (5, 23, 200, 11, 1);
|
||||||
|
|
||||||
|
INSERt INTO recipes_nestings(recipe_id, includes_recipe_id) VALUES (6, 4);
|
||||||
|
INSERt INTO recipes_nestings(recipe_id, includes_recipe_id) VALUES (6, 5);
|
||||||
|
|
||||||
INSERT INTO chores (name, period_type, period_days) VALUES ('{$localizationService->Localize('Changed towels in the bathroom')}', 'manually', 5); --1
|
INSERT INTO chores (name, period_type, period_days) VALUES ('{$localizationService->Localize('Changed towels in the bathroom')}', 'manually', 5); --1
|
||||||
INSERT INTO chores (name, period_type, period_days) VALUES ('{$localizationService->Localize('Cleaned the kitchen floor')}', 'dynamic-regular', 7); --2
|
INSERT INTO chores (name, period_type, period_days) VALUES ('{$localizationService->Localize('Cleaned the kitchen floor')}', 'dynamic-regular', 7); --2
|
||||||
@ -184,6 +195,8 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
$stockService->AddProduct(21, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-10 days')), $this->RandomPrice());
|
||||||
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
$stockService->AddProduct(22, 1, date('Y-m-d', strtotime('+200 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-20 days')), $this->RandomPrice());
|
||||||
|
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-40 days')), $this->RandomPrice());
|
||||||
|
$stockService->AddProduct(23, 1, date('Y-m-d', strtotime('+2 days')), StockService::TRANSACTION_TYPE_PURCHASE, date('Y-m-d', strtotime('-50 days')), $this->RandomPrice());
|
||||||
$stockService->AddMissingProductsToShoppingList();
|
$stockService->AddMissingProductsToShoppingList();
|
||||||
|
|
||||||
$choresService = new ChoresService();
|
$choresService = new ChoresService();
|
||||||
|
@ -123,15 +123,15 @@
|
|||||||
@foreach($recipeNestings as $recipeNesting)
|
@foreach($recipeNestings as $recipeNesting)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="fit-content">
|
<td class="fit-content">
|
||||||
<a class="btn btn-sm btn-info recipe-include-edit-button" href="#" data-recipe-include-id="{{ $recipeNesting->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 }}">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-sm btn-danger recipe-inlcude-delete-button" href="#" data-recipe-include-id="{{ $recipeNesting->id }}" data-recipe-include-name="{{ FindObjectInArrayByPropertyValue($recipes, 'id', $recipeNesting->recipe_id)->name }}">
|
<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 }}">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ FindObjectInArrayByPropertyValue($recipes, 'id', $recipeNesting->recipe_id)->name }}
|
{{ FindObjectInArrayByPropertyValue($recipes, 'id', $recipeNesting->includes_recipe_id)->name }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -142,4 +142,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="recipe-include-editform-modal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content text-center">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 id="recipe-include-editform-title" class="modal-title w-100"></h4>
|
||||||
|
</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>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ $L('Cancel') }}</button>
|
||||||
|
<button id="save-recipe-include-button" data-dismiss="modal" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@stop
|
@stop
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
@extends('layout.default')
|
|
||||||
|
|
||||||
@if($mode == 'edit')
|
|
||||||
@section('title', $L('Edit included recipe'))
|
|
||||||
@else
|
|
||||||
@section('title', $L('Add included recipe'))
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@section('viewJsName', 'recipeincludeform')
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12 col-md-6 col-xl-5 pb-3">
|
|
||||||
<h1>@yield('title')</h1>
|
|
||||||
<h3 class="text-muted">{{ $L('Recipe') }} <strong>{{ $recipe->name }}</strong></h3>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
Grocy.EditMode = '{{ $mode }}';
|
|
||||||
Grocy.EditObjectParentId = {{ $recipe->id }};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@if($mode == 'edit')
|
|
||||||
<script>Grocy.EditObjectId = {{ $recipeInclude->id }};</script>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<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 $recipe)
|
|
||||||
<option @if($mode == 'edit' && $recipe->id == $recipeInclude->includes_recipe_id) selected="selected" @endif value="{{ $recipe->id }}">{{ $recipe->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
<div class="invalid-feedback">{{ $L('A recipe is required') }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button id="save-recipe-include-button" class="btn btn-success">{{ $L('Save') }}</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@stop
|
|
@ -62,6 +62,41 @@
|
|||||||
<i class="fas fa-expand-arrows-alt"></i>
|
<i class="fas fa-expand-arrows-alt"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Subrecipes first -->
|
||||||
|
@foreach($selectedRecipeSubRecipes as $selectedRecipeSubRecipe)
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="mb-0">{{ $selectedRecipeSubRecipe->name }}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@php $selectedRecipeSubRecipePositionsFiltered = FindAllObjectsInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_id', $selectedRecipeSubRecipe->id); @endphp
|
||||||
|
@if(count($selectedRecipeSubRecipePositionsFiltered) > 0)
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="mb-0">{{ $L('Ingredients') }}</h5>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
@foreach($selectedRecipeSubRecipePositionsFiltered as $selectedRecipePosition)
|
||||||
|
<li class="list-group-item">
|
||||||
|
{{ $selectedRecipePosition->amount }} {{ 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', $selectedRecipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list) }} @endif</span>
|
||||||
|
|
||||||
|
@if(!empty($selectedRecipePosition->note))
|
||||||
|
<div class="text-muted">{{ $selectedRecipePosition->note }}</div>
|
||||||
|
@endif
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
@endif
|
||||||
|
@if(!empty($selectedRecipeSubRecipe->description))
|
||||||
|
<div class="card-body">
|
||||||
|
<h5>{{ $L('Preparation') }}</h5>
|
||||||
|
{!! $selectedRecipeSubRecipe->description !!}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<!-- Selected recipe -->
|
||||||
|
@if($selectedRecipePositions->count() > 0)
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="mb-0">{{ $L('Ingredients') }}</h5>
|
<h5 class="mb-0">{{ $L('Ingredients') }}</h5>
|
||||||
</div>
|
</div>
|
||||||
@ -77,10 +112,13 @@
|
|||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
|
@endif
|
||||||
|
@if(!empty($selectedRecipe->description))
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5>{{ $L('Preparation') }}</h5>
|
<h5>{{ $L('Preparation') }}</h5>
|
||||||
{!! $selectedRecipe->description !!}
|
{!! $selectedRecipe->description !!}
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user