From 482a520062edb59a3d5a069904f4878d7d178466 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Sat, 6 Jul 2019 15:28:49 +0200 Subject: [PATCH] Slightly modified new recipe stock fulfillment API endpoints (references #289) --- changelog/50_2.4.3_2019-xx-xx.md | 1 + controllers/RecipesApiController.php | 41 +++--- grocy.openapi.json | 208 +++++++++++++-------------- routes.php | 4 +- 4 files changed, 128 insertions(+), 126 deletions(-) diff --git a/changelog/50_2.4.3_2019-xx-xx.md b/changelog/50_2.4.3_2019-xx-xx.md index 9afdb414..792d434b 100644 --- a/changelog/50_2.4.3_2019-xx-xx.md +++ b/changelog/50_2.4.3_2019-xx-xx.md @@ -2,3 +2,4 @@ - Fixed that "Track date only" chores were always tracked today, regardless of the given date - Fixed that the "week costs" were wrong after removing a meal plan entry - Fixed wrong recipes costs calculation with nested recipes when the base recipe servings are > 1 (also affected the meal plan when adding such a recipe there) +- Improved recipes API - added new endpoints to get stock fulfillment information (thanks @Aerex) diff --git a/controllers/RecipesApiController.php b/controllers/RecipesApiController.php index 819fad6b..3f3ee0cf 100644 --- a/controllers/RecipesApiController.php +++ b/controllers/RecipesApiController.php @@ -41,23 +41,28 @@ class RecipesApiController extends BaseApiController } } - public function GetRecipeRequirements(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) - { - try { - if(!$args['recipeId']){ - return $this->ApiResponse($this->RecipesService->GetRecipesResolved()); - } - $recipeResolved = FindObjectInArrayByPropertyValue($this->RecipesService->GetRecipesResolved(), 'recipe_id', $args['recipeId']); - if(!$recipeResolved) { - $errorMsg ='Recipe requirments do not exist for recipe_id ' . $args['recipe_id']; - $GenericError = $this->GenericErrorResponse($response, $errorMsg); - return $GenericError; - } - return $this->ApiResponse($recipeResolved); - } - catch (\Exception $ex) - { + public function GetRecipeFulfillment(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) + { + try + { + if(!isset($args['recipeId'])) + { + return $this->ApiResponse($this->RecipesService->GetRecipesResolved()); + } + + $recipeResolved = FindObjectInArrayByPropertyValue($this->RecipesService->GetRecipesResolved(), 'recipe_id', $args['recipeId']); + if(!$recipeResolved) + { + throw new \Exception('Recipe does not exist'); + } + else + { + return $this->ApiResponse($recipeResolved); + } + } + catch (\Exception $ex) + { return $this->GenericErrorResponse($response, $ex->getMessage()); - } - } + } + } } diff --git a/grocy.openapi.json b/grocy.openapi.json index c886bd34..292b64da 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -1663,6 +1663,47 @@ } } }, + "/recipes/{recipeId}/fulfillment": { + "get": { + "summary": "Get stock fulfillment information for the given recipe", + "tags": [ + "Recipes" + ], + "parameters": [ + { + "in": "path", + "name": "recipeId", + "required": true, + "description": "A valid recipe id", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "A RecipeFulfillmentResponse object", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecipeFulfillmentResponse" + } + } + } + }, + "400": { + "description": "The operation was not successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenericErrorResponse" + } + } + } + } + } + } + }, "/recipes/{recipeId}/consume": { "post": { "summary": "Consumes all products of the given recipe", @@ -1687,84 +1728,39 @@ } } }, - "/recipes/{recipeId}/requirements": { - "get": { - "summary": "Get requirements for recipe", - "tags": [ - "Recipes" - ], - "parameters": [ - { - "in": "path", - "name": "recipeId", - "required": true, - "description": "A valid recipe id", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "A requirements recipe object", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RecipeRequirements" - } - } - } - }, - "400": { - "description": "The operation was not successful", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenericErrorResponse" - } - } - } - } - } - } - }, - "/recipes/requirements": { - "get": { - "summary": "Get all requirements for recipes", - "tags": [ - "Recipes" - ], - "responses": { - "200": { - "description": "An array of requirements recipe objects", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/RecipeRequirements" - } - ] - } - } - } - } - }, - "400": { - "description": "The operation was not successful", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenericErrorResponse" - } - } - } - } - } - } - }, + "/recipes/fulfillment": { + "get": { + "summary": "Get stock fulfillment information for all recipe", + "tags": [ + "Recipes" + ], + "responses": { + "200": { + "description": "An array of RecipeFulfillmentResponse objects", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RecipeFulfillmentResponse" + } + } + } + } + }, + "400": { + "description": "The operation was not successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenericErrorResponse" + } + } + } + } + } + } + }, "/chores": { "get": { "summary": "Returns all chores incl. the next estimated execution time per chore", @@ -2453,34 +2449,34 @@ "location_id": "4" } }, - "RecipeRequirements": { - "type": "object", - "properties": { - "recipe_id": { - "type": "integer" - }, - "need_fulfilled": { - "type": "boolean" - }, - "need_fulfilled_with_shopping_list": { - "type": "boolean" - }, - "missing_products_count": { - "type": "integer" - }, - "costs": { - "type": "number", - "format": "double" - } - }, - "example": { - "recipe_id": "1", - "need_fulfilled": "0", - "need_fulfilled_with_shopping_list": "0", - "missing_products_count": "2", - "costs": "17.74" - } - }, + "RecipeFulfillmentResponse": { + "type": "object", + "properties": { + "recipe_id": { + "type": "integer" + }, + "need_fulfilled": { + "type": "boolean" + }, + "need_fulfilled_with_shopping_list": { + "type": "boolean" + }, + "missing_products_count": { + "type": "integer" + }, + "costs": { + "type": "number", + "format": "double" + } + }, + "example": { + "recipe_id": "1", + "need_fulfilled": "0", + "need_fulfilled_with_shopping_list": "0", + "missing_products_count": "2", + "costs": "17.74" + } + }, "ProductDetailsResponse": { "type": "object", "properties": { diff --git a/routes.php b/routes.php index 17fe9d49..38a24ab2 100644 --- a/routes.php +++ b/routes.php @@ -173,9 +173,9 @@ $app->group('/api', function() if (GROCY_FEATURE_FLAG_RECIPES) { $this->post('/recipes/{recipeId}/add-not-fulfilled-products-to-shoppinglist', '\Grocy\Controllers\RecipesApiController:AddNotFulfilledProductsToShoppingList'); - $this->get('/recipes/{recipeId}/requirements', '\Grocy\Controllers\RecipesApiController:GetRecipeRequirements'); - $this->get('/recipes/requirements', '\Grocy\Controllers\RecipesApiController:GetRecipeRequirements'); + $this->get('/recipes/{recipeId}/fulfillment', '\Grocy\Controllers\RecipesApiController:GetRecipeFulfillment'); $this->post('/recipes/{recipeId}/consume', '\Grocy\Controllers\RecipesApiController:ConsumeRecipe'); + $this->get('/recipes/fulfillment', '\Grocy\Controllers\RecipesApiController:GetRecipeFulfillment'); } // Chores