Skip to content

Commit

Permalink
[59539] Correctly reschedule parent when it no longer has children
Browse files Browse the repository at this point in the history
But only if it has a predecessor. If it does not have any predecessor
nor child, then it can't stay in automatic mode.
  • Loading branch information
cbliard committed Jan 15, 2025
1 parent 35ef6c7 commit e6355a2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
33 changes: 25 additions & 8 deletions app/services/work_packages/update_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,34 @@ def reset_custom_values(work_package)
end

def reschedule_related(work_package)
rescheduled = if work_package.saved_change_to_parent_id? && work_package.parent_id_before_last_save
reschedule_former_siblings(work_package).dependent_results
else
[]
end
moved_work_packages = [work_package]

# if parent changed, we find a child or a predecessor of the former parent to
# give it to the SetScheduleService so that the former parent is rescheduled.
if parent_just_changed?(work_package)
former_parent_id = work_package.parent_id_before_last_save
some_child_or_predecessor = find_some_child_or_predecessor(former_parent_id)
if some_child_or_predecessor
moved_work_packages << some_child_or_predecessor
else # rubocop:disable Style/EmptyElse
# aha! switch former parent to manual mode?
end
end

rescheduled + reschedule(work_package, [work_package]).dependent_results
reschedule(work_package, moved_work_packages).dependent_results
end

def reschedule_former_siblings(work_package)
reschedule(work_package, WorkPackage.where(parent_id: work_package.parent_id_before_last_save))
def parent_just_changed?(work_package)
work_package.saved_change_to_parent_id? && work_package.parent_id_before_last_save
end

def find_some_child_or_predecessor(former_parent_id)
former_parent = WorkPackage.find(former_parent_id)
if a_child = former_parent.children.first
a_child
elsif a_relation = Relation.follows.of_successor(former_parent).first
a_relation.predecessor
end
end

def reschedule(work_package, work_packages)
Expand Down
37 changes: 31 additions & 6 deletions spec/services/work_packages/update_service_integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1196,12 +1196,6 @@

let(:attributes) { { parent: nil } }

before do
work_package.reload
parent_work_package.reload
sibling_work_package.reload
end

it "removes the parent and reschedules it" do
expect(subject)
.to be_success
Expand All @@ -1220,6 +1214,37 @@
end
end

context "when removing the last child of an automatically scheduled parent" do
let(:attributes) { { parent: nil } }

describe "when the parent has predecessors and successors" do
let_work_packages(<<~TABLE)
hierarchy | MTWTFSS | scheduling mode | predecessors
predecessor | X | manual |
parent | XXX | automatic | predecessor
work_package | XXX | manual |
successor | X | automatic | parent
TABLE

it "keeps former parent duration and moves it to its soonest start date, and successors are rescheduled" do
expect(subject)
.to be_success
expect(subject.all_results.pluck(:subject))
.to contain_exactly("work_package", "parent", "successor")
expect(work_package.reload.parent).to be_nil

expect_work_packages(subject.all_results + [predecessor], <<~TABLE)
subject | MTWTFSS | scheduling mode |
predecessor | X | manual |
parent | XXX | automatic |
successor | X | automatic |
work_package | XXX | manual |
TABLE
end
end
end

describe "replacing the attachments" do
let!(:old_attachment) do
create(:attachment, container: work_package)
Expand Down

0 comments on commit e6355a2

Please sign in to comment.