diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 662e22ee8..c9e8da2f1 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -277,6 +277,8 @@ module QueriesHelper link_to_if(value > 0, format_hours(value), project_time_entries_path(item.project, :issue_id => "~#{item.id}")) when :attachments value.to_a.map {|a| format_object(a)}.join(" ").html_safe + when :attachments_filesize + value == 0 ? '' : number_to_human_size(value) else format_object(value) end diff --git a/app/models/issue.rb b/app/models/issue.rb index f727853e2..393873375 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1188,6 +1188,14 @@ class Issue < ActiveRecord::Base @watchers_count ||= self.watchers.count(:id) end + def attachments_count + @attachments_count ||= self.attachments.count(:id) + end + + def attachments_filesize + @attachments_filesize ||= self.attachments.sum(:filesize) + end + # Preloads relations for a collection of issues def self.load_relations(issues) if issues.any? diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index c64eaef57..32ac3b15d 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -54,6 +54,24 @@ class IssueQuery < Query " AND #{Watcher.table_name}.watchable_id = #{Issue.table_name}.id), 0)" end, :default_order => 'desc'), + QueryColumn.new( + :attachments_count, + :sortable => + lambda do + "COALESCE((SELECT COUNT(author_id) FROM #{Attachment.table_name}" \ + " WHERE #{Attachment.table_name}.container_type = 'Issue'" \ + " AND #{Attachment.table_name}.container_id = #{Issue.table_name}.id), 0)" + end, + :default_order => 'desc'), + QueryColumn.new( + :attachments_filesize, + :sortable => + lambda do + "COALESCE((SELECT SUM(filesize) FROM #{Attachment.table_name}" \ + " WHERE #{Attachment.table_name}.container_type = 'Issue'" \ + " AND #{Attachment.table_name}.container_id = #{Issue.table_name}.id), 0)" + end, + :default_order => 'desc'), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date", :groupable => true), QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", diff --git a/config/locales/en.yml b/config/locales/en.yml index a20874799..fdb9dde5a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -370,6 +370,8 @@ en: field_editable: Editable field_watcher: Watcher field_watchers_count: Watchers count + field_attachments_count: Files count + field_attachments_filesize: Total file size field_content: Content field_group_by: Group results by field_sharing: Sharing diff --git a/config/locales/ja.yml b/config/locales/ja.yml index e4ac5f1de..eced7c792 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -329,6 +329,8 @@ ja: field_editable: 編集可能 field_watcher: ウォッチャー field_watchers_count: ウォッチ数 + field_attachments_count: 添付ファイル数 + field_attachments_filesize: 添付ファイル合計サイズ field_content: 内容 field_group_by: グループ条件 field_sharing: 共有 diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 86f450821..379a0b891 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -1388,6 +1388,28 @@ class IssuesControllerTest < Redmine::ControllerTest assert_equal [2, 1, 0], issues_in_list.map {|issue| issue.watchers_count}.first(3) end + def test_index_sort_by_attachments_count_and_filesize + user = User.find(2) + file = uploaded_test_file("testfile.txt", "text/plain") + Attachment.delete_all + 2.times.each do + a = Attachment.new(:container => Issue.find(1), :file => file, :author => user) + a.filesize = 0.5.megabyte + a.save! + end + a = Attachment.new(:container => Issue.find(2), :file => file, :author => user) + a.filesize = 2.megabyte + a.save! + # sort by attachments count + get(:index, :params => {:sort => 'attachments_count:desc'}) + assert_response :success + assert_equal [2, 1, 0], issues_in_list.map {|issue| issue.attachments_count}.first(3) + # sort by attachments filesize + get(:index, :params => {:sort => 'attachments_filesize:desc'}) + assert_response :success + assert_equal [2.megabyte, 1.megabyte, 0], issues_in_list.map {|issue| issue.attachments_filesize}.first(3) + end + def test_index_sort_by_user_custom_field cf = IssueCustomField. create!( diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 50c6586c2..686b0057b 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -3532,4 +3532,17 @@ class IssueTest < ActiveSupport::TestCase end assert_equal 2, issue.watchers_count end + + def test_attachments_count_and_filesize + issue = Issue.generate! + user = User.find(2) + attachments_filesize = 2.times.collect do + a = Attachment.new(:container => issue, + :file => uploaded_test_file("testfile.txt", "text/plain"), + :author => user) + a.save! && a + end.sum{ |a| a.filesize } + assert_equal 2, issue.attachments_count + assert_equal attachments_filesize, issue.attachments_filesize + end end