From: redacted Date: Wed, 20 Oct 2021 12:42:09 +0200 Subject: =?UTF-8?q?Add=20partial=5Fderived=20option=20for=20issue=20dates?= =?UTF-8?q?=0AThis=20implements=20the=20suggestions=20from=20feature=20#34?= =?UTF-8?q?609.=0AWith=20this=20parent=20issues=20can=20have=20start=20dat?= =?UTF-8?q?es=20earlier=20than=20child=20issue=0Aand=20due=20dates=20later?= =?UTF-8?q?=20than=20child=20issues=20but=20not=20the=20other=20way=20arou?= =?UTF-8?q?nd.?= --- app/helpers/settings_helper.rb | 1 + app/models/issue.rb | 21 +++++++++++++++++++++ config/locales/de.yml | 3 +++ config/locales/en-GB.yml | 3 +++ config/locales/en.yml | 3 +++ 5 files changed, 31 insertions(+) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index c3b8e7a25..abf4ae0fc 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -185,6 +185,7 @@ module SettingsHelper def parent_issue_dates_options options = [ [:label_parent_task_attributes_derived, 'derived'], + [:label_parent_task_attributes_partially_derived, 'partially_derived'], [:label_parent_task_attributes_independent, 'independent'] ] diff --git a/app/models/issue.rb b/app/models/issue.rb index 55962f0fe..733158efb 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -745,6 +745,14 @@ class Issue < ActiveRecord::Base errors.add :due_date, :greater_than_start_date end + if dates_partially_derived? && start_date && start_date_changed? && start_date > children.minimum(:start_date) + errors.add :start_date, :later_than_minimum_start_date, :date => format_date(children.minimum(:start_date)) + end + + if dates_partially_derived? && due_date && due_date_changed? && due_date < children.maximum(:due_date) + errors.add :due_date, :earlier_than_maximum_due_date, :date => format_date(children.maximum(:due_date)) + end + if start_date && start_date_changed? && soonest_start && start_date < soonest_start errors.add :start_date, :earlier_than_minimum_start_date, :date => format_date(soonest_start) end @@ -1412,6 +1420,10 @@ class Issue < ActiveRecord::Base !leaf? && Setting.parent_issue_dates == 'derived' end + def dates_partially_derived? + !leaf? && Setting.parent_issue_dates == 'partially_derived' + end + def priority_derived? !leaf? && Setting.parent_issue_priority == 'derived' end @@ -1829,6 +1841,15 @@ class Issue < ActiveRecord::Base end end + if p.dates_partially_derived? + # start/due dates = lowest/highest dates of children or own date + p.start_date = [p.children.minimum(:start_date), p.start_date].compact.min + p.due_date = [p.children.maximum(:due_date),p.due_date].compact.max + if p.start_date && p.due_date && p.due_date < p.start_date + p.start_date, p.due_date = p.due_date, p.start_date + end + end + if p.done_ratio_derived? # done ratio = average ratio of children weighted with their total estimated hours unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio diff --git a/config/locales/de.yml b/config/locales/de.yml index 1bb53c4d0..da933c255 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -146,6 +146,8 @@ de: circular_dependency: "Diese Beziehung würde eine zyklische Abhängigkeit erzeugen" cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einem seiner untergeordneten Tickets verlinkt werden" earlier_than_minimum_start_date: "kann wegen eines Vorgängertickets nicht vor %{date} liegen" + later_than_minimum_start_date: "kann wegen eines Untertickets nicht nach %{date} liegen" + earlier_than_maximum_due_date: "kann wegen eines Untertickets nicht vor %{date} liegen" not_a_regexp: "ist kein gültiger regulärer Ausdruck" open_issue_with_closed_parent: "Ein offenes Ticket kann nicht an ein geschlossenes übergeordnetes Ticket angehängt werden" must_contain_uppercase: "muss Großbuchstaben (A-Z) enthalten" @@ -1173,6 +1175,7 @@ de: field_remote_ip: IP-Adresse label_parent_task_attributes: Eigenschaften übergeordneter Tickets label_parent_task_attributes_derived: Abgeleitet von untergeordneten Tickets + label_parent_task_attributes_partially_derived: Teilweise abgeleitet von untergeordneten Tickets label_parent_task_attributes_independent: Unabhängig von untergeordneten Tickets label_time_entries_visibility_all: Alle Zeitaufwände label_time_entries_visibility_own: Nur eigene Aufwände diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 453e86fa7..e170c8cdb 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -134,6 +134,8 @@ en-GB: circular_dependency: "This relation would create a circular dependency" cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks" earlier_than_minimum_start_date: "cannot be earlier than %{date} because of preceding issues" + later_than_minimum_start_date: "cannot be later than %{date} because of child issues" + earlier_than_maximum_due_date: "cannot be earlier than %{date} because of child issues" not_a_regexp: "is not a valid regular expression" open_issue_with_closed_parent: "An open issue cannot be attached to a closed parent task" must_contain_uppercase: "must contain uppercase letters (A-Z)" @@ -1132,6 +1134,7 @@ en-GB: field_time_entries_visibility: Time logs visibility setting_password_max_age: Require password change after label_parent_task_attributes: Parent tasks attributes + label_parent_task_attributes_partially_derived: Partially calculated from subtasks label_parent_task_attributes_derived: Calculated from subtasks label_parent_task_attributes_independent: Independent of subtasks label_time_entries_visibility_all: All time entries diff --git a/config/locales/en.yml b/config/locales/en.yml index 8fd84ff13..61feec4aa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -130,6 +130,8 @@ en: circular_dependency: "This relation would create a circular dependency" cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks" earlier_than_minimum_start_date: "cannot be earlier than %{date} because of preceding issues" + earlier_than_maximum_due_date: "cannot be earlier than %{date} because of child issues" + later_than_minimum_start_date: "cannot be later than %{date} because of child issues" not_a_regexp: "is not a valid regular expression" open_issue_with_closed_parent: "An open issue cannot be attached to a closed parent task" must_contain_uppercase: "must contain uppercase letters (A-Z)" @@ -1064,6 +1066,7 @@ en: label_blank_value: blank label_parent_task_attributes: Parent tasks attributes label_parent_task_attributes_derived: Calculated from subtasks + label_parent_task_attributes_partially_derived: Partially calculated from subtasks label_parent_task_attributes_independent: Independent of subtasks label_time_entries_visibility_all: All time entries label_time_entries_visibility_own: Time entries created by the user -- 2.30.2