diff --git a/controllers/RecipesController.php b/controllers/RecipesController.php index 5457fac1..8f992492 100644 --- a/controllers/RecipesController.php +++ b/controllers/RecipesController.php @@ -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', [ 'recipes' => $recipes, 'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(), @@ -42,7 +45,9 @@ class RecipesController extends BaseController 'selectedRecipe' => $selectedRecipe, 'selectedRecipePositions' => $selectedRecipePositions, '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(), 'recipesFulfillment' => $this->RecipesService->GetRecipesFulfillment(), 'recipesSumFulfillment' => $this->RecipesService->GetRecipesSumFulfillment(), - 'recipes' => $this->Database->recipes(), + 'recipes' => $this->Database->recipes()->orderBy('name'), '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') - ]); - } - } } diff --git a/localization/de.php b/localization/de.php index aa44381f..2470808d 100644 --- a/localization/de.php +++ b/localization/de.php @@ -280,6 +280,10 @@ return array( 'No picture available' => 'Kein Bild vorhanden', 'Filter by product group' => 'Nach Produktgruppe filtern', '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 'manually' => 'Manuell', @@ -364,5 +368,13 @@ return array( 'Vegetables/Fruits' => 'Obst/Gemüse', 'Refrigerated products' => 'Kühlregal', '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' ); diff --git a/migrations/0043.sql b/migrations/0043.sql index 795ce707..14af620b 100644 --- a/migrations/0043.sql +++ b/migrations/0043.sql @@ -23,3 +23,18 @@ AS ( ) SELECT * 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; diff --git a/public/viewjs/recipeform.js b/public/viewjs/recipeform.js index 2e530176..66ea483b 100644 --- a/public/viewjs/recipeform.js +++ b/public/viewjs/recipeform.js @@ -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 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) { 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(), 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) { @@ -238,7 +244,11 @@ $("#recipe-include-add-button").on("click", function(e) Grocy.Api.Post('edit-object/recipes/' + Grocy.EditObjectId, $('#recipe-form').serializeJSON(), 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) { @@ -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({ minHeight: '300px', lang: L('summernote_locale') diff --git a/public/viewjs/recipeincludeform.js b/public/viewjs/recipeincludeform.js deleted file mode 100644 index 8146a3e6..00000000 --- a/public/viewjs/recipeincludeform.js +++ /dev/null @@ -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(); - } - } -}); diff --git a/routes.php b/routes.php index abe93f6d..3014f735 100644 --- a/routes.php +++ b/routes.php @@ -40,7 +40,6 @@ $app->group('', function() $this->get('/recipes', '\Grocy\Controllers\RecipesController:Overview'); $this->get('/recipe/{recipeId}', '\Grocy\Controllers\RecipesController:RecipeEditForm'); $this->get('/recipe/{recipeId}/pos/{recipePosId}', '\Grocy\Controllers\RecipesController:RecipePosEditForm'); - $this->get('/recipe/{recipeId}/included_recipe/{recipeIncludeId}', '\Grocy\Controllers\RecipesController:RecipeIncludeEditForm'); // Chore routes $this->get('/choresoverview', '\Grocy\Controllers\ChoresController:Overview'); diff --git a/services/DemoDataGeneratorService.php b/services/DemoDataGeneratorService.php index 15e5f703..6b494926 100644 --- a/services/DemoDataGeneratorService.php +++ b/services/DemoDataGeneratorService.php @@ -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('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('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 ('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('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) 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 (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('Sandwiches')}', '{$loremIpsumWithHtmlFormattings}'); --3 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, 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, 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) 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('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(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(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(); $choresService = new ChoresService(); diff --git a/views/recipeform.blade.php b/views/recipeform.blade.php index c7747244..a9751dae 100644 --- a/views/recipeform.blade.php +++ b/views/recipeform.blade.php @@ -123,15 +123,15 @@ @foreach($recipeNestings as $recipeNesting)