summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorEric Davis <edavis@littlestreamsoftware.com>2009-12-11 18:48:34 +0000
committerEric Davis <edavis@littlestreamsoftware.com>2009-12-11 18:48:34 +0000
commit4fe14e71c2d76a2e92da0aaa71e18493d65b1fc1 (patch)
tree0ef000f0e3985772228928b0acdca1a292f82ef6 /app
parenta83501364d0aa5e5e6d7a9e4ccfa2be5dab555b0 (diff)
downloadredmine-4fe14e71c2d76a2e92da0aaa71e18493d65b1fc1.tar.gz
redmine-4fe14e71c2d76a2e92da0aaa71e18493d65b1fc1.zip
Adds a Setting to control how an Issue's done_ratio is calculated:
* Issue field (default) - the done_ratio field for the Issue * Issue status - uses the Issue Status's value #4274 git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3151 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/issue_statuses_controller.rb11
-rw-r--r--app/models/issue.rb29
-rw-r--r--app/models/issue_status.rb12
-rw-r--r--app/views/issue_statuses/_form.rhtml5
-rw-r--r--app/views/issue_statuses/list.rhtml7
-rw-r--r--app/views/issues/_attributes.rhtml2
-rw-r--r--app/views/issues/_form_update.rhtml2
-rw-r--r--app/views/issues/bulk_edit.rhtml2
-rw-r--r--app/views/issues/context_menu.rhtml3
-rw-r--r--app/views/settings/_issues.rhtml3
10 files changed, 73 insertions, 3 deletions
diff --git a/app/controllers/issue_statuses_controller.rb b/app/controllers/issue_statuses_controller.rb
index bee7f4833..3be6abf3f 100644
--- a/app/controllers/issue_statuses_controller.rb
+++ b/app/controllers/issue_statuses_controller.rb
@@ -18,7 +18,7 @@
class IssueStatusesController < ApplicationController
before_filter :require_admin
- verify :method => :post, :only => [ :destroy, :create, :update, :move ],
+ verify :method => :post, :only => [ :destroy, :create, :update, :move, :update_issue_done_ratio ],
:redirect_to => { :action => :list }
def index
@@ -66,4 +66,13 @@ class IssueStatusesController < ApplicationController
flash[:error] = "Unable to delete issue status"
redirect_to :action => 'list'
end
+
+ def update_issue_done_ratio
+ if IssueStatus.update_issue_done_ratios
+ flash[:notice] = l(:notice_issue_done_ratios_updated)
+ else
+ flash[:error] = l(:error_issue_done_ratios_not_updated)
+ end
+ redirect_to :action => 'list'
+ end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index a0f47fdb8..2062e58e8 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -45,6 +45,8 @@ class Issue < ActiveRecord::Base
acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
:author_key => :author_id
+
+ DONE_RATIO_OPTIONS = %w(issue_field issue_status)
validates_presence_of :subject, :priority, :project, :tracker, :author, :status
validates_length_of :subject, :maximum => 255
@@ -55,7 +57,8 @@ class Issue < ActiveRecord::Base
:conditions => Project.allowed_to_condition(args.first || User.current, :view_issues) } }
named_scope :open, :conditions => ["#{IssueStatus.table_name}.is_closed = ?", false], :include => :status
-
+
+ before_save :update_done_ratio_from_issue_status
after_save :create_journal
# Returns true if usr or current user is allowed to view the issue
@@ -162,6 +165,22 @@ class Issue < ActiveRecord::Base
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
end
+ def done_ratio
+ if Issue.use_status_for_done_ratio? && !self.status.default_done_ratio.blank?
+ self.status.default_done_ratio
+ else
+ read_attribute(:done_ratio)
+ end
+ end
+
+ def self.use_status_for_done_ratio?
+ Setting.issue_done_ratio == 'issue_status'
+ end
+
+ def self.use_field_for_done_ratio?
+ Setting.issue_done_ratio == 'issue_field'
+ end
+
def validate
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
errors.add :due_date, :not_a_date
@@ -198,6 +217,14 @@ class Issue < ActiveRecord::Base
end
end
+ # Set the done_ratio using the status if that setting is set. This will keep the done_ratios
+ # even if the user turns off the setting later
+ def update_done_ratio_from_issue_status
+ if Issue.use_status_for_done_ratio? && !self.status.default_done_ratio.blank?
+ self.done_ratio = self.status.default_done_ratio
+ end
+ end
+
def after_save
# Reload is needed in order to get the right status
reload
diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb
index ca33d37d6..a9c1db584 100644
--- a/app/models/issue_status.rb
+++ b/app/models/issue_status.rb
@@ -33,6 +33,18 @@ class IssueStatus < ActiveRecord::Base
def self.default
find(:first, :conditions =>["is_default=?", true])
end
+
+ # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+
+ def self.update_issue_done_ratios
+ if Issue.use_status_for_done_ratio?
+ IssueStatus.find(:all, :conditions => ["default_done_ratio >= 0"]).each do |status|
+ Issue.update_all(["done_ratio = ?", status.default_done_ratio],
+ ["status_id = ?", status.id])
+ end
+ end
+
+ return Issue.use_status_for_done_ratio?
+ end
# Returns an array of all statuses the given role can switch to
# Uses association cache when called more than one time
diff --git a/app/views/issue_statuses/_form.rhtml b/app/views/issue_statuses/_form.rhtml
index b6a5bc19f..e36dec824 100644
--- a/app/views/issue_statuses/_form.rhtml
+++ b/app/views/issue_statuses/_form.rhtml
@@ -5,6 +5,11 @@
<p><label for="issue_status_name"><%=l(:field_name)%><span class="required"> *</span></label>
<%= text_field 'issue_status', 'name' %></p>
+<% if Issue.use_status_for_done_ratio? %>
+<p><label for="issue_done_ratio"><%=l(:field_done_ratio)%></label>
+<%= select 'issue_status', :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+<% end %>
+
<p><label for="issue_status_is_closed"><%=l(:field_is_closed)%></label>
<%= check_box 'issue_status', 'is_closed' %></p>
diff --git a/app/views/issue_statuses/list.rhtml b/app/views/issue_statuses/list.rhtml
index ca973153d..a98ed0cd8 100644
--- a/app/views/issue_statuses/list.rhtml
+++ b/app/views/issue_statuses/list.rhtml
@@ -1,5 +1,6 @@
<div class="contextual">
<%= link_to l(:label_issue_status_new), {:action => 'new'}, :class => 'icon icon-add' %>
+<%= link_to(l(:label_update_issue_done_ratios), {:action => 'update_issue_done_ratio'}, :class => 'icon icon-multiple', :method => 'post', :confirm => l(:text_are_you_sure)) if Issue.use_status_for_done_ratio? %>
</div>
<h2><%=l(:label_issue_status_plural)%></h2>
@@ -7,6 +8,9 @@
<table class="list">
<thead><tr>
<th><%=l(:field_status)%></th>
+ <% if Issue.use_status_for_done_ratio? %>
+ <th><%=l(:field_done_ratio)%></th>
+ <% end %>
<th><%=l(:field_is_default)%></th>
<th><%=l(:field_is_closed)%></th>
<th><%=l(:button_sort)%></th>
@@ -16,6 +20,9 @@
<% for status in @issue_statuses %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to status.name, :action => 'edit', :id => status %></td>
+ <% if Issue.use_status_for_done_ratio? %>
+ <td align="center"><%= h status.default_done_ratio %></td>
+ <% end %>
<td align="center"><%= image_tag 'true.png' if status.is_default? %></td>
<td align="center"><%= image_tag 'true.png' if status.is_closed? %></td>
<td align="center" style="width:15%;"><%= reorder_links('issue_status', {:action => 'update', :id => status}) %></td>
diff --git a/app/views/issues/_attributes.rhtml b/app/views/issues/_attributes.rhtml
index 9adf0f153..f8fc8d672 100644
--- a/app/views/issues/_attributes.rhtml
+++ b/app/views/issues/_attributes.rhtml
@@ -34,7 +34,9 @@
<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
<p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
+<% if Issue.use_field_for_done_ratio? %>
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+<% end %>
</div>
<div style="clear:both;"> </div>
diff --git a/app/views/issues/_form_update.rhtml b/app/views/issues/_form_update.rhtml
index 5304ee23a..e29c41a7c 100644
--- a/app/views/issues/_form_update.rhtml
+++ b/app/views/issues/_form_update.rhtml
@@ -4,7 +4,9 @@
<p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
</div>
<div class="splitcontentright">
+<% if Issue.use_field_for_done_ratio? %>
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
+<% end %>
<% unless @issue.assignable_versions.empty? %>
<p><%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %></p>
<% end %>
diff --git a/app/views/issues/bulk_edit.rhtml b/app/views/issues/bulk_edit.rhtml
index f428566b2..b298c3c46 100644
--- a/app/views/issues/bulk_edit.rhtml
+++ b/app/views/issues/bulk_edit.rhtml
@@ -39,8 +39,10 @@
<%= text_field_tag 'start_date', '', :size => 10 %><%= calendar_for('start_date') %></label>
<label><%= l(:field_due_date) %>:
<%= text_field_tag 'due_date', '', :size => 10 %><%= calendar_for('due_date') %></label>
+<% if Issue.use_field_for_done_ratio? %>
<label><%= l(:field_done_ratio) %>:
<%= select_tag 'done_ratio', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></label>
+<% end %>
</p>
<% @custom_fields.each do |custom_field| %>
diff --git a/app/views/issues/context_menu.rhtml b/app/views/issues/context_menu.rhtml
index 6cb05606a..4a1d0c310 100644
--- a/app/views/issues/context_menu.rhtml
+++ b/app/views/issues/context_menu.rhtml
@@ -77,6 +77,7 @@
</ul>
</li>
<% end -%>
+ <% if Issue.use_field_for_done_ratio? %>
<li class="folder">
<a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
<ul>
@@ -86,7 +87,7 @@
<% end -%>
</ul>
</li>
-
+ <% end %>
<% if !@issue.nil? %>
<% if @can[:log_time] -%>
<li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue},
diff --git a/app/views/settings/_issues.rhtml b/app/views/settings/_issues.rhtml
index b0277fab3..725d57da6 100644
--- a/app/views/settings/_issues.rhtml
+++ b/app/views/settings/_issues.rhtml
@@ -11,6 +11,9 @@
<%= check_box_tag 'settings[display_subprojects_issues]', 1, Setting.display_subprojects_issues? %>
</p>
+<p><label><%= l(:setting_issue_done_ratio) %></label>
+<%= select_tag 'settings[issue_done_ratio]', options_for_select(Issue::DONE_RATIO_OPTIONS.collect {|i| [l(i.to_sym), i]}, Setting.issue_done_ratio) %></p>
+
<p><label><%= l(:setting_issues_export_limit) %></label>
<%= text_field_tag 'settings[issues_export_limit]', Setting.issues_export_limit, :size => 6 %></p>
</div>