From eb4a748da36a1b7d0a2a0683d32e514da0f232f3 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Sat, 19 Dec 2020 10:28:35 +0100 Subject: [PATCH] Consume opened products first (closes #1183) --- changelog/60_UNRELEASED_2020-xx-xx.md | 4 +++- controllers/StockApiController.php | 2 +- grocy.openapi.json | 2 +- localization/strings.pot | 4 ++-- services/StockService.php | 6 +++--- views/consume.blade.php | 2 +- views/recipes.blade.php | 2 +- views/transfer.blade.php | 2 +- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/changelog/60_UNRELEASED_2020-xx-xx.md b/changelog/60_UNRELEASED_2020-xx-xx.md index fe27139f..6ca5ec77 100644 --- a/changelog/60_UNRELEASED_2020-xx-xx.md +++ b/changelog/60_UNRELEASED_2020-xx-xx.md @@ -47,6 +47,8 @@ - This "Quick consume amount" can optionally also be used as the default on the consume page (new stock setting / top right corner settings menu) - Products can now be duplicated (new button on the products list page, all fields will be preset from the copied product, except the name) - When consuming or opening a parent product, which is currently not in stock, any in-stock sub product will now be consumed/opened (like already automatically done when consuming recipes) +- Opened stock entries get now consumed first by default when no specific stock entry is used/selected + - So the default consume rule is now "Opened first, then first due first, then first in first out" - Optimized/clarified what the total/unit price is on the purchase page (thanks @kriddles) - On the purchase page the amount field is now displayed above/before the due date for better `TAB` handling (thanks @kriddles) - Changed that when `FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING` is disabled, products now get internally a due date of "never overdue" (aka `2999-12-31`) instead of today (thanks @kriddles) @@ -94,7 +96,7 @@ ### Recipe improvements/fixes - It's now possible to print recipes (button next to the recipe title) (thanks @zsarnett) -- Changed that recipe costs are now based on the costs of the products picked by the default consume rule "First due first, then first in first out" (thanks @kriddles) +- Changed that recipe costs are now based on the costs of the products picked by the default consume rule ("Opened first, then first due first, then first in first out") (thanks @kriddles) - Recipe costs were based on the last purchase price per product before, so this now better reflects the current real costs - Improved the recipe add workflow (a recipe called "New recipe" is now not automatically created when starting to add a recipe) (thanks @zsarnett) - On the recipe page, the calories and costs per ingredient are now shown to get a better overview of how much each ingredient contributed diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index 0843a1fc..0475dee1 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -586,7 +586,7 @@ class StockApiController extends BaseApiController $allowSubproductSubstitution = true; } - return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockEntries($args['productId'], false, $allowSubproductSubstitution, false), $request->getQueryParams()); + return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockEntries($args['productId'], false, $allowSubproductSubstitution, true), $request->getQueryParams()); } public function ProductStockLocations(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) diff --git a/grocy.openapi.json b/grocy.openapi.json index 28f0da1d..5c6a6c15 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -1644,7 +1644,7 @@ }, "/stock/products/{productId}/entries": { "get": { - "summary": "Returns all stock entries of the given product in order of next use (first due first, then first in first out)", + "summary": "Returns all stock entries of the given product in order of next use (Opened first, then first due first, then first in first out)", "tags": [ "Stock" ], diff --git a/localization/strings.pot b/localization/strings.pot index 17da74b8..06314463 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -847,7 +847,7 @@ msgstr "" msgid "Use a specific stock item" msgstr "" -msgid "The first item in this list would be picked by the default rule which is \"First due first, then first in first out\"" +msgid "The first item in this list would be picked by the default rule which is \"Opened first, then first due first, then first in first out\"" msgstr "" msgid "Mark %1$s of %2$s as open" @@ -1699,7 +1699,7 @@ msgstr "" msgid "Not enough in stock (not included in costs), %s ingredient missing" msgstr "" -msgid "Based on the prices of the default consume rule which is \"First due first, then first in first out\"" +msgid "Based on the prices of the default consume rule which is \"Opened first, then first due first, then first in first out\"" msgstr "" msgid "Not enough in stock (not included in costs), %1$s missing, %2$s already on shopping list" diff --git a/services/StockService.php b/services/StockService.php index 8bcb6f2f..371ac5fe 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -691,10 +691,10 @@ class StockService extends BaseService $result = $this->getDatabase()->stock()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen); // In order of next use: - // First due first, then first in first out + // Opened first, then first due first, then first in first out if ($ordered) { - return $result->orderBy('best_before_date', 'ASC')->orderBy('purchased_date', 'ASC'); + return $result->orderBy('open', 'DESC')->orderBy('best_before_date', 'ASC')->orderBy('purchased_date', 'ASC'); } return $result; @@ -702,7 +702,7 @@ class StockService extends BaseService public function GetProductStockEntriesForLocation($productId, $locationId, $excludeOpened = false, $allowSubproductSubstitution = false) { - $stockEntries = $this->GetProductStockEntries($productId, $excludeOpened, $allowSubproductSubstitution); + $stockEntries = $this->GetProductStockEntries($productId, $excludeOpened, $allowSubproductSubstitution, true); return FindAllObjectsInArrayByPropertyValue($stockEntries, 'location_id', $locationId); } diff --git a/views/consume.blade.php b/views/consume.blade.php index b712993c..6a530a2e 100644 --- a/views/consume.blade.php +++ b/views/consume.blade.php @@ -118,7 +118,7 @@ for="use_specific_stock_entry">{{ $__t('Use a specific stock item') }}   + title="{{ $__t('The first item in this list would be picked by the default rule which is "Opened first, then first due first, then first in first out"') }}">