diff --git a/localization/de.php b/localization/de.php index 811c09c5..142acfe0 100644 --- a/localization/de.php +++ b/localization/de.php @@ -300,7 +300,9 @@ return array( 'Chore execution successfully undone' => 'Ausführung erfolgreich rückgängig gemacht', 'Undo' => 'Rückgängig machen', 'Booking successfully undone' => 'Buchung erfolgreich rückgängig gemacht', - 'Charge cycle successfully undone' => 'Ladezyklus erfolgreich rückgängig gemacht', + 'Charge cycle successfully undone' => 'Ladezyklus erfolgreich rückgängig gemacht', + 'This cannot be negative and must be an integral number' => 'Diese darf nicht negativ und muss eine ganze Zahl sein', + 'Disable stock fulfillment checking for this ingredient' => 'Bestandsprüfung für diese Zutat deaktivieren', //Constants - Chore types 'manually' => 'Manuell', diff --git a/migrations/0045.sql b/migrations/0045.sql new file mode 100644 index 00000000..1723f6c6 --- /dev/null +++ b/migrations/0045.sql @@ -0,0 +1,83 @@ +ALTER TABLE recipes_pos RENAME TO recipes_pos_old; + +CREATE TABLE recipes_pos ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + recipe_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + amount REAL NOT NULL DEFAULT 0, + note TEXT, + qu_id INTEGER, + only_check_single_unit_in_stock TINYINT NOT NULL DEFAULT 0, + ingredient_group TEXT, + not_check_stock_fulfillment TINYINT NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +); + +DROP TRIGGER recipes_pos_qu_id_default; +CREATE TRIGGER recipes_pos_qu_id_default AFTER INSERT ON recipes_pos +BEGIN + UPDATE recipes_pos + SET qu_id = (SELECT qu_id_stock FROM products where id = product_id) + WHERE qu_id IS NULL + AND id = NEW.id; +END; + +INSERT INTO recipes_pos + (recipe_id, product_id, amount, note, qu_id, only_check_single_unit_in_stock, ingredient_group, row_created_timestamp) +SELECT recipe_id, product_id, amount, note, qu_id, only_check_single_unit_in_stock, ingredient_group, row_created_timestamp +FROM recipes_pos_old; + +DROP TABLE recipes_pos_old; + +DROP VIEW recipes_fulfillment; +CREATE VIEW recipes_fulfillment +AS +SELECT + r.id AS recipe_id, + rp.id AS recipe_pos_id, + rp.product_id AS product_id, + rp.amount AS recipe_amount, + IFNULL(sc.amount, 0) AS stock_amount, + CASE WHEN IFNULL(sc.amount, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END THEN 1 ELSE 0 END AS need_fulfilled, + CASE WHEN IFNULL(sc.amount, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END < 0 THEN ABS(IFNULL(sc.amount, 0) - CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END) ELSE 0 END AS missing_amount, + IFNULL(sl.amount, 0) AS amount_on_shopping_list, + CASE WHEN IFNULL(sc.amount, 0) + IFNULL(sl.amount, 0) >= CASE WHEN rp.only_check_single_unit_in_stock = 1 THEN 1 ELSE IFNULL(rp.amount, 0) END THEN 1 ELSE 0 END AS need_fulfilled_with_shopping_list, + rp.qu_id +FROM recipes r +JOIN recipes_pos rp + ON r.id = rp.recipe_id +LEFT JOIN ( + SELECT product_id, SUM(amount + amount_autoadded) AS amount + FROM shopping_list + GROUP BY product_id) sl + ON rp.product_id = sl.product_id +LEFT JOIN stock_current sc + ON rp.product_id = sc.product_id +WHERE rp.not_check_stock_fulfillment = 0 + +UNION + +-- Just add all recipe positions which should not be checked against stock with fulfilled need + +SELECT + r.id AS recipe_id, + rp.id AS recipe_pos_id, + rp.product_id AS product_id, + rp.amount AS recipe_amount, + IFNULL(sc.amount, 0) AS stock_amount, + 1 AS need_fulfilled, + 0 AS missing_amount, + IFNULL(sl.amount, 0) AS amount_on_shopping_list, + 1 AS need_fulfilled_with_shopping_list, + rp.qu_id +FROM recipes r +JOIN recipes_pos rp + ON r.id = rp.recipe_id +LEFT JOIN ( + SELECT product_id, SUM(amount + amount_autoadded) AS amount + FROM shopping_list + GROUP BY product_id) sl + ON rp.product_id = sl.product_id +LEFT JOIN stock_current sc + ON rp.product_id = sc.product_id +WHERE rp.not_check_stock_fulfillment = 1; diff --git a/public/viewjs/recipeposform.js b/public/viewjs/recipeposform.js index 71a43db7..a8dd2458 100644 --- a/public/viewjs/recipeposform.js +++ b/public/viewjs/recipeposform.js @@ -105,10 +105,22 @@ $("#only_check_single_unit_in_stock").on("click", function() if (this.checked) { $("#qu_id").removeAttr("disabled"); + $("#amount").attr("min", "0.01"); + $("#amount").attr("step", "0.01"); + $("#amount").parent().find(".invalid-feedback").text(L("This cannot be negative")); + Grocy.FrontendHelpers.ValidateForm("recipe-pos-form"); } else { $("#qu_id").attr("disabled", ""); - Grocy.Components.ProductPicker.GetPicker().trigger("change"); + $("#amount").attr("min", "0"); + $("#amount").attr("step", "1"); + Grocy.Components.ProductPicker.GetPicker().trigger("change"); // Selects the default quantity unit of the selected product + $("#amount").parent().find(".invalid-feedback").text(L("This cannot be negative and must be an integral number")); + Grocy.FrontendHelpers.ValidateForm("recipe-pos-form"); } }); + +// Click twice to trigger on-click but not change the actual checked state +$("#only_check_single_unit_in_stock").click(); +$("#only_check_single_unit_in_stock").click(); diff --git a/views/recipeform.blade.php b/views/recipeform.blade.php index e7b8f8e9..1d616b1a 100644 --- a/views/recipeform.blade.php +++ b/views/recipeform.blade.php @@ -83,7 +83,7 @@ - + @@ -91,8 +91,8 @@ {{ FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id)->name }} - {{ $recipePosition->amount }} {{ Pluralize($recipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name_plural) }} - @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->amount_on_shopping_list) }} @endif + @if($recipePosition->amount == round($recipePosition->amount)){{ round($recipePosition->amount) }}@else{{ $recipePosition->amount }}@endif {{ Pluralize($recipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $recipePosition->qu_id)->name_plural) }} + @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $recipePosition->id)->amount_on_shopping_list)) }} @endif diff --git a/views/recipeposform.blade.php b/views/recipeposform.blade.php index 9dcb9119..c3d15656 100644 --- a/views/recipeposform.blade.php +++ b/views/recipeposform.blade.php @@ -42,7 +42,7 @@ 'label' => 'Amount', 'min' => 0, 'value' => $value, - 'invalidFeedback' => $L('This cannot be negative'), + 'invalidFeedback' => $L('This cannot be negative and must be an integral number'), 'additionalGroupCssClasses' => 'col-4' )) @@ -55,6 +55,7 @@
{{ $L('A quantity unit is required') }}
+
@@ -68,6 +69,12 @@
+
+ + not_check_stock_fulfillment == 1) checked @endif class="form-check-input" type="checkbox" id="not_check_stock_fulfillment" name="not_check_stock_fulfillment" value="1"> + +
+
diff --git a/views/recipes.blade.php b/views/recipes.blade.php index 44897f71..3dc4552c 100644 --- a/views/recipes.blade.php +++ b/views/recipes.blade.php @@ -81,8 +81,8 @@
{{ $selectedRecipePosition->ingredient_group }}
@endif
  • - {{ $selectedRecipePosition->amount }} {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} - @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list) }} @endif + @if($selectedRecipePosition->amount == round($selectedRecipePosition->amount)){{ round($selectedRecipePosition->amount) }}@else{{ $selectedRecipePosition->amount }}@endif {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} + @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', round($selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif @if(!empty($selectedRecipePosition->note))
    {!! nl2br($selectedRecipePosition->note) !!}
    @@ -112,8 +112,8 @@
    {{ $selectedRecipePosition->ingredient_group }}
    @endif
  • - {{ $selectedRecipePosition->amount }} {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} - @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list) }} @endif + @if($selectedRecipePosition->amount == round($selectedRecipePosition->amount)){{ round($selectedRecipePosition->amount) }}@else{{ $selectedRecipePosition->amount }}@endif {{ Pluralize($selectedRecipePosition->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} + @if(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $L('Enough in stock') }} @else {{ $L('Not enough in stock, #1 missing, #2 already on shopping list', round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount), round(FindObjectInArrayByPropertyValue($recipesFulfillment, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list)) }} @endif @if(!empty($selectedRecipePosition->note))
    {!! nl2br($selectedRecipePosition->note) !!}