diff --git a/app/services/work_packages/set_schedule_service.rb b/app/services/work_packages/set_schedule_service.rb index df9afc55b422..2ca837047108 100644 --- a/app/services/work_packages/set_schedule_service.rb +++ b/app/services/work_packages/set_schedule_service.rb @@ -116,16 +116,13 @@ def reschedule_ancestor(scheduled, dependency) # ancestors limits moving it. Then it is moved to the earliest date possible. This limitation is propagated transtitively # to all following work packages. def reschedule_by_follows(scheduled, dependency) - delta = if dependency.follows_moved.first - date_rescheduling_delta(dependency.follows_moved.first.to) - else - 0 - end - + delta = follows_delta(dependency) min_start_date = dependency.max_date_of_followed if delta.zero? && min_start_date reschedule_to_date(scheduled, min_start_date) + elsif !scheduled.start_date + schedule_on_missing_dates(scheduled, min_start_date) elsif !delta.zero? reschedule_by_delta(scheduled, delta, min_start_date) end @@ -149,9 +146,24 @@ def reschedule_to_date(scheduled, date) end def reschedule_by_delta(scheduled, delta, min_start_date) - required_delta = [min_start_date - scheduled.start_date, [delta, 0].min].max + required_delta = [min_start_date - (scheduled.start_date || min_start_date), [delta, 0].min].max scheduled.start_date += required_delta scheduled.due_date += required_delta if scheduled.due_date end + + # If the start_date of scheduled is nil at this point something + # went wrong before. So we fix it now by setting the date. + def schedule_on_missing_dates(scheduled, min_start_date) + scheduled.start_date = min_start_date + scheduled.due_date = scheduled.start_date + 1 if scheduled.due_date && scheduled.due_date < scheduled.start_date + end + + def follows_delta(dependency) + if dependency.follows_moved.first + date_rescheduling_delta(dependency.follows_moved.first.to) + else + 0 + end + end end diff --git a/spec/services/work_packages/set_schedule_service_spec.rb b/spec/services/work_packages/set_schedule_service_spec.rb index f03e414c3c0d..eb74f276e511 100644 --- a/spec/services/work_packages/set_schedule_service_spec.rb +++ b/spec/services/work_packages/set_schedule_service_spec.rb @@ -233,6 +233,16 @@ def stub_follower_child(parent, start, due) end end end + + context 'when the follower has no start date (which should not happen)' do + let(:follower1_start_date) { nil } + + it_behaves_like 'reschedules' do + let(:expected) do + { following_work_package1 => [Date.today + 6.days, Date.today + 7.day] } + end + end + end end context 'moving forward with the follower having some space left' do @@ -369,6 +379,20 @@ def stub_follower_child(parent, start, due) end end + context 'moving backwards with the follower having no start date (which should not happen)' do + let(:follower1_start_date) { nil } + + before do + work_package.due_date = Date.today - 5.days + end + + it_behaves_like 'reschedules' do + let(:expected) do + { following_work_package1 => [Date.today - 4.days, follower1_due_date] } + end + end + end + context 'removing the dates on the predecessor' do before do work_package.start_date = work_package.due_date = nil