Allow accumulating min. stock amounts on parent product level (closes #384)

This commit is contained in:
Bernd Bestel 2019-09-26 10:36:49 +02:00
parent 75f8ecfad2
commit 828ab8eba0
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
4 changed files with 150 additions and 1 deletions

View File

@ -1,4 +1,5 @@
- Fixed that barcode lookups now compare the whole barcode, not parts of it (e. g. when you have two products with the barcodes "$1" and "$10" and scan "$1" maybe the product of "$10" was found till now)
- It's now possible to accumulate min. stock amounts on parent product level (new option per product, means the sub product will never be "missing" then, only the parent product)
- It's now possible to display a recipe directly from the meal plan (new "eye button") (thanks @kriddles)
- Improved the responsiveness of the meal plan and calendar page by automatically switching to a day calendar view on smaller screens (thanks for the idea @kriddles)
- The calendar now also contains all planned recipes from the meal plan on the corresponding day

View File

@ -1519,3 +1519,9 @@ msgstr ""
msgid "Display recipe"
msgstr ""
msgid "Accumulate sub products min. stock amount"
msgstr ""
msgid "If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be \"missing\", only this product"
msgstr ""

131
migrations/0092.sql Normal file
View File

@ -0,0 +1,131 @@
ALTER TABLE products
ADD cumulate_min_stock_amount_of_subproducts TINYINT DEFAULT 0;
CREATE VIEW products_view
AS
SELECT *, CASE WHEN (SELECT 1 FROM products WHERE parent_product_id = p.id) NOTNULL THEN 1 ELSE 0 END AS has_sub_products
FROM products p;
DROP VIEW stock_missing_products;
CREATE VIEW stock_missing_products
AS
-- Products which are not sub products and not with "cumulate_min_stock_amount_of_subproducts"
SELECT
p.id,
MAX(p.name) AS name,
p.min_stock_amount - IFNULL(SUM(s.amount), 0) AS amount_missing,
CASE WHEN IFNULL(SUM(s.amount), 0) > 0 THEN 1 ELSE 0 END AS is_partly_in_stock
FROM products_view p
LEFT JOIN stock_current s
ON p.id = s.product_id
WHERE p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 0
AND p.parent_product_id IS NULL
GROUP BY p.id
HAVING IFNULL(SUM(s.amount), 0) < p.min_stock_amount
UNION
-- Products which have sub products and with "cumulate_min_stock_amount_of_subproducts"
SELECT
p.id,
MAX(p.name) AS name,
SUM(sub_p.min_stock_amount) - IFNULL(SUM(s.amount), 0) AS amount_missing,
CASE WHEN IFNULL(SUM(s.amount), 0) > 0 THEN 1 ELSE 0 END AS is_partly_in_stock
FROM products_view p
JOIN products_resolved pr
ON p.id = pr.parent_product_id
JOIN products sub_p
ON pr.sub_product_id = sub_p.id
LEFT JOIN stock_current s
ON pr.sub_product_id = s.product_id
WHERE sub_p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 1
AND p.has_sub_products IS NOT NULL
GROUP BY p.id
HAVING IFNULL(SUM(s.amount), 0) < SUM(sub_p.min_stock_amount)
UNION
-- Sub products where the parent product has not "cumulate_min_stock_amount_of_subproducts"
SELECT
sub_p.id,
MAX(sub_p.name) AS name,
SUM(sub_p.min_stock_amount) - IFNULL(SUM(s.amount), 0) AS amount_missing,
CASE WHEN IFNULL(SUM(s.amount), 0) > 0 THEN 1 ELSE 0 END AS is_partly_in_stock
FROM products_view p
JOIN products_resolved pr
ON p.id = pr.parent_product_id
JOIN products sub_p
ON pr.sub_product_id = sub_p.id
LEFT JOIN stock_current s
ON pr.sub_product_id = s.product_id
WHERE sub_p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 0
AND sub_p.parent_product_id IS NOT NULL
GROUP BY sub_p.id
HAVING IFNULL(SUM(s.amount), 0) < sub_p.min_stock_amount;
DROP VIEW stock_missing_products_including_opened;
CREATE VIEW stock_missing_products_including_opened
AS
/* This is basically the same view as stock_missing_products, but the column amount_missing includes opened amounts */
-- Products which are not sub products and not with "cumulate_min_stock_amount_of_subproducts"
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_view p
LEFT JOIN stock_current s
ON p.id = s.product_id
WHERE p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 0
AND p.parent_product_id IS NULL
GROUP BY p.id
HAVING IFNULL(SUM(s.amount), 0) < p.min_stock_amount
UNION
-- Products which have sub products and with "cumulate_min_stock_amount_of_subproducts"
SELECT
p.id,
MAX(p.name) AS name,
SUM(sub_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_view p
JOIN products_resolved pr
ON p.id = pr.parent_product_id
JOIN products sub_p
ON pr.sub_product_id = sub_p.id
LEFT JOIN stock_current s
ON pr.sub_product_id = s.product_id
WHERE sub_p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 1
AND p.has_sub_products IS NOT NULL
GROUP BY p.id
HAVING IFNULL(SUM(s.amount), 0) < SUM(sub_p.min_stock_amount)
UNION
-- Sub products where the parent product has not "cumulate_min_stock_amount_of_subproducts"
SELECT
sub_p.id,
MAX(sub_p.name) AS name,
SUM(sub_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_view p
JOIN products_resolved pr
ON p.id = pr.parent_product_id
JOIN products sub_p
ON pr.sub_product_id = sub_p.id
LEFT JOIN stock_current s
ON pr.sub_product_id = s.product_id
WHERE sub_p.min_stock_amount != 0
AND p.cumulate_min_stock_amount_of_subproducts = 0
AND sub_p.parent_product_id IS NOT NULL
GROUP BY sub_p.id
HAVING IFNULL(SUM(s.amount), 0) < sub_p.min_stock_amount;

View File

@ -94,9 +94,20 @@
'label' => 'Minimum stock amount',
'min' => 0,
'value' => $value,
'invalidFeedback' => $__t('The amount cannot be lower than %s', '0')
'invalidFeedback' => $__t('The amount cannot be lower than %s', '0'),
'additionalGroupCssClasses' => 'mb-1'
))
<div class="form-group">
<div class="form-check">
<input type="hidden" name="cumulate_min_stock_amount_of_subproducts" value="0">
<input @if($mode == 'edit' && $product->cumulate_min_stock_amount_of_subproducts == 1) checked @endif class="form-check-input" type="checkbox" id="cumulate_min_stock_amount_of_subproducts" name="cumulate_min_stock_amount_of_subproducts" value="1">
<label class="form-check-label" for="cumulate_min_stock_amount_of_subproducts">{{ $__t('Accumulate sub products min. stock amount') }}
<span class="text-muted small">{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be "missing", only this product') }}</span>
</label>
</div>
</div>
@php if($mode == 'edit') { $value = $product->default_best_before_days; } else { $value = 0; } @endphp
@include('components.numberpicker', array(
'id' => 'default_best_before_days',