Project

General

Profile

Patch #1666 » explicit_version_completion_v2.patch

fix validation bug + always show current target version - Peter Van den Bosch, 2008-07-21 18:18

View differences:

app/models/issue.rb (working copy)
113 113
    if start_date && soonest_start && start_date < soonest_start
114 114
      errors.add :start_date, :activerecord_error_invalid
115 115
    end
116
    
117
    if fixed_version_id
118
      #status and version have to retrieved from their id, because the objects only get updated upon saving
119
      new_status = IssueStatus.find_by_id(status_id)
120
      if !new_status.is_closed? && Version.find_by_id(fixed_version_id).completed?
121
        errors.add :fixed_version, :activerecord_error_version_completed
122
      end    
123
    end
116 124
  end
117 125
  
118 126
  def validate_on_create
app/models/version.rb (working copy)
26 26
  validates_length_of :name, :maximum => 60
27 27
  validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date, :allow_nil => true
28 28
  
29
  def validate
30
    if completed? && open_issues_count > 0
31
      errors.add :completed, :activerecord_error_open_issues
32
    end
33
  end
34
  
29 35
  def start_date
30 36
    effective_date
31 37
  end
......
44 50
    @spent_hours ||= TimeEntry.sum(:hours, :include => :issue, :conditions => ["#{Issue.table_name}.fixed_version_id = ?", id]).to_f
45 51
  end
46 52
  
47
  # Returns true if the version is completed: due date reached and no open issues
48
  def completed?
49
    effective_date && (effective_date <= Date.today) && (open_issues_count == 0)
50
  end
51
  
52 53
  def completed_pourcent
53 54
    if fixed_issues.count == 0
54 55
      0
......
69 70
  
70 71
  # Returns true if the version is overdue: due date reached and some open issues
71 72
  def overdue?
72
    effective_date && (effective_date < Date.today) && (open_issues_count > 0)
73
    effective_date && (effective_date < Date.today) && (!self.completed?)
73 74
  end
74 75
  
75 76
  def open_issues_count
app/models/project.rb (working copy)
171 171
    children.select {|child| child.active?}
172 172
  end
173 173
  
174
  def incomplete_versions
175
    versions.reject(&:completed?).sort
176
  end
177
  
174 178
  # Returns an array of the trackers used by the project and its sub projects
175 179
  def rolled_up_trackers
176 180
    @rolled_up_trackers ||=
app/controllers/issues_controller.rb (working copy)
99 99
    @journals.each_with_index {|j,i| j.indice = i+1}
100 100
    @journals.reverse! if User.current.wants_comments_in_reverse_order?
101 101
    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
102
    @targetable_versions = ([@issue.fixed_version] + @project.incomplete_versions).compact.uniq.sort
102 103
    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
103 104
    @priorities = Enumeration::get_values('IPRI')
104 105
    @time_entry = TimeEntry.new
......
133 134
    end    
134 135
    @issue.status = default_status
135 136
    @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)).uniq
137
    @targetable_versions = ([@issue.fixed_version] + @project.incomplete_versions).compact.uniq.sort
136 138
    
137 139
    if request.get? || request.xhr?
138 140
      @issue.start_date ||= Date.today
......
158 160
  
159 161
  def edit
160 162
    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
163
    @targetable_versions = ([@issue.fixed_version] + @project.incomplete_versions).compact.uniq.sort
161 164
    @priorities = Enumeration::get_values('IPRI')
162 165
    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
163 166
    
......
323 326
  
324 327
  def context_menu
325 328
    @issues = Issue.find_all_by_id(params[:ids], :include => :project)
329
    projects = @issues.collect(&:project).compact.uniq
330
    @project = projects.first if projects.size == 1
331
    
326 332
    if (@issues.size == 1)
327 333
      @issue = @issues.first
328 334
      @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
329 335
      @assignables = @issue.assignable_users
330 336
      @assignables << @issue.assigned_to if @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
337
      @targetable_versions = ([@issue.fixed_version] + @project.incomplete_versions).compact.uniq.sort
331 338
    end
332
    projects = @issues.collect(&:project).compact.uniq
333
    @project = projects.first if projects.size == 1
334

  
339
    
335 340
    @can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
336 341
            :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
337 342
            :update => (@issue && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && !@allowed_statuses.empty?))),
app/controllers/projects_controller.rb (working copy)
213 213
  def roadmap
214 214
    @trackers = @project.trackers.find(:all, :conditions => ["is_in_roadmap=?", true])
215 215
    retrieve_selected_tracker_ids(@trackers)
216
    @versions = @project.versions.sort
217
    @versions = @versions.select {|v| !v.completed? } unless params[:completed]
216
    @versions = params[:completed] ? @project.versions.sort : @project.incomplete_versions
218 217
  end
219 218
  
220 219
  def activity
app/views/versions/_form.rhtml (working copy)
5 5
<p><%= f.text_field :description, :size => 60 %></p>
6 6
<p><%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %></p>
7 7
<p><%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
8
<p><%= f.check_box :completed, :label => :label_completed_version %>
8 9
</div>
app/views/issues/_form.rhtml (working copy)
30 30
                     {:controller => 'projects', :action => 'add_issue_category', :id => @project},
31 31
                     :class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
32 32
<%= content_tag('p', f.select(:fixed_version_id, 
33
                              (@project.versions.sort.collect {|v| [v.name, v.id]}),
34
                              { :include_blank => true })) unless @project.versions.empty? %>
33
                              (@targetable_versions.collect {|v| [v.name, v.id]}),
34
                              { :include_blank => true })) unless @targetable_versions.empty? %>
35 35
</div>
36 36

  
37 37
<div class="splitcontentright">
app/views/issues/bulk_edit.rhtml (working copy)
27 27
<label><%= l(:field_fixed_version) %>: 
28 28
<%= select_tag('fixed_version_id', content_tag('option', l(:label_no_change_option), :value => '') +
29 29
                                   content_tag('option', l(:label_none), :value => 'none') +
30
                                   options_from_collection_for_select(@project.versions, :id, :name)) %></label>
30
                                   options_from_collection_for_select(@project.incomplete_versions, :id, :name)) %></label>
31 31
</p>
32 32

  
33 33
<p>
app/views/issues/_form_update.rhtml (working copy)
5 5
<div class="splitcontentright">
6 6
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
7 7
<%= content_tag('p', f.select(:fixed_version_id, 
8
                          (@project.versions.sort.collect {|v| [v.name, v.id]}),
9
                          { :include_blank => true })) unless @project.versions.empty? %>
8
                          (@targetable_versions.collect {|v| [v.name, v.id]}),
9
                          { :include_blank => true })) unless @targetable_versions.empty? %>
10 10
</div>
app/views/issues/context_menu.rhtml (working copy)
20 20
		<% end -%>
21 21
		</ul>
22 22
	</li>
23
	<% unless @project.versions.empty? -%>
23
	<% unless @targetable_versions.empty? -%>
24 24
	<li class="folder">			
25 25
		<a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
26 26
		<ul>
27
		<% @project.versions.sort.each do |v| -%>
27
		<% @targetable_versions.each do |v| -%>
28 28
		    <li><%= context_menu_link v.name, {:controller => 'issues', :action => 'edit', :id => @issue, 'issue[fixed_version_id]' => v, :back_to => @back}, :method => :post,
29 29
		                              :selected => (v == @issue.fixed_version), :disabled => !@can[:update] %></li>
30 30
		<% end -%>
lang/en.yml (working copy)
35 35
activerecord_error_greater_than_start_date: must be greater than start date
36 36
activerecord_error_not_same_project: doesn't belong to the same project
37 37
activerecord_error_circular_dependency: This relation would create a circular dependency
38
activerecord_error_version_completed: is a completed version
39
activerecord_error_open_issues: There are still open issues
38 40

  
39 41
general_fmt_age: %d yr
40 42
general_fmt_age_plural: %d yrs
......
464 466
label_stay_logged_in: Stay logged in
465 467
label_disabled: disabled
466 468
label_show_completed_versions: Show completed versions
469
label_completed_version: Completed
467 470
label_me: me
468 471
label_board: Forum
469 472
label_board_new: New forum
lang/fr.yml (working copy)
35 35
activerecord_error_greater_than_start_date: doit être postérieur à la date de début
36 36
activerecord_error_not_same_project: n'appartient pas au même projet
37 37
activerecord_error_circular_dependency: Cette relation créerait une dépendance circulaire
38
activerecord_error_version_completed: est une version complétée
39
activerecord_error_open_issues: Il reste encore des demandes ouvertes
38 40

  
39 41
general_fmt_age: %d an
40 42
general_fmt_age_plural: %d ans
......
464 466
label_stay_logged_in: Rester connecté
465 467
label_disabled: désactivé
466 468
label_show_completed_versions: Voir les versions passées
469
label_completed_version: Complété
467 470
label_me: moi
468 471
label_board: Forum
469 472
label_board_new: Nouveau forum
lang/nl.yml (working copy)
35 35
activerecord_error_greater_than_start_date: moet hoger zijn dan startdatum
36 36
activerecord_error_not_same_project: hoort niet bij hetzelfde project
37 37
activerecord_error_circular_dependency: Deze relatie zou een circulaire afhankelijkheid tot gevolg hebben
38
activerecord_error_version_completed: is een afgeronde versie
39
activerecord_error_open_issues: Er zijn nog open issues
38 40

  
39 41
general_fmt_age: %d jr
40 42
general_fmt_age_plural: %d jr
......
403 405
label_stay_logged_in: Blijf ingelogd
404 406
label_disabled: uitgeschakeld
405 407
label_show_completed_versions: Toon afgeronde versies
408
label_completed_version: Afgerond
406 409
label_me: ik
407 410
label_board: Forum
408 411
label_board_new: Nieuw forum
db/migrate/095_add_versions_completed_status.rb (revision 0)
1
class AddVersionsCompletedStatus < ActiveRecord::Migration
2
  def self.up
3
    add_column :versions, :completed, :boolean, :default => false
4
  end
5

  
6
  def self.down
7
    remove_column :versions, :completed
8
  end
9
end
(3-3/3)