From e6020432c62277f738f5db74aa305dc838019401 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Sat, 10 Aug 2019 12:44:09 +0200 Subject: [PATCH] Add chores due date rollover (closes #340) --- changelog/52_UNRELEASED_2019-xx-xx.md | 8 +++-- localization/strings.pot | 6 ++++ migrations/0078.sql | 45 +++++++++++++++++++++++++++ views/choreform.blade.php | 10 ++++++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 migrations/0078.sql diff --git a/changelog/52_UNRELEASED_2019-xx-xx.md b/changelog/52_UNRELEASED_2019-xx-xx.md index 44e0c01e..7f80ea56 100644 --- a/changelog/52_UNRELEASED_2019-xx-xx.md +++ b/changelog/52_UNRELEASED_2019-xx-xx.md @@ -1,6 +1,8 @@ +- Chores improvements + - New option "Due date rollover" per chore which means the chore can never be overdue, the due date will shift forward each day when due - General improvements/fixes - Improved the handling which entry page to use with disabled feature flags (thanks @nielstholenaar) - - The Userfield type "Preset list" had always the caption "Product group" (thanks @oncleben31) + - Fixed that the Userfield type "Preset list" had always the caption "Product group" instead of the configured one (thanks @oncleben31) - API improvements - - New endpoint `/stock/shoppinglist/remove-product` to remove an product from a shopping lsit (thanks @Forceu) - - When adding a product through (`stock/product/{productId}/add` or `stock/product/{productId}/inventory`) with omitted best before date and if the given product has "Default best before days" set, the best before date is calculated based on that (so far always today was used which is still the case when no date is supplied and also the product has no "Default best before days set) (thanks @Forceu) + - New endpoint `/stock/shoppinglist/remove-product` to remove a product from a shopping list (thanks @Forceu) + - When adding a product (through `stock/product/{productId}/add` or `stock/product/{productId}/inventory`) with omitted best before date and if the given product has "Default best before days" set, the best before date is calculated based on that (so far always today was used which is still the case when no date is supplied and also the product has no "Default best before days set) (thanks @Forceu) diff --git a/localization/strings.pot b/localization/strings.pot index a71486c5..5148d7b7 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -1286,3 +1286,9 @@ msgstr "" msgid "Undo task \"%s\"" msgstr "" + +msgid "Due date rollover" +msgstr "" + +msgid "When enabled the chore can never be overdue, the due date will shift forward each day when due" +msgstr "" diff --git a/migrations/0078.sql b/migrations/0078.sql new file mode 100644 index 00000000..a3a2a63d --- /dev/null +++ b/migrations/0078.sql @@ -0,0 +1,45 @@ +ALTER TABLE chores +ADD rollover TINYINT DEFAULT 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 +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')), '+1 day') + WHEN 'weekly' THEN + CASE + WHEN period_config LIKE '%sunday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 0') + WHEN period_config LIKE '%monday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 1') + WHEN period_config LIKE '%tuesday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 2') + WHEN period_config LIKE '%wednesday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 3') + WHEN period_config LIKE '%thursday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 4') + WHEN period_config LIKE '%friday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 5') + WHEN period_config LIKE '%saturday%' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '1 days', 'weekday 6') + END + WHEN 'monthly' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+1 month', 'start of month', '+' || CAST(h.period_days - 1 AS TEXT) || ' day') + END AS next_estimated_execution_time, + h.track_date_only, + h.rollover +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; diff --git a/views/choreform.blade.php b/views/choreform.blade.php index 93216262..5fd8c49a 100644 --- a/views/choreform.blade.php +++ b/views/choreform.blade.php @@ -97,6 +97,16 @@ +
+
+ + rollover == 1) checked @endif class="form-check-input" type="checkbox" id="rollover" name="rollover" value="1"> + +
+
+ @include('components.userfieldsform', array( 'userfields' => $userfields, 'entity' => 'chores'