Feature #34609

Setting for partially independent start-date, end-date in parent tickets

Added by Holger Mößinger almost 2 years ago. Updated about 1 year ago.

Status:NewStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:Issues
Target version:-
Resolution:

Description

In issue #5490 the global settings option for an independent subtask priority/start date/due date/done ratio was implemented (closed in #5490-91). There were some fixes to this or related functionality in #21449, #20994 and #27533.

In note #5490-91 Jean-Philippe Lang mentioned a third "restricted children" option as to vaguely specified.

I would like to propose a specification for this third option allowing a hybrid approach, where it is still possible to set a separate start- and end-date for the parent ticket and calculate the overall date according to the following ruleset.

For the start date:
  • If the start date of the parent ticket is "older/lower" than the the oldest date of the subtickets, the parent tickets own start date is used (just like in the independent setting now).
  • If the start date of any of the subtickets is older than the parent ticket, then the oldest subticket date is used (just like in the dependent setting now).
For the end date:
  • If the end date of the parent ticket is "newer" than the the newest date of the subtickets, the parent tickets own end date is used (just like in the independent setting now).
  • If the end date of any of the subtickets is newer than the parent ticket then newest subticket date is used (just like in the dependent setting now).

As an example:
Let have a parent-ticket with a start-date as 01. March 2021.
Adding a subticket with a start-date of 10. March 2021, the parent-ticket keeps the start-date 01. March 2021.
Adding another subticket with a start-date of 15. February 2021, the parent start-date gets updated to 15. February too.
Now setting the parent-ticket start-date to 05. February is allowed.
Setting the parent-ticket start-date to 05. March, raises an error stating a subticket restricts the start-date to 15. February.
(The user could even be asked if he wants to update the subticket date(s) accordingly, but I would consider that optional at first.)

UI-wise I would suggest leaving the start and end Dates in the parent tickets visible and editable but check for the above conditions when submitting changes.

Adding this feature would allow to have parent tickets keep track of their scheduled dates while automatically moving them if subtask requires it. This would make working with project schedules e.g. Gantt-Chart more useful.

patch34609-0.diff Magnifier (7.22 KB) Holger Mößinger, 2021-10-20 12:51

patch34609-1.diff Magnifier (17.8 KB) Holger Mößinger, 2021-10-21 18:00

ParentTaskAttributes.png (9.59 KB) Holger Mößinger, 2021-10-21 18:17

AllValidationsFailed.png (32.2 KB) Holger Mößinger, 2021-10-21 18:17

IssueList.png (17.6 KB) Holger Mößinger, 2021-10-21 18:17

patch34609-2.diff Magnifier (41.5 KB) Holger Mößinger, 2021-10-27 09:22

History

#1 Updated by Holger Mößinger about 1 year ago

To not just ask for features to be added or changed, but rather provide some input myself, let me add the following suggestion for an implementation to discuss.
Maybe someone with more advanced Redmine knowledge then myself could have a look whether this is feasible and would stand a chance to be added into the Redmine codebase.
I might then be able to provide a patch.

Based on Github Commit 506fc9d74cdb67af2eaea27662420ec07e32b2f3 or Redmine SVN R21238 I have identified the following code to be related to how start-date and due-date in parent issues are handled:

/app/models/issue.rb:L1411


  def dates_derived?
    !leaf? && Setting.parent_issue_dates == 'derived'
  end

which defines dates_derived, for all issues with child-issues, if the corresponding configuration option is set.

/app/models/issue.rb:L529


    if dates_derived?
      names -= %w(start_date due_date)
    end

which removes start-date and due-date from the available/editable fields.

/app/models/issue.rb:L1823


      if p.dates_derived?
        # start/due dates = lowest/highest dates of children
        p.start_date = p.children.minimum(:start_date)
        p.due_date = p.children.maximum(:due_date)
        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

which controls how the field values are calculated if the config option is set to "derived".

app/helpers/settings_helper.rb:L185


  def parent_issue_dates_options
    options = [
      [:label_parent_task_attributes_derived, 'derived'],
      [:label_parent_task_attributes_independent, 'independent']
    ]

which defines the available configuration options for how dates are handled.

I would now suggest adding another option "partially derived" to

app/helpers/settings_helper.rb


  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']
    ]

as well as a definition of "dates_partially_derived" to

/app/models/issue.rb


  def dates_partially_derived?
    !leaf? && Setting.parent_issue_dates == 'partially_derived'
  end

and a new calculation method (not tested yet, consider as pseudo code) for the partially derived case to

/app/models/issue.rb:


      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

The same partial options could also be added to parent_issue_priority_options and parent_issue_done_ratio_options.
This would result in the following overall behaviour when the partial options are selected.

  • Start-date can not be later than first child start date, but can be sooner
  • Due-date can not be sooner than last child end date, but can be later
  • Done ratio can not be higher than combined children's done ration, but can be lower
  • Priority can not be lower than maximum child priority, but can be higher

However, at first, I would only consider handling the dates, leaving done-ratio and priority for later.

Of course there is more to this, like localization e.g. in config/locales/en-GB.yml or config/locales/de.yml, I would suggest the following:

config/locales/en-GB.yml


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

config/locales/de.yml


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

Another topic are the test cases in /test/unit/issue_subtasking_test.rb

Currently the tests for date related functionality are:
  • test_parent_dates_should_be_read_only_with_parent_issue_dates_set_to_derived
  • test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_derived
  • test_reschuling_a_parent_should_reschedule_subtasks_with_parent_issue_dates_set_to_derived
  • test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent
  • test_parent_dates_should_not_be_updated_with_parent_issue_dates_set_to_independent
  • test_reschuling_a_parent_should_not_reschedule_subtasks_with_parent_issue_dates_set_to_independent
I would definitely add:
  • test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_partially_derived
  • test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_partially_derived

I am not yet sure about the rescheduling part, which possibly means my suggestion above might also be incomplete.

As stated above, suggestions and hints are welcome. In the meantime I will be working on getting this to run.

#2 Updated by Holger Mößinger about 1 year ago

Attached is a patch against git commit 8075884bc48deb3b7af94799d6eba943e999dcb2 which implements the functionality described above.

The patch basically consists of the changes outlined in #34609-1.
In addition I had to add a bit of code to app/models/issue.rb validate_issue.

Also included are localizations for the locales en, en-GB and de.

I have no unit tests yet, because the tests don't run on my machine for some unrelated reason.
Manual testing against an fresh installation based on 8075884bc48deb3b7af94799d6eba943e999dcb2 looks good so far.

Maybe someone could have a look at this.

#3 Updated by Holger Mößinger about 1 year ago

Update: patch34609-1.diff (against fe5c3f81de620ebe1c7cc61dcd4a41165c78de00 which is R21254) contains the full functionality as described above.

When "Start date / Due date" is set to "Partially calculated from subtasks":
  • Start-date can not be later than first child start date, but can be sooner
  • Due-date can not be sooner than last child end date, but can be later
When "% Done" is set to "Partially calculated from subtasks":
  • Done ratio can not be higher than combined children's done ration, but can be lower
When Priority is set to "Partially calculated from subtasks":
  • Priority can not be lower than maximum child priority, but can be higher

Still no unit tests.
Manual testing against an fresh installation based on fe5c3f81de620ebe1c7cc61dcd4a41165c78de00 looks good.

Someone experienced having a look at the code would be very much appreciated.

#4 Updated by Holger Mößinger about 1 year ago

Let me add some impressions on how this looks like in real life.

With settings for issues like this

and you have issues like this

then the following fails for each of the fields that are tested

Suggestions are welcome!

#5 Updated by Holger Mößinger about 1 year ago

The patch34609-2 adds reschedule functionality for issues with partially derived dates set to issue.rb, which was missing before.

Also included is the update of the added locales to all localization files.
In total I have added the following to en.yml, de-DE.yml and en-GB.yml.
  • label_parent_task_attributes_partially_derived
  • later_than_minimum_start_date
  • earlier_than_maximum_due_date
  • priority_lower_than_children
  • done_ratio_higher_than_children

However for some reason rake locales:update did not copy all five new strings from en.yml to all other locale files but just the first one.

The patch is again against the currently up to date Redmine master on Github 0056c128624fdadd0fff82aef6e6a96c6ef817b9 corresponding to SVN R21261.

Next up, getting tests cases set up in test/unit/issue_subtasking_test.rb.

Starting point for tests are the following functions:

  • test_parent_dates_should_be_read_only_with_parent_issue_dates_set_to_derived
  • test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_derived
  • test_reschuling_a_parent_should_reschedule_subtasks_with_parent_issue_dates_set_to_derived
  • test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent
  • test_parent_dates_should_not_be_updated_with_parent_issue_dates_set_to_independent
  • test_reschuling_a_parent_should_not_reschedule_subtasks_with_parent_issue_dates_set_to_independent

To test the functionality of the partially derived start and due dates I propose to add the following tests

  • test_reschuling_a_parent_should_reschedule_subtasks_with_parent_issue_dates_set_to_partially_derived_if_child_dates_outside_parent_range
  • test_reschuling_a_parent_should_not_reschedule_subtasks_with_parent_issue_dates_set_to_partially_derived_if_child_dates_in_parent_range
  • test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_partially_derived
  • test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_partially_derived_if_child_dates_outside_parent_range
  • test_parent_dates_should_not_change_with_parent_issue_dates_set_to_partially_derived_if_child_dates_inside_parent_range

#6 Updated by Holger Mößinger about 1 year ago

I've added unit test for all new functionality as well as fixed a bug that showed itself during testing.
The test are added to the file "test/unit/issue_subtasking_test.rb" which I ran using ruby test/unit/issue_substasking.rb as well as via the full test run using rake test.

rake test summary said:
4995 runs, 21332 assertions, 3 failures, 1 error, 6 skips.

The problematic tests are as follows:

  • Failure 1: "I18nTest#test_locales_validness" and
  • Failure 2: "I18nTest:test_language_options" from test/unit/lib/redmine/i18n_test.rb, both with "Expected 50, Actual 49".

I am still looking into this. It might be related to the above mentioned (#34609-5):

However for some reason rake locales:update did not copy all five new strings from en.yml [...].

The locale configurations for en, en-GB and de contain all five new entries

  1. en:activerecord:errors:messages:earlier_than_maximum_due_date (Line 133)
  2. en:activerecord:errors:messages:later_than_minimum_start_date (Line 134)
  3. en:activerecord:errors:messages:priority_lower_than_children (Line 135)
  4. en:activerecord:errors:messages:done_ratio_higher_than_children (Line 136)
  5. en:label_parent_task_attributes_partially_derived (Line 1070)

rake locales:update transfers only the last new entry to all other locale files.

EDIT: According to its description locales:update is not able to update the first four entries, as they are not top-level. These would need to be added manually or locale:update would need to be expanded to handle added non-top-level keys.

On the other hand running these tests via ruby test/unit/lib/redmine/i18n_test.rb on the current origin/master, without my changes results in the same failure. So it might not be related to my changes at all.

  • Failure 3: "AttachmentControllerTest#test_thumbnail_for_pdf_should_be_png" and
  • Error 1: AttachmentTest#test_thumbnail_should_generate_the_thumbnail" from "test/unit/attachement_test.rb"

These two seem unrelated, something about a security policy.

Attached the patch (patch34609-3.diff) including all changes against the now current Git 7b9f5af and SVN R21268.

I would consider it ready for a review.

Somewhat off topic: As part of my effort to this patch I will provide up-to-date documentation on how to set up a Redmine development system on Debian 11, which might be a useful addition to the Developer_Guide or rather a subpage of it.

Also available in: Atom PDF