From a4d479d04707f4e5a4775e8c58026188b979a3be Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Thu, 19 Sep 2019 18:11:03 +0200 Subject: [PATCH] Also consider opened products for minimum stock amounts (optionally, but by default) (closes #353) --- changelog/52_UNRELEASED_2019-xx-xx.md | 1 + config-dist.php | 5 +++++ migrations/0086.sql | 13 +++++++++++++ services/StockService.php | 17 ++++++++++++++--- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 migrations/0086.sql diff --git a/changelog/52_UNRELEASED_2019-xx-xx.md b/changelog/52_UNRELEASED_2019-xx-xx.md index 8d2623d8..472be953 100644 --- a/changelog/52_UNRELEASED_2019-xx-xx.md +++ b/changelog/52_UNRELEASED_2019-xx-xx.md @@ -19,6 +19,7 @@ - On the quantity unit edit page default conversion can be defined for each unit - Products "inherit" the default conversion and additionally can have their own / override the default ones - It's now possible to print a "Location Content Sheet" with the current stock per location - new button at the top of the stock overview page (thought to hang it at the location, note used amounts on paper and track it in grocy later) +- New `config.php` setting `FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT` to configure if opened products should be considered for minimum stock amounts (defaults to `true`, so opened products will now be considered missing by default - please change this setting if you want the old behaviour) - The product description now can have formattings (HTML/WYSIWYG editor like for recipes) - "Factor purchase to stock quantity unit" (product option) can now also be a decimal number when "Allow partial units in stock" is enabled - New "Sub feature flags" in `config.php` to disable some sub-features (hide the corresponding UI elements) if you don't need them (all new feature flags default to `true`, so no changed behaviour when not configured) diff --git a/config-dist.php b/config-dist.php index b2e76a08..bb16506e 100644 --- a/config-dist.php +++ b/config-dist.php @@ -117,8 +117,13 @@ Setting('FEATURE_FLAG_BATTERIES', true); Setting('FEATURE_FLAG_EQUIPMENT', true); Setting('FEATURE_FLAG_CALENDAR', true); + # Sub feature flags Setting('FEATURE_FLAG_STOCK_PRICE_TRACKING', true); Setting('FEATURE_FLAG_STOCK_LOCATION_TRACKING', true); Setting('FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING', true); Setting('FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING', true); + + +# Feature settings +Setting('FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT', true); // When set to false, opened products will not be considered for minimum stock amounts diff --git a/migrations/0086.sql b/migrations/0086.sql new file mode 100644 index 00000000..09c2b47c --- /dev/null +++ b/migrations/0086.sql @@ -0,0 +1,13 @@ +CREATE VIEW stock_missing_products_including_opened +AS +SELECT + p.id, + MAX(p.name) AS name, + p.min_stock_amount - (IFNULL(SUM(s.amount), 0) - IFNULL(SUM(s.amount_opened), 0)) AS amount_missing, + CASE WHEN IFNULL(SUM(s.amount), 0) > 0 THEN 1 ELSE 0 END AS is_partly_in_stock +FROM products p +LEFT JOIN stock_current s + ON p.id = s.product_id +WHERE p.min_stock_amount != 0 +GROUP BY p.id +HAVING IFNULL(SUM(s.amount), 0) - IFNULL(SUM(s.amount_opened), 0) < p.min_stock_amount; diff --git a/services/StockService.php b/services/StockService.php index 494d395e..5587d06f 100644 --- a/services/StockService.php +++ b/services/StockService.php @@ -11,10 +11,16 @@ class StockService extends BaseService public function GetCurrentStock($includeNotInStockButMissingProducts = false) { - $sql = 'SELECT * FROM stock_current UNION SELECT id, 0, 0, null, 0, 0, 0 FROM stock_missing_products WHERE id NOT IN (SELECT product_id FROM stock_current)'; + $missingProductsView = 'stock_missing_products_including_opened'; + if (!GROCY_FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT) + { + $missingProductsView = 'stock_missing_products'; + } + + $sql = 'SELECT * FROM stock_current UNION SELECT id, 0, 0, null, 0, 0, 0 FROM ' . $missingProductsView . ' WHERE id NOT IN (SELECT product_id FROM stock_current)'; if ($includeNotInStockButMissingProducts) { - $sql = 'SELECT * FROM stock_current WHERE best_before_date IS NOT NULL UNION SELECT id, 0, 0, null, 0, 0, 0 FROM stock_missing_products WHERE id NOT IN (SELECT product_id FROM stock_current)'; + $sql = 'SELECT * FROM stock_current WHERE best_before_date IS NOT NULL UNION SELECT id, 0, 0, null, 0, 0, 0 FROM ' . $missingProductsView . ' WHERE id NOT IN (SELECT product_id FROM stock_current)'; } return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); @@ -40,7 +46,12 @@ class StockService extends BaseService public function GetMissingProducts() { - $sql = 'SELECT * FROM stock_missing_products'; + $sql = 'SELECT * FROM stock_missing_products_including_opened'; + if (!GROCY_FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT) + { + $sql = 'SELECT * FROM stock_missing_products'; + } + return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ); }