Skip to content

Reports: Download all #620

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

Merged
merged 7 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ html {
}

.row.exports {
padding: 10px;
padding: 20px 0;
}

.table-responsive {
Expand Down
80 changes: 65 additions & 15 deletions app/controllers/reports_controller.rb
Original file line number Diff line number Diff line change
@@ -1,48 +1,98 @@
require 'zip'

class ReportsController < ApplicationController
before_action :authenticate_user!

layout "report"

def user_list
@members = current_organization.members.active.
includes(:user).
order("members.member_uid")
@members = report_collection("Member")

report_responder('Member', current_organization, @members)
end

def post_list
@post_type = (params[:type] || "offer").capitalize.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 }
@posts = report_collection(@post_type)

report_responder('Post', current_organization, @posts, @post_type)
end

def transfer_list
@transfers = current_organization.all_transfers_with_accounts
@transfers = report_collection('Transfer')

report_responder('Transfer', current_organization, @transfers)
end

def download_all
filename = "#{current_organization.name.parameterize}_#{Date.today}.zip"
temp_file = Tempfile.new(filename)

begin
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zipfile|
%w(Member Transfer Inquiry Offer).each do |report_class|
add_csv_to_zip(report_class, zipfile)
end
end
zip_data = File.read(temp_file.path)
send_data(zip_data, type: 'application/zip', disposition: 'attachment', filename: filename)
rescue Errno::ENOENT
redirect_to download_all_report_path
ensure
temp_file.close
temp_file.unlink
end
end

private

def report_responder(report_class, *args)
respond_to do |format|
format.html
format.csv { download_report("Report::Csv::#{report_class}", *args) }
format.pdf { download_report("Report::Pdf::#{report_class}", *args) }
format.csv { download_report("Csv::#{report_class}", *args) }
format.pdf { download_report("Pdf::#{report_class}", *args) }
end
end

def download_report(report_class, *args)
report = report_class.constantize.new(*args)
report = get_report(report_class, *args)
send_data report.run, filename: report.name, type: report.mime_type
end

def get_report(report_class, *args)
"Report::#{report_class}".constantize.new(*args)
end

def report_collection(report_class)
case report_class.to_s
when 'Member'
current_organization.members.active.includes(:user).order('members.member_uid')
when 'Transfer'
current_organization.all_transfers_with_accounts
when 'Inquiry', 'Offer'
report_class = report_class.constantize if report_class.is_a?(String)

current_organization.posts.of_active_members.active.
merge(report_class.all).
includes(:user, :category).
group_by(&:category).
sort_by { |category, _| category.try(:name).to_s }
end
end

def add_csv_to_zip(report_class, zip)
collection = report_collection(report_class)

report = if report_class.in? %w(Inquiry Offer)
get_report("Csv::Post", current_organization, collection, report_class.constantize)
else
get_report("Csv::#{report_class}", current_organization, collection)
end

file = Tempfile.new
file.write(report.run)
file.rewind

zip.add("#{report_class.pluralize}_#{Date.today}.csv", file.path)
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>
<li class="divider" role="presentation"></li>
<li>
<%= link_to download_all_report_path do %>
<%= glyph :download %>
<%= t 'reports.download_all' %>
<% end %>
</li>
</ul>
</li>
5 changes: 1 addition & 4 deletions config/locales/ca.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ ca:
show:
info: Aquesta %{type} pertany a %{organization}.
reports:
cat_with_users:
title: Serveis ofertats
download: Descarregar
user_list:
title: Llistat d'usuaris
download_all: Descarregar tot
shared:
movements:
delete_reason: Esteu segur d'esborrar aquest comentari?
Expand Down
5 changes: 1 addition & 4 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ en:
show:
info: This %{type} belongs to %{organization}.
reports:
cat_with_users:
title: Offered Services
download: Download
user_list:
title: User List
download_all: Download all
shared:
movements:
delete_reason: Are you sure to delete this comment?
Expand Down
5 changes: 1 addition & 4 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ es:
show:
info: Esta %{type} pertenece a %{organization}.
reports:
cat_with_users:
title: Servicios ofrecidos
download: Descargar
user_list:
title: Listado usuarios
download_all: Descargar todo
shared:
movements:
delete_reason: "¿Está seguro de borrar este comentario?"
Expand Down
5 changes: 1 addition & 4 deletions config/locales/eu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ eu:
show:
info: "%{type} hau %{organization}(e)ri dagokio."
reports:
cat_with_users:
title: Eskaintzen diren zerbitzuak
download: Jaitsi
user_list:
title: Erabiltzaile zerrenda
download_all:
shared:
movements:
delete_reason: Zihur zaude azalpen hau ezabatu nahi duzula?
Expand Down
5 changes: 1 addition & 4 deletions config/locales/gl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ gl:
show:
info: Este %{type} pertence a %{organization}.
reports:
cat_with_users:
title: Servizos ofrecidos
download: Descarga
user_list:
title: Lista de persoas usuarias
download_all:
shared:
movements:
delete_reason: Estás seguro/a de borrar este comentario?
Expand Down
5 changes: 1 addition & 4 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,8 @@ pt-BR:
show:
info: Este %{type} pertence a %{organization}.
reports:
cat_with_users:
title: Serviços oferecidos
download: Baixar
user_list:
title: Lista de usuários
download_all:
shared:
movements:
delete_reason: Tem certeza de que quer apagar este comentário?
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 "download_all"
end
end

Expand Down
19 changes: 19 additions & 0 deletions spec/controllers/reports_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,24 @@
expect(response.media_type).to eq("application/pdf")
end
end

describe 'GET #download_all' do
it 'downloads a zip' do
get :download_all

expect(response.media_type).to eq('application/zip')
expect(response.body).to include('Inquiries')
expect(response.body).to include('Offers')
expect(response.body).to include('Members')
expect(response.body).to include('Transfers')
end

it 'redirects to download_all_report_path (retry) if zip is not ready' do
allow(subject).to receive(:add_csv_to_zip).and_raise(Errno::ENOENT)
get :download_all

expect(response).to redirect_to(download_all_report_path)
end
end
end
end