diff options
-rw-r--r-- | app/helpers/queries_helper.rb | 2 | ||||
-rw-r--r-- | app/models/issue_query.rb | 6 | ||||
-rw-r--r-- | app/models/query.rb | 20 | ||||
-rw-r--r-- | lib/redmine/database.rb | 13 | ||||
-rw-r--r-- | lib/redmine/export/pdf/issues_pdf_helper.rb | 2 | ||||
-rw-r--r-- | test/functional/issues_controller_test.rb | 26 |
6 files changed, 64 insertions, 5 deletions
diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 01d10d883..261291727 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -128,7 +128,7 @@ module QueriesHelper items.each do |item| group_name = group_count = nil if query.grouped? - group = query.group_by_column.value(item) + group = query.group_by_column.group_value(item) if first || group != previous_group if group.blank? && group != false group_name = "(#{l(:label_blank_value)})" diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 0f2b8e2bd..2e01507ac 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -30,7 +30,7 @@ class IssueQuery < Query QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"), QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true), QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true), - QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'), + TimestampQueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc', :groupable => true), QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date", :groupable => true), @@ -41,8 +41,8 @@ class IssueQuery < Query " WHERE subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)", :default_order => 'desc'), QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true), - QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'), - QueryColumn.new(:closed_on, :sortable => "#{Issue.table_name}.closed_on", :default_order => 'desc'), + TimestampQueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc', :groupable => true), + TimestampQueryColumn.new(:closed_on, :sortable => "#{Issue.table_name}.closed_on", :default_order => 'desc', :groupable => true), QueryColumn.new(:last_updated_by, :sortable => lambda {User.fields_for_order_statement("last_journal_user")}), QueryColumn.new(:relations, :caption => :label_related_issues), QueryColumn.new(:attachments, :caption => :label_attachment_plural), diff --git a/app/models/query.rb b/app/models/query.rb index 1e8080b86..1aa09d2a2 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -71,11 +71,31 @@ class QueryColumn object.send name end + # Returns the group that object belongs to when grouping query results + def group_value(object) + value(object) + end + def css_classes name end end +class TimestampQueryColumn < QueryColumn + + def groupable + if @groupable + Redmine::Database.timestamp_to_date(sortable, User.current.time_zone) + end + end + + def group_value(object) + if time = value(object) + User.current.time_to_date(time) + end + end +end + class QueryAssociationColumn < QueryColumn def initialize(association, attribute, options={}) diff --git a/lib/redmine/database.rb b/lib/redmine/database.rb index 02580d160..c18470a41 100644 --- a/lib/redmine/database.rb +++ b/lib/redmine/database.rb @@ -64,6 +64,19 @@ module Redmine end end + # Returns a SQL statement to cast a timestamp column to a date given a time zone + # Returns nil if not implemented for the current database + def timestamp_to_date(column, time_zone) + if postgresql? + if time_zone + identifier = ActiveSupport::TimeZone.find_tzinfo(time_zone.name).identifier + "(#{column}::timestamptz AT TIME ZONE '#{identifier}')::date" + else + "#{column}::date" + end + end + end + # Resets database information def reset @postgresql_unaccent = nil diff --git a/lib/redmine/export/pdf/issues_pdf_helper.rb b/lib/redmine/export/pdf/issues_pdf_helper.rb index 7e2c8a85f..3a6183893 100644 --- a/lib/redmine/export/pdf/issues_pdf_helper.rb +++ b/lib/redmine/export/pdf/issues_pdf_helper.rb @@ -303,7 +303,7 @@ module Redmine issue_list(issues) do |issue, level| if query.grouped? && - (group = query.group_by_column.value(issue)) != previous_group + (group = query.group_by_column.group_value(issue)) != previous_group pdf.SetFontStyle('B',10) group_label = group.blank? ? 'None' : group.to_s.dup group_label << " (#{result_count_by_group[group]})" diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 9f4c412da..044cc0c54 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -352,6 +352,32 @@ class IssuesControllerTest < Redmine::ControllerTest end end + def test_index_grouped_by_created_on + skip unless IssueQuery.new.groupable_columns.detect {|c| c.name == :created_on} + + get :index, :params => { + :set_filter => 1, + :group_by => 'created_on' + } + assert_response :success + + assert_select 'tr.group span.name', :text => '07/19/2006' do + assert_select '+ span.count', :text => '2' + end + end + + def test_index_grouped_by_created_on_as_pdf + skip unless IssueQuery.new.groupable_columns.detect {|c| c.name == :created_on} + + get :index, :params => { + :set_filter => 1, + :group_by => 'created_on', + :format => 'pdf' + } + assert_response :success + assert_equal 'application/pdf', response.content_type + end + def test_index_with_query_grouped_by_list_custom_field get :index, :params => { :project_id => 1, |