class GenerateContractsZipJob < ApplicationJob queue_as :default include Rails.application.routes.url_helpers include ActionView::Helpers::UrlHelper before_perform do |job| @project = job.arguments.first @download = job.arguments.second @release_type = job.arguments.third @release_ids = job.arguments.fourth @search_query = job.arguments.fifth @type_filter = job.arguments[5] @folder_name = "#{@project.name.parameterize}_#{release_name.gsub('_', '-')}" @download.update!(name: @folder_name, status: :pending) end def perform(project, download, release_type, release_ids, search_query, type_filter) ::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files| zipfile_name = "#{dir}/#{@folder_name}.zip" Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| files.each do |attachment| zipfile.add(attachment, File.join("#{dir}/", attachment)) end if @release_type.constantize.include?(CsvExportable) csv_file = generate_csv releases zipfile.get_output_stream("#{@folder_name}.csv") { |f| f.puts(csv_file) } end end @download.file.attach(io: File.open(zipfile_name), filename: "#{@folder_name}.zip") end rescue StandardError => e Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message) @download.failure! ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.failure")) end after_perform do |job| if @download.pending? && @download.file.attached? @download.success! downloads_folder_link = link_to("Files > Downloads", project_downloads_path(I18n.locale, @project)) download_button = link_to("Download", rails_blob_path(@download.file, disposition: "attachment", only_path: true), class: "btn btn-success", target: :_blank) ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.success", downloads_folder_link: downloads_folder_link, download_button: download_button, release_type: job.arguments.third.titleize)) end end private def generate_csv(releases) release_class = @release_type.constantize headers = release_class.csv_headers CSV.generate(headers: true) do |csv| csv << headers releases.each do |release| csv_row_data = release.to_csv_row csv << csv_row_data end end end def release_name @release_type.constantize.model_name.plural end def all_releases @project.public_send(release_name) end def releases if @release_ids.any? return all_releases.where(id: @release_ids) end results = all_releases if all_releases.respond_to?(:complete, :incomplete) results = case @type_filter when 'complete' all_releases.complete when 'incomplete' all_releases.incomplete else all_releases end end results = results.search(@search_query) if @search_query.present? results end end