diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index 1830f943..8e54aae2 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -31,6 +31,30 @@ class StockApiController extends BaseApiController } } + public function AddExpiredProductsToShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) + { + User::checkPermission($request, User::PERMISSION_SHOPPINGLIST_ITEMS_ADD); + + try + { + $requestBody = $request->getParsedBody(); + + $listId = 1; + + if (array_key_exists('list_id', $requestBody) && !empty($requestBody['list_id']) && is_numeric($requestBody['list_id'])) + { + $listId = intval($requestBody['list_id']); + } + + $this->getStockService()->AddExpiredProductsToShoppingList($listId); + return $this->EmptyApiResponse($response); + } + catch (\Exception $ex) + { + return $this->GenericErrorResponse($response, $ex->getMessage()); + } + } + public function AddProduct(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) { User::checkPermission($request, User::PERMISSION_STOCK_PURCHASE); diff --git a/grocy.openapi.json b/grocy.openapi.json index b569a82a..e95ca282 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -2356,6 +2356,48 @@ } } }, + "/stock/shoppinglist/add-expired-products": { + "post": { + "summary": "Adds expired products 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 given shopping list", diff --git a/localization/de/strings.po b/localization/de/strings.po index 40027e0c..c44db13c 100644 --- a/localization/de/strings.po +++ b/localization/de/strings.po @@ -1,10 +1,10 @@ -# +# # Translators: # Hagen Tasche , 2020 # Luca RHK , 2020 # Tobias Wolter , 2020 # Bernd Bestel , 2020 -# +# msgid "" msgstr "" "Project-Id-Version: \n" @@ -2035,3 +2035,6 @@ msgstr "Speichern & fortfahren" msgid "Save & return to recipes" msgstr "Speichern & zurück zu Rezepte" + +msgid "Add expired products" +msgstr "Abgelaufene Produkte hinzufügen" diff --git a/localization/strings.pot b/localization/strings.pot index ed3ccb92..18952083 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -1909,3 +1909,6 @@ msgstr "" msgid "Journal summary for this product" msgstr "" + +msgid "Add expired products" +msgstr "" diff --git a/public/index.php b/public/index.php index 12546063..8fb557f9 100644 --- a/public/index.php +++ b/public/index.php @@ -1,5 +1,4 @@ group('/api', function (RouteCollectorProxy $group) { if (GROCY_FEATURE_FLAG_SHOPPINGLIST) { $group->post('/stock/shoppinglist/add-missing-products', '\Grocy\Controllers\StockApiController:AddMissingProductsToShoppingList'); + $group->post('/stock/shoppinglist/add-expired-products', '\Grocy\Controllers\StockApiController:AddExpiredProductsToShoppingList'); $group->post('/stock/shoppinglist/clear', '\Grocy\Controllers\StockApiController:ClearShoppingList'); $group->post('/stock/shoppinglist/add-product', '\Grocy\Controllers\StockApiController:AddProductToShoppingList'); $group->post('/stock/shoppinglist/remove-product', '\Grocy\Controllers\StockApiController:RemoveProductFromShoppingList'); diff --git a/services/StockService.php b/services/StockService.php index 768c3e92..e8005b58 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -52,6 +52,33 @@ class StockService extends BaseService } } + public function AddExpiredProductsToShoppingList($listId = 1) + { + if (!$this->ShoppingListExists($listId)) + { + throw new \Exception('Shopping list does not exist'); + } + + $expiredProducts = $this->GetExpiredProducts(); + + foreach ($expiredProducts as $expiredProduct) + { + $product = $this->getDatabase()->products()->where('id', $expiredProduct->id)->fetch(); + + $alreadyExistingEntry = $this->getDatabase()->shopping_list()->where('product_id', $expiredProduct->id)->fetch(); + + if ( ! $alreadyExistingEntry) + { + $shoppinglistRow = $this->getDatabase()->shopping_list()->createRow([ + 'product_id' => $expiredProduct->id, + 'amount' => 1, + 'shopping_list_id' => $listId + ]); + $shoppinglistRow->save(); + } + } + } + public function AddProduct(int $productId, float $amount, $bestBeforeDate, $transactionType, $purchasedDate, $price, $quFactorPurchaseToStock, $locationId = null, $shoppingLocationId = null, &$transactionId = null) { if (!$this->ProductExists($productId)) @@ -479,6 +506,13 @@ class StockService extends BaseService return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); } + public function GetExpiredProducts() + { + $sql = 'SELECT products.* FROM stock JOIN products ON (stock.product_id = products.id) WHERE best_before_date < CURRENT_DATE'; + + return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); + } + public function GetProductDetails(int $productId) { if (!$this->ProductExists($productId)) diff --git a/views/shoppinglist.blade.php b/views/shoppinglist.blade.php index cb53234e..4b81e588 100644 --- a/views/shoppinglist.blade.php +++ b/views/shoppinglist.blade.php @@ -96,6 +96,11 @@ href="#"> {{ $__t('Add products that are below defined min. stock amount') }} + + {{ $__t('Add expired products') }} +