@@ -234,10 +234,11 class ProjectsController < ApplicationController | |||||
234 |
|
234 | |||
235 | def save_activities |
|
235 | def save_activities | |
236 | if request.post? && params[:enumerations] |
|
236 | if request.post? && params[:enumerations] | |
237 | params[:enumerations].each do |id, activity| |
|
237 | Project.transaction do | |
238 | @project.update_or_build_time_entry_activity(id, activity) |
|
238 | params[:enumerations].each do |id, activity| | |
|
239 | @project.update_or_create_time_entry_activity(id, activity) | |||
|
240 | end | |||
239 | end |
|
241 | end | |
240 | @project.save |
|
|||
241 | end |
|
242 | end | |
242 |
|
243 | |||
243 | redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project |
|
244 | redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project | |
@@ -245,7 +246,7 class ProjectsController < ApplicationController | |||||
245 |
|
246 | |||
246 | def reset_activities |
|
247 | def reset_activities | |
247 | @project.time_entry_activities.each do |time_entry_activity| |
|
248 | @project.time_entry_activities.each do |time_entry_activity| | |
248 | time_entry_activity.destroy |
|
249 | time_entry_activity.destroy(time_entry_activity.parent) | |
249 | end |
|
250 | end | |
250 | redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project |
|
251 | redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project | |
251 | end |
|
252 | end |
@@ -170,19 +170,24 class Project < ActiveRecord::Base | |||||
170 | end |
|
170 | end | |
171 | end |
|
171 | end | |
172 |
|
172 | |||
173 |
# Will |
|
173 | # Will create a new Project specific Activity or update an existing one | |
174 | def update_or_build_time_entry_activity(id, activity_hash) |
|
174 | # | |
|
175 | # This will raise a ActiveRecord::Rollback if the TimeEntryActivity | |||
|
176 | # does not successfully save. | |||
|
177 | def update_or_create_time_entry_activity(id, activity_hash) | |||
175 | if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id') |
|
178 | if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id') | |
176 |
self. |
|
179 | self.create_time_entry_activity_if_needed(activity_hash) | |
177 | else |
|
180 | else | |
178 | activity = project.time_entry_activities.find_by_id(id.to_i) |
|
181 | activity = project.time_entry_activities.find_by_id(id.to_i) | |
179 | activity.update_attributes(activity_hash) if activity |
|
182 | activity.update_attributes(activity_hash) if activity | |
180 | end |
|
183 | end | |
181 | end |
|
184 | end | |
182 |
|
185 | |||
183 | # Builds new activity |
|
186 | # Create a new TimeEntryActivity if it overrides a system TimeEntryActivity | |
184 | def build_time_entry_activity_if_needed(activity) |
|
187 | # | |
185 | # Only new override activities are built |
|
188 | # This will raise a ActiveRecord::Rollback if the TimeEntryActivity | |
|
189 | # does not successfully save. | |||
|
190 | def create_time_entry_activity_if_needed(activity) | |||
186 | if activity['parent_id'] |
|
191 | if activity['parent_id'] | |
187 |
|
192 | |||
188 | parent_activity = TimeEntryActivity.find(activity['parent_id']) |
|
193 | parent_activity = TimeEntryActivity.find(activity['parent_id']) | |
@@ -190,7 +195,13 class Project < ActiveRecord::Base | |||||
190 | activity['position'] = parent_activity.position |
|
195 | activity['position'] = parent_activity.position | |
191 |
|
196 | |||
192 | if Enumeration.overridding_change?(activity, parent_activity) |
|
197 | if Enumeration.overridding_change?(activity, parent_activity) | |
193 |
self.time_entry_activities. |
|
198 | project_activity = self.time_entry_activities.create(activity) | |
|
199 | ||||
|
200 | if project_activity.new_record? | |||
|
201 | raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved" | |||
|
202 | else | |||
|
203 | self.time_entries.update_all("activity_id = #{project_activity.id}", ["activity_id = ?", parent_activity.id]) | |||
|
204 | end | |||
194 | end |
|
205 | end | |
195 | end |
|
206 | end | |
196 | end |
|
207 | end |
@@ -55,4 +55,4 time_entries_004: | |||||
55 | hours: 7.65 |
|
55 | hours: 7.65 | |
56 | user_id: 1 |
|
56 | user_id: 1 | |
57 | tyear: 2007 |
|
57 | tyear: 2007 | |
58 | No newline at end of file |
|
58 |
@@ -24,7 +24,7 class ProjectsController; def rescue_action(e) raise e end; end | |||||
24 | class ProjectsControllerTest < ActionController::TestCase |
|
24 | class ProjectsControllerTest < ActionController::TestCase | |
25 | fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details, |
|
25 | fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details, | |
26 | :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, |
|
26 | :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, | |
27 | :attachments, :custom_fields, :custom_values |
|
27 | :attachments, :custom_fields, :custom_values, :time_entries | |
28 |
|
28 | |||
29 | def setup |
|
29 | def setup | |
30 | @controller = ProjectsController.new |
|
30 | @controller = ProjectsController.new | |
@@ -586,6 +586,27 class ProjectsControllerTest < ActionController::TestCase | |||||
586 | assert_nil TimeEntryActivity.find_by_id(project_activity_two.id) |
|
586 | assert_nil TimeEntryActivity.find_by_id(project_activity_two.id) | |
587 | end |
|
587 | end | |
588 |
|
588 | |||
|
589 | def test_reset_activities_should_reassign_time_entries_back_to_the_system_activity | |||
|
590 | @request.session[:user_id] = 2 # manager | |||
|
591 | project_activity = TimeEntryActivity.new({ | |||
|
592 | :name => 'Project Specific Design', | |||
|
593 | :parent => TimeEntryActivity.find(9), | |||
|
594 | :project => Project.find(1), | |||
|
595 | :active => true | |||
|
596 | }) | |||
|
597 | assert project_activity.save | |||
|
598 | assert TimeEntry.update_all("activity_id = '#{project_activity.id}'", ["project_id = ? AND activity_id = ?", 1, 9]) | |||
|
599 | assert 3, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size | |||
|
600 | ||||
|
601 | delete :reset_activities, :id => 1 | |||
|
602 | assert_response :redirect | |||
|
603 | assert_redirected_to 'projects/ecookbook/settings/activities' | |||
|
604 | ||||
|
605 | assert_nil TimeEntryActivity.find_by_id(project_activity.id) | |||
|
606 | assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size, "TimeEntries still assigned to project specific activity" | |||
|
607 | assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "TimeEntries still assigned to project specific activity" | |||
|
608 | end | |||
|
609 | ||||
589 | def test_save_activities_routing |
|
610 | def test_save_activities_routing | |
590 | assert_routing({:method => :post, :path => 'projects/64/activities/save'}, |
|
611 | assert_routing({:method => :post, :path => 'projects/64/activities/save'}, | |
591 | :controller => 'projects', :action => 'save_activities', :id => '64') |
|
612 | :controller => 'projects', :action => 'save_activities', :id => '64') | |
@@ -683,6 +704,46 class ProjectsControllerTest < ActionController::TestCase | |||||
683 | assert !activity_two.active? |
|
704 | assert !activity_two.active? | |
684 | end |
|
705 | end | |
685 |
|
706 | |||
|
707 | def test_save_activities_when_creating_new_activities_will_convert_existing_data | |||
|
708 | assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size | |||
|
709 | ||||
|
710 | @request.session[:user_id] = 2 # manager | |||
|
711 | post :save_activities, :id => 1, :enumerations => { | |||
|
712 | "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate | |||
|
713 | } | |||
|
714 | assert_response :redirect | |||
|
715 | ||||
|
716 | # No more TimeEntries using the system activity | |||
|
717 | assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries still assigned to system activities" | |||
|
718 | # All TimeEntries using project activity | |||
|
719 | project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1) | |||
|
720 | 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" | |||
|
721 | end | |||
|
722 | ||||
|
723 | def test_save_activities_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised | |||
|
724 | # TODO: Need to cause an exception on create but these tests | |||
|
725 | # aren't setup for mocking. Just create a record now so the | |||
|
726 | # second one is a dupicate | |||
|
727 | parent = TimeEntryActivity.find(9) | |||
|
728 | TimeEntryActivity.create!({:name => parent.name, :project_id => 1, :position => parent.position, :active => true}) | |||
|
729 | TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1), :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'}) | |||
|
730 | ||||
|
731 | assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size | |||
|
732 | assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size | |||
|
733 | ||||
|
734 | @request.session[:user_id] = 2 # manager | |||
|
735 | post :save_activities, :id => 1, :enumerations => { | |||
|
736 | "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design | |||
|
737 | "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"} # Development, Change custom value | |||
|
738 | } | |||
|
739 | assert_response :redirect | |||
|
740 | ||||
|
741 | # TimeEntries shouldn't have been reassigned on the failed record | |||
|
742 | assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries are not assigned to system activities" | |||
|
743 | # TimeEntries shouldn't have been reassigned on the saved record either | |||
|
744 | assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size, "Time Entries are not assigned to system activities" | |||
|
745 | end | |||
|
746 | ||||
686 | # A hook that is manually registered later |
|
747 | # A hook that is manually registered later | |
687 | class ProjectBasedTemplate < Redmine::Hook::ViewListener |
|
748 | class ProjectBasedTemplate < Redmine::Hook::ViewListener | |
688 | def view_layouts_base_html_head(context) |
|
749 | def view_layouts_base_html_head(context) |
General Comments 0
You need to be logged in to leave comments.
Login now