diff --git a/changelog/67_UNRELEASED_xxxx-xx-xx.md b/changelog/67_UNRELEASED_xxxx-xx-xx.md index 45cccde3..f96124d6 100644 --- a/changelog/67_UNRELEASED_xxxx-xx-xx.md +++ b/changelog/67_UNRELEASED_xxxx-xx-xx.md @@ -25,7 +25,8 @@ ### Chores -- xxx +- The `Daily` period type has been changed to be schedule the chore at the _same time_ each `n` days + - This period type scheduled chores `n` days _after the last execution_ before, which is also possible by using the `Hourly` period type and a corresponding period interval; all existing `Daily` schedules will be converted to that on migration ### Calendar diff --git a/localization/strings.pot b/localization/strings.pot index 8d02bc23..f90e7b8e 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -1256,8 +1256,8 @@ msgstr "" msgid "Assignment type" msgstr "" -msgid "This means the next execution of this chore is scheduled %s day after the last execution" -msgid_plural "This means the next execution of this chore is scheduled %s days after the last execution" +msgid "This means the next execution of this chore is scheduled at the same time (based on the start date) every day" +msgid_plural "This means the next execution of this chore is scheduled at the same time (based on the start date) every %s days" msgstr[0] "" msgstr[1] "" diff --git a/migrations/0169.sql b/migrations/0169.sql new file mode 100644 index 00000000..72a11886 --- /dev/null +++ b/migrations/0169.sql @@ -0,0 +1,77 @@ +UPDATE chores +SET period_type = 'hourly', +period_interval = IFNULL(period_interval, 1) * 24 +WHERE period_type = 'daily'; + +DROP VIEW chores_current; +CREATE VIEW chores_current +AS +SELECT + x.chore_id AS id, -- Dummy, LessQL needs an id column + x.chore_id, + x.chore_name, + x.last_tracked_time, + CASE WHEN x.rollover = 1 AND DATETIME('now', 'localtime') > x.next_estimated_execution_time THEN + CASE WHEN IFNULL(x.track_date_only, 0) = 1 THEN + DATETIME(STRFTIME('%Y-%m-%d', DATETIME('now', 'localtime')) || ' 23:59:59') + ELSE + DATETIME(STRFTIME('%Y-%m-%d', DATETIME('now', 'localtime')) || ' ' || STRFTIME('%H:%M:%S', x.next_estimated_execution_time)) + END + ELSE + CASE WHEN IFNULL(x.track_date_only, 0) = 1 THEN + DATETIME(STRFTIME('%Y-%m-%d', x.next_estimated_execution_time) || ' 23:59:59') + ELSE + x.next_estimated_execution_time + END + END AS next_estimated_execution_time, + x.track_date_only, + x.next_execution_assigned_to_user_id +FROM ( + +SELECT + h.id AS chore_id, + h.name AS chore_name, + MAX(l.tracked_time) AS last_tracked_time, + CASE WHEN MAX(l.tracked_time) IS NULL THEN + h.start_date + ELSE + CASE h.period_type + WHEN 'manually' THEN '2999-12-31 23:59:59' + WHEN 'hourly' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' hour') + WHEN 'daily' THEN DATETIME(SUBSTR(CAST(DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' days') AS TEXT), 1, 11) || SUBSTR(CAST(h.start_date AS TEXT), -8)) + WHEN 'weekly' THEN ( + SELECT next + FROM ( + SELECT 'sunday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 0') AS next + UNION + SELECT 'monday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 1') AS next + UNION + SELECT 'tuesday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 2') AS next + UNION + SELECT 'wednesday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 3') AS next + UNION + SELECT 'thursday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 4') AS next + UNION + SELECT 'friday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 5') AS next + UNION + SELECT 'saturday' AS day, DATETIME((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 6') AS next + ) + WHERE INSTR(period_config, day) > 0 + ORDER BY next + LIMIT 1 + ) + WHEN 'monthly' THEN DATETIME(MAX(l.tracked_time), 'start of month', '+' || CAST(h.period_interval AS TEXT) || ' month', '+' || CAST(h.period_days - 1 AS TEXT) || ' day') + WHEN 'yearly' THEN DATETIME(SUBSTR(CAST(DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' years') AS TEXT), 1, 4) || SUBSTR(CAST(h.start_date AS TEXT), 5, 6) || SUBSTR(CAST(DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' years') AS TEXT), -9)) + WHEN 'adaptive' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(IFNULL((SELECT average_frequency_hours FROM chores_execution_average_frequency WHERE chore_id = h.id), 0) AS TEXT) || ' hour') + END + 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 +WHERE h.active = 1 +GROUP BY h.id, h.name, h.period_days +) x; diff --git a/public/viewjs/choreform.js b/public/viewjs/choreform.js index 66d45874..ec8fe1da 100644 --- a/public/viewjs/choreform.js +++ b/public/viewjs/choreform.js @@ -158,7 +158,7 @@ $('.input-group-chore-period-type').on('change keyup', function(e) } else if (periodType === 'daily') { - $('#chore-schedule-info').text(__n(periodInterval, "This means the next execution of this chore is scheduled %s day after the last execution", "This means the next execution of this chore is scheduled %s days after the last execution")); + $('#chore-schedule-info').text(__n(periodInterval, "This means the next execution of this chore is scheduled at the same time (based on the start date) every day", "This means the next execution of this chore is scheduled at the same time (based on the start date) every %s days")); } else if (periodType === 'weekly') { diff --git a/views/choreform.blade.php b/views/choreform.blade.php index 56b2f8cb..c97ea1fc 100644 --- a/views/choreform.blade.php +++ b/views/choreform.blade.php @@ -171,7 +171,7 @@ $value = date('Y-m-d H:i:s'); if ($mode == 'edit') { - $value = date('Y-m-d', strtotime($chore->start_date)); + $value = date('Y-m-d H:i:s', strtotime($chore->start_date)); } @endphp @include('components.datetimepicker', array(