Revision 4053
Added by Eric Davis almost 15 years ago
trunk/app/controllers/project_enumerations_controller.rb | ||
---|---|---|
1 |
class ProjectEnumerationsController < ApplicationController |
|
2 |
before_filter :find_project |
|
3 |
before_filter :authorize |
|
4 |
|
|
5 |
def save |
|
6 |
if request.post? && params[:enumerations] |
|
7 |
Project.transaction do |
|
8 |
params[:enumerations].each do |id, activity| |
|
9 |
@project.update_or_create_time_entry_activity(id, activity) |
|
10 |
end |
|
11 |
end |
|
12 |
flash[:notice] = l(:notice_successful_update) |
|
13 |
end |
|
14 |
|
|
15 |
redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project |
|
16 |
end |
|
17 |
|
|
18 |
end |
trunk/app/controllers/projects_controller.rb | ||
---|---|---|
238 | 238 |
@project = nil |
239 | 239 |
end |
240 | 240 |
|
241 |
def save_activities |
|
242 |
if request.post? && params[:enumerations] |
|
243 |
Project.transaction do |
|
244 |
params[:enumerations].each do |id, activity| |
|
245 |
@project.update_or_create_time_entry_activity(id, activity) |
|
246 |
end |
|
247 |
end |
|
248 |
flash[:notice] = l(:notice_successful_update) |
|
249 |
end |
|
250 |
|
|
251 |
redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project |
|
252 |
end |
|
253 |
|
|
254 | 241 |
def reset_activities |
255 | 242 |
@project.time_entry_activities.each do |time_entry_activity| |
256 | 243 |
time_entry_activity.destroy(time_entry_activity.parent) |
trunk/app/views/projects/settings/_activities.rhtml | ||
---|---|---|
1 |
<% form_tag({:controller => 'projects', :action => 'save_activities', :id => @project}, :class => "tabular") do %>
|
|
1 |
<% form_tag({:controller => 'project_enumerations', :action => 'save', :id => @project}, :class => "tabular") do %>
|
|
2 | 2 |
|
3 | 3 |
<table class="list"> |
4 | 4 |
<thead><tr> |
trunk/config/routes.rb | ||
---|---|---|
200 | 200 |
project_actions.connect 'projects.:format', :action => 'add', :format => /xml/ |
201 | 201 |
project_actions.connect 'projects/:id/:action', :action => /edit|destroy|archive|unarchive/ |
202 | 202 |
project_actions.connect 'projects/:id/files/new', :controller => 'files', :action => 'new' |
203 |
project_actions.connect 'projects/:id/activities/save', :action => 'save_activities'
|
|
203 |
project_actions.connect 'projects/:id/activities/save', :controller => 'project_enumerations', :action => 'save'
|
|
204 | 204 |
end |
205 | 205 |
|
206 | 206 |
projects.with_options :conditions => {:method => :put} do |project_actions| |
trunk/lib/redmine.rb | ||
---|---|---|
87 | 87 |
map.permission :view_time_entries, :timelog => [:details, :report] |
88 | 88 |
map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member |
89 | 89 |
map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin |
90 |
map.permission :manage_project_activities, {:projects => [:save_activities, :reset_activities]}, :require => :member
|
|
90 |
map.permission :manage_project_activities, {:projects => [:reset_activities], :project_enumerations => [:save]}, :require => :member
|
|
91 | 91 |
end |
92 | 92 |
|
93 | 93 |
map.project_module :news do |map| |
trunk/test/functional/project_enumerations_controller_test.rb | ||
---|---|---|
1 |
require File.dirname(__FILE__) + '/../test_helper' |
|
2 |
|
|
3 |
class ProjectEnumerationsControllerTest < ActionController::TestCase |
|
4 |
fixtures :all |
|
5 |
|
|
6 |
def setup |
|
7 |
@request.session[:user_id] = nil |
|
8 |
Setting.default_language = 'en' |
|
9 |
end |
|
10 |
|
|
11 |
def test_save_to_override_system_activities |
|
12 |
@request.session[:user_id] = 2 # manager |
|
13 |
billable_field = TimeEntryActivityCustomField.find_by_name("Billable") |
|
14 |
|
|
15 |
post :save, :id => 1, :enumerations => { |
|
16 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate |
|
17 |
"10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value |
|
18 |
"14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value |
|
19 |
"11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes |
|
20 |
} |
|
21 |
|
|
22 |
assert_response :redirect |
|
23 |
assert_redirected_to 'projects/ecookbook/settings/activities' |
|
24 |
|
|
25 |
# Created project specific activities... |
|
26 |
project = Project.find('ecookbook') |
|
27 |
|
|
28 |
# ... Design |
|
29 |
design = project.time_entry_activities.find_by_name("Design") |
|
30 |
assert design, "Project activity not found" |
|
31 |
|
|
32 |
assert_equal 9, design.parent_id # Relate to the system activity |
|
33 |
assert_not_equal design.parent.id, design.id # Different records |
|
34 |
assert_equal design.parent.name, design.name # Same name |
|
35 |
assert !design.active? |
|
36 |
|
|
37 |
# ... Development |
|
38 |
development = project.time_entry_activities.find_by_name("Development") |
|
39 |
assert development, "Project activity not found" |
|
40 |
|
|
41 |
assert_equal 10, development.parent_id # Relate to the system activity |
|
42 |
assert_not_equal development.parent.id, development.id # Different records |
|
43 |
assert_equal development.parent.name, development.name # Same name |
|
44 |
assert development.active? |
|
45 |
assert_equal "0", development.custom_value_for(billable_field).value |
|
46 |
|
|
47 |
# ... Inactive Activity |
|
48 |
previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity") |
|
49 |
assert previously_inactive, "Project activity not found" |
|
50 |
|
|
51 |
assert_equal 14, previously_inactive.parent_id # Relate to the system activity |
|
52 |
assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records |
|
53 |
assert_equal previously_inactive.parent.name, previously_inactive.name # Same name |
|
54 |
assert previously_inactive.active? |
|
55 |
assert_equal "1", previously_inactive.custom_value_for(billable_field).value |
|
56 |
|
|
57 |
# ... QA |
|
58 |
assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified" |
|
59 |
end |
|
60 |
|
|
61 |
def test_save_will_update_project_specific_activities |
|
62 |
@request.session[:user_id] = 2 # manager |
|
63 |
|
|
64 |
project_activity = TimeEntryActivity.new({ |
|
65 |
:name => 'Project Specific', |
|
66 |
:parent => TimeEntryActivity.find(:first), |
|
67 |
:project => Project.find(1), |
|
68 |
:active => true |
|
69 |
}) |
|
70 |
assert project_activity.save |
|
71 |
project_activity_two = TimeEntryActivity.new({ |
|
72 |
:name => 'Project Specific Two', |
|
73 |
:parent => TimeEntryActivity.find(:last), |
|
74 |
:project => Project.find(1), |
|
75 |
:active => true |
|
76 |
}) |
|
77 |
assert project_activity_two.save |
|
78 |
|
|
79 |
|
|
80 |
post :save, :id => 1, :enumerations => { |
|
81 |
project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate |
|
82 |
project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate |
|
83 |
} |
|
84 |
|
|
85 |
assert_response :redirect |
|
86 |
assert_redirected_to 'projects/ecookbook/settings/activities' |
|
87 |
|
|
88 |
# Created project specific activities... |
|
89 |
project = Project.find('ecookbook') |
|
90 |
assert_equal 2, project.time_entry_activities.count |
|
91 |
|
|
92 |
activity_one = project.time_entry_activities.find_by_name(project_activity.name) |
|
93 |
assert activity_one, "Project activity not found" |
|
94 |
assert_equal project_activity.id, activity_one.id |
|
95 |
assert !activity_one.active? |
|
96 |
|
|
97 |
activity_two = project.time_entry_activities.find_by_name(project_activity_two.name) |
|
98 |
assert activity_two, "Project activity not found" |
|
99 |
assert_equal project_activity_two.id, activity_two.id |
|
100 |
assert !activity_two.active? |
|
101 |
end |
|
102 |
|
|
103 |
def test_save_when_creating_new_activities_will_convert_existing_data |
|
104 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size |
|
105 |
|
|
106 |
@request.session[:user_id] = 2 # manager |
|
107 |
post :save, :id => 1, :enumerations => { |
|
108 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate |
|
109 |
} |
|
110 |
assert_response :redirect |
|
111 |
|
|
112 |
# No more TimeEntries using the system activity |
|
113 |
assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries still assigned to system activities" |
|
114 |
# All TimeEntries using project activity |
|
115 |
project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1) |
|
116 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(project_specific_activity.id, 1).size, "No Time Entries assigned to the project activity" |
|
117 |
end |
|
118 |
|
|
119 |
def test_save_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised |
|
120 |
# TODO: Need to cause an exception on create but these tests |
|
121 |
# aren't setup for mocking. Just create a record now so the |
|
122 |
# second one is a dupicate |
|
123 |
parent = TimeEntryActivity.find(9) |
|
124 |
TimeEntryActivity.create!({:name => parent.name, :project_id => 1, :position => parent.position, :active => true}) |
|
125 |
TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1), :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'}) |
|
126 |
|
|
127 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size |
|
128 |
assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size |
|
129 |
|
|
130 |
@request.session[:user_id] = 2 # manager |
|
131 |
post :save, :id => 1, :enumerations => { |
|
132 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design |
|
133 |
"10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"} # Development, Change custom value |
|
134 |
} |
|
135 |
assert_response :redirect |
|
136 |
|
|
137 |
# TimeEntries shouldn't have been reassigned on the failed record |
|
138 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries are not assigned to system activities" |
|
139 |
# TimeEntries shouldn't have been reassigned on the saved record either |
|
140 |
assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size, "Time Entries are not assigned to system activities" |
|
141 |
end |
|
142 |
end |
trunk/test/functional/projects_controller_test.rb | ||
---|---|---|
427 | 427 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "TimeEntries still assigned to project specific activity" |
428 | 428 |
end |
429 | 429 |
|
430 |
def test_save_activities_to_override_system_activities |
|
431 |
@request.session[:user_id] = 2 # manager |
|
432 |
billable_field = TimeEntryActivityCustomField.find_by_name("Billable") |
|
433 |
|
|
434 |
post :save_activities, :id => 1, :enumerations => { |
|
435 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate |
|
436 |
"10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value |
|
437 |
"14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value |
|
438 |
"11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes |
|
439 |
} |
|
440 |
|
|
441 |
assert_response :redirect |
|
442 |
assert_redirected_to 'projects/ecookbook/settings/activities' |
|
443 |
|
|
444 |
# Created project specific activities... |
|
445 |
project = Project.find('ecookbook') |
|
446 |
|
|
447 |
# ... Design |
|
448 |
design = project.time_entry_activities.find_by_name("Design") |
|
449 |
assert design, "Project activity not found" |
|
450 |
|
|
451 |
assert_equal 9, design.parent_id # Relate to the system activity |
|
452 |
assert_not_equal design.parent.id, design.id # Different records |
|
453 |
assert_equal design.parent.name, design.name # Same name |
|
454 |
assert !design.active? |
|
455 |
|
|
456 |
# ... Development |
|
457 |
development = project.time_entry_activities.find_by_name("Development") |
|
458 |
assert development, "Project activity not found" |
|
459 |
|
|
460 |
assert_equal 10, development.parent_id # Relate to the system activity |
|
461 |
assert_not_equal development.parent.id, development.id # Different records |
|
462 |
assert_equal development.parent.name, development.name # Same name |
|
463 |
assert development.active? |
|
464 |
assert_equal "0", development.custom_value_for(billable_field).value |
|
465 |
|
|
466 |
# ... Inactive Activity |
|
467 |
previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity") |
|
468 |
assert previously_inactive, "Project activity not found" |
|
469 |
|
|
470 |
assert_equal 14, previously_inactive.parent_id # Relate to the system activity |
|
471 |
assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records |
|
472 |
assert_equal previously_inactive.parent.name, previously_inactive.name # Same name |
|
473 |
assert previously_inactive.active? |
|
474 |
assert_equal "1", previously_inactive.custom_value_for(billable_field).value |
|
475 |
|
|
476 |
# ... QA |
|
477 |
assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified" |
|
478 |
end |
|
479 |
|
|
480 |
def test_save_activities_will_update_project_specific_activities |
|
481 |
@request.session[:user_id] = 2 # manager |
|
482 |
|
|
483 |
project_activity = TimeEntryActivity.new({ |
|
484 |
:name => 'Project Specific', |
|
485 |
:parent => TimeEntryActivity.find(:first), |
|
486 |
:project => Project.find(1), |
|
487 |
:active => true |
|
488 |
}) |
|
489 |
assert project_activity.save |
|
490 |
project_activity_two = TimeEntryActivity.new({ |
|
491 |
:name => 'Project Specific Two', |
|
492 |
:parent => TimeEntryActivity.find(:last), |
|
493 |
:project => Project.find(1), |
|
494 |
:active => true |
|
495 |
}) |
|
496 |
assert project_activity_two.save |
|
497 |
|
|
498 |
|
|
499 |
post :save_activities, :id => 1, :enumerations => { |
|
500 |
project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate |
|
501 |
project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate |
|
502 |
} |
|
503 |
|
|
504 |
assert_response :redirect |
|
505 |
assert_redirected_to 'projects/ecookbook/settings/activities' |
|
506 |
|
|
507 |
# Created project specific activities... |
|
508 |
project = Project.find('ecookbook') |
|
509 |
assert_equal 2, project.time_entry_activities.count |
|
510 |
|
|
511 |
activity_one = project.time_entry_activities.find_by_name(project_activity.name) |
|
512 |
assert activity_one, "Project activity not found" |
|
513 |
assert_equal project_activity.id, activity_one.id |
|
514 |
assert !activity_one.active? |
|
515 |
|
|
516 |
activity_two = project.time_entry_activities.find_by_name(project_activity_two.name) |
|
517 |
assert activity_two, "Project activity not found" |
|
518 |
assert_equal project_activity_two.id, activity_two.id |
|
519 |
assert !activity_two.active? |
|
520 |
end |
|
521 |
|
|
522 |
def test_save_activities_when_creating_new_activities_will_convert_existing_data |
|
523 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size |
|
524 |
|
|
525 |
@request.session[:user_id] = 2 # manager |
|
526 |
post :save_activities, :id => 1, :enumerations => { |
|
527 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate |
|
528 |
} |
|
529 |
assert_response :redirect |
|
530 |
|
|
531 |
# No more TimeEntries using the system activity |
|
532 |
assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries still assigned to system activities" |
|
533 |
# All TimeEntries using project activity |
|
534 |
project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1) |
|
535 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(project_specific_activity.id, 1).size, "No Time Entries assigned to the project activity" |
|
536 |
end |
|
537 |
|
|
538 |
def test_save_activities_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised |
|
539 |
# TODO: Need to cause an exception on create but these tests |
|
540 |
# aren't setup for mocking. Just create a record now so the |
|
541 |
# second one is a dupicate |
|
542 |
parent = TimeEntryActivity.find(9) |
|
543 |
TimeEntryActivity.create!({:name => parent.name, :project_id => 1, :position => parent.position, :active => true}) |
|
544 |
TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1), :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'}) |
|
545 |
|
|
546 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size |
|
547 |
assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size |
|
548 |
|
|
549 |
@request.session[:user_id] = 2 # manager |
|
550 |
post :save_activities, :id => 1, :enumerations => { |
|
551 |
"9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design |
|
552 |
"10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"} # Development, Change custom value |
|
553 |
} |
|
554 |
assert_response :redirect |
|
555 |
|
|
556 |
# TimeEntries shouldn't have been reassigned on the failed record |
|
557 |
assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries are not assigned to system activities" |
|
558 |
# TimeEntries shouldn't have been reassigned on the saved record either |
|
559 |
assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size, "Time Entries are not assigned to system activities" |
|
560 |
end |
|
561 |
|
|
562 | 430 |
# A hook that is manually registered later |
563 | 431 |
class ProjectBasedTemplate < Redmine::Hook::ViewListener |
564 | 432 |
def view_layouts_base_html_head(context) |
trunk/test/integration/routing_test.rb | ||
---|---|---|
185 | 185 |
should_route :post, "/projects/33/files/new", :controller => 'files', :action => 'new', :id => '33' |
186 | 186 |
should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64' |
187 | 187 |
should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64' |
188 |
should_route :post, "/projects/64/activities/save", :controller => 'projects', :action => 'save_activities', :id => '64'
|
|
188 |
should_route :post, "/projects/64/activities/save", :controller => 'project_enumerations', :action => 'save', :id => '64'
|
|
189 | 189 |
|
190 | 190 |
should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'edit', :id => '1', :format => 'xml' |
191 | 191 |
|
Also available in: Unified diff
Refactor: move method, ProjectsController#save_activities to ProjectEnumerationsController#save