Compare commits
3 Commits
make-direc
...
improve-do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bda6c3480 | ||
|
|
98afad4174 | ||
|
|
3471e21429 |
20
app/assets/javascripts/download_releases.js
Normal file
20
app/assets/javascripts/download_releases.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
$(document).on("click", "#download_releases", function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const releasable_ids = JSON.parse($("#selected_releases_form").attr('data-releasable-ids'));
|
||||||
|
const total_entries = $('#total_entries').val();
|
||||||
|
|
||||||
|
const input_ids = $('<input>').attr({ type: 'hidden', name: 'release_ids', value: JSON.stringify(releasable_ids) });
|
||||||
|
const search_query = $('<input>').attr({ type: 'hidden', name: 'search_query', value: $("form input[type='search']").val() });
|
||||||
|
const type_filter = $('<input>').attr({ type: 'hidden', name: 'type_filter', value: $('#type_filter_value').val() });
|
||||||
|
|
||||||
|
const download_count = releasable_ids.length > 0 ? releasable_ids.length : total_entries;
|
||||||
|
|
||||||
|
$(this).parent().append(input_ids);
|
||||||
|
$(this).parent().append(search_query);
|
||||||
|
$(this).parent().append(type_filter);
|
||||||
|
|
||||||
|
if (confirm(`${download_count} release(s) will be downloaded. Is this correct?`)){
|
||||||
|
Rails.fire($(this).parent()[0], 'submit');
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -7,28 +7,41 @@ class ContractDownloadsController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
authorize policy_scope(Download).create
|
authorize policy_scope(Download).create
|
||||||
fetch_releases
|
|
||||||
|
download = @project.downloads.create!(release_type: release_type)
|
||||||
download = @project.downloads.create!(release_type: params[:release_type])
|
|
||||||
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
|
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
|
||||||
|
|
||||||
if other_downloads_in_progress.any?
|
if other_downloads_in_progress.any?
|
||||||
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: params[:release_type] }, :layout => false
|
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: release_type }, :layout => false
|
||||||
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
|
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
|
||||||
else
|
else
|
||||||
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: params[:release_type].titleize))
|
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: release_type.titleize))
|
||||||
end
|
end
|
||||||
|
|
||||||
GenerateContractsZipJob.perform_later(@project, download, params[:release_type], @releases.ids)
|
GenerateContractsZipJob.perform_later(@project, download, release_type, release_ids, search_query, type_filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_releases
|
def release_type
|
||||||
@releases = policy_scope(@project.public_send(releases))
|
params[:release_type]
|
||||||
end
|
end
|
||||||
|
|
||||||
def releases
|
def search_query
|
||||||
params[:release_type].constantize.model_name.plural
|
params[:search_query]
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_filter
|
||||||
|
params[:type_filter]
|
||||||
|
end
|
||||||
|
|
||||||
|
def release_ids
|
||||||
|
JSON.parse(params[:release_ids])
|
||||||
|
rescue StandardError
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def release_name(release_type)
|
||||||
|
release_type.constantize.model_name.plural
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ module TagsHelper
|
|||||||
disable_with: disabled_content,
|
disable_with: disabled_content,
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
|
id: "selected_releases_form",
|
||||||
data: {
|
data: {
|
||||||
releasable_ids: [],
|
releasable_ids: [],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
@project = job.arguments.first
|
@project = job.arguments.first
|
||||||
@download = job.arguments.second
|
@download = job.arguments.second
|
||||||
@release_type = job.arguments.third
|
@release_type = job.arguments.third
|
||||||
@folder_name = "#{@project.name.parameterize}_#{get_release_name(@release_type).gsub('_', '-')}"
|
@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)
|
@download.update!(name: @folder_name, status: :pending)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(project, download, release_type, release_ids)
|
def perform(project, download, release_type, release_ids, search_query, type_filter)
|
||||||
releases = project.public_send(get_release_name(release_type)).where(id: release_ids)
|
|
||||||
|
|
||||||
::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files|
|
::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files|
|
||||||
zipfile_name = "#{dir}/#{@folder_name}.zip"
|
zipfile_name = "#{dir}/#{@folder_name}.zip"
|
||||||
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
||||||
@@ -31,7 +32,7 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
end
|
end
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message)
|
Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message)
|
||||||
|
|
||||||
@download.failure!
|
@download.failure!
|
||||||
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.failure"))
|
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.failure"))
|
||||||
end
|
end
|
||||||
@@ -61,7 +62,32 @@ class GenerateContractsZipJob < ApplicationJob
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_release_name(release_type)
|
def release_name
|
||||||
release_type.constantize.model_name.plural
|
@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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class ReleaseContractCollectionService
|
|||||||
end
|
end
|
||||||
|
|
||||||
files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
|
files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
|
||||||
raise StandardError.new "Contracts or Contract Templates not found." unless files.any?
|
# raise StandardError.new "Contracts or Contract Templates not found." unless files.any?
|
||||||
yield(dir, files)
|
yield(dir, files)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
<input id="total_entries" type=hidden value=<%= @appearance_releases.total_entries %> />
|
||||||
<div id="upload-progress-container" class="mb-1"></div>
|
<div id="upload-progress-container" class="mb-1"></div>
|
||||||
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2">
|
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2">
|
||||||
<% if policy(AppearanceRelease).new? %>
|
<% if policy(AppearanceRelease).new? %>
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %>
|
<% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %>
|
||||||
<%= link_to "Download All", [@project, :contract_downloads, release_type: @appearance_releases.name], method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %>
|
<%= button_to "Download", [@project, :contract_downloads, release_type: @appearance_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ $("form input[type='search']").val("<%= params[:query] %>");
|
|||||||
$("#type_filter_actions").html("<%= j render 'type_filter_actions' %>");
|
$("#type_filter_actions").html("<%= j render 'type_filter_actions' %>");
|
||||||
$("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>");
|
$("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>");
|
||||||
$('#type_filter_value').val("<%= params[:type_filter] %>");
|
$('#type_filter_value').val("<%= params[:type_filter] %>");
|
||||||
|
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
|
||||||
|
$("#total_entries").val(<%= @appearance_releases.total_entries %>);
|
||||||
@@ -542,9 +542,9 @@ CREATE TABLE public.broadcast_recordings (
|
|||||||
updated_at timestamp(6) without time zone NOT NULL,
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
duration double precision,
|
duration double precision,
|
||||||
hidden boolean DEFAULT false,
|
hidden boolean DEFAULT false,
|
||||||
starred boolean DEFAULT false,
|
|
||||||
name character varying,
|
name character varying,
|
||||||
description text
|
description text,
|
||||||
|
starred boolean DEFAULT false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -1492,6 +1492,7 @@ CREATE TABLE public.settings (
|
|||||||
--
|
--
|
||||||
|
|
||||||
CREATE SEQUENCE public.settings_id_seq
|
CREATE SEQUENCE public.settings_id_seq
|
||||||
|
AS integer
|
||||||
START WITH 1
|
START WITH 1
|
||||||
INCREMENT BY 1
|
INCREMENT BY 1
|
||||||
NO MINVALUE
|
NO MINVALUE
|
||||||
@@ -1527,6 +1528,7 @@ CREATE TABLE public.taggings (
|
|||||||
--
|
--
|
||||||
|
|
||||||
CREATE SEQUENCE public.taggings_id_seq
|
CREATE SEQUENCE public.taggings_id_seq
|
||||||
|
AS integer
|
||||||
START WITH 1
|
START WITH 1
|
||||||
INCREMENT BY 1
|
INCREMENT BY 1
|
||||||
NO MINVALUE
|
NO MINVALUE
|
||||||
@@ -1557,6 +1559,7 @@ CREATE TABLE public.tags (
|
|||||||
--
|
--
|
||||||
|
|
||||||
CREATE SEQUENCE public.tags_id_seq
|
CREATE SEQUENCE public.tags_id_seq
|
||||||
|
AS integer
|
||||||
START WITH 1
|
START WITH 1
|
||||||
INCREMENT BY 1
|
INCREMENT BY 1
|
||||||
NO MINVALUE
|
NO MINVALUE
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe GenerateContractsZipJob do
|
|||||||
describe ".perform_later" do
|
describe ".perform_later" do
|
||||||
it "enqueues a background job for generating zip file" do
|
it "enqueues a background job for generating zip file" do
|
||||||
expect {
|
expect {
|
||||||
GenerateContractsZipJob.perform_later(project, download, "AppearanceRelease", project.appearance_releases.ids)
|
GenerateContractsZipJob.perform_later(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
|
||||||
}.to have_enqueued_job
|
}.to have_enqueued_job
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -28,7 +28,7 @@ describe GenerateContractsZipJob do
|
|||||||
shared_examples "generates ZIP containig CSV file with all releases data" do
|
shared_examples "generates ZIP containig CSV file with all releases data" do
|
||||||
it "generates ZIP containing CSV file with all releases data for all release types" do
|
it "generates ZIP containing CSV file with all releases data for all release types" do
|
||||||
lowercase_plural = subject.constantize.model_name.plural
|
lowercase_plural = subject.constantize.model_name.plural
|
||||||
GenerateContractsZipJob.perform_now(project, download, subject, project.public_send(lowercase_plural).ids)
|
GenerateContractsZipJob.perform_now(project, download, subject, project.public_send(lowercase_plural).ids, '', '')
|
||||||
|
|
||||||
generated_zip = download.file.blob.download
|
generated_zip = download.file.blob.download
|
||||||
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
||||||
@@ -50,8 +50,111 @@ describe GenerateContractsZipJob do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples "generates ZIP containig CSV file with specific releases data" do
|
||||||
|
it "generates ZIP containing CSV file with all selected releases data for selected releases" do
|
||||||
|
lowercase_plural = subject.constantize.model_name.plural
|
||||||
|
all_releases = project.public_send(lowercase_plural)
|
||||||
|
included_releases = all_releases.where(id: all_releases.ids[0..1])
|
||||||
|
not_included_releases = all_releases.where.not(id: all_releases.ids[0..1])
|
||||||
|
GenerateContractsZipJob.perform_now(project, download, subject, included_releases.ids, '', '')
|
||||||
|
|
||||||
|
generated_zip = download.file.blob.download
|
||||||
|
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
||||||
|
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
|
||||||
|
while entry = io.get_next_entry
|
||||||
|
next unless entry.name == csv_file_name
|
||||||
|
|
||||||
|
csv_file = entry.get_input_stream.read
|
||||||
|
|
||||||
|
release_class = Object.const_get subject
|
||||||
|
release_headers = release_class.csv_headers
|
||||||
|
|
||||||
|
release_headers.each do |header|
|
||||||
|
expect(csv_file).to match header
|
||||||
|
expect(csv_file).not_to match translation_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
included_releases.each do |release|
|
||||||
|
expect(csv_file).to match release.person_first_name
|
||||||
|
end
|
||||||
|
|
||||||
|
not_included_releases.each do |release|
|
||||||
|
expect(csv_file).not_to match release.person_first_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates ZIP containing CSV file with all filtered releases data for filtered releases" do
|
||||||
|
lowercase_plural = subject.constantize.model_name.plural
|
||||||
|
GenerateContractsZipJob.perform_now(project, download, subject, [], '', 'complete')
|
||||||
|
|
||||||
|
complete_releases = project.public_send(lowercase_plural).complete
|
||||||
|
incomplete_releases = project.public_send(lowercase_plural).incomplete
|
||||||
|
|
||||||
|
generated_zip = download.file.blob.download
|
||||||
|
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
||||||
|
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
|
||||||
|
while entry = io.get_next_entry
|
||||||
|
next unless entry.name == csv_file_name
|
||||||
|
|
||||||
|
csv_file = entry.get_input_stream.read
|
||||||
|
|
||||||
|
release_class = Object.const_get subject
|
||||||
|
release_headers = release_class.csv_headers
|
||||||
|
|
||||||
|
release_headers.each do |header|
|
||||||
|
expect(csv_file).to match header
|
||||||
|
expect(csv_file).not_to match translation_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
complete_releases.each do |release|
|
||||||
|
expect(csv_file).to match release.person_first_name
|
||||||
|
end
|
||||||
|
|
||||||
|
incomplete_releases.each do |release|
|
||||||
|
expect(csv_file).not_to match release.person_first_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates ZIP containing CSV file with all search query matching releases" do
|
||||||
|
lowercase_plural = subject.constantize.model_name.plural
|
||||||
|
matched_releases = project.public_send(lowercase_plural).search('Brad')
|
||||||
|
not_matched_releases = project.public_send(lowercase_plural).where.not(id: matched_releases.ids)
|
||||||
|
GenerateContractsZipJob.perform_now(project, download, subject, [], 'Brad', '')
|
||||||
|
|
||||||
|
generated_zip = download.file.blob.download
|
||||||
|
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
|
||||||
|
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
|
||||||
|
while entry = io.get_next_entry
|
||||||
|
next unless entry.name == csv_file_name
|
||||||
|
|
||||||
|
csv_file = entry.get_input_stream.read
|
||||||
|
|
||||||
|
release_class = Object.const_get subject
|
||||||
|
release_headers = release_class.csv_headers
|
||||||
|
|
||||||
|
release_headers.each do |header|
|
||||||
|
expect(csv_file).to match header
|
||||||
|
expect(csv_file).not_to match translation_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
matched_releases.each do |release|
|
||||||
|
expect(csv_file).to match release.person_first_name
|
||||||
|
end
|
||||||
|
|
||||||
|
not_matched_releases.each do |release|
|
||||||
|
expect(csv_file).not_to match release.person_first_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "updates a download record and creates attachment for it" do
|
it "updates a download record and creates attachment for it" do
|
||||||
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids)
|
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
|
||||||
|
|
||||||
expect(download.project).to eq project
|
expect(download.project).to eq project
|
||||||
expect(download.release_type).to eq "AppearanceRelease"
|
expect(download.release_type).to eq "AppearanceRelease"
|
||||||
@@ -69,9 +172,12 @@ describe GenerateContractsZipJob do
|
|||||||
|
|
||||||
context "generates ZIP for appearance releases" do
|
context "generates ZIP for appearance releases" do
|
||||||
let(:release) { create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe") }
|
let(:release) { create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe") }
|
||||||
|
let(:incomplete_release) { create(:appearance_release_with_contract_template, project: project, person_name: "Jane Doe") }
|
||||||
|
let(:complete_release) { create(:appearance_release_with_contract_template, :non_native, project: project, person_name: "Brad Doe") }
|
||||||
subject { 'AppearanceRelease' }
|
subject { 'AppearanceRelease' }
|
||||||
|
|
||||||
it_behaves_like "generates ZIP containig CSV file with all releases data"
|
it_behaves_like "generates ZIP containig CSV file with all releases data"
|
||||||
|
it_behaves_like "generates ZIP containig CSV file with specific releases data"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "generates ZIP for location releases" do
|
context "generates ZIP for location releases" do
|
||||||
@@ -125,7 +231,7 @@ describe GenerateContractsZipJob do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "updates status to 'failure' and sends user a notification" do
|
it "updates status to 'failure' and sends user a notification" do
|
||||||
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids)
|
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
|
||||||
|
|
||||||
expect(download.status).to eq "failure"
|
expect(download.status).to eq "failure"
|
||||||
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure"))
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure"))
|
||||||
|
|||||||
Reference in New Issue
Block a user