Mercurial > hg > soundsoftware-site
comparison app/controllers/timelog_controller.rb @ 441:cbce1fd3b1b7 redmine-1.2
Update to Redmine 1.2-stable branch (Redmine SVN rev 6000)
author | Chris Cannam |
---|---|
date | Mon, 06 Jun 2011 14:24:13 +0100 |
parents | 8661b858af72 |
children | 0c939c159af4 |
comparison
equal
deleted
inserted
replaced
245:051f544170fe | 441:cbce1fd3b1b7 |
---|---|
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 |
18 class TimelogController < ApplicationController | 18 class TimelogController < ApplicationController |
19 menu_item :issues | 19 menu_item :issues |
20 before_filter :find_project, :only => [:new, :create] | 20 before_filter :find_project, :only => [:new, :create] |
21 before_filter :find_time_entry, :only => [:show, :edit, :update, :destroy] | 21 before_filter :find_time_entry, :only => [:show, :edit, :update] |
22 before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy] | |
22 before_filter :authorize, :except => [:index] | 23 before_filter :authorize, :except => [:index] |
23 before_filter :find_optional_project, :only => [:index] | 24 before_filter :find_optional_project, :only => [:index] |
24 accept_key_auth :index, :show, :create, :update, :destroy | 25 accept_key_auth :index, :show, :create, :update, :destroy |
25 | 26 |
26 helper :sort | 27 helper :sort |
38 'project' => "#{Project.table_name}.name", | 39 'project' => "#{Project.table_name}.name", |
39 'issue' => 'issue_id', | 40 'issue' => 'issue_id', |
40 'hours' => 'hours' | 41 'hours' => 'hours' |
41 | 42 |
42 cond = ARCondition.new | 43 cond = ARCondition.new |
43 if @project.nil? | 44 if @issue |
44 cond << Project.allowed_to_condition(User.current, :view_time_entries) | 45 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}" |
45 elsif @issue.nil? | 46 elsif @project |
46 cond << @project.project_condition(Setting.display_subprojects_issues?) | 47 cond << @project.project_condition(Setting.display_subprojects_issues?) |
47 else | |
48 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}" | |
49 end | 48 end |
50 | 49 |
51 retrieve_date_range | 50 retrieve_date_range |
52 cond << ['spent_on BETWEEN ? AND ?', @from, @to] | 51 cond << ['spent_on BETWEEN ? AND ?', @from, @to] |
53 | 52 |
54 TimeEntry.visible_by(User.current) do | 53 respond_to do |format| |
55 respond_to do |format| | 54 format.html { |
56 format.html { | 55 # Paginate results |
57 # Paginate results | 56 @entry_count = TimeEntry.visible.count(:include => [:project, :issue], :conditions => cond.conditions) |
58 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions) | 57 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page'] |
59 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page'] | 58 @entries = TimeEntry.visible.find(:all, |
60 @entries = TimeEntry.find(:all, | 59 :include => [:project, :activity, :user, {:issue => :tracker}], |
61 :include => [:project, :activity, :user, {:issue => :tracker}], | 60 :conditions => cond.conditions, |
62 :conditions => cond.conditions, | 61 :order => sort_clause, |
63 :order => sort_clause, | 62 :limit => @entry_pages.items_per_page, |
64 :limit => @entry_pages.items_per_page, | 63 :offset => @entry_pages.current.offset) |
65 :offset => @entry_pages.current.offset) | 64 @total_hours = TimeEntry.visible.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f |
66 @total_hours = TimeEntry.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f | 65 |
67 | 66 render :layout => !request.xhr? |
68 render :layout => !request.xhr? | 67 } |
69 } | 68 format.api { |
70 format.api { | 69 @entry_count = TimeEntry.visible.count(:include => [:project, :issue], :conditions => cond.conditions) |
71 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions) | 70 @offset, @limit = api_offset_and_limit |
72 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page'] | 71 @entries = TimeEntry.visible.find(:all, |
73 @entries = TimeEntry.find(:all, | 72 :include => [:project, :activity, :user, {:issue => :tracker}], |
74 :include => [:project, :activity, :user, {:issue => :tracker}], | 73 :conditions => cond.conditions, |
75 :conditions => cond.conditions, | 74 :order => sort_clause, |
76 :order => sort_clause, | 75 :limit => @limit, |
77 :limit => @entry_pages.items_per_page, | 76 :offset => @offset) |
78 :offset => @entry_pages.current.offset) | 77 } |
79 } | 78 format.atom { |
80 format.atom { | 79 entries = TimeEntry.visible.find(:all, |
81 entries = TimeEntry.find(:all, | 80 :include => [:project, :activity, :user, {:issue => :tracker}], |
82 :include => [:project, :activity, :user, {:issue => :tracker}], | 81 :conditions => cond.conditions, |
83 :conditions => cond.conditions, | 82 :order => "#{TimeEntry.table_name}.created_on DESC", |
84 :order => "#{TimeEntry.table_name}.created_on DESC", | 83 :limit => Setting.feeds_limit.to_i) |
85 :limit => Setting.feeds_limit.to_i) | 84 render_feed(entries, :title => l(:label_spent_time)) |
86 render_feed(entries, :title => l(:label_spent_time)) | 85 } |
87 } | 86 format.csv { |
88 format.csv { | 87 # Export all entries |
89 # Export all entries | 88 @entries = TimeEntry.visible.find(:all, |
90 @entries = TimeEntry.find(:all, | 89 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], |
91 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], | 90 :conditions => cond.conditions, |
92 :conditions => cond.conditions, | 91 :order => sort_clause) |
93 :order => sort_clause) | 92 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv') |
94 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv') | 93 } |
95 } | |
96 end | |
97 end | 94 end |
98 end | 95 end |
99 | 96 |
100 def show | 97 def show |
101 respond_to do |format| | 98 respond_to do |format| |
162 format.api { render_validation_errors(@time_entry) } | 159 format.api { render_validation_errors(@time_entry) } |
163 end | 160 end |
164 end | 161 end |
165 end | 162 end |
166 | 163 |
164 def bulk_edit | |
165 @available_activities = TimeEntryActivity.shared.active | |
166 @custom_fields = TimeEntry.first.available_custom_fields | |
167 end | |
168 | |
169 def bulk_update | |
170 attributes = parse_params_for_bulk_time_entry_attributes(params) | |
171 | |
172 unsaved_time_entry_ids = [] | |
173 @time_entries.each do |time_entry| | |
174 time_entry.reload | |
175 time_entry.attributes = attributes | |
176 call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry }) | |
177 unless time_entry.save | |
178 # Keep unsaved time_entry ids to display them in flash error | |
179 unsaved_time_entry_ids << time_entry.id | |
180 end | |
181 end | |
182 set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids) | |
183 redirect_back_or_default({:controller => 'timelog', :action => 'index', :project_id => @projects.first}) | |
184 end | |
185 | |
167 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed } | 186 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed } |
168 def destroy | 187 def destroy |
169 if @time_entry.destroy && @time_entry.destroyed? | 188 @time_entries.each do |t| |
170 respond_to do |format| | 189 begin |
171 format.html { | 190 unless t.destroy && t.destroyed? |
172 flash[:notice] = l(:notice_successful_delete) | 191 respond_to do |format| |
173 redirect_to :back | 192 format.html { |
174 } | 193 flash[:error] = l(:notice_unable_delete_time_entry) |
175 format.api { head :ok } | 194 redirect_to :back |
176 end | 195 } |
177 else | 196 format.api { render_validation_errors(t) } |
178 respond_to do |format| | 197 end |
179 format.html { | 198 return |
180 flash[:error] = l(:notice_unable_delete_time_entry) | 199 end |
181 redirect_to :back | 200 rescue ::ActionController::RedirectBackError |
182 } | 201 redirect_to :action => 'index', :project_id => @projects.first |
183 format.api { render_validation_errors(@time_entry) } | 202 return |
184 end | 203 end |
185 end | 204 end |
186 rescue ::ActionController::RedirectBackError | 205 |
187 redirect_to :action => 'index', :project_id => @time_entry.project | 206 respond_to do |format| |
207 format.html { | |
208 flash[:notice] = l(:notice_successful_delete) | |
209 redirect_back_or_default(:action => 'index', :project_id => @projects.first) | |
210 } | |
211 format.api { head :ok } | |
212 end | |
188 end | 213 end |
189 | 214 |
190 private | 215 private |
191 def find_time_entry | 216 def find_time_entry |
192 @time_entry = TimeEntry.find(params[:id]) | 217 @time_entry = TimeEntry.find(params[:id]) |
195 return false | 220 return false |
196 end | 221 end |
197 @project = @time_entry.project | 222 @project = @time_entry.project |
198 rescue ActiveRecord::RecordNotFound | 223 rescue ActiveRecord::RecordNotFound |
199 render_404 | 224 render_404 |
225 end | |
226 | |
227 def find_time_entries | |
228 @time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids]) | |
229 raise ActiveRecord::RecordNotFound if @time_entries.empty? | |
230 @projects = @time_entries.collect(&:project).compact.uniq | |
231 @project = @projects.first if @projects.size == 1 | |
232 rescue ActiveRecord::RecordNotFound | |
233 render_404 | |
234 end | |
235 | |
236 def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids) | |
237 if unsaved_time_entry_ids.empty? | |
238 flash[:notice] = l(:notice_successful_update) unless time_entries.empty? | |
239 else | |
240 flash[:error] = l(:notice_failed_to_save_time_entries, | |
241 :count => unsaved_time_entry_ids.size, | |
242 :total => time_entries.size, | |
243 :ids => '#' + unsaved_time_entry_ids.join(', #')) | |
244 end | |
200 end | 245 end |
201 | 246 |
202 def find_project | 247 def find_project |
203 if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present? | 248 if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present? |
204 @issue = Issue.find(issue_id) | 249 @issue = Issue.find(issue_id) |
267 @from, @to = @to, @from if @from && @to && @from > @to | 312 @from, @to = @to, @from if @from && @to && @from > @to |
268 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today) | 313 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today) |
269 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today) | 314 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today) |
270 end | 315 end |
271 | 316 |
317 def parse_params_for_bulk_time_entry_attributes(params) | |
318 attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?} | |
319 attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} | |
320 attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] | |
321 attributes | |
322 end | |
272 end | 323 end |