Merge pull request #4490 from tchak/fix-more-export-issues

Fix more export issues
This commit is contained in:
Paul Chavard 2019-11-07 14:33:51 +01:00 committed by GitHub
commit 91002865b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 159 additions and 16 deletions

View file

@ -33,6 +33,12 @@ class Champs::RepetitionChamp < Champ
end end
end end
# We have to truncate the label here as spreadsheets have a (30 char) limit on length.
def libelle_for_export
str = "(#{type_de_champ.stable_id}) #{libelle}"
ActiveStorage::Filename.new(str).sanitized.truncate(30)
end
class Row < Hashie::Dash class Row < Hashie::Dash
property :index property :index
property :dossier_id property :dossier_id

View file

@ -472,7 +472,19 @@ class Dossier < ApplicationRecord
log_dossier_operation(avis.claimant, :demander_un_avis, avis) log_dossier_operation(avis.claimant, :demander_un_avis, avis)
end end
def spreadsheet_columns def spreadsheet_columns_csv
spreadsheet_columns(with_etablissement: true)
end
def spreadsheet_columns_xlsx
spreadsheet_columns
end
def spreadsheet_columns_ods
spreadsheet_columns
end
def spreadsheet_columns(with_etablissement: false)
columns = [ columns = [
['ID', id.to_s], ['ID', id.to_s],
['Email', user.email] ['Email', user.email]
@ -485,6 +497,39 @@ class Dossier < ApplicationRecord
['Prénom', individual&.prenom], ['Prénom', individual&.prenom],
['Date de naissance', individual&.birthdate] ['Date de naissance', individual&.birthdate]
] ]
elsif with_etablissement
columns += [
['Établissement SIRET', etablissement&.siret],
['Établissement siège social', etablissement&.siege_social],
['Établissement NAF', etablissement&.naf],
['Établissement libellé NAF', etablissement&.libelle_naf],
['Établissement Adresse', etablissement&.adresse],
['Établissement numero voie', etablissement&.numero_voie],
['Établissement type voie', etablissement&.type_voie],
['Établissement nom voie', etablissement&.nom_voie],
['Établissement complément adresse', etablissement&.complement_adresse],
['Établissement code postal', etablissement&.code_postal],
['Établissement localité', etablissement&.localite],
['Établissement code INSEE localité', etablissement&.code_insee_localite],
['Entreprise SIREN', etablissement&.entreprise_siren],
['Entreprise capital social', etablissement&.entreprise_capital_social],
['Entreprise numero TVA intracommunautaire', etablissement&.entreprise_numero_tva_intracommunautaire],
['Entreprise forme juridique', etablissement&.entreprise_forme_juridique],
['Entreprise forme juridique code', etablissement&.entreprise_forme_juridique_code],
['Entreprise nom commercial', etablissement&.entreprise_nom_commercial],
['Entreprise raison sociale', etablissement&.entreprise_raison_sociale],
['Entreprise SIRET siège social', etablissement&.entreprise_siret_siege_social],
['Entreprise code effectif entreprise', etablissement&.entreprise_code_effectif_entreprise],
['Entreprise date de création', etablissement&.entreprise_date_creation],
['Entreprise nom', etablissement&.entreprise_nom],
['Entreprise prénom', etablissement&.entreprise_prenom],
['Association RNA', etablissement&.association_rna],
['Association titre', etablissement&.association_titre],
['Association objet', etablissement&.association_objet],
['Association date de création', etablissement&.association_date_creation],
['Association date de déclaration', etablissement&.association_date_declaration],
['Association date de publication', etablissement&.association_date_publication]
]
else else
columns << ['Entreprise raison sociale', etablissement&.entreprise_raison_sociale] columns << ['Entreprise raison sociale', etablissement&.entreprise_raison_sociale]
end end

View file

@ -16,21 +16,21 @@ class ProcedureExportV2Service
@tables = [:dossiers, :etablissements, :avis] + champs_repetables_options @tables = [:dossiers, :etablissements, :avis] + champs_repetables_options
end end
def to_csv(table = :dossiers) def to_csv
SpreadsheetArchitect.to_csv(options_for(table)) SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv))
end end
def to_xlsx def to_xlsx
# We recursively build multi page spreadsheet # We recursively build multi page spreadsheet
@tables.reduce(nil) do |package, table| @tables.reduce(nil) do |package, table|
SpreadsheetArchitect.to_axlsx_package(options_for(table), package) SpreadsheetArchitect.to_axlsx_package(options_for(table, :xlsx), package)
end.to_stream.read end.to_stream.read
end end
def to_ods def to_ods
# We recursively build multi page spreadsheet # We recursively build multi page spreadsheet
@tables.reduce(nil) do |spreadsheet, table| @tables.reduce(nil) do |spreadsheet, table|
SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table), spreadsheet) SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet)
end.bytes end.bytes
end end
@ -53,7 +53,7 @@ class ProcedureExportV2Service
[dossier.champs, dossier.champs_private] [dossier.champs, dossier.champs_private]
.flatten .flatten
.filter { |champ| champ.is_a?(Champs::RepetitionChamp) } .filter { |champ| champ.is_a?(Champs::RepetitionChamp) }
end.group_by(&:libelle) end.group_by(&:libelle_for_export)
end end
def champs_repetables_options def champs_repetables_options
@ -70,21 +70,16 @@ class ProcedureExportV2Service
row_style: { background_color: nil, color: "000000", font_size: 12 } row_style: { background_color: nil, color: "000000", font_size: 12 }
} }
def sanitize_sheet_name(name) def options_for(table, format)
ActiveStorage::Filename.new(name.to_s).sanitized.truncate(30)
end
def options_for(table)
case table case table
when :dossiers when :dossiers
{ instances: dossiers.to_a, sheet_name: 'Dossiers' }.merge(DEFAULT_STYLES) { instances: dossiers.to_a, sheet_name: 'Dossiers', spreadsheet_columns: :"spreadsheet_columns_#{format}" }.merge(DEFAULT_STYLES)
when :etablissements when :etablissements
{ instances: etablissements.to_a, sheet_name: 'Etablissements' }.merge(DEFAULT_STYLES) { instances: etablissements.to_a, sheet_name: 'Etablissements' }.merge(DEFAULT_STYLES)
when :avis when :avis
{ instances: avis.to_a, sheet_name: 'Avis' }.merge(DEFAULT_STYLES) { instances: avis.to_a, sheet_name: 'Avis' }.merge(DEFAULT_STYLES)
when Array when Array
# We have to truncate the label here as spreadsheets have a (30 char) limit on length. { instances: table.last, sheet_name: table.first }.merge(DEFAULT_STYLES)
{ instances: table.last, sheet_name: sanitize_sheet_name(table.first) }.merge(DEFAULT_STYLES)
end end
end end
end end

View file

@ -1,4 +1,5 @@
require 'spec_helper' require 'spec_helper'
require 'csv'
describe ProcedureExportV2Service do describe ProcedureExportV2Service do
describe 'to_data' do describe 'to_data' do
@ -150,6 +151,91 @@ describe ProcedureExportV2Service do
] ]
end end
context 'as csv' do
subject do
Tempfile.create do |f|
f << ProcedureExportV2Service.new(procedure, procedure.dossiers).to_csv
f.rewind
CSV.read(f.path)
end
end
let(:nominal_headers) do
[
"ID",
"Email",
"Établissement SIRET",
"Établissement siège social",
"Établissement NAF",
"Établissement libellé NAF",
"Établissement Adresse",
"Établissement numero voie",
"Établissement type voie",
"Établissement nom voie",
"Établissement complément adresse",
"Établissement code postal",
"Établissement localité",
"Établissement code INSEE localité",
"Entreprise SIREN",
"Entreprise capital social",
"Entreprise numero TVA intracommunautaire",
"Entreprise forme juridique",
"Entreprise forme juridique code",
"Entreprise nom commercial",
"Entreprise raison sociale",
"Entreprise SIRET siège social",
"Entreprise code effectif entreprise",
"Entreprise date de création",
"Entreprise nom",
"Entreprise prénom",
"Association RNA",
"Association titre",
"Association objet",
"Association date de création",
"Association date de déclaration",
"Association date de publication",
"Archivé",
"État du dossier",
"Dernière mise à jour le",
"Déposé le",
"Passé en instruction le",
"Traité le",
"Motivation de la décision",
"Instructeurs",
"textarea",
"date",
"datetime",
"number",
"decimal_number",
"integer_number",
"checkbox",
"civilite",
"email",
"phone",
"address",
"yes_no",
"simple_drop_down_list",
"multiple_drop_down_list",
"linked_drop_down_list",
"pays",
"regions",
"departements",
"engagement",
"dossier_link",
"piece_justificative",
"siret",
"carte",
"text"
]
end
let(:dossiers_sheet_headers) { subject.first }
it 'should have headers' do
expect(dossiers_sheet_headers).to match(nominal_headers)
end
end
it 'should have headers' do it 'should have headers' do
expect(dossiers_sheet.headers).to match(nominal_headers) expect(dossiers_sheet.headers).to match(nominal_headers)
@ -225,7 +311,7 @@ describe ProcedureExportV2Service do
let(:champ_repetition) { dossiers.first.champs.find { |champ| champ.type_champ == 'repetition' } } let(:champ_repetition) { dossiers.first.champs.find { |champ| champ.type_champ == 'repetition' } }
it 'should have sheets' do it 'should have sheets' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle]) expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export])
end end
it 'should have headers' do it 'should have headers' do
@ -247,7 +333,18 @@ describe ProcedureExportV2Service do
end end
it 'should have valid sheet name' do it 'should have valid sheet name' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', "A - B - C"]) expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', "(#{champ_repetition.type_de_champ.stable_id}) A - B - C"])
end
end
context 'with non unique labels' do
let(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
let(:champ_repetition) { dossier.champs.find { |champ| champ.type_champ == 'repetition' } }
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, procedure: procedure, libelle: champ_repetition.libelle) }
let!(:another_champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
it 'should have sheets' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export, another_champ_repetition.libelle_for_export])
end end
end end
end end