diff --git a/changelog/60_UNRELEASED_2020-xx-xx.md b/changelog/60_UNRELEASED_2020-xx-xx.md index e3bfc992..ec86bcb9 100644 --- a/changelog/60_UNRELEASED_2020-xx-xx.md +++ b/changelog/60_UNRELEASED_2020-xx-xx.md @@ -199,6 +199,7 @@ - New endpoints GET/POST/PUT `/users/{userId}/permissions` for the new user permissions feature mentioned above - The stock journal (entity `stock_log`) is now also available via the endpoint `/objects/{entity}` (=> `/objects/stock_log`) - Performance improvements of the `/stock/products/*` endpoints (thanks @fipwmaqzufheoxq92ebc) +- The endpoint `/stock/products/{productId}/locations` now also has an optional query parameter `include_sub_products` to optionally also return locations of sub products of the given product - Fixed that the endpoint `/objects/{entity}/{objectId}` always returned successfully, even when the given object not exists (now returns `404` when the object is not found) (thanks @fipwmaqzufheoxq92ebc) - Fixed that the endpoint `/stock/volatile` didn't include products which expire today (thanks @fipwmaqzufheoxq92ebc) - Fixed that the endpoint `/objects/{entity}` did not include Userfields for Userentities (so the effective endpoint `/objects/userobjects`) diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index 7b1608d6..4ac52728 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -578,7 +578,6 @@ class StockApiController extends BaseApiController public function ProductStockEntries(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { $allowSubproductSubstitution = false; - if (isset($request->getQueryParams()['include_sub_products']) && filter_var($request->getQueryParams()['include_sub_products'], FILTER_VALIDATE_BOOLEAN)) { $allowSubproductSubstitution = true; @@ -589,7 +588,13 @@ class StockApiController extends BaseApiController public function ProductStockLocations(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { - return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockLocations($args['productId']), $request->getQueryParams()); + $allowSubproductSubstitution = false; + if (isset($request->getQueryParams()['include_sub_products']) && filter_var($request->getQueryParams()['include_sub_products'], FILTER_VALIDATE_BOOLEAN)) + { + $allowSubproductSubstitution = true; + } + + return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockLocations($args['productId'], $allowSubproductSubstitution), $request->getQueryParams()); } public function RemoveProductFromShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) diff --git a/grocy.openapi.json b/grocy.openapi.json index 53f97c4c..205a498a 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -1518,6 +1518,15 @@ "type": "integer" } }, + { + "in": "query", + "name": "include_sub_products", + "required": false, + "description": "If sub product locations should be included (if the given product is a parent product and in addition to the ones of the given product)", + "schema": { + "type": "boolean" + } + }, { "$ref": "#/components/parameters/query" }, diff --git a/services/StockService.php b/services/StockService.php index b400da0d..923f853d 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -662,27 +662,27 @@ class StockService extends BaseService public function GetProductStockEntries($productId, $excludeOpened = false, $allowSubproductSubstitution = false, $ordered = true) { - // In order of next use: - // First due first, then first in first out - $sqlWhereProductId = 'product_id = ' . $productId; - if ($allowSubproductSubstitution) { $sqlWhereProductId = 'product_id IN (SELECT sub_product_id FROM products_resolved WHERE parent_product_id = ' . $productId . ')'; } $sqlWhereAndOpen = 'AND open IN (0, 1)'; - if ($excludeOpened) { $sqlWhereAndOpen = 'AND open = 0'; } + $result = $this->getDatabase()->stock()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen); + + // In order of next use: + // First due first, then first in first out if ($ordered) { return $result->orderBy('best_before_date', 'ASC')->orderBy('purchased_date', 'ASC'); } + return $result; } @@ -692,9 +692,15 @@ class StockService extends BaseService return FindAllObjectsInArrayByPropertyValue($stockEntries, 'location_id', $locationId); } - public function GetProductStockLocations($productId) + public function GetProductStockLocations($productId, $allowSubproductSubstitution = false) { - return $this->getDatabase()->stock_current_locations()->where('product_id', $productId); + $sqlWhereProductId = 'product_id = ' . $productId; + if ($allowSubproductSubstitution) + { + $sqlWhereProductId = 'product_id IN (SELECT sub_product_id FROM products_resolved WHERE parent_product_id = ' . $productId . ')'; + } + + return $this->getDatabase()->stock_current_locations()->where($sqlWhereProductId); } public function GetStockEntry($entryId)