Mercurial > hg > soundsoftware-site
comparison app/controllers/issues_controller.rb @ 1115:433d4f72a19b redmine-2.2
Update to Redmine SVN revision 11137 on 2.2-stable branch
author | Chris Cannam |
---|---|
date | Mon, 07 Jan 2013 12:01:42 +0000 |
parents | cbb26bc654de |
children | bb32da3bea34 622f24f53b42 261b3d9a4903 |
comparison
equal
deleted
inserted
replaced
929:5f33065ddc4b | 1115:433d4f72a19b |
---|---|
1 # Redmine - project management software | 1 # Redmine - project management software |
2 # Copyright (C) 2006-2011 Jean-Philippe Lang | 2 # Copyright (C) 2006-2012 Jean-Philippe Lang |
3 # | 3 # |
4 # This program is free software; you can redistribute it and/or | 4 # This program is free software; you can redistribute it and/or |
5 # modify it under the terms of the GNU General Public License | 5 # modify it under the terms of the GNU General Public License |
6 # as published by the Free Software Foundation; either version 2 | 6 # as published by the Free Software Foundation; either version 2 |
7 # of the License, or (at your option) any later version. | 7 # of the License, or (at your option) any later version. |
18 class IssuesController < ApplicationController | 18 class IssuesController < ApplicationController |
19 menu_item :new_issue, :only => [:new, :create] | 19 menu_item :new_issue, :only => [:new, :create] |
20 default_search_scope :issues | 20 default_search_scope :issues |
21 | 21 |
22 before_filter :find_issue, :only => [:show, :edit, :update] | 22 before_filter :find_issue, :only => [:show, :edit, :update] |
23 before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :move, :perform_move, :destroy] | 23 before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy] |
24 before_filter :check_project_uniqueness, :only => [:move, :perform_move] | |
25 before_filter :find_project, :only => [:new, :create] | 24 before_filter :find_project, :only => [:new, :create] |
26 before_filter :authorize, :except => [:index] | 25 before_filter :authorize, :except => [:index] |
27 before_filter :find_optional_project, :only => [:index] | 26 before_filter :find_optional_project, :only => [:index] |
28 before_filter :check_for_default_issue_status, :only => [:new, :create] | 27 before_filter :check_for_default_issue_status, :only => [:new, :create] |
29 before_filter :build_new_issue_from_params, :only => [:new, :create] | 28 before_filter :build_new_issue_from_params, :only => [:new, :create] |
49 include RepositoriesHelper | 48 include RepositoriesHelper |
50 helper :sort | 49 helper :sort |
51 include SortHelper | 50 include SortHelper |
52 include IssuesHelper | 51 include IssuesHelper |
53 helper :timelog | 52 helper :timelog |
54 helper :gantt | |
55 include Redmine::Export::PDF | 53 include Redmine::Export::PDF |
56 | |
57 verify :method => [:post, :delete], | |
58 :only => :destroy, | |
59 :render => { :nothing => true, :status => :method_not_allowed } | |
60 | |
61 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed } | |
62 verify :method => :post, :only => :bulk_update, :render => {:nothing => true, :status => :method_not_allowed } | |
63 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed } | |
64 | 54 |
65 def index | 55 def index |
66 retrieve_query | 56 retrieve_query |
67 sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) | 57 sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) |
68 sort_update(@query.sortable_columns) | 58 sort_update(@query.sortable_columns) |
59 @query.sort_criteria = sort_criteria.to_a | |
69 | 60 |
70 if @query.valid? | 61 if @query.valid? |
71 case params[:format] | 62 case params[:format] |
72 when 'csv', 'pdf' | 63 when 'csv', 'pdf' |
73 @limit = Setting.issues_export_limit.to_i | 64 @limit = Setting.issues_export_limit.to_i |
89 @issue_count_by_group = @query.issue_count_by_group | 80 @issue_count_by_group = @query.issue_count_by_group |
90 | 81 |
91 respond_to do |format| | 82 respond_to do |format| |
92 format.html { render :template => 'issues/index', :layout => !request.xhr? } | 83 format.html { render :template => 'issues/index', :layout => !request.xhr? } |
93 format.api { | 84 format.api { |
94 Issue.load_relations(@issues) if include_in_api_response?('relations') | 85 Issue.load_visible_relations(@issues) if include_in_api_response?('relations') |
95 } | 86 } |
96 format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } | 87 format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } |
97 format.csv { send_data(issues_to_csv(@issues, @project, @query, params), :type => 'text/csv; header=present', :filename => 'export.csv') } | 88 format.csv { send_data(issues_to_csv(@issues, @project, @query, params), :type => 'text/csv; header=present', :filename => 'export.csv') } |
98 format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') } | 89 format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') } |
99 end | 90 end |
107 rescue ActiveRecord::RecordNotFound | 98 rescue ActiveRecord::RecordNotFound |
108 render_404 | 99 render_404 |
109 end | 100 end |
110 | 101 |
111 def show | 102 def show |
112 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC") | 103 @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all |
113 @journals.each_with_index {|j,i| j.indice = i+1} | 104 @journals.each_with_index {|j,i| j.indice = i+1} |
105 @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) | |
114 @journals.reverse! if User.current.wants_comments_in_reverse_order? | 106 @journals.reverse! if User.current.wants_comments_in_reverse_order? |
115 | 107 |
116 if User.current.allowed_to?(:view_changesets, @project) | 108 @changesets = @issue.changesets.visible.all |
117 @changesets = @issue.changesets.visible.all | 109 @changesets.reverse! if User.current.wants_comments_in_reverse_order? |
118 @changesets.reverse! if User.current.wants_comments_in_reverse_order? | |
119 end | |
120 | 110 |
121 @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } | 111 @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } |
122 @allowed_statuses = @issue.new_statuses_allowed_to(User.current) | 112 @allowed_statuses = @issue.new_statuses_allowed_to(User.current) |
123 @edit_allowed = User.current.allowed_to?(:edit_issues, @project) | 113 @edit_allowed = User.current.allowed_to?(:edit_issues, @project) |
124 @priorities = IssuePriority.active | 114 @priorities = IssuePriority.active |
125 @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) | 115 @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) |
126 respond_to do |format| | 116 respond_to do |format| |
127 format.html { render :template => 'issues/show' } | 117 format.html { |
118 retrieve_previous_and_next_issue_ids | |
119 render :template => 'issues/show' | |
120 } | |
128 format.api | 121 format.api |
129 format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } | 122 format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } |
130 format.pdf { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") } | 123 format.pdf { |
124 pdf = issue_to_pdf(@issue, :journals => @journals) | |
125 send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") | |
126 } | |
131 end | 127 end |
132 end | 128 end |
133 | 129 |
134 # Add a new issue | 130 # Add a new issue |
135 # The new issue will be created from an existing one if copy_from parameter is given | 131 # The new issue will be created from an existing one if copy_from parameter is given |
136 def new | 132 def new |
137 respond_to do |format| | 133 respond_to do |format| |
138 format.html { render :action => 'new', :layout => !request.xhr? } | 134 format.html { render :action => 'new', :layout => !request.xhr? } |
139 format.js { render :partial => 'attributes' } | 135 format.js { render :partial => 'update_form' } |
140 end | 136 end |
141 end | 137 end |
142 | 138 |
143 def create | 139 def create |
144 call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) | 140 call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) |
141 @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) | |
145 if @issue.save | 142 if @issue.save |
146 attachments = Attachment.attach_files(@issue, params[:attachments]) | |
147 call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue}) | 143 call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue}) |
148 respond_to do |format| | 144 respond_to do |format| |
149 format.html { | 145 format.html { |
150 render_attachment_warning_if_needed(@issue) | 146 render_attachment_warning_if_needed(@issue) |
151 flash[:notice] = l(:notice_issue_successful_create, :id => "<a href='#{issue_path(@issue)}'>##{@issue.id}</a>") | 147 flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject)) |
152 redirect_to(params[:continue] ? { :action => 'new', :project_id => @project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } : | 148 redirect_to(params[:continue] ? { :action => 'new', :project_id => @issue.project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } : |
153 { :action => 'show', :id => @issue }) | 149 { :action => 'show', :id => @issue }) |
154 } | 150 } |
155 format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) } | 151 format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) } |
156 end | 152 end |
157 return | 153 return |
162 end | 158 end |
163 end | 159 end |
164 end | 160 end |
165 | 161 |
166 def edit | 162 def edit |
167 update_issue_from_params | 163 return unless update_issue_from_params |
168 | |
169 @journal = @issue.current_journal | |
170 | 164 |
171 respond_to do |format| | 165 respond_to do |format| |
172 format.html { } | 166 format.html { } |
173 format.xml { } | 167 format.xml { } |
174 end | 168 end |
175 end | 169 end |
176 | 170 |
177 def update | 171 def update |
178 update_issue_from_params | 172 return unless update_issue_from_params |
179 | 173 @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) |
180 if @issue.save_issue_with_child_records(params, @time_entry) | 174 saved = false |
175 begin | |
176 saved = @issue.save_issue_with_child_records(params, @time_entry) | |
177 rescue ActiveRecord::StaleObjectError | |
178 @conflict = true | |
179 if params[:last_journal_id] | |
180 @conflict_journals = @issue.journals_after(params[:last_journal_id]).all | |
181 @conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) | |
182 end | |
183 end | |
184 | |
185 if saved | |
181 render_attachment_warning_if_needed(@issue) | 186 render_attachment_warning_if_needed(@issue) |
182 flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? | 187 flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? |
183 | 188 |
184 respond_to do |format| | 189 respond_to do |format| |
185 format.html { redirect_back_or_default({:action => 'show', :id => @issue}) } | 190 format.html { redirect_back_or_default({:action => 'show', :id => @issue}) } |
186 format.api { head :ok } | 191 format.api { render_api_ok } |
187 end | 192 end |
188 else | 193 else |
189 render_attachment_warning_if_needed(@issue) | |
190 flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? | |
191 @journal = @issue.current_journal | |
192 | |
193 respond_to do |format| | 194 respond_to do |format| |
194 format.html { render :action => 'edit' } | 195 format.html { render :action => 'edit' } |
195 format.api { render_validation_errors(@issue) } | 196 format.api { render_validation_errors(@issue) } |
196 end | 197 end |
197 end | 198 end |
198 end | 199 end |
199 | 200 |
200 # Bulk edit a set of issues | 201 # Bulk edit/copy a set of issues |
201 def bulk_edit | 202 def bulk_edit |
202 @issues.sort! | 203 @issues.sort! |
203 @available_statuses = @projects.map{|p|Workflow.available_statuses(p)}.inject{|memo,w|memo & w} | 204 @copy = params[:copy].present? |
204 @custom_fields = @projects.map{|p|p.all_issue_custom_fields}.inject{|memo,c|memo & c} | 205 @notes = params[:notes] |
205 @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a} | 206 |
206 @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t} | 207 if User.current.allowed_to?(:move_issues, @projects) |
208 @allowed_projects = Issue.allowed_target_projects_on_move | |
209 if params[:issue] | |
210 @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s} | |
211 if @target_project | |
212 target_projects = [@target_project] | |
213 end | |
214 end | |
215 end | |
216 target_projects ||= @projects | |
217 | |
218 if @copy | |
219 @available_statuses = [IssueStatus.default] | |
220 else | |
221 @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) | |
222 end | |
223 @custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&) | |
224 @assignables = target_projects.map(&:assignable_users).reduce(:&) | |
225 @trackers = target_projects.map(&:trackers).reduce(:&) | |
226 @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) | |
227 @categories = target_projects.map {|p| p.issue_categories}.reduce(:&) | |
228 if @copy | |
229 @attachments_present = @issues.detect {|i| i.attachments.any?}.present? | |
230 @subtasks_present = @issues.detect {|i| !i.leaf?}.present? | |
231 end | |
232 | |
233 @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) | |
234 render :layout => false if request.xhr? | |
207 end | 235 end |
208 | 236 |
209 def bulk_update | 237 def bulk_update |
210 @issues.sort! | 238 @issues.sort! |
239 @copy = params[:copy].present? | |
211 attributes = parse_params_for_bulk_issue_attributes(params) | 240 attributes = parse_params_for_bulk_issue_attributes(params) |
212 | 241 |
213 unsaved_issue_ids = [] | 242 unsaved_issue_ids = [] |
243 moved_issues = [] | |
244 | |
245 if @copy && params[:copy_subtasks].present? | |
246 # Descendant issues will be copied with the parent task | |
247 # Don't copy them twice | |
248 @issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}} | |
249 end | |
250 | |
214 @issues.each do |issue| | 251 @issues.each do |issue| |
215 issue.reload | 252 issue.reload |
253 if @copy | |
254 issue = issue.copy({}, | |
255 :attachments => params[:copy_attachments].present?, | |
256 :subtasks => params[:copy_subtasks].present? | |
257 ) | |
258 end | |
216 journal = issue.init_journal(User.current, params[:notes]) | 259 journal = issue.init_journal(User.current, params[:notes]) |
217 issue.safe_attributes = attributes | 260 issue.safe_attributes = attributes |
218 call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) | 261 call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) |
219 unless issue.save | 262 if issue.save |
263 moved_issues << issue | |
264 else | |
220 # Keep unsaved issue ids to display them in flash error | 265 # Keep unsaved issue ids to display them in flash error |
221 unsaved_issue_ids << issue.id | 266 unsaved_issue_ids << issue.id |
222 end | 267 end |
223 end | 268 end |
224 set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) | 269 set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) |
225 redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) | 270 |
271 if params[:follow] | |
272 if @issues.size == 1 && moved_issues.size == 1 | |
273 redirect_to :controller => 'issues', :action => 'show', :id => moved_issues.first | |
274 elsif moved_issues.map(&:project).uniq.size == 1 | |
275 redirect_to :controller => 'issues', :action => 'index', :project_id => moved_issues.map(&:project).first | |
276 end | |
277 else | |
278 redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project}) | |
279 end | |
226 end | 280 end |
227 | 281 |
228 def destroy | 282 def destroy |
229 @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f | 283 @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f |
230 if @hours > 0 | 284 if @hours > 0 |
253 # nothing to do, issue was already deleted (eg. by a parent) | 307 # nothing to do, issue was already deleted (eg. by a parent) |
254 end | 308 end |
255 end | 309 end |
256 respond_to do |format| | 310 respond_to do |format| |
257 format.html { redirect_back_or_default(:action => 'index', :project_id => @project) } | 311 format.html { redirect_back_or_default(:action => 'index', :project_id => @project) } |
258 format.api { head :ok } | 312 format.api { render_api_ok } |
259 end | 313 end |
260 end | 314 end |
261 | 315 |
262 private | 316 private |
263 def find_issue | |
264 # Issue.visible.find(...) can not be used to redirect user to the login form | |
265 # if the issue actually exists but requires authentication | |
266 @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category]) | |
267 unless @issue.visible? | |
268 deny_access | |
269 return | |
270 end | |
271 @project = @issue.project | |
272 rescue ActiveRecord::RecordNotFound | |
273 render_404 | |
274 end | |
275 | 317 |
276 def find_project | 318 def find_project |
277 project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id] | 319 project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id]) |
278 @project = Project.find(project_id) | 320 @project = Project.find(project_id) |
279 rescue ActiveRecord::RecordNotFound | 321 rescue ActiveRecord::RecordNotFound |
280 render_404 | 322 render_404 |
323 end | |
324 | |
325 def retrieve_previous_and_next_issue_ids | |
326 retrieve_query_from_session | |
327 if @query | |
328 sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) | |
329 sort_update(@query.sortable_columns, 'issues_index_sort') | |
330 limit = 500 | |
331 issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version]) | |
332 if (idx = issue_ids.index(@issue.id)) && idx < limit | |
333 if issue_ids.size < 500 | |
334 @issue_position = idx + 1 | |
335 @issue_count = issue_ids.size | |
336 end | |
337 @prev_issue_id = issue_ids[idx - 1] if idx > 0 | |
338 @next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1) | |
339 end | |
340 end | |
281 end | 341 end |
282 | 342 |
283 # Used by #edit and #update to set some common instance variables | 343 # Used by #edit and #update to set some common instance variables |
284 # from the params | 344 # from the params |
285 # TODO: Refactor, not everything in here is needed by #edit | 345 # TODO: Refactor, not everything in here is needed by #edit |
286 def update_issue_from_params | 346 def update_issue_from_params |
287 @allowed_statuses = @issue.new_statuses_allowed_to(User.current) | |
288 @priorities = IssuePriority.active | |
289 @edit_allowed = User.current.allowed_to?(:edit_issues, @project) | 347 @edit_allowed = User.current.allowed_to?(:edit_issues, @project) |
290 @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) | 348 @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) |
291 @time_entry.attributes = params[:time_entry] | 349 @time_entry.attributes = params[:time_entry] |
292 | 350 |
293 @notes = params[:notes] || (params[:issue].present? ? params[:issue][:notes] : nil) | 351 @issue.init_journal(User.current) |
294 @issue.init_journal(User.current, @notes) | 352 |
295 @issue.safe_attributes = params[:issue] | 353 issue_attributes = params[:issue] |
354 if issue_attributes && params[:conflict_resolution] | |
355 case params[:conflict_resolution] | |
356 when 'overwrite' | |
357 issue_attributes = issue_attributes.dup | |
358 issue_attributes.delete(:lock_version) | |
359 when 'add_notes' | |
360 issue_attributes = issue_attributes.slice(:notes) | |
361 when 'cancel' | |
362 redirect_to issue_path(@issue) | |
363 return false | |
364 end | |
365 end | |
366 @issue.safe_attributes = issue_attributes | |
367 @priorities = IssuePriority.active | |
368 @allowed_statuses = @issue.new_statuses_allowed_to(User.current) | |
369 true | |
296 end | 370 end |
297 | 371 |
298 # TODO: Refactor, lots of extra code in here | 372 # TODO: Refactor, lots of extra code in here |
299 # TODO: Changing tracker on an existing issue should not trigger this | 373 # TODO: Changing tracker on an existing issue should not trigger this |
300 def build_new_issue_from_params | 374 def build_new_issue_from_params |
301 if params[:id].blank? | 375 if params[:id].blank? |
302 @issue = Issue.new | 376 @issue = Issue.new |
303 @issue.copy_from(params[:copy_from]) if params[:copy_from] | 377 if params[:copy_from] |
378 begin | |
379 @copy_from = Issue.visible.find(params[:copy_from]) | |
380 @copy_attachments = params[:copy_attachments].present? || request.get? | |
381 @copy_subtasks = params[:copy_subtasks].present? || request.get? | |
382 @issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks) | |
383 rescue ActiveRecord::RecordNotFound | |
384 render_404 | |
385 return | |
386 end | |
387 end | |
304 @issue.project = @project | 388 @issue.project = @project |
305 else | 389 else |
306 @issue = @project.issues.visible.find(params[:id]) | 390 @issue = @project.issues.visible.find(params[:id]) |
307 end | 391 end |
308 | 392 |
309 @issue.project = @project | 393 @issue.project = @project |
310 @issue.author = User.current | 394 @issue.author ||= User.current |
311 # Tracker must be set before custom field values | 395 # Tracker must be set before custom field values |
312 @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) | 396 @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) |
313 if @issue.tracker.nil? | 397 if @issue.tracker.nil? |
314 render_error l(:error_no_tracker_in_project) | 398 render_error l(:error_no_tracker_in_project) |
315 return false | 399 return false |
316 end | 400 end |
317 @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date? | 401 @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date? |
318 if params[:issue].is_a?(Hash) | 402 @issue.safe_attributes = params[:issue] |
319 @issue.safe_attributes = params[:issue] | 403 |
320 if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record? | |
321 @issue.watcher_user_ids = params[:issue]['watcher_user_ids'] | |
322 end | |
323 end | |
324 @priorities = IssuePriority.active | 404 @priorities = IssuePriority.active |
325 @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) | 405 @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) |
406 @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq | |
326 end | 407 end |
327 | 408 |
328 def check_for_default_issue_status | 409 def check_for_default_issue_status |
329 if IssueStatus.default.nil? | 410 if IssueStatus.default.nil? |
330 render_error l(:error_no_default_issue_status) | 411 render_error l(:error_no_default_issue_status) |
333 end | 414 end |
334 | 415 |
335 def parse_params_for_bulk_issue_attributes(params) | 416 def parse_params_for_bulk_issue_attributes(params) |
336 attributes = (params[:issue] || {}).reject {|k,v| v.blank?} | 417 attributes = (params[:issue] || {}).reject {|k,v| v.blank?} |
337 attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} | 418 attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} |
338 attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] | 419 if custom = attributes[:custom_field_values] |
420 custom.reject! {|k,v| v.blank?} | |
421 custom.keys.each do |k| | |
422 if custom[k].is_a?(Array) | |
423 custom[k] << '' if custom[k].delete('__none__') | |
424 else | |
425 custom[k] = '' if custom[k] == '__none__' | |
426 end | |
427 end | |
428 end | |
339 attributes | 429 attributes |
340 end | 430 end |
341 end | 431 end |