diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 04d9a78ada..aed4cd83fa 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -28,6 +28,7 @@ class UsersController < ApplicationController include SortHelper helper :custom_fields include CustomFieldsHelper + include UsersHelper helper :principal_memberships helper :activities include ActivitiesHelper @@ -61,6 +62,9 @@ class UsersController < ApplicationController @groups = Group.givable.sort render :layout => !request.xhr? } + format.csv { + send_data(users_to_csv(scope.order(sort_clause)), :type => 'text/csv; header=present', :filename => 'users.csv') + } format.api end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index d7812867be..c0d9544999 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -18,12 +18,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module UsersHelper + include ApplicationHelper + def users_status_options_for_select(selected) user_count_by_status = User.group('status').count.to_hash - options_for_select([[l(:label_all), ''], - ["#{l(:status_active)} (#{user_count_by_status[1].to_i})", '1'], - ["#{l(:status_registered)} (#{user_count_by_status[2].to_i})", '2'], - ["#{l(:status_locked)} (#{user_count_by_status[3].to_i})", '3']], selected.to_s) + options_for_select([[l(:label_all), '']] + (User.valid_statuses.map {|c| ["#{l('status_' + User::LABEL_BY_STATUS[c])} (#{user_count_by_status[c].to_i})", c]}), selected.to_s) end def user_mail_notification_options(user) @@ -61,4 +60,32 @@ module UsersHelper end tabs end + + def users_to_csv(users) + Redmine::Export::CSV.generate(:encoding => params[:encoding]) do |csv| + columns = [ + 'login', + 'firstname', + 'lastname', + 'mail', + 'admin', + 'created_on', + 'last_login_on', + 'status' + ] + + # csv header fields + csv << columns.map{|column| l('field_' + column)} + # csv lines + users.each do |user| + csv << columns.map do |column| + if column == 'status' + l(("status_#{User::LABEL_BY_STATUS[user.status]}")) + else + format_object(user.send(column), false) + end + end + end + end + end end diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 3fc82b6401..75c9eb465c 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -4,7 +4,7 @@
<%= l(:label_no_data) %>
<% end %> diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 42dae0f507..1f2dd4f326 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -64,6 +64,47 @@ class UsersControllerTest < Redmine::ControllerTest end end + def test_index_csv + with_settings :default_language => 'en' do + get :index, :params => { :format => 'csv' } + assert_response :success + + assert_equal User.logged.status(1).count, response.body.chomp.split("\n").size - 1 + assert_include 'active', response.body + assert_not_include 'locked', response.body + assert_equal 'text/csv; header=present', @response.content_type + end + end + + def test_index_csv_with_status_filter + with_settings :default_language => 'en' do + get :index, :params => { :status => 3, :format => 'csv' } + assert_response :success + + assert_equal User.logged.status(3).count, response.body.chomp.split("\n").size - 1 + assert_include 'locked', response.body + assert_not_include 'active', response.body + assert_equal 'text/csv; header=present', @response.content_type + end + end + + def test_index_csv_with_name_filter + get :index, :params => {:name => 'John', :format => 'csv'} + assert_response :success + + assert_equal User.logged.like('John').count, response.body.chomp.split("\n").size - 1 + assert_include 'John', response.body + assert_equal 'text/csv; header=present', @response.content_type + end + + def test_index_csv_with_group_filter + get :index, :params => {:group_id => '10', :format => 'csv'} + assert_response :success + + assert_equal Group.find(10).users.count, response.body.chomp.split("\n").size - 1 + assert_equal 'text/csv; header=present', @response.content_type + end + def test_show @request.session[:user_id] = nil get :show, :params => {:id => 2}