From 903ebc7d541832b058dbfdceed0437514fe02193 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Mon, 4 Nov 2019 19:17:39 +0100 Subject: [PATCH] Only consider stock amount at the given location on consume, if supplied --- controllers/StockApiController.php | 8 +++++++- grocy.openapi.json | 10 ++++++++++ services/StockService.php | 21 +++++++++++++++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index b3ee9b0d..39a4f2a7 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -201,13 +201,19 @@ class StockApiController extends BaseApiController $specificStockEntryId = $requestBody['stock_entry_id']; } + $locationId = null; + if (array_key_exists('location_id', $requestBody) && !empty($requestBody['location_id']) && is_numeric($requestBody['location_id'])) + { + $locationId = $requestBody['location_id']; + } + $recipeId = null; if (array_key_exists('recipe_id', $requestBody) && is_numeric($requestBody['recipe_id'])) { $recipeId = $requestBody['recipe_id']; } - $bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId, $recipeId); + $bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId, $recipeId, $locationId); return $this->ApiResponse($this->Database->stock_log($bookingId)); } catch (\Exception $ex) diff --git a/grocy.openapi.json b/grocy.openapi.json index 0a96f7d9..1e44a202 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -1385,6 +1385,11 @@ "type": "number", "format": "integer", "description": "A valid recipe id for which this product was used (for statistical purposes only)" + }, + "location_id": { + "type": "number", + "format": "integer", + "description": "A valid location id (if supplied, only stock at the given location is considered, if ommitted, stock of any location is considered)" } }, "example": { @@ -1802,6 +1807,11 @@ "type": "number", "format": "integer", "description": "A valid recipe id for which this product was used (for statistical purposes only)" + }, + "location_id": { + "type": "number", + "format": "integer", + "description": "A valid location id (if supplied, only stock at the given location is considered, if ommitted, stock of any location is considered)" } }, "example": { diff --git a/services/StockService.php b/services/StockService.php index bf18ad4f..714ead6c 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -264,13 +264,18 @@ class StockService extends BaseService } } - public function ConsumeProduct(int $productId, float $amount, bool $spoiled, $transactionType, $specificStockEntryId = 'default', $recipeId = null) + public function ConsumeProduct(int $productId, float $amount, bool $spoiled, $transactionType, $specificStockEntryId = 'default', $recipeId = null, $locationId = null) { if (!$this->ProductExists($productId)) { throw new \Exception('Product does not exist'); } + if ($locationId !== null & !$this->LocationExists($locationId)) + { + throw new \Exception('Location does not exist'); + } + // Tare weight handling // The given amount is the new total amount including the container weight (gross) // The amount to be posted needs to be the absolute value of the given amount - stock amount - tare weight @@ -287,12 +292,20 @@ class StockService extends BaseService if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION) { - $productStockAmount = $this->Database->stock()->where('product_id', $productId)->sum('amount'); - $potentialStockEntries = $this->GetProductStockEntries($productId); + if ($locationId === null) // Consume from any location + { + $productStockAmount = $this->Database->stock()->where('product_id', $productId)->sum('amount'); + $potentialStockEntries = $this->GetProductStockEntries($productId); + } + else // Consume only from the supplied location + { + $productStockAmount = $this->Database->stock()->where('product_id = :1 AND location_id = :2', $productId, $locationId)->sum('amount'); + $potentialStockEntries = $this->GetProductStockEntriesForLocation($productId, $locationId); + } if ($amount > $productStockAmount) { - throw new \Exception('Amount to be consumed cannot be > current stock amount'); + throw new \Exception('Amount to be consumed cannot be > current stock amount (if supplied, at the desired location)'); } if ($specificStockEntryId !== 'default')