]> source.dussan.org Git - redmine.git/commitdiff
Fixed: "None" category issue count is empty while grouping by category (#4308).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Wed, 2 Dec 2009 18:57:17 +0000 (18:57 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Wed, 2 Dec 2009 18:57:17 +0000 (18:57 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3112 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/helpers/queries_helper.rb
app/models/custom_field.rb
app/models/query.rb
app/views/issues/_list.rhtml
test/fixtures/custom_fields.yml
test/fixtures/custom_values.yml
test/functional/issues_controller_test.rb
test/unit/query_test.rb

index 518226c8fea9dfd355e507f29213e7a051b43fa4..ecfac55ad1e174ab9d8ab64ea46e1b823c125644 100644 (file)
@@ -27,44 +27,38 @@ module QueriesHelper
                       content_tag('th', column.caption)
   end
   
-  def column_value(column, issue)
-    if column.is_a?(QueryCustomFieldColumn)
-      cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
-      show_value(cv)
-    else
-      value = issue.send(column.name)
-    end
-  end
-  
   def column_content(column, issue)
-    if column.is_a?(QueryCustomFieldColumn)
-      cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
-      show_value(cv)
-    else
-      value = issue.send(column.name)
-      if value.is_a?(Date)
-        format_date(value)
-      elsif value.is_a?(Time)
-        format_time(value)
+    value = column.value(issue)
+    
+    case value.class.name
+    when 'String'
+      if column.name == :subject
+        link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
+      else
+        h(value)
+      end
+    when 'Time'
+      format_time(value)
+    when 'Date'
+      format_date(value)
+    when 'Fixnum', 'Float'
+      if column.name == :done_ratio
+        progress_bar(value, :width => '80px')
       else
-        case column.name
-        when :subject
-        h((!@project.nil? && @project != issue.project) ? "#{issue.project.name} - " : '') +
-          link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
-        when :project
-          link_to(h(value), :controller => 'projects', :action => 'show', :id => value)
-        when :assigned_to
-          link_to_user value
-        when :author
-          link_to_user value
-        when :done_ratio
-          progress_bar(value, :width => '80px')
-        when :fixed_version
-          link_to(h(value), { :controller => 'versions', :action => 'show', :id => issue.fixed_version_id })
-        else
-          h(value)
-        end
+        value.to_s
       end
+    when 'User'
+      link_to_user value
+    when 'Project'
+      link_to(h(value), :controller => 'projects', :action => 'show', :id => value)
+    when 'Version'
+      link_to(h(value), :controller => 'versions', :action => 'show', :id => value)
+    when 'TrueClass'
+      l(:general_text_Yes)
+    when 'FalseClass'
+      l(:general_text_No)
+    else
+      h(value)
     end
   end
 end
index 5160fcf8a834208cc201634c9a565a911b788087..c7031afeae07eb77167bf1a712bfc36f5058fb96 100644 (file)
@@ -67,6 +67,25 @@ class CustomField < ActiveRecord::Base
     end
   end
   
+  def cast_value(value)
+    casted = nil
+    unless value.blank?
+      case field_format
+      when 'string', 'text', 'list'
+        casted = value
+      when 'date'
+        casted = begin; value.to_date; rescue; nil end
+      when 'bool'
+        casted = (value == '1' ? true : false)
+      when 'int'
+        casted = value.to_i
+      when 'float'
+        casted = value.to_f
+      end
+    end
+    casted
+  end
+  
   # Returns a ORDER BY clause that can used to sort customized
   # objects by their value of the custom field.
   # Returns false, if the custom field can not be used for sorting.
index c691736e90cf2f5d5a5fc1acec3a94a4e4b7a55e..f7aeb0ea045b3502d371ec0f3bceb9f11c087d9c 100644 (file)
@@ -37,6 +37,10 @@ class QueryColumn
   def sortable?
     !sortable.nil?
   end
+  
+  def value(issue)
+    issue.send name
+  end
 end
 
 class QueryCustomFieldColumn < QueryColumn
@@ -58,6 +62,11 @@ class QueryCustomFieldColumn < QueryColumn
   def custom_field
     @cf
   end
+  
+  def value(issue)
+    cv = issue.custom_values.detect {|v| v.custom_field_id == @cf.id}
+    cv && @cf.cast_value(cv.value)
+  end
 end
 
 class Query < ActiveRecord::Base
@@ -407,16 +416,20 @@ class Query < ActiveRecord::Base
   
   # Returns the issue count by group or nil if query is not grouped
   def issue_count_by_group
+    r = nil
     if grouped?
       begin
         # Rails will raise an (unexpected) RecordNotFound if there's only a nil group value
-        Issue.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement)
+        r = Issue.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement)
       rescue ActiveRecord::RecordNotFound
-        {nil => issue_count}
+        r = {nil => issue_count}
+      end
+      c = group_by_column
+      if c.is_a?(QueryCustomFieldColumn)
+        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
       end
-    else
-      nil
     end
+    r
   rescue ::ActiveRecord::StatementInvalid => e
     raise StatementInvalid.new(e.message)
   end
index f51a70883c3f58e82106be33797931588e259c44..a7a7b062243e8a5ec7fcedf185bdb1f637526e5a 100644 (file)
        <% previous_group = false %>
        <tbody>
        <% issues.each do |issue| -%>
-  <% if @query.grouped? && (group = column_value(@query.group_by_column, issue) || '') != previous_group %>
+  <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %>
     <% reset_cycle %>
     <tr class="group open">
        <td colspan="<%= query.columns.size + 2 %>">
                <span class="expander" onclick="toggleRowGroup(this); return false;">&nbsp;</span>
-       <%= group.blank? ? 'None' : group %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
+       <%= group.blank? ? 'None' : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
        </td>
                </tr>
                <% previous_group = group %>
index dcbef29d69d43a6913f214d51ebd3fabc9878174..70577176e5276988450b02cb33ad76b2d2469e1d 100644 (file)
@@ -101,3 +101,17 @@ custom_fields_007:
   field_format: bool
   default_value: ""
   editable: true
+custom_fields_008: 
+  name: Custom date
+  min_length: 0
+  regexp: ""
+  is_for_all: true
+  is_filter: false
+  type: IssueCustomField
+  max_length: 0
+  possible_values: ""
+  id: 8
+  is_required: false
+  field_format: date
+  default_value: ""
+  editable: true
index 7c4ce4794dda5b4677ec92e748951aacdc5fe3bd..76ce067a74509d75cea6391a5e27f1b88b92a2cf 100644 (file)
@@ -95,3 +95,9 @@ custom_values_016:
   customized_id: 11
   id: 16
   value: '1'
+custom_values_017: 
+  customized_type: Issue
+  custom_field_id: 8
+  customized_id: 1
+  id: 17
+  value: '2009-12-01'
index 4c6b25358ae2746fd7f67dce1569ad62cfe80d1e..93e29957e07be3f4744786e93c326bbe0fe20d31 100644 (file)
@@ -177,10 +177,7 @@ class IssuesControllerTest < ActionController::TestCase
     assert_response :success
     assert_template 'index.rhtml'
     assert_not_nil assigns(:issues)
-    count_by_group = assigns(:issue_count_by_group)
-    assert_kind_of Hash, count_by_group
-    assert_kind_of Tracker, count_by_group.keys.first
-    assert_not_nil count_by_group[Tracker.find(1)]
+    assert_not_nil assigns(:issue_count_by_group)
   end
   
   def test_index_with_query_grouped_by_list_custom_field
@@ -188,10 +185,7 @@ class IssuesControllerTest < ActionController::TestCase
     assert_response :success
     assert_template 'index.rhtml'
     assert_not_nil assigns(:issues)
-    count_by_group = assigns(:issue_count_by_group)
-    assert_kind_of Hash, count_by_group
-    assert_kind_of String, count_by_group.keys.first
-    assert_not_nil count_by_group['MySQL']
+    assert_not_nil assigns(:issue_count_by_group)
   end
   
   def test_index_sort_by_field_not_included_in_columns
index f405833d45a93ca1b1e077f35b1fa0dac51597fc..31d3cd1dd9c2800a2699131112f532525ebbf80f 100644 (file)
@@ -276,6 +276,32 @@ class QueryTest < ActiveSupport::TestCase
     end
   end
   
+  def test_issue_count_by_association_group
+    q = Query.new(:name => '_', :group_by => 'assigned_to')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+    assert count_by_group.has_key?(User.find(3))
+  end
+
+  def test_issue_count_by_list_custom_field_group
+    q = Query.new(:name => '_', :group_by => 'cf_1')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+    assert count_by_group.has_key?('MySQL')
+  end
+  
+  def test_issue_count_by_date_custom_field_group
+    q = Query.new(:name => '_', :group_by => 'cf_8')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+  end
+  
   def test_label_for
     q = Query.new
     assert_equal 'assigned_to', q.label_for('assigned_to_id')