Make it possible to copy meal plan days (closes #573)

This commit is contained in:
Bernd Bestel 2021-07-12 20:44:42 +02:00
parent 7b0bc9e472
commit 71cede74a3
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
5 changed files with 153 additions and 2 deletions

View File

@ -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

View File

@ -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 ""

View File

@ -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;

View File

@ -30,11 +30,12 @@ var calendar = $("#calendar").fullCalendar({
{
$(".fc-day-header").prepend('\
<div class="btn-group mr-2 my-1"> \
<button type="button" class="btn btn-outline-dark btn-xs add-recipe-button""><i class="fas fa-plus"></i></a></button> \
<button type="button" class="btn btn-outline-dark btn-xs add-recipe-button" data-toggle="tooltip" title="' + __t('Add recipe') + '"><i class="fas fa-plus"></i></a></button> \
<button type="button" class="btn btn-outline-dark btn-xs dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button> \
<div class="dropdown-menu"> \
<a class="dropdown-item add-note-button" href="#">' + __t('Add note') + '</a> \
<a class="dropdown-item add-product-button" href="#">' + __t('Add product') + '</a> \
<a class="dropdown-item copy-day-button" href="#">' + __t('Copy this day') + '</a> \
</div> \
</div>');
@ -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

View File

@ -14,7 +14,7 @@
rel="stylesheet">
<style>
.fc-event-container:not(:last-child) {
.fc-event-container {
border-bottom: 1px solid !important;
border-color: #d6d6d6 !important;
}
@ -181,4 +181,43 @@
</div>
</div>
</div>
<div class="modal fade"
id="copy-day-modal"
tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 id="copy-day-modal-title"
class="modal-title w-100"></h4>
</div>
<div class="modal-body">
<form id="copy-day-form"
novalidate>
@include('components.datetimepicker', array(
'id' => 'copy_to_date',
'label' => 'Day',
'format' => 'YYYY-MM-DD',
'initWithNow' => false,
'limitEndToNow' => false,
'limitStartToNow' => false,
'isRequired' => true,
'additionalCssClasses' => 'date-only-datetimepicker',
'invalidFeedback' => $__t('A date is required')
))
</form>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-copy-day-button"
data-dismiss="modal"
class="btn btn-primary">{{ $__t('Copy') }}</button>
</div>
</div>
</div>
</div>
@stop