Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reports: Download all #620

Merged
merged 7 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ruby File.read('.ruby-version').strip
gem 'rails', '~> 6.1.1'
gem 'rails-i18n', '~> 6.0.0'
gem 'rdiscount', '~> 2.2.0.1'
gem 'rubyzip', '~> 2.3.0'
gem 'activeadmin', '~> 2.9.0'
gem 'bootsnap', '~> 1.7.3', require: false
gem 'has_scope', '~> 0.7.2'
Expand Down
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ DEPENDENCIES
rspec-rails (~> 4.0.0)
rubocop (~> 1.6)
rubocop-rails (~> 2.9)
rubyzip (~> 2.3.0)
sassc-rails (~> 2.1.2)
select2-rails (~> 4.0.13)
selenium-webdriver (~> 3.142)
Expand Down
5 changes: 5 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -668,3 +668,8 @@ label[required]::after{
display: inline;
margin: 0 !important;
}

.hr-5 {
margin-top: 5px;
margin-bottom: 5px;
}
66 changes: 66 additions & 0 deletions app/controllers/reports_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'zip'
class ReportsController < ApplicationController
before_action :authenticate_user!

Expand Down Expand Up @@ -31,6 +32,24 @@ def transfer_list
report_responder('Transfer', current_organization, @transfers)
end

def all_list
filename = "#{current_organization.name.gsub(' ', '_')}.zip"
temp_file = Tempfile.new(filename)
begin
Zip::OutputStream.open(temp_file) { |zos| }
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zipfile|
add_csvs_to_zip(%w[Member Transfer Inquiries Offers], zipfile)
end
zip_data = File.read(temp_file.path)
send_data(zip_data, type: 'application/zip', disposition: 'attachment', filename: filename)
rescue Errno::ENOENT
redirect_to all_list_report_path
markets marked this conversation as resolved.
Show resolved Hide resolved
ensure
temp_file.close
temp_file.unlink
end
end

private

def report_responder(report_class, *args)
Expand All @@ -45,4 +64,51 @@ def download_report(report_class, *args)
report = report_class.constantize.new(*args)
send_data report.run, filename: report.name, type: report.mime_type
end

def add_csvs_to_zip(report_classes, zip)
report_classes.each do |report_class|
collection = return_collection(report_class)
report = do_report(report_class, collection)
file = Tempfile.new
file.write(report.run)
file.rewind
zip.add("#{report_class}.csv", file.path)
end
end

def return_collection(report_class)
case report_class
when 'Member'
current_organization.members.active.includes(:user).order('members.member_uid')
when 'Transfer'
current_organization.all_transfers_with_accounts
when 'Inquiries'
return_collection_posts('Inquiry')
when 'Offers'
return_collection_posts('Offer')
else
[]
end
end

def return_collection_posts(type)
@post_type = type.constantize
@posts = current_organization.posts.of_active_members.active.
merge(@post_type.all).
includes(:user, :category).
group_by(&:category).
to_a.
sort_by { |category, _| category.try(:name).to_s }
end

def do_report(report_class, collection)
case report_class
when 'Inquiries'
'Report::Csv::Post'.constantize.new(current_organization, collection, 'Inquiry'.constantize)
when 'Offers'
'Report::Csv::Post'.constantize.new(current_organization, collection, 'Offer'.constantize)
else
"Report::Csv::#{report_class}".constantize.new(current_organization, collection)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,12 @@
<%= Transfer.model_name.human(count: :many) %>
<% end %>
</li>
<hr class="hr-5">
<li>
<%= link_to all_list_report_path do %>
<%= glyph :download %>
<%= t 'reports.download_all' %>
<% end %>
</li>
</ul>
</li>
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ en:
cat_with_users:
title: Offered Services
download: Download
download_all: Download all
user_list:
title: User List
shared:
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
get "offer_list" => :post_list, type: "offer"
get "inquiry_list" => :post_list, type: "inquiry"
get "transfer_list"
get "all_list"
end
end

Expand Down
17 changes: 17 additions & 0 deletions spec/controllers/reports_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
expect(response.media_type).to eq("application/pdf")
end
end
describe 'GET #all_list' do
it 'downloads a zip' do
get :all_list
expect(response.body).to include('Inquiries.csv')
expect(response.body).to include('Offers.csv')
expect(response.body).to include('Member.csv')
expect(response.body).to include('Transfer.csv')
expect(response.media_type).to eq('application/zip')
end
end

describe 'GET #post_list' do
let(:report_posts) { test_organization.posts.of_active_members.group_by(&:category) }
Expand Down Expand Up @@ -89,5 +99,12 @@
expect(response.media_type).to eq("application/pdf")
end
end

describe 'the return_collection method' do
it 'returns an empty array if the class is not defined' do
rc = ReportsController.new
expect(rc.send(:return_collection, 'noclass')).to eq []
end
end
end
end