From d201c54455fd15d0069de5a60bc99a57cc380ba3 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sun, 8 Nov 2009 13:03:41 +0000 Subject: [PATCH] Adds version status to limit issue assignments (#1245). Available version statuses are: * open: no restriction * locked: can not assign new issues to the version * closed: can not assign new issues and can not reopen assigned issues git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3020 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/issue.rb | 25 ++++++++++++ app/models/version.rb | 11 ++++- app/views/issues/_form.rhtml | 6 +-- app/views/issues/_form_update.rhtml | 6 +-- app/views/issues/bulk_edit.rhtml | 2 +- app/views/issues/context_menu.rhtml | 4 +- app/views/projects/settings/_versions.rhtml | 13 +++--- app/views/versions/_form.rhtml | 1 + config/locales/bg.yml | 4 ++ config/locales/bs.yml | 4 ++ config/locales/ca.yml | 4 ++ config/locales/cs.yml | 4 ++ config/locales/da.yml | 4 ++ config/locales/de.yml | 4 ++ config/locales/el.yml | 4 ++ config/locales/en.yml | 5 +++ config/locales/es.yml | 4 ++ config/locales/fi.yml | 4 ++ config/locales/fr.yml | 5 +++ config/locales/gl.yml | 4 ++ config/locales/he.yml | 4 ++ config/locales/hu.yml | 4 ++ config/locales/it.yml | 4 ++ config/locales/ja.yml | 4 ++ config/locales/ko.yml | 4 ++ config/locales/lt.yml | 4 ++ config/locales/nl.yml | 4 ++ config/locales/no.yml | 4 ++ config/locales/pl.yml | 4 ++ config/locales/pt-BR.yml | 4 ++ config/locales/pt.yml | 4 ++ config/locales/ro.yml | 4 ++ config/locales/ru.yml | 4 ++ config/locales/sk.yml | 4 ++ config/locales/sl.yml | 4 ++ config/locales/sr.yml | 4 ++ config/locales/sv.yml | 4 ++ config/locales/th.yml | 4 ++ config/locales/tr.yml | 4 ++ config/locales/uk.yml | 4 ++ config/locales/vi.yml | 4 ++ config/locales/zh-TW.yml | 4 ++ config/locales/zh.yml | 4 ++ db/migrate/20091108092559_add_versions_status.rb | 9 +++++ public/stylesheets/application.css | 2 + test/fixtures/issues.yml | 32 +++++++++++++++ test/fixtures/versions.yml | 3 ++ test/unit/issue_test.rb | 51 ++++++++++++++++++++++++ test/unit/version_test.rb | 1 + 49 files changed, 293 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20091108092559_add_versions_status.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index f7b2f8a3..ea6eb130 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -143,6 +143,14 @@ class Issue < ActiveRecord::Base if start_date && soonest_start && start_date < soonest_start errors.add :start_date, :invalid end + + if fixed_version + if !assignable_versions.include?(fixed_version) + errors.add :fixed_version_id, :inclusion + elsif reopened? && fixed_version.closed? + errors.add_to_base I18n.t(:error_can_not_reopen_issue_on_closed_version) + end + end end def validate_on_create @@ -193,6 +201,18 @@ class Issue < ActiveRecord::Base self.status.is_closed? end + # Return true if the issue is being reopened + def reopened? + if !new_record? && status_id_changed? + status_was = IssueStatus.find_by_id(status_id_was) + status_new = IssueStatus.find_by_id(status_id) + if status_was && status_new && status_was.is_closed? && !status_new.is_closed? + return true + end + end + false + end + # Returns true if the issue is overdue def overdue? !due_date.nil? && (due_date < Date.today) && !status.is_closed? @@ -203,6 +223,11 @@ class Issue < ActiveRecord::Base project.assignable_users end + # Versions that the issue can be assigned to + def assignable_versions + @assignable_versions ||= (project.versions.open + [Version.find_by_id(fixed_version_id_was)]).compact.uniq.sort + end + # Returns true if this issue is blocked by another issue that is still open def blocked? !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil? diff --git a/app/models/version.rb b/app/models/version.rb index 13d33e25..dc72e821 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -22,11 +22,16 @@ class Version < ActiveRecord::Base acts_as_attachable :view_permission => :view_files, :delete_permission => :manage_files + VERSION_STATUSES = %w(open locked closed) + validates_presence_of :name validates_uniqueness_of :name, :scope => [:project_id] validates_length_of :name, :maximum => 60 validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true - + validates_inclusion_of :status, :in => VERSION_STATUSES + + named_scope :open, :conditions => {:status => 'open'} + def start_date effective_date end @@ -45,6 +50,10 @@ class Version < ActiveRecord::Base @spent_hours ||= TimeEntry.sum(:hours, :include => :issue, :conditions => ["#{Issue.table_name}.fixed_version_id = ?", id]).to_f end + def closed? + status == 'closed' + end + # Returns true if the version is completed: due date reached and no open issues def completed? effective_date && (effective_date <= Date.today) && (open_issues_count == 0) diff --git a/app/views/issues/_form.rhtml b/app/views/issues/_form.rhtml index fac2d6a3..c61c79d6 100644 --- a/app/views/issues/_form.rhtml +++ b/app/views/issues/_form.rhtml @@ -32,9 +32,9 @@ {:controller => 'projects', :action => 'add_issue_category', :id => @project}, :class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %>

<% end %> -<%= content_tag('p', f.select(:fixed_version_id, - (@project.versions.sort.collect {|v| [v.name, v.id]}), - { :include_blank => true })) unless @project.versions.empty? %> +<% unless @issue.assignable_versions.empty? %> +

<%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %>

+<% end %>
diff --git a/app/views/issues/_form_update.rhtml b/app/views/issues/_form_update.rhtml index 3f17a030..5304ee23 100644 --- a/app/views/issues/_form_update.rhtml +++ b/app/views/issues/_form_update.rhtml @@ -5,8 +5,8 @@

<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>

-<%= content_tag('p', f.select(:fixed_version_id, - (@project.versions.sort.collect {|v| [v.name, v.id]}), - { :include_blank => true })) unless @project.versions.empty? %> +<% unless @issue.assignable_versions.empty? %> +

<%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %>

+<% end %>
diff --git a/app/views/issues/bulk_edit.rhtml b/app/views/issues/bulk_edit.rhtml index 4ea9ffd3..10a5bb5a 100644 --- a/app/views/issues/bulk_edit.rhtml +++ b/app/views/issues/bulk_edit.rhtml @@ -27,7 +27,7 @@ + options_from_collection_for_select(@project.versions.open.sort, :id, :name)) %>

diff --git a/app/views/issues/context_menu.rhtml b/app/views/issues/context_menu.rhtml index ae9a1afc..073f12bd 100644 --- a/app/views/issues/context_menu.rhtml +++ b/app/views/issues/context_menu.rhtml @@ -27,11 +27,11 @@ <% end -%> - <% unless @project.nil? || @project.versions.empty? -%> + <% unless @project.nil? || @project.versions.open.empty? -%>

  • <%= l(:field_fixed_version) %>