mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 01:32:38 +00:00
Implemented chore period intervals to have more flexible schedules (closes #312)
This commit is contained in:
parent
554ac104f8
commit
28b23fd313
@ -4,5 +4,8 @@
|
||||
### Recipe fixes
|
||||
- Fixed that recipes were displayed without ingredients if the total recipe count was > 100
|
||||
|
||||
### Chores improvements
|
||||
- Added a "period interval" option per chore to have more flexible schedules (possible for the daily/weekly/monthly schedules, means "schedule this chore only every x days/weeks/months" to have for example biweekly schedules)
|
||||
|
||||
### General & other improvements
|
||||
- New Input shorthands for date fields to increase/decrease the date by 1 month/year (shift + arrow keys, see the full list [here](https://github.com/grocy/grocy#input-shorthands-for-date-fields))
|
||||
|
@ -1546,3 +1546,15 @@ msgstr ""
|
||||
|
||||
msgid "Are you sure to remove the included recipe \"%s\"?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Period interval"
|
||||
msgstr ""
|
||||
|
||||
msgid "This means the next execution of this chore should only be scheduled every %s days"
|
||||
msgstr ""
|
||||
|
||||
msgid "This means the next execution of this chore should only be scheduled every %s weeks"
|
||||
msgstr ""
|
||||
|
||||
msgid "This means the next execution of this chore should only be scheduled every %s months"
|
||||
msgstr ""
|
||||
|
47
migrations/0094.sql
Normal file
47
migrations/0094.sql
Normal file
@ -0,0 +1,47 @@
|
||||
ALTER TABLE chores
|
||||
ADD period_interval INTEGER NOT NULL DEFAULT 1 CHECK(period_interval > 0);
|
||||
|
||||
DROP VIEW chores_current;
|
||||
CREATE VIEW chores_current
|
||||
AS
|
||||
SELECT
|
||||
x.chore_id,
|
||||
x.last_tracked_time,
|
||||
CASE WHEN x.rollover = 1 AND DATETIME('now', 'localtime') > x.next_estimated_execution_time THEN
|
||||
DATETIME(STRFTIME('%Y-%m-%d', DATETIME('now', 'localtime')) || ' ' || STRFTIME('%H:%M:%S', x.next_estimated_execution_time))
|
||||
ELSE
|
||||
x.next_estimated_execution_time
|
||||
END AS next_estimated_execution_time,
|
||||
x.track_date_only,
|
||||
x.next_execution_assigned_to_user_id
|
||||
FROM (
|
||||
|
||||
SELECT
|
||||
h.id AS chore_id,
|
||||
MAX(l.tracked_time) AS last_tracked_time,
|
||||
CASE h.period_type
|
||||
WHEN 'manually' THEN '2999-12-31 23:59:59'
|
||||
WHEN 'dynamic-regular' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_days AS TEXT) || ' day')
|
||||
WHEN 'daily' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+' || CAST(h.period_interval AS TEXT) || ' day')
|
||||
WHEN 'weekly' THEN
|
||||
CASE
|
||||
WHEN period_config LIKE '%sunday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 0')
|
||||
WHEN period_config LIKE '%monday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 1')
|
||||
WHEN period_config LIKE '%tuesday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 2')
|
||||
WHEN period_config LIKE '%wednesday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 3')
|
||||
WHEN period_config LIKE '%thursday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 4')
|
||||
WHEN period_config LIKE '%friday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 5')
|
||||
WHEN period_config LIKE '%saturday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 6')
|
||||
END
|
||||
WHEN 'monthly' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+' || CAST(h.period_interval AS TEXT) || ' month', 'start of month', '+' || CAST(h.period_days - 1 AS TEXT) || ' day')
|
||||
END AS next_estimated_execution_time,
|
||||
h.track_date_only,
|
||||
h.rollover,
|
||||
h.next_execution_assigned_to_user_id
|
||||
FROM chores h
|
||||
LEFT JOIN chores_log l
|
||||
ON h.id = l.chore_id
|
||||
AND l.undone = 0
|
||||
GROUP BY h.id, h.period_days
|
||||
|
||||
) x;
|
@ -118,6 +118,7 @@ $('.input-group-chore-period-type').on('change', function(e)
|
||||
{
|
||||
var periodType = $('#period_type').val();
|
||||
var periodDays = $('#period_days').val();
|
||||
var periodInterval = $('#period_interval').val();
|
||||
|
||||
$(".period-type-input").addClass("d-none");
|
||||
$(".period-type-" + periodType).removeClass("d-none");
|
||||
@ -139,11 +140,13 @@ $('.input-group-chore-period-type').on('change', function(e)
|
||||
else if (periodType === 'daily')
|
||||
{
|
||||
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled 1 day after the last execution'));
|
||||
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s days', periodInterval.toString()));
|
||||
}
|
||||
else if (periodType === 'weekly')
|
||||
{
|
||||
$('#chore-period-type-info').text(__t('This means the next execution of this chore is scheduled 1 day after the last execution, but only for the weekdays selected below'));
|
||||
$("#period_config").val($(".period-type-weekly input:checkbox:checked").map(function () { return this.value; }).get().join(","));
|
||||
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s weeks', periodInterval.toString()));
|
||||
}
|
||||
else if (periodType === 'monthly')
|
||||
{
|
||||
@ -152,6 +155,7 @@ $('.input-group-chore-period-type').on('change', function(e)
|
||||
$("#period_days").attr("min", "1");
|
||||
$("#period_days").attr("max", "31");
|
||||
$("#period_days").parent().find(".invalid-feedback").text(__t('The amount must be between %1$s and %2$s', "1", "31"));
|
||||
$('#chore-period-interval-info').text(__t('This means the next execution of this chore should only be scheduled every %s months', periodInterval.toString()));
|
||||
}
|
||||
|
||||
Grocy.FrontendHelpers.ValidateForm('chore-form');
|
||||
|
@ -86,6 +86,18 @@
|
||||
|
||||
<input type="hidden" id="period_config" name="period_config" value="@if($mode == 'edit'){{ $chore->period_config }}@endif">
|
||||
|
||||
@php if($mode == 'edit') { $value = $chore->period_interval; } else { $value = 1; } @endphp
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'period_interval',
|
||||
'label' => 'Period interval',
|
||||
'value' => $value,
|
||||
'min' => '1',
|
||||
'additionalCssClasses' => 'input-group-chore-period-type',
|
||||
'invalidFeedback' => $__t('This cannot be lower than %s', '1'),
|
||||
'additionalGroupCssClasses' => 'period-type-input period-type-daily period-type-weekly period-type-monthly',
|
||||
'hintId' => 'chore-period-interval-info'
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_CHORES_ASSIGNMENTS)
|
||||
<div class="form-group">
|
||||
<label for="assignment_type">{{ $__t('Assignment type') }} <span id="chore-assignment-type-info" class="small text-muted"></span></label>
|
||||
|
Loading…
x
Reference in New Issue
Block a user