Add last_month export

This commit is contained in:
Paul Chavard 2021-06-16 11:46:25 +02:00
parent f5f4aa9bf2
commit f238710044
14 changed files with 125 additions and 50 deletions

View file

@ -146,6 +146,7 @@ module Instructeurs
def download_export
export_format = params[:export_format]
time_span_type = params[:time_span_type] || Export.time_span_types.fetch(:everything)
groupe_instructeurs = current_instructeur
.groupe_instructeurs
.where(procedure: procedure)
@ -155,11 +156,11 @@ module Instructeurs
.fetch_values('tous', 'archives')
.sum
export = Export.find_or_create_export(export_format, groupe_instructeurs)
export = Export.find_or_create_export(export_format, time_span_type, groupe_instructeurs)
if export.ready? && export.old? && params[:force_export]
export.destroy
export = Export.find_or_create_export(export_format, groupe_instructeurs)
export = Export.find_or_create_export(export_format, time_span_type, groupe_instructeurs)
end
if export.ready?
@ -221,7 +222,7 @@ module Instructeurs
end
def assign_exports
@xlsx_export, @csv_export, @ods_export = Export.find_for_groupe_instructeurs(groupe_instructeur_ids)
@exports = Export.find_for_groupe_instructeurs(groupe_instructeur_ids)
end
def assign_to

View file

@ -107,4 +107,10 @@ module DossierHelper
return base_url if siren.blank?
"#{base_url}/entreprise/#{siren}"
end
def exports_list(exports)
Export::FORMATS.map do |(format, time_span_type)|
[format, time_span_type, exports[format] && exports[format][time_span_type]]
end
end
end

View file

@ -2,11 +2,12 @@
#
# Table name: exports
#
# id :bigint not null, primary key
# format :string not null
# key :text not null
# created_at :datetime not null
# updated_at :datetime not null
# id :bigint not null, primary key
# format :string not null
# key :text not null
# time_span_type :string default("everything"), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Export < ApplicationRecord
MAX_DUREE_CONSERVATION_EXPORT = 3.hours
@ -17,6 +18,11 @@ class Export < ApplicationRecord
xlsx: 'xlsx'
}
enum time_span_type: {
everything: 'everything',
monthly: 'monthly'
}
has_and_belongs_to_many :groupe_instructeurs
has_one_attached :file
@ -27,13 +33,19 @@ class Export < ApplicationRecord
after_create_commit :compute_async
FORMATS = [:xlsx, :ods, :csv].flat_map do |format|
Export.time_span_types.values.map do |time_span_type|
[format, time_span_type]
end
end
def compute_async
ExportJob.perform_later(self)
end
def compute
file.attach(
io: io,
io: io(since: since),
filename: filename,
content_type: content_type,
# We generate the exports ourselves, so they are safe
@ -41,6 +53,10 @@ class Export < ApplicationRecord
)
end
def since
time_span_type == Export.time_span_types.fetch(:monthly) ? 30.days.ago : nil
end
def ready?
file.attached?
end
@ -49,16 +65,24 @@ class Export < ApplicationRecord
updated_at < 20.minutes.ago
end
def self.find_or_create_export(format, groupe_instructeurs)
def self.find_or_create_export(format, time_span_type, groupe_instructeurs)
create_with(groupe_instructeurs: groupe_instructeurs)
.create_or_find_by(format: format, key: generate_cache_key(groupe_instructeurs.map(&:id)))
.create_or_find_by(format: format,
time_span_type: time_span_type,
key: generate_cache_key(groupe_instructeurs.map(&:id)))
end
def self.find_for_groupe_instructeurs(groupe_instructeurs_ids)
exports = where(key: generate_cache_key(groupe_instructeurs_ids))
['xlsx', 'csv', 'ods']
.map { |format| exports.find { |export| export.format == format } }
[:xlsx, :csv, :ods].map do |format|
[
format,
Export.time_span_types.values.map do |time_span_type|
[time_span_type, exports.find { |export| export.format == format.to_s && export.time_span_type == time_span_type }]
end.filter { |(_, export)| export.present? }.to_h
]
end.filter { |(_, exports)| exports.present? }.to_h
end
def self.generate_cache_key(groupe_instructeurs_ids)
@ -72,8 +96,11 @@ class Export < ApplicationRecord
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
end
def io
def io(since: nil)
dossiers = Dossier.where(groupe_instructeur: groupe_instructeurs)
if since.present?
dossiers = dossiers.where('dossiers.en_construction_at > ?', since)
end
service = ProcedureExportService.new(procedure, dossiers)
case format.to_sym

View file

@ -2,20 +2,20 @@
%span.dropdown
%button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'download-menu' }
Télécharger tous les dossiers
#download-menu.dropdown-content.fade-in-down{ style: 'width: 330px' }
#download-menu.dropdown-content.fade-in-down{ style: 'width: 450px' }
%ul.dropdown-items
- [[xlsx_export, :xlsx], [ods_export, :ods], [csv_export, :csv]].each do |(export, format)|
- exports_list(exports).each do |(format, time_span_type, export)|
%li
- if export.nil?
= link_to t("#{format}_html", scope: [:instructeurs, :procedure, :export_stale]), download_export_instructeur_procedure_path(procedure, export_format: format), remote: true
= link_to t("#{time_span_type}_#{format}_html", scope: [:instructeurs, :procedure, :export_stale]), download_export_instructeur_procedure_path(procedure, time_span_type: time_span_type, export_format: format), remote: true
- elsif export.ready?
= link_to t(:export_ready_html, export_time: time_ago_in_words(export.updated_at), export_format: ".#{format}", scope: [:instructeurs, :procedure]), export.file.service_url, target: "_blank", rel: "noopener"
= link_to t("export_#{time_span_type}_ready_html", export_time: time_ago_in_words(export.updated_at), export_format: ".#{format}", scope: [:instructeurs, :procedure]), export.file.service_url, target: "_blank", rel: "noopener"
- if export.old?
= button_to download_export_instructeur_procedure_path(procedure, export_format: format, force_export: true), class: "button small", style: "padding-right: 2px", title: t(:short, export_format: ".#{format}", scope: [:instructeurs, :procedure, :export_stale]), remote: true, method: :get, params: { export_format: format, force_export: true } do
= button_to download_export_instructeur_procedure_path(procedure, export_format: format, time_span_type: time_span_type, force_export: true), class: "button small", style: "padding-right: 2px", title: t("#{time_span_type}_short", export_format: ".#{format}", scope: [:instructeurs, :procedure, :export_stale]), remote: true, method: :get, params: { export_format: format, time_span_type: time_span_type, force_export: true } do
.icon.retry
- else
%span{ 'data-export-poll-url': download_export_instructeur_procedure_path(procedure, export_format: format, no_progress_notification: true) }
= t(:export_pending_html, export_time: time_ago_in_words(export.created_at), export_format: ".#{format}", scope: [:instructeurs, :procedure])
= t("export_#{time_span_type}_pending_html", export_time: time_ago_in_words(export.created_at), export_format: ".#{format}", scope: [:instructeurs, :procedure])
- if procedure.feature_enabled?(:archive_zip_globale)
%li
= link_to t(:download_archive, scope: [:instructeurs, :procedure]), instructeur_archives_path(procedure)

View file

@ -1,9 +1,10 @@
<%= render_to_element('.procedure-actions', partial: "download_dossiers",
locals: { procedure: @procedure, xlsx_export: @xlsx_export, csv_export: @csv_export, ods_export: @ods_export, dossier_count: @dossier_count }) %>
<%= render_to_element('.procedure-actions', partial: "download_dossiers", locals: { procedure: @procedure, exports: @exports, dossier_count: @dossier_count }) %>
<% [[@xlsx_export, :xlsx], [@csv_export, :csv], [@ods_export, :ods]].each do |(export, format)| %>
<% if export && !export.ready? %>
<%= fire_event('export:update', { url: download_export_instructeur_procedure_path(@procedure, export_format: format, no_progress_notification: true) }.to_json ) %>
<% @exports.each do |format, exports| %>
<% exports.each do |time_span_type, export| %>
<% if !export.ready? %>
<%= fire_event('export:update', { url: download_export_instructeur_procedure_path(@procedure, export_format: format, time_span_type: time_span_type, no_progress_notification: true) }.to_json) %>
<% end %>
<% end %>
<% end %>

View file

@ -49,8 +49,7 @@
badge: number_with_html_delimiter(@archives_count))
.procedure-actions
= render partial: "download_dossiers",
locals: { procedure: @procedure, xlsx_export: @xlsx_export, csv_export: @csv_export, ods_export: @ods_export, dossier_count: @tous_count + @archives_count }
= render partial: "download_dossiers", locals: { procedure: @procedure, exports: @exports, dossier_count: @tous_count + @archives_count }
.container
- if @statut == 'a-suivre'