feat: Added recipes/requirements route

- feat: Added requirements route to allow clients to access the requirements fulfilments of recipes
This commit is contained in:
grocy 2019-06-20 23:10:30 -05:00
parent a9c0539305
commit 7a51fb77b0
3 changed files with 3181 additions and 2687 deletions

View File

@ -40,4 +40,24 @@ class RecipesApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
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)
{
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@ -234,8 +234,22 @@
}
},
"responses": {
"204": {
"description": "The operation was successful"
"200": {
"description": "The operation was successful",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"created_object_id": {
"type": "number",
"format": "integer",
"description": "The id of the created object"
}
}
}
}
}
},
"400": {
"description": "The operation was not successful",
@ -438,6 +452,109 @@
}
}
},
"/userfields/{entity}/{objectId}": {
"get": {
"summary": "Returns all userfields with their values of the given object of the given entity",
"tags": [
"Generic entity interactions"
],
"parameters": [
{
"in": "path",
"name": "entity",
"required": true,
"description": "A valid entity name",
"schema": {
"$ref": "#/components/internalSchemas/ExposedEntity"
}
},
{
"in": "path",
"name": "objectId",
"required": true,
"description": "A valid object id of the given entity",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "An entity object",
"content": {
"application/json": {
"schema": {
"type": "object",
"description": "Just key/value pairs of userfields"
}
}
}
},
"400": {
"description": "The operation was not successful",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
},
"put": {
"summary": "Edits the given userfields of the given object of the given entity",
"tags": [
"Generic entity interactions"
],
"parameters": [
{
"in": "path",
"name": "entity",
"required": true,
"description": "A valid entity name",
"schema": {
"$ref": "#/components/internalSchemas/ExposedEntity"
}
},
{
"in": "path",
"name": "objectId",
"required": true,
"description": "A valid object id of the given entity",
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"description": "A valid entity object of the entity specified in parameter *entity*",
"required": true,
"content": {
"application/json": {
"schema": {
"description": "Just key/value pairs of userfields"
}
}
}
},
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/files/{group}/{fileName}": {
"get": {
"summary": "Serves the given file",
@ -1229,6 +1346,16 @@
"type": "string",
"format": "date",
"description": "The best before date which applies to added products"
},
"location_id": {
"type": "number",
"format": "integer",
"description": "If omitted, the default location of the product is used (only applies to added products)"
},
"price": {
"type": "number",
"format": "double",
"description": "If omitted, the last price of the product is used (only applies to added products)"
}
}
}
@ -1325,26 +1452,84 @@
},
"/stock/shoppinglist/add-missing-products": {
"post": {
"summary": "Adds currently missing products (below defined min. stock amount) to the shopping list",
"summary": "Adds currently missing products (below defined min. stock amount) to the given shopping list",
"tags": [
"Stock"
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"list_id": {
"type": "integer",
"description": "The shopping list to use, when omitted, the default shopping list (with id 1) is used"
}
},
"example": {
"list_id": 2
}
}
}
}
},
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing shopping list)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
},
"/stock/shoppinglist/clear": {
"post": {
"summary": "Removes all items from the shopping list",
"summary": "Removes all items from the given shopping list",
"tags": [
"Stock"
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"list_id": {
"type": "integer",
"description": "The shopping list id to clear, when omitted, the default shopping list (with id 1) is used"
}
},
"example": {
"list_id": 2
}
}
}
}
},
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing shopping list)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericErrorResponse"
}
}
}
}
}
}
@ -1478,6 +1663,84 @@
}
}
},
"/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/{recipeId}/consume": {
"post": {
"summary": "Consumes all products of the given recipe",
@ -1959,6 +2222,7 @@
"locations",
"quantity_units",
"shopping_list",
"shopping_lists",
"recipes",
"recipes_pos",
"recipes_nestings",
@ -1966,7 +2230,9 @@
"task_categories",
"product_groups",
"equipment",
"api_keys"
"api_keys",
"userfields",
"meal_plan"
]
},
"ExposedEntitiesPreventListing": {
@ -2007,10 +2273,23 @@
"qu_id_stock": {
"type": "integer"
},
"enable_tare_weight_handling": {
"type": "integer"
},
"not_check_stock_fulfillment_for_recipes": {
"type": "integer"
},
"product_group_id": {
"type": "integer"
},
"qu_factor_purchase_to_stock": {
"type": "number",
"format": "double"
},
"tare_weight": {
"type": "number",
"format": "double"
},
"barcode": {
"type": "string",
"description": "Can contain multiple barcodes separated by comma"
@ -2025,6 +2304,11 @@
"minimum": 0,
"default": 0
},
"default_best_before_days_after_open": {
"type": "integer",
"minimum": 0,
"default": 0
},
"picture_file_name": {
"type": "string"
},
@ -2035,6 +2319,26 @@
"type": "string",
"format": "date-time"
}
},
"example": {
"id": "1",
"name": "Cookies",
"description": null,
"location_id": "4",
"qu_id_purchase": "3",
"qu_id_stock": "3",
"qu_factor_purchase_to_stock": "1.0",
"barcode": "cok1",
"min_stock_amount": "8",
"default_best_before_days": "0",
"row_created_timestamp": "2019-05-02 20:12:26",
"product_group_id": "1",
"picture_file_name": "cookies.jpg",
"default_best_before_days_after_open": "0",
"allow_partial_units_in_stock": "0",
"enable_tare_weight_handling": "0",
"tare_weight": "0.0",
"not_check_stock_fulfillment_for_recipes": "0"
}
},
"QuantityUnit": {
@ -2055,7 +2359,18 @@
"row_created_timestamp": {
"type": "string",
"format": "date-time"
},
"plural_forms": {
"type": "string"
}
},
"example": {
"id": "2",
"name": "Piece",
"description": null,
"row_created_timestamp": "2019-05-02 20:12:25",
"name_plural": "Pieces",
"plural_forms": null
}
},
"Location": {
@ -2074,6 +2389,12 @@
"type": "string",
"format": "date-time"
}
},
"example": {
"id": "2",
"name": "0",
"description": null,
"row_created_timestamp": "2019-05-02 20:12:25"
}
},
"StockEntry": {
@ -2085,6 +2406,9 @@
"product_id": {
"type": "integer"
},
"location_id": {
"type": "integer"
},
"amount": {
"type": "double"
},
@ -2100,10 +2424,61 @@
"type": "string",
"description": "A unique id which references this stock entry during its lifetime"
},
"price": {
"type": "double"
},
"open": {
"type": "integer"
},
"opened_date": {
"type": "string",
"format": "date"
},
"row_created_timestamp": {
"type": "string",
"format": "date-time"
}
},
"example": {
"id": "77",
"product_id": "1",
"amount": "2",
"best_before_date": "2019-07-07",
"purchased_date": "2019-05-03",
"stock_id": "5ccc6b2421979",
"price": null,
"open": "0",
"opened_date": null,
"row_created_timestamp": "2019-05-03 18:24:04",
"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"
}
},
"ProductDetailsResponse": {
@ -2142,7 +2517,67 @@
},
"location": {
"$ref": "#/components/schemas/Location"
},
"average_shelf_life_days": {
"type": "number",
"format": "integer"
},
"spoil_rate_percent": {
"type": "number",
"format": "double"
}
},
"example": {
"product": {
"id": "1",
"name": "Cookies",
"description": null,
"location_id": "4",
"qu_id_purchase": "3",
"qu_id_stock": "3",
"qu_factor_purchase_to_stock": "1.0",
"barcode": "cok1",
"min_stock_amount": "8",
"default_best_before_days": "0",
"row_created_timestamp": "2019-05-02 20:12:26",
"product_group_id": "1",
"picture_file_name": "cookies.jpg",
"default_best_before_days_after_open": "0",
"allow_partial_units_in_stock": "0",
"enable_tare_weight_handling": "0",
"tare_weight": "0.0",
"not_check_stock_fulfillment_for_recipes": "0"
},
"last_purchased": null,
"last_used": null,
"stock_amount": "2",
"stock_amount_opened": null,
"quantity_unit_purchase": {
"id": "3",
"name": "Pack",
"description": null,
"row_created_timestamp": "2019-05-02 20:12:25",
"name_plural": "Packs",
"plural_forms": null
},
"quantity_unit_stock": {
"id": "3",
"name": "Pack",
"description": null,
"row_created_timestamp": "2019-05-02 20:12:25",
"name_plural": "Packs",
"plural_forms": null
},
"last_price": null,
"next_best_before_date": "2019-07-07",
"location": {
"id": "4",
"name": "Candy cupboard",
"description": null,
"row_created_timestamp": "2019-05-02 20:12:25"
},
"average_shelf_life_days": -1,
"spoil_rate_percent": 0
}
},
"ProductPriceHistory": {
@ -2209,6 +2644,27 @@
"type": "string",
"format": "date-time"
}
},
"example": {
"chore": {
"id": 0,
"name": "string",
"description": "string",
"period_type": "manually",
"period_days": 0,
"row_created_timestamp": "2019-05-04T11:31:04.563Z"
},
"last_tracked": "2019-05-04T11:31:04.563Z",
"track_count": 0,
"last_done_by": {
"id": 0,
"username": "string",
"first_name": "string",
"last_name": "string",
"display_name": "string",
"row_created_timestamp": "2019-05-04T11:31:04.564Z"
},
"next_estimated_execution_time": "2019-05-04T11:31:04.564Z"
}
},
"BatteryDetailsResponse": {
@ -2230,6 +2686,19 @@
"type": "string",
"format": "date-time"
}
},
"example": {
"battery": {
"id": "1",
"name": "Battery1",
"description": "Warranty ends 2023",
"used_in": "TV remote control",
"charge_interval_days": "0",
"row_created_timestamp": "2019-05-02 20:12:26"
},
"last_charged": "2019-03-13 18:12:28",
"charge_cycles_count": 4,
"next_estimated_charge_time": "2999-12-31 23:59:59"
}
},
"Session": {
@ -2418,6 +2887,9 @@
"period_days": {
"type": "integer"
},
"track_date_only": {
"type": "boolean"
},
"row_created_timestamp": {
"type": "string",
"format": "date-time"

View File

@ -156,6 +156,8 @@ $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->post('/recipes/{recipeId}/consume', '\Grocy\Controllers\RecipesApiController:ConsumeRecipe');
}