Merge pull request #440 from opf/feature/migrate_planning_element_types_data_to_types

pull/437/merge
Hagen Schink 11 years ago
commit fe96d1e582
  1. 258
      db/migrate/20130916123916_planning_element_types_data_to_types.rb
  2. 20
      db/migrate/20130917122118_remove_is_in_chlog_from_types.rb
  3. 1
      db/seeds/all.rb
  4. 1
      doc/CHANGELOG.md
  5. 8
      features/custom_fields/create_bool.feature
  6. 5
      lib/redmine/default_data/loader.rb
  7. 3
      spec/factories/type_factory.rb
  8. 4
      test/fixtures/types.yml

@ -0,0 +1,258 @@
#-- copyright
# OpenProject is a project management system.
#
# Copyright (C) 2012-2013 the OpenProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# See doc/COPYRIGHT.rdoc for more details.
#++
class PlanningElementTypesDataToTypes < ActiveRecord::Migration
def up
add_new_id_column
add_pe_types_to_types
add_workflow_for_former_pe_types
enable_types_in_projects
end
def down
remove_types_in_projects
remove_workflow_for_former_pe_types
remove_pe_types_from_types
remove_new_id_column
end
private
def add_new_id_column
add_column :legacy_planning_element_types, :new_id, :integer
end
def add_pe_types_to_types
say_with_time "Adding existing planning_element_types to types. Storing new id in legacy table." do
max_position = get_max_position
return if max_position.blank?
insert_legacy_types_into_types(max_position)
add_new_id_to_legacy_table(max_position)
end
end
def get_max_position
max_position = select_all <<-SQL
SELECT MAX(position) as max
FROM #{db_types_table}
SQL
max_position.first['max']
end
def insert_legacy_types_into_types(max_position)
execute <<-SQL
INSERT INTO #{db_types_table}
(
name,
in_aggregation,
is_milestone,
is_default,
is_in_roadmap,
position,
color_id,
created_at,
updated_at
)
SELECT
name,
in_aggregation,
is_milestone,
is_default,
#{quoted_false},
position + #{max_position},
color_id,
created_at,
updated_at
FROM #{db_legacy_types_table}
ORDER BY id ASC
SQL
end
def add_new_id_to_legacy_table(max_position_existing_types)
# Set the new_id column of every row in the
# legacy_planning_element_types table
# to be
# * the value of the id column of the entry in the types
# table
# * that has a position that is equal to the
# entry in the legacy_planning_element_types' position column minus
# the maximum position that existed before
#
# Those are the new id values of the legacy_planning_element_types that
# where just added as new types.
execute <<-SQL
UPDATE #{db_legacy_types_table}
SET new_id = (SELECT #{db_types_table}.id
FROM #{db_types_table}
WHERE #{db_types_table}.position - #{max_position_existing_types} = #{db_legacy_types_table}.position)
SQL
end
def add_workflow_for_former_pe_types
say_with_time "Creating default workflows for migrated types" do
all_status_ids = select_all <<-SQL
SELECT id
FROM #{db_status_table}
SQL
all_status_ids = all_status_ids.map{ |s| s['id'] }
# Select all roles
# that are not builtin.
# This prevents anonymous and non member roles to receive
# workflows.
all_role_ids = select_all <<-SQL
SELECT id
FROM #{db_roles_table}
WHERE builtin = 0
SQL
all_role_ids = all_role_ids.map{ |s| s['id'] }
all_type_ids = select_all <<-SQL
SELECT new_id
FROM #{db_legacy_types_table}
SQL
all_type_ids = all_type_ids.map{ |s| s['new_id'] }
all_workflow_states = []
all_role_ids.each do |role_id|
all_type_ids.each do |type_id|
all_status_ids.each do |status_a_id|
all_status_ids.each do |status_b_id|
all_workflow_states << "(#{quote(role_id)}, #{quote(type_id)}, #{quote(status_a_id)}, #{quote(status_b_id)})" unless status_a_id == status_b_id
end
end
end
end
all_workflow_states = all_workflow_states.join(", ")
return if all_workflow_states.blank?
execute <<-SQL
INSERT INTO #{db_workflows_table}
(
role_id,
type_id,
old_status_id,
new_status_id
)
VALUES
#{all_workflow_states}
SQL
end
end
def enable_types_in_projects
say_with_time "Enabling new types in those projects that had the former legacy_planning_element_types enabled" do
execute <<-SQL
INSERT INTO #{db_projects_types_table}
(
project_id,
type_id
)
SELECT project_id, new_id
FROM #{db_legacy_enabled_types_table} AS epet
LEFT JOIN #{db_legacy_types_table} AS pet
ON epet.planning_element_type_id = pet.id
SQL
end
end
def remove_types_in_projects
say_with_time "Removing enabled types from projects" do
execute <<-SQL
DELETE FROM #{db_projects_types_table}
WHERE
type_id IN (SELECT new_id
FROM #{db_legacy_types_table})
SQL
end
end
def remove_workflow_for_former_pe_types
say_with_time "Removing workflows from pe_types" do
execute <<-SQL
DELETE FROM #{db_workflows_table}
WHERE
type_id IN (SELECT new_id
FROM #{db_legacy_types_table})
SQL
end
end
def remove_pe_types_from_types
say_with_time "Removing all types that are former planning_element_types" do
execute <<-SQL
DELETE FROM #{db_types_table}
WHERE
id IN (SELECT new_id
FROM #{db_legacy_types_table})
SQL
end
end
def remove_new_id_column
remove_column :legacy_planning_element_types, :new_id
end
def db_types_table
@db_types_table ||= quote_table_name('types')
end
def db_legacy_types_table
@db_legacy_types_table ||= quote_table_name('legacy_planning_element_types')
end
def db_status_table
@db_status_table ||= quote_table_name('issue_statuses')
end
def db_roles_table
@db_roles_table ||= quote_table_name('roles')
end
def db_workflows_table
@db_workflows_table ||= quote_table_name('workflows')
end
def db_legacy_enabled_types_table
@db_legacy_enabled_types ||= quote_table_name('legacy_enabled_planning_element_types')
end
def db_projects_types_table
@db_projects_types_table ||= quote_table_name('projects_types')
end
def say_with_time message
super do
suppress_messages do
yield
end
end
end
end

@ -0,0 +1,20 @@
#-- copyright
# OpenProject is a project management system.
#
# Copyright (C) 2012-2013 the OpenProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# See doc/COPYRIGHT.rdoc for more details.
#++
class RemoveIsInChlogFromTypes < ActiveRecord::Migration
def up
remove_column :types, :is_in_chlog
end
def down
add_column :types, :is_in_chlog, :boolean, :default => false, :null => false
end
end

@ -42,7 +42,6 @@ Type.find_or_create_by_is_standard(true, name: 'none',
position: 0,
color_id: default_color.id,
is_default: true,
is_in_chlog: true,
is_in_roadmap: true,
in_aggregation: true,
is_milestone: false)

@ -31,6 +31,7 @@ See doc/COPYRIGHT.rdoc for more details.
* `#1913` [Timelines] Enable drag&drop for select2 items in order to rearrange the order of the columns
* `#1978` Migrate legacy issues
* `#1982` Migrate planning element types
* `#2019` Migrate auto completes controller tests
## 3.0.0pre16

@ -34,10 +34,10 @@ Feature: Localized boolean custom fields can be created
| en |
| de |
And there are the following types:
| name | position | is_in_chlog |
| Bug | 1 | true |
| Feature | 2 | true |
| Support | 3 | false |
| name | position |
| Bug | 1 |
| Feature | 2 |
| Support | 3 |
When I go to the custom fields page
When I follow "New custom field" within "#tab-content-WorkPackageCustomField"

@ -138,7 +138,6 @@ module Redmine
Type.create! :name => l(:default_type_bug),
:color_id => colors[:pjRed],
:is_default => true,
:is_in_chlog => true,
:is_in_roadmap => false,
:in_aggregation => true,
:is_milestone => false,
@ -147,7 +146,6 @@ module Redmine
Type.create! :name => l(:default_type_feature),
:is_default => true,
:color_id => colors[:pjLime],
:is_in_chlog => true,
:is_in_roadmap => true,
:in_aggregation => true,
:is_milestone => false,
@ -156,7 +154,6 @@ module Redmine
Type.create! :name => l(:default_type_support),
:is_default => true,
:color_id => colors[:pjBlue],
:is_in_chlog => false,
:is_in_roadmap => false,
:in_aggregation => true,
:is_milestone => false,
@ -165,7 +162,6 @@ module Redmine
Type.create! :name => l(:default_type_phase),
:is_default => true,
:color_id => colors[:pjSilver],
:is_in_chlog => false,
:is_in_roadmap => false,
:in_aggregation => true,
:is_milestone => false,
@ -174,7 +170,6 @@ module Redmine
Type.create! :name => l(:default_type_milestone),
:is_default => true,
:color_id => colors[:pjPurple],
:is_in_chlog => false,
:is_in_roadmap => true,
:in_aggregation => true,
:is_milestone => true,

@ -36,12 +36,10 @@ FactoryGirl.define do
name "None"
is_standard true
is_default true
is_in_chlog true
end
factory :type_bug, :class => Type do
name "Bug"
is_in_chlog true
position 1
# reuse existing type with the given name
@ -66,7 +64,6 @@ FactoryGirl.define do
end
factory :type_with_workflow, :class => Type do
is_in_chlog true
sequence(:name) { |n| "Type #{n}" }
sequence(:position) { |n| n }
after :build do |t|

@ -30,25 +30,21 @@
types_001:
name: Bug
id: 1
is_in_chlog: true
position: 1
is_default: true
types_002:
name: Feature request
id: 2
is_in_chlog: true
position: 2
is_default: true
types_003:
name: Support request
id: 3
is_in_chlog: false
position: 3
is_default: true
types_999:
name: none
id: 999
is_standard: true
is_in_chlog: true
position: 0
is_default: true

Loading…
Cancel
Save