diff --git a/Gemfile b/Gemfile index 0317203bb..173ad6a3b 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index 62465c48e..d9eb8b504 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 8df55ae59..b6047b93d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -221,7 +221,7 @@ html { } .row.exports { - padding: 10px; + padding: 20px 0; } .table-responsive { diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index b757574e3..5b2b271fa 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -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 diff --git a/app/views/application/menus/_organization_reports_menu.html.erb b/app/views/application/menus/_organization_reports_menu.html.erb index d87571675..9b590189b 100644 --- a/app/views/application/menus/_organization_reports_menu.html.erb +++ b/app/views/application/menus/_organization_reports_menu.html.erb @@ -29,5 +29,12 @@ <%= Transfer.model_name.human(count: :many) %> <% end %> +
+