Project

General

Profile

Patch #2196 » issues_controller.rb.diff

Anh Kỳ Huỳnh, 2008-11-15 17:43

View differences:

app/controllers/issues_controller.rb (working copy)
5 5
# modify it under the terms of the GNU General Public License
6 6
# as published by the Free Software Foundation; either version 2
7 7
# of the License, or (at your option) any later version.
8
# 
8
#
9 9
# This program is distributed in the hope that it will be useful,
10 10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 12
# GNU General Public License for more details.
13
# 
13
#
14 14
# You should have received a copy of the GNU General Public License
15 15
# along with this program; if not, write to the Free Software
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
class IssuesController < ApplicationController
19 19
  menu_item :new_issue, :only => :new
20
  
20

  
21 21
  before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment]
22 22
  before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
23 23
  before_filter :find_project, :only => [:new, :update_form, :preview, :gantt, :calendar]
......
27 27

  
28 28
  helper :journals
29 29
  helper :projects
30
  include ProjectsHelper   
30
  include ProjectsHelper
31 31
  helper :custom_fields
32 32
  include CustomFieldsHelper
33 33
  helper :ifpdf
......
76 76
  rescue ActiveRecord::RecordNotFound
77 77
    render_404
78 78
  end
79
  
79

  
80 80
  def changes
81 81
    sort_init "#{Issue.table_name}.id", "desc"
82 82
    sort_update
......
92 92
  rescue ActiveRecord::RecordNotFound
93 93
    render_404
94 94
  end
95
  
95

  
96 96
  def show
97 97
    @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
98 98
    @journals.each_with_index {|j,i| j.indice = i+1}
......
123 123
    end
124 124
    @issue.attributes = params[:issue]
125 125
    @issue.author = User.current
126
    
126

  
127 127
    default_status = IssueStatus.default
128 128
    unless default_status
129 129
      flash.now[:error] = 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
130 130
      render :nothing => true, :layout => true
131 131
      return
132
    end    
132
    end
133 133
    @issue.status = default_status
134 134
    @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)).uniq
135
    
135

  
136 136
    if request.get? || request.xhr?
137 137
      @issue.start_date ||= Date.today
138 138
    else
......
145 145
        Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
146 146
        redirect_to :controller => 'issues', :action => 'show', :id => @issue
147 147
        return
148
      end		
149
    end	
148
      end
149
    end
150 150
    @priorities = Enumeration::get_values('IPRI')
151 151
    render :layout => !request.xhr?
152 152
  end
153
  
153

  
154 154
  # Attributes that can be updated on workflow transition (without :edit permission)
155 155
  # TODO: make it configurable (at least per role)
156 156
  UPDATABLE_ATTRS_ON_TRANSITION = %w(status_id assigned_to_id fixed_version_id done_ratio) unless const_defined?(:UPDATABLE_ATTRS_ON_TRANSITION)
157
  
157

  
158 158
  def edit
159 159
    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
160 160
    @priorities = Enumeration::get_values('IPRI')
161 161
    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
162 162
    @time_entry = TimeEntry.new
163
    
163

  
164 164
    @notes = params[:notes]
165 165
    journal = @issue.init_journal(User.current, @notes)
166 166
    # User can change issue attributes only if he has :edit permission or if a workflow transition is allowed
......
174 174
    if request.post?
175 175
      @time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
176 176
      @time_entry.attributes = params[:time_entry]
177
      @time_entry.comments = @time_entry.comments.strip unless @time_entry.comments.nil?
177 178
      attachments = attach_files(@issue, params[:attachments])
178 179
      attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
179 180
      if (@time_entry.hours.nil? || @time_entry.valid?) && @issue.save
180 181
        # Log spend time
181 182
        if current_role.allowed_to?(:log_time)
182
          @time_entry.save
183
          not_save = (@time_entry.hours.nil? or @time_entry.hours.zero?)
184
          not_save = (not_save and (@time_entry.comments.nil? or @time_entry.comments.empty?))
185
          @time_entry.save unless not_save
183 186
        end
184 187
        if !journal.new_record?
185 188
          # Only send notification if something was actually changed
......
213 216
      page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
214 217
    }
215 218
  end
216
  
219

  
217 220
  # Bulk edit a set of issues
218 221
  def bulk_edit
219 222
    if request.post?
......
222 225
      assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
223 226
      category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
224 227
      fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
225
      
226
      unsaved_issue_ids = []      
228

  
229
      unsaved_issue_ids = []
227 230
      @issues.each do |issue|
228 231
        journal = issue.init_journal(User.current, params[:notes])
229 232
        issue.priority = priority if priority
......
266 269
      User.current.memberships.each {|m| @allowed_projects << m.project if m.role.allowed_to?(:move_issues)}
267 270
    end
268 271
    @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
269
    @target_project ||= @project    
272
    @target_project ||= @project
270 273
    @trackers = @target_project.trackers
271 274
    if request.post?
272 275
      new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
......
285 288
    end
286 289
    render :layout => false if request.xhr?
287 290
  end
288
  
291

  
289 292
  def destroy
290 293
    @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
291 294
    if @hours > 0
......
321 324
    journal.save
322 325
    redirect_to :action => 'show', :id => @issue
323 326
  end
324
  
327

  
325 328
  def gantt
326 329
    @gantt = Redmine::Helpers::Gantt.new(params)
327 330
    retrieve_query
328 331
    if @query.valid?
329 332
      events = []
330 333
      # Issues that have start and due dates
331
      events += Issue.find(:all, 
334
      events += Issue.find(:all,
332 335
                           :order => "start_date, due_date",
333
                           :include => [:tracker, :status, :assigned_to, :priority, :project], 
336
                           :include => [:tracker, :status, :assigned_to, :priority, :project],
334 337
                           :conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
335 338
                           )
336 339
      # Issues that don't have a due date but that are assigned to a version with a date
337
      events += Issue.find(:all, 
340
      events += Issue.find(:all,
338 341
                           :order => "start_date, effective_date",
339
                           :include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version], 
342
                           :include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version],
340 343
                           :conditions => ["(#{@query.statement}) AND (((start_date>=? and start_date<=?) or (effective_date>=? and effective_date<=?) or (start_date<? and effective_date>?)) and start_date is not null and due_date is null and effective_date is not null)", @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to, @gantt.date_from, @gantt.date_to]
341 344
                           )
342 345
      # Versions
343 346
      events += Version.find(:all, :include => :project,
344 347
                                   :conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @gantt.date_from, @gantt.date_to])
345
                                   
348

  
346 349
      @gantt.events = events
347 350
    end
348
    
351

  
349 352
    respond_to do |format|
350 353
      format.html { render :template => "issues/gantt.rhtml", :layout => !request.xhr? }
351 354
      format.png  { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{@project.identifier}-gantt.png") } if @gantt.respond_to?('to_image')
352 355
      format.pdf  { send_data(render(:template => "issues/gantt.rfpdf", :layout => false), :type => 'application/pdf', :filename => "#{@project.identifier}-gantt.pdf") }
353 356
    end
354 357
  end
355
  
358

  
356 359
  def calendar
357 360
    if params[:year] and params[:year].to_i > 1900
358 361
      @year = params[:year].to_i
359 362
      if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
360 363
        @month = params[:month].to_i
361
      end    
364
      end
362 365
    end
363 366
    @year ||= Date.today.year
364 367
    @month ||= Date.today.month
365
    
368

  
366 369
    @calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
367 370
    retrieve_query
368 371
    if @query.valid?
369 372
      events = []
370
      events += Issue.find(:all, 
371
                           :include => [:tracker, :status, :assigned_to, :priority, :project], 
373
      events += Issue.find(:all,
374
                           :include => [:tracker, :status, :assigned_to, :priority, :project],
372 375
                           :conditions => ["(#{@query.statement}) AND ((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
373 376
                           )
374 377
      events += Version.find(:all, :include => :project,
375 378
                                   :conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
376
                                     
379

  
377 380
      @calendar.events = events
378 381
    end
379
    
382

  
380 383
    render :layout => false if request.xhr?
381 384
  end
382
  
385

  
383 386
  def context_menu
384 387
    @issues = Issue.find_all_by_id(params[:ids], :include => :project)
385 388
    if (@issues.size == 1)
......
400 403
      @assignables = @project.assignable_users
401 404
      @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
402 405
    end
403
    
406

  
404 407
    @priorities = Enumeration.get_values('IPRI').reverse
405 408
    @statuses = IssueStatus.find(:all, :order => 'position')
406 409
    @back = request.env['HTTP_REFERER']
407
    
410

  
408 411
    render :layout => false
409 412
  end
410 413

  
......
412 415
    @issue = Issue.new(params[:issue])
413 416
    render :action => :new, :layout => false
414 417
  end
415
  
418

  
416 419
  def preview
417 420
    @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
418 421
    @attachements = @issue.attachments if @issue
419 422
    @text = params[:notes] || (params[:issue] ? params[:issue][:description] : nil)
420 423
    render :partial => 'common/preview'
421 424
  end
422
  
425

  
423 426
private
424 427
  def find_issue
425 428
    @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
......
427 430
  rescue ActiveRecord::RecordNotFound
428 431
    render_404
429 432
  end
430
  
433

  
431 434
  # Filter for bulk operations
432 435
  def find_issues
433 436
    @issues = Issue.find_all_by_id(params[:id] || params[:ids])
......
442 445
  rescue ActiveRecord::RecordNotFound
443 446
    render_404
444 447
  end
445
  
448

  
446 449
  def find_project
447 450
    @project = Project.find(params[:project_id])
448 451
  rescue ActiveRecord::RecordNotFound
449 452
    render_404
450 453
  end
451
  
454

  
452 455
  def find_optional_project
453 456
    return true unless params[:project_id]
454 457
    @project = Project.find(params[:project_id])
......
456 459
  rescue ActiveRecord::RecordNotFound
457 460
    render_404
458 461
  end
459
  
462

  
460 463
  # Retrieve query from session or build a new query
461 464
  def retrieve_query
462 465
    if !params[:query_id].blank?
    (1-1/1)