Added new hourly chore period type (closes #266)

This commit is contained in:
Bernd Bestel
2022-02-09 20:02:11 +01:00
parent c9a2041fae
commit 10d7d44825
8 changed files with 92 additions and 2 deletions

View File

@@ -52,6 +52,7 @@
- For all existing chores, the start date will be set to the first tracked execution time (or today, for chores which were never tracked) on migration - For all existing chores, the start date will be set to the first tracked execution time (or today, for chores which were never tracked) on migration
- The `Yearly` period type has been changed to be schedule the chore on the _same day_ each year - The `Yearly` period type has been changed to be schedule the chore on the _same day_ each year
- This period type scheduled chores 1 year _after the last execution_ before, which is also possible by using the `Daily` period type and a period interval of 365 days - all existing `Yearly` schedules will be converted to that on migration - This period type scheduled chores 1 year _after the last execution_ before, which is also possible by using the `Daily` period type and a period interval of 365 days - all existing `Yearly` schedules will be converted to that on migration
- Added a new `Hourly` period type (to schedule chores every `x` hours)
### Calendar ### Calendar

View File

@@ -29,3 +29,6 @@ msgstr ""
msgid "yearly" msgid "yearly"
msgstr "" msgstr ""
msgid "hourly"
msgstr ""

View File

@@ -30,3 +30,6 @@ msgstr "Monthly"
msgid "yearly" msgid "yearly"
msgstr "Yearly" msgstr "Yearly"
msgid "hourly"
msgstr "Hourly"

View File

@@ -1261,6 +1261,11 @@ msgid_plural "This means the next execution of this chore is scheduled %s days a
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "This means the next execution of this chore is scheduled %s hour after the last execution"
msgid_plural "This means the next execution of this chore is scheduled %s hours after the last execution"
msgstr[0] ""
msgstr[1] ""
msgid "This means the next execution of this chore is scheduled every week on the selected weekdays" msgid "This means the next execution of this chore is scheduled every week on the selected weekdays"
msgid_plural "This means the next execution of this chore is scheduled every %s weeks on the selected weekdays" msgid_plural "This means the next execution of this chore is scheduled every %s weeks on the selected weekdays"
msgstr[0] "" msgstr[0] ""

72
migrations/0166.sql Normal file
View File

@@ -0,0 +1,72 @@
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 'dynamic-regular' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_days AS TEXT) || ' day')
WHEN 'hourly' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' hour')
WHEN 'daily' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_interval AS TEXT) || ' day')
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))
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;

View File

@@ -159,6 +159,10 @@ $('.input-group-chore-period-type').on('change keyup', function(e)
$("#period_days").removeAttr("max"); $("#period_days").removeAttr("max");
$('#chore-schedule-info').text(__n(periodDays, "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(periodDays, "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"));
} }
else if (periodType === 'hourly')
{
$('#chore-schedule-info').text(__n(periodInterval, "This means the next execution of this chore is scheduled %s hour after the last execution", "This means the next execution of this chore is scheduled %s hours after the last execution"));
}
else if (periodType === 'daily') 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 %s day after the last execution", "This means the next execution of this chore is scheduled %s days after the last execution"));

View File

@@ -12,6 +12,8 @@ class ChoresService extends BaseService
const CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST = 'who-least-did-first'; const CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST = 'who-least-did-first';
const CHORE_PERIOD_TYPE_HOURLY = 'hourly';
const CHORE_PERIOD_TYPE_DAILY = 'daily'; const CHORE_PERIOD_TYPE_DAILY = 'daily';
const CHORE_PERIOD_TYPE_DYNAMIC_REGULAR = 'dynamic-regular'; const CHORE_PERIOD_TYPE_DYNAMIC_REGULAR = 'dynamic-regular';

View File

@@ -161,7 +161,7 @@
'value' => $value, 'value' => $value,
'min' => '1', 'min' => '1',
'additionalCssClasses' => 'input-group-chore-period-type', 'additionalCssClasses' => 'input-group-chore-period-type',
'additionalGroupCssClasses' => 'period-type-input period-type-daily period-type-weekly period-type-monthly period-type-yearly' 'additionalGroupCssClasses' => 'period-type-input period-type-hourly period-type-daily period-type-weekly period-type-monthly period-type-yearly'
)) ))
<p id="chore-schedule-info" <p id="chore-schedule-info"