diff --git a/changelog/62_UNRELEASED_xxxx-xx-xx.md b/changelog/62_UNRELEASED_xxxx-xx-xx.md index bf4a5d78..5febf134 100644 --- a/changelog/62_UNRELEASED_xxxx-xx-xx.md +++ b/changelog/62_UNRELEASED_xxxx-xx-xx.md @@ -71,6 +71,7 @@ - Improved the meal plan page loading time (drastically when having a big history of meal plan entries) - Meal plan entries can now be visually marked as "done" (new button per entry) - This happens automatically on consuming a recipe/product from the meal plan page +- It's now possible to copy all entries of a day to another day (in the dropdown of the add button in the header of each day column) - Fixed that stock fulfillment checking used the desired servings of the recipe (those selected on the recipes page, not them from the meal plan entry) ### Chores improvements/fixes diff --git a/localization/strings.pot b/localization/strings.pot index e8bb3805..33305a54 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -2181,3 +2181,12 @@ msgstr "" msgid "This product shouldn't be frozen" msgstr "" + +msgid "Copy all meal plan entries of %s" +msgstr "" + +msgid "A date is required" +msgstr "" + +msgid "Day" +msgstr "" diff --git a/migrations/0139.sql b/migrations/0139.sql index 0aadadd4..c564fc39 100644 --- a/migrations/0139.sql +++ b/migrations/0139.sql @@ -87,6 +87,22 @@ BEGIN WHERE id = NEW.id AND type = 'recipe' AND recipe_id IS NOT NULL; + + -- Enforce "when null then empty" for certain columns + UPDATE meal_plan + SET recipe_id = NULL + WHERE id = NEW.id + AND IFNULL(recipe_id, '') = ''; + + UPDATE meal_plan + SET product_id = NULL + WHERE id = NEW.id + AND IFNULL(product_id, '') = ''; + + UPDATE meal_plan + SET product_qu_id = NULL + WHERE id = NEW.id + AND IFNULL(product_qu_id, '') = ''; END; DROP TRIGGER remove_internal_recipe; @@ -294,4 +310,20 @@ BEGIN WHERE id = NEW.id AND type = 'recipe' AND recipe_id IS NOT NULL; + + -- Enforce "when null then empty" for certain columns + UPDATE meal_plan + SET recipe_id = NULL + WHERE id = NEW.id + AND IFNULL(recipe_id, '') = ''; + + UPDATE meal_plan + SET product_id = NULL + WHERE id = NEW.id + AND IFNULL(product_id, '') = ''; + + UPDATE meal_plan + SET product_qu_id = NULL + WHERE id = NEW.id + AND IFNULL(product_qu_id, '') = ''; END; diff --git a/public/viewjs/mealplan.js b/public/viewjs/mealplan.js index 6a66e938..b8711859 100644 --- a/public/viewjs/mealplan.js +++ b/public/viewjs/mealplan.js @@ -30,11 +30,12 @@ var calendar = $("#calendar").fullCalendar({ { $(".fc-day-header").prepend('\
\ - \ + \ \ \
'); @@ -370,6 +371,18 @@ $(document).on("click", ".edit-meal-plan-entry-button", function(e) Grocy.MealPlanEntryEditObjectId = mealPlanEntry.id; }); +$(document).on("click", ".copy-day-button", function(e) +{ + var day = $(this).parent().parent().parent().data("date"); + + $("#copy-day-modal-title").text(__t("Copy all meal plan entries of %s", day.toString())); + $("#day").val(day.toString()); + Grocy.Components.DateTimePicker.Clear(); + $("#copy-day-modal").modal("show"); + Grocy.FrontendHelpers.ValidateForm("copy-day-form"); + Grocy.IsMealPlanEntryEditAction = false; +}); + $("#add-recipe-modal").on("shown.bs.modal", function(e) { Grocy.Components.RecipePicker.GetInputElement().focus(); @@ -385,6 +398,11 @@ $("#add-product-modal").on("shown.bs.modal", function(e) Grocy.Components.ProductPicker.GetInputElement().focus(); }) +$("#copy-day-modal").on("shown.bs.modal", function(e) +{ + Grocy.Components.DateTimePicker.GetInputElement().focus(); +}) + $(document).on("click", ".remove-recipe-button, .remove-note-button, .remove-product-button", function(e) { var mealPlanEntry = JSON.parse($(this).parents(".fc-h-event:first").attr("data-meal-plan-entry")); @@ -539,6 +557,58 @@ $('#save-add-product-button').on('click', function(e) } }); +var itemsToCopy = 0; +var itemsCopied = 0; +$('#save-copy-day-button').on('click', function(e) +{ + e.preventDefault(); + + if (document.getElementById("copy-day-form").checkValidity() === false) //There is at least one validation error + { + return false; + } + + var dayFrom = $("#day").val(); + var dayTo = Grocy.Components.DateTimePicker.GetValue(); + + Grocy.Api.Get('objects/meal_plan?query[]=day=' + dayFrom, + function(sourceMealPlanEntries) + { + itemsToCopy = sourceMealPlanEntries.length; + + sourceMealPlanEntries.forEach((item) => + { + item.day = dayTo; + item.done = 0; + delete item.id; + delete item.row_created_timestamp; + + Grocy.Api.Post("objects/meal_plan", item, + function(result) + { + itemsCopied++; + + if (itemsCopied == itemsToCopy) + { + window.location.reload(); + } + }, + function(xhr) + { + Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); + } + ); + }); + + //window.location.reload(); + }, + function(xhr) + { + console.error(xhr); + } + ); +}); + $('#add-recipe-form input').keydown(function(event) { if (event.keyCode === 13) //Enter diff --git a/views/mealplan.blade.php b/views/mealplan.blade.php index 27b87d8f..962c131d 100644 --- a/views/mealplan.blade.php +++ b/views/mealplan.blade.php @@ -14,7 +14,7 @@ rel="stylesheet">