Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[59539] Migrate scheduling mode and lags #17235

Draft
wants to merge 29 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
778b04c
[42388] Migrate scheduling mode and lags
cbliard Nov 20, 2024
7c0f1fb
Define a 'scheduling mode' column in table_helpers
cbliard Nov 22, 2024
f792612
[59539] Migration: followers and parents have automatic scheduling mode
cbliard Nov 22, 2024
54d9159
[59539] Migration: set lag for follows relations
cbliard Nov 22, 2024
f13d7c1
[59539] Respect non-working days when computing lags in migration
cbliard Nov 25, 2024
8a206dc
[59539] Only set lag for the closest relation in the migration
cbliard Nov 25, 2024
dc7ff3a
[59539] Keep manual scheduling mode in migration
cbliard Nov 27, 2024
f35db43
[59539] Make work packages manually scheduled by default
cbliard Nov 28, 2024
31f6586
Show non-working days in the rendered table of table helpers
cbliard Dec 10, 2024
293d43e
[59539] Start as soon as possible in automatic scheduling mode
cbliard Dec 10, 2024
5a8400c
Fix broken feature test
cbliard Dec 11, 2024
0cb43e3
Simplify method calls
cbliard Dec 11, 2024
cc6bd02
table helpers: rename properties column to predecessors
cbliard Dec 12, 2024
d21e70a
[59539] Correctly reschedule predecessors needing relations rescheduling
cbliard Dec 13, 2024
28f0719
refactor: reword some tests cases
cbliard Dec 13, 2024
7923850
[59539] Update seeding data to be compatible with new automatic sched…
cbliard Dec 16, 2024
b8c7bb2
[59539] switch scheduling mode when modifying follows relations
cbliard Dec 17, 2024
176cfaa
Fix unit tests broken by previous commit
cbliard Dec 17, 2024
9987998
refactor: rewrite with positive assertions
cbliard Dec 24, 2024
88b2f6a
table_helpers: Fix issue with empty tables
cbliard Dec 24, 2024
e17260c
refactor: make test output and code less verbose
cbliard Dec 24, 2024
3d80092
Add missing magic comment `# frozen_string_literal: true`
cbliard Jan 6, 2025
62b609b
Move some tests at the `UpdateService` integration test level
cbliard Jan 6, 2025
c8902b2
refactor: rewrite test using schedule helpers
cbliard Jan 7, 2025
aa95b5c
refactor: replace condition term with guard clause
cbliard Jan 7, 2025
0464d6c
Make test assertion clearer
cbliard Jan 7, 2025
a90fb94
Move dates handling to `SetAttributesService`
cbliard Jan 7, 2025
0fb2ae7
[59539] Reschedule when switching parent to automatic mode
cbliard Jan 8, 2025
555fce9
Merge branch 'dev' into feature/42388-new-automatic-scheduling-mode
cbliard Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[59539] Migration: set lag for follows relations
To preserve dates, a lag is set for follows relations when both the
predecessor and the follower have dates.
  • Loading branch information
cbliard committed Dec 16, 2024
commit 54d91594150883c086bb4ba7a1d553dbfe40a21a
14 changes: 14 additions & 0 deletions app/workers/work_packages/automatic_mode/migrate_values_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def perform
change_scheduling_mode_to_manual
change_scheduling_mode_to_automatic_for_followers
change_scheduling_mode_to_automatic_for_parents
set_lags_for_follows_relations
copy_values_to_work_packages_and_update_journals
end
end
Expand Down Expand Up @@ -97,6 +98,19 @@ def change_scheduling_mode_to_automatic_for_parents
SQL
end

def set_lags_for_follows_relations
execute(<<~SQL.squish)
UPDATE relations
SET lag = COALESCE(wp_succ.start_date, wp_succ.due_date) - COALESCE(wp_pred.due_date, wp_pred.start_date) - 1
FROM work_packages wp_pred, work_packages wp_succ
WHERE relations.relation_type = 'follows'
AND relations.to_id = wp_pred.id
AND relations.from_id = wp_succ.id
AND COALESCE(wp_succ.start_date, wp_succ.due_date) IS NOT NULL
AND COALESCE(wp_pred.due_date, wp_pred.start_date) IS NOT NULL
SQL
end

def copy_values_to_work_packages_and_update_journals
updated_work_package_ids = copy_values_to_work_packages
create_journals_for_updated_work_packages(updated_work_package_ids)
Expand Down
49 changes: 49 additions & 0 deletions spec/migrations/update_scheduling_mode_and_lags_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,53 @@
expect(child).to be_schedule_manually
end
end

context "for 2 work packages following each other with distant dates" do
let_work_packages(<<~TABLE)
subject | MTWTFSS | properties
predecessor 1 | XX |
follower 1 | XX | follows predecessor 1

# only start dates
predecessor 2 | [ |
follower 2 | [ | follows predecessor 2

# only due dates
predecessor 3 | ] |
follower 3 | ] | follows predecessor 3 with lag 1
TABLE

it "sets a lag to the relation to ensure the distance is kept" do
run_migration

expect(follower1).to be_schedule_automatically
relations = _table.relations.map(&:reload)
expect(relations.map(&:lag)).to all(eq(2))
end
end

context "for 2 work packages following each other with missing dates" do
let_work_packages(<<~TABLE)
subject | MTWTFSS | properties
# only predecessor has dates
predecessor 1 | XX |
follower 1 | | follows predecessor 1

# only successor has dates
predecessor 2 | |
follower 2 | XX | follows predecessor 2

# none have dates
predecessor 3 | |
follower 3 | | follows predecessor 3 with lag 1
TABLE

it "does not change the existing lag" do
run_migration

expect(follower1).to be_schedule_automatically
relations = _table.relations.map(&:reload)
expect(relations.map(&:lag)).to eq([0, 0, 1])
end
end
end
2 changes: 1 addition & 1 deletion spec/support/table_helpers/column_type/properties.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def relations_for_raw_value(raw_value)

def parse_property(property)
case property
when /^follows (\w+)(?: with lag (\d+))?/
when /^follows (.+?)(?: with lag (\d+))?\s*$/
{
relations: {
raw: property,
Expand Down
7 changes: 6 additions & 1 deletion spec/support/table_helpers/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@

module TableHelpers
class Table
def initialize(work_packages_by_identifier)
def initialize(work_packages_by_identifier, relations)
@work_packages_by_identifier = work_packages_by_identifier
@relations = relations
end

def work_package(name)
Expand All @@ -41,6 +42,10 @@ def work_packages
@work_packages_by_identifier.values
end

def relations
@relations
end

private

def normalize_name(name)
Expand Down
28 changes: 20 additions & 8 deletions spec/support/table_helpers/table_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def work_package_identifiers
end

def create_work_packages
work_packages_by_identifier = Factory.new(self).create
Table.new(work_packages_by_identifier)
work_packages_by_identifier, relations = Factory.new(self).create
Table.new(work_packages_by_identifier, relations)
end

def order_like!(other_table)
Expand All @@ -93,11 +93,14 @@ def order_like!(other_table)
end

class Factory
attr_reader :table_data, :work_packages_by_identifier
include Identifier

attr_reader :table_data, :work_packages_by_identifier, :relations

def initialize(table_data)
@table_data = table_data
@work_packages_by_identifier = {}
@relations = []
end

def create
Expand All @@ -108,7 +111,7 @@ def create
table_data.work_package_identifiers.each do |identifier| # rubocop:disable Style/CombinableLoops
create_follows_relations(identifier)
end
work_packages_by_identifier
[work_packages_by_identifier, relations]
end

def create_work_package(identifier)
Expand All @@ -123,11 +126,10 @@ def create_work_package(identifier)
end

def create_follows_relations(identifier)
relations = work_package_relations(identifier)
relations.each do |relation|
predecessor = work_packages_by_identifier[relation[:predecessor].to_sym]
work_package_relations(identifier).each do |relation|
predecessor = find_work_package_by_name(relation[:predecessor])
follower = work_packages_by_identifier[identifier]
FactoryBot.create(
relations << FactoryBot.create(
:follows_relation,
from: follower,
to: predecessor,
Expand All @@ -136,6 +138,16 @@ def create_follows_relations(identifier)
end
end

def find_work_package_by_name(name)
identifier = to_identifier(name)
work_package = work_packages_by_identifier[identifier]
if work_package.nil?
raise "Work package with name #{name.inspect} (identifier: #{identifier.inspect}) not found. " \
"Available work package identifiers: #{work_packages_by_identifier.keys}."
end
work_package
end

def lookup_parent(identifier)
if identifier
@work_packages_by_identifier[identifier] || create_work_package(identifier)
Expand Down