Skip to content

Commit

Permalink
Procedure export dossiers with champs siret
Browse files Browse the repository at this point in the history
  • Loading branch information
tchak committed Nov 22, 2018
1 parent cbe83fb commit b44cc92
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 19 deletions.
18 changes: 13 additions & 5 deletions app/controllers/new_gestionnaire/procedures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,21 @@ def remove_filter
end

def download_dossiers
export = procedure.generate_export
filename = procedure.export_filename
options = params.permit(:limit, :since, tables: [])

respond_to do |format|
format.csv { send_data(SpreadsheetArchitect.to_csv(data: export[:data], headers: export[:headers]), filename: "#{filename}.csv") }
format.xlsx { send_data(SpreadsheetArchitect.to_xlsx(data: export[:data], headers: export[:headers]), filename: "#{filename}.xlsx") }
format.ods { send_data(SpreadsheetArchitect.to_ods(data: export[:data], headers: export[:headers]), filename: "#{filename}.ods") }
format.csv do
send_data(procedure.to_csv(options),
filename: procedure.export_filename(:csv))
end
format.xlsx do
send_data(procedure.to_xlsx(options),
filename: procedure.export_filename(:xlsx))
end
format.ods do
send_data(procedure.to_ods(options),
filename: procedure.export_filename(:ods))
end
end
end

Expand Down
4 changes: 2 additions & 2 deletions app/models/dossier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ class Dossier < ApplicationRecord
scope :en_construction, -> { not_archived.state_en_construction }
scope :en_instruction, -> { not_archived.state_en_instruction }
scope :termine, -> { not_archived.state_termine }
scope :downloadable_sorted, -> { state_not_brouillon.includes(:etablissement, :champs, :champs_private, :user, :individual, :followers_gestionnaires).order(en_construction_at: 'asc') }
scope :downloadable_sorted, -> { state_not_brouillon.includes(:etablissement, :user, :individual, :followers_gestionnaires, champs: { etablissement: [], type_de_champ: :drop_down_list }, champs_private: { etablissement: [], type_de_champ: :drop_down_list }).order(en_construction_at: 'asc') }
scope :en_cours, -> { not_archived.state_en_construction_ou_instruction }
scope :without_followers, -> { left_outer_joins(:follows).where(follows: { id: nil }) }
scope :followed_by, -> (gestionnaire) { joins(:follows).where(follows: { gestionnaire: gestionnaire }) }
scope :with_champs, -> { includes(champs: :type_de_champ) }
scope :nearing_end_of_retention, -> (duration = '1 month') { joins(:procedure).where("en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ?", duration) }

scope :since, -> (since) { where('dossiers.created_at >= ?', since) }
scope :for_api, -> {
includes(commentaires: [],
champs: [
Expand Down
24 changes: 14 additions & 10 deletions app/models/procedure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,21 +247,25 @@ def total_dossier
self.dossiers.state_not_brouillon.size
end

def export_filename
def export_filename(format)
procedure_identifier = path || "procedure-#{id}"
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}"
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
end

def generate_export
exportable_dossiers = dossiers.downloadable_sorted
def export(options = {})
Procedure::Export.new(self, **options.to_h.symbolize_keys)
end

headers = exportable_dossiers&.first&.export_headers || []
data = exportable_dossiers.any? ? exportable_dossiers.map(&:export_values) : [[]]
def to_csv(options = {})
export(options).to_csv
end

{
headers: headers,
data: data
}
def to_xlsx(options = {})
export(options).to_xlsx
end

def to_ods(options = {})
export(options).to_ods
end

def procedure_overview(start_date)
Expand Down
240 changes: 240 additions & 0 deletions app/models/procedure/export.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
class Procedure::Export
include DossierHelper

ATTRIBUTES = [
:id,
:created_at,
:updated_at,
:archived,
:email,
:state,
:initiated_at,
:received_at,
:processed_at,
:motivation,
:emails_instructeurs,
:individual_gender,
:individual_prenom,
:individual_nom,
:individual_birthdate
]

ETABLISSEMENT_ATTRIBUTES = [
:siret,
:siege_social,
:naf,
:libelle_naf,
:adresse,
:numero_voie,
:type_voie,
:nom_voie,
:complement_adresse,
:code_postal,
:localite,
:code_insee_localite
]

ENTREPRISE_ATTRIBUTES = [
:siren,
:capital_social,
:numero_tva_intracommunautaire,
:forme_juridique,
:forme_juridique_code,
:nom_commercial,
:raison_sociale,
:siret_siege_social,
:code_effectif_entreprise,
:date_creation,
:nom,
:prenom
]

def initialize(procedure, tables: [], since: nil, limit: nil)
@procedure = procedure
@dossiers = procedure.dossiers.downloadable_sorted
if since
@dossiers = @dossiers.since(since)
end
if limit
@dossiers = @dossiers.limit(limit)
end
@dossiers = @dossiers.to_a
@tables = tables.map(&:to_sym)
end

def to_csv
SpreadsheetArchitect.to_csv(to_table_data(:dossiers))
end

def to_xlsx
package = SpreadsheetArchitect.to_axlsx_package(to_table_data(:dossiers))

@tables.reduce(package) do |package, table|
SpreadsheetArchitect.to_axlsx_package(to_table_data(table), package)
end.to_stream.read
end

def to_ods
spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet(to_table_data(:dossiers))

@tables.reduce(spreadsheet) do |spreadsheet, table|
SpreadsheetArchitect.to_rodf_spreadsheet(to_table_data(table), spreadsheet)
end.to_stream.read
end

private

def to_table_data(table)
case table
when :dossiers
dossiers_table_data
when :etablissements
etablissements_table_data
end
end

def empty_table_data(sheet_name, headers = [])
{
sheet_name: sheet_name,
headers: headers,
data: [[]]
}
end

def dossiers_table_data
if @dossiers.any?
{
sheet_name: 'Dossiers',
headers: dossiers_headers,
data: dossiers_data
}
else
empty_table_data('Dossiers', dossiers_headers)
end
end

def etablissements_table_data
@etablissements = @dossiers.flat_map do |dossier|
dossier.champs.select do |champ|
champ.is_a?(Champs::SiretChamp)
end + dossier.champs_private.select do |champ|
champ.is_a?(Champs::SiretChamp)
end.map(&:etablissement).compact
end

if @etablissements.any?
{
sheet_name: 'Etablissements',
headers: etablissements_headers,
data: etablissements_data
}
else
empty_table_data('Etablissements', etablissements_headers)
end
end

def dossiers_headers
headers = ATTRIBUTES.map do |key|
label_for_export(key.to_s)
end
headers += @procedure.types_de_champ.map do |champ|
label_for_export(champ.libelle)
end
headers += @procedure.types_de_champ_private.map do |champ|
label_for_export(champ.libelle)
end
headers += ETABLISSEMENT_ATTRIBUTES.map do |key|
label_for_export("etablissement.#{key}")
end
headers += ENTREPRISE_ATTRIBUTES.map do |key|
label_for_export("entreprise.#{key}")
end
headers
end

def dossiers_data
@dossiers.map do |dossier|
values = ATTRIBUTES.map do |key|
case key
when :email
dossier.user.email
when :state
dossier_legacy_state(dossier)
when :initiated_at
dossier.en_construction_at
when :received_at
dossier.en_instruction_at
when :individual_prenom
dossier.individual&.prenom
when :individual_nom
dossier.individual&.nom
when :individual_birthdate
dossier.individual&.birthdate
when :individual_gender
dossier.individual&.gender
when :emails_instructeurs
dossier.followers_gestionnaires.map(&:email).join(' ')
else
dossier.read_attribute(key)
end.to_s
end
values += dossier.champs.map do |champ|
value_for_export(champ)
end
values += dossier.champs_private.map do |champ|
value_for_export(champ)
end
values += etablissement_data(dossier.etablissement)
values
end
end

def etablissements_headers
headers = [:dossier_id, :libelle]
headers += ETABLISSEMENT_ATTRIBUTES.map do |key|
label_for_export("etablissement.#{key}")
end
headers += ENTREPRISE_ATTRIBUTES.map do |key|
label_for_export("entreprise.#{key}")
end
headers
end

def etablissements_data
@etablissements.map do |etablissement|
data = [
etablissement.champ.dossier_id,
label_for_export(etablissement.champ.libelle)
]
data += etablissement_data(etablissement)
end
end

def etablissement_data(etablissement)
data = ETABLISSEMENT_ATTRIBUTES.map do |key|
case key
when :adresse
etablissement&.adresse&.chomp&.gsub("\r\n", ' ')&.delete("\r")
else
etablissement&.read_attribute(key)
end
end
data += ENTREPRISE_ATTRIBUTES.map do |key|
case key
when :date_creation
etablissement&.entreprise_date_creation&.to_datetime
else
etablissement&.read_attribute(:"entreprise_#{key}")
end
end
data
end

def label_for_export(label)
label.parameterize.underscore.to_sym
end

def value_for_export(champ)
champ.for_export
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
%li
= link_to "Au format .csv", download_dossiers_gestionnaire_procedure_path(format: :csv, procedure_id: procedure.id), target: "_blank"
%li
= link_to "Au format .xlsx", download_dossiers_gestionnaire_procedure_path(format: :xlsx, procedure_id: procedure.id), target: "_blank"
= link_to "Au format .xlsx", download_dossiers_gestionnaire_procedure_path(format: :xlsx, procedure_id: procedure.id, tables: [:etablissements]), target: "_blank"
%li
= link_to "Au format .ods", download_dossiers_gestionnaire_procedure_path(format: :ods, procedure_id: procedure.id), target: "_blank"
= link_to "Au format .ods", download_dossiers_gestionnaire_procedure_path(format: :ods, procedure_id: procedure.id, tables: [:etablissements]), target: "_blank"

0 comments on commit b44cc92

Please sign in to comment.