feat(export_template): use in export service
This commit is contained in:
parent
f014006542
commit
c209cac62f
6 changed files with 283 additions and 6 deletions
|
@ -19,8 +19,9 @@ module DossierExportConcern
|
|||
types_de_champ.flat_map do |type_de_champ|
|
||||
champ = filled_champ(type_de_champ, row_id)
|
||||
if export_template.present?
|
||||
columns = export_template.columns_for_stable_id(type_de_champ.stable_id)
|
||||
columns.map { [_1.libelle, type_de_champ.champ_value_for_export(champ, _1.column)] }
|
||||
export_template
|
||||
.columns_for_stable_id(type_de_champ.stable_id)
|
||||
.map { |exported_column| exported_column.libelle_with_value(champ) }
|
||||
else
|
||||
type_de_champ.libelles_for_export.map do |(libelle, path)|
|
||||
[libelle, type_de_champ.champ_value_for_export(champ, path)]
|
||||
|
@ -37,7 +38,7 @@ module DossierExportConcern
|
|||
|
||||
def dossier_values_for_export(with_etablissement: false, export_template: nil)
|
||||
if export_template.present?
|
||||
return export_template.dossier_exported_columns.map { [_1.libelle, _1.column.get_value(self)] }
|
||||
return export_template.dossier_exported_columns.map { _1.libelle_with_value(self) }
|
||||
end
|
||||
|
||||
columns = [
|
||||
|
|
|
@ -9,4 +9,8 @@ class ExportedColumn
|
|||
end
|
||||
|
||||
def id = { id: column.id, libelle: }.to_json
|
||||
|
||||
def libelle_with_value(champ_or_dossier)
|
||||
[libelle, column.value(champ_or_dossier)]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -115,7 +115,7 @@ class ProcedureExportService
|
|||
{
|
||||
sheet_name: type_de_champ_repetition.libelle_for_export,
|
||||
instances: rows,
|
||||
spreadsheet_columns: Proc.new { |instance| instance.spreadsheet_columns(types_de_champ) }
|
||||
spreadsheet_columns: Proc.new { |instance| instance.spreadsheet_columns(types_de_champ, export_template: @export_template) }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -152,7 +152,7 @@ class ProcedureExportService
|
|||
types_de_champ = procedure.types_de_champ_for_procedure_export.to_a
|
||||
|
||||
Proc.new do |instance|
|
||||
instance.send(:"spreadsheet_columns_#{format}", types_de_champ: types_de_champ)
|
||||
instance.send(:"spreadsheet_columns_#{format}", types_de_champ: types_de_champ, export_template: @export_template)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,9 @@ describe Columns::DossierColumn do
|
|||
expect(procedure.find_column(label: "Prénom").value(dossier)).to eq("Paul")
|
||||
expect(procedure.find_column(label: "Nom").value(dossier)).to eq("Sim")
|
||||
expect(procedure.find_column(label: "Civilité").value(dossier)).to eq("M.")
|
||||
expect(procedure.find_column(label: "Dépôt pour un tiers").value(dossier)).to eq(true)
|
||||
expect(procedure.find_column(label: "Nom du mandataire").value(dossier)).to eq("Christophe")
|
||||
expect(procedure.find_column(label: "Prénom du mandataire").value(dossier)).to eq("Martin")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -22,7 +25,67 @@ describe Columns::DossierColumn do
|
|||
let(:dossier) { create(:dossier, :en_instruction, :with_entreprise, procedure:) }
|
||||
|
||||
it 'retrieve entreprise information' do
|
||||
expect(procedure.find_column(label: "Nº dossier").value(dossier)).to eq(dossier.id)
|
||||
expect(procedure.find_column(label: "Email").value(dossier)).to eq(dossier.user_email_for(:display))
|
||||
expect(procedure.find_column(label: "France connecté ?").value(dossier)).to eq(false)
|
||||
expect(procedure.find_column(label: "Entreprise forme juridique").value(dossier)).to eq("SA à conseil d'administration (s.a.i.)")
|
||||
expect(procedure.find_column(label: "Entreprise SIREN").value(dossier)).to eq('440117620')
|
||||
expect(procedure.find_column(label: "Entreprise nom commercial").value(dossier)).to eq('GRTGAZ')
|
||||
expect(procedure.find_column(label: "Entreprise raison sociale").value(dossier)).to eq('GRTGAZ')
|
||||
expect(procedure.find_column(label: "Entreprise SIRET siège social").value(dossier)).to eq('44011762001530')
|
||||
expect(procedure.find_column(label: "Date de création").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Établissement SIRET").value(dossier)).to eq('44011762001530')
|
||||
expect(procedure.find_column(label: "Libellé NAF").value(dossier)).to eq('Transports par conduites')
|
||||
expect(procedure.find_column(label: "Établissement code postal").value(dossier)).to eq('92270')
|
||||
expect(procedure.find_column(label: "Établissement siège social").value(dossier)).to eq(true)
|
||||
expect(procedure.find_column(label: "Établissement NAF").value(dossier)).to eq('4950Z')
|
||||
expect(procedure.find_column(label: "Établissement Adresse").value(dossier)).to eq("GRTGAZ\r IMMEUBLE BORA\r 6 RUE RAOUL NORDLING\r 92270 BOIS COLOMBES\r")
|
||||
expect(procedure.find_column(label: "Établissement numero voie").value(dossier)).to eq('6')
|
||||
expect(procedure.find_column(label: "Établissement type voie").value(dossier)).to eq('RUE')
|
||||
expect(procedure.find_column(label: "Établissement nom voie").value(dossier)).to eq('RAOUL NORDLING')
|
||||
expect(procedure.find_column(label: "Établissement complément adresse").value(dossier)).to eq('IMMEUBLE BORA')
|
||||
expect(procedure.find_column(label: "Établissement localité").value(dossier)).to eq('BOIS COLOMBES')
|
||||
expect(procedure.find_column(label: "Établissement code INSEE localité").value(dossier)).to eq('92009')
|
||||
expect(procedure.find_column(label: "Entreprise SIREN").value(dossier)).to eq('440117620')
|
||||
expect(procedure.find_column(label: "Entreprise capital social").value(dossier)).to eq(537_100_000)
|
||||
expect(procedure.find_column(label: "Entreprise numero TVA intracommunautaire").value(dossier)).to eq('FR27440117620')
|
||||
expect(procedure.find_column(label: "Entreprise forme juridique code").value(dossier)).to eq('5599')
|
||||
expect(procedure.find_column(label: "Entreprise code effectif entreprise").value(dossier)).to eq('51')
|
||||
expect(procedure.find_column(label: "Entreprise état administratif").value(dossier)).to eq("actif")
|
||||
expect(procedure.find_column(label: "Entreprise nom").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Entreprise prénom").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association RNA").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association titre").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association objet").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association date de création").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association date de déclaration").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Association date de publication").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Date de création").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Date du dernier évènement").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Date de dépot").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Date de passage en construction").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Date de passage en instruction").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
|
||||
expect(procedure.find_column(label: "Date de traitement").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "État du dossier").value(dossier)).to eq('en_instruction')
|
||||
expect(procedure.find_column(label: "Archivé").value(dossier)).to eq(false)
|
||||
expect(procedure.find_column(label: "Motivation de la décision").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Date de dernière modification (usager)").value(dossier)).to eq(nil)
|
||||
expect(procedure.find_column(label: "Instructeurs").value(dossier)).to eq('')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when procedure for entreprise which is also an association' do
|
||||
let(:procedure) { create(:procedure, for_individual: false, groupe_instructeurs: [groupe_instructeur]) }
|
||||
let(:etablissement) { create(:etablissement, :is_association) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, procedure:, etablissement:) }
|
||||
|
||||
it 'retrieve also association information' do
|
||||
expect(procedure.find_column(label: "Association RNA").value(dossier)).to eq("W072000535")
|
||||
expect(procedure.find_column(label: "Association titre").value(dossier)).to eq("ASSOCIATION POUR LA PROMOTION DE SPECTACLES AU CHATEAU DE ROCHEMAURE")
|
||||
expect(procedure.find_column(label: "Association objet").value(dossier)).to eq("mise en oeuvre et réalisation de spectacles au chateau de rochemaure")
|
||||
expect(procedure.find_column(label: "Association date de création").value(dossier)).to eq(Date.parse("1990-04-24"))
|
||||
expect(procedure.find_column(label: "Association date de déclaration").value(dossier)).to eq(Date.parse("2014-11-28"))
|
||||
expect(procedure.find_column(label: "Association date de publication").value(dossier)).to eq(Date.parse("1990-05-16"))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
206
spec/services/procedure_export_service_tabular_spec.rb
Normal file
206
spec/services/procedure_export_service_tabular_spec.rb
Normal file
|
@ -0,0 +1,206 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'csv'
|
||||
|
||||
describe ProcedureExportService do
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
let(:procedure) { create(:procedure, types_de_champ_public:, for_individual:, ask_birthday: true, instructeurs: [instructeur]) }
|
||||
let(:service) { ProcedureExportService.new(procedure, procedure.dossiers, instructeur, export_template) }
|
||||
let(:export_template) { create(:export_template, kind:, exported_columns:, groupe_instructeur: procedure.defaut_groupe_instructeur) }
|
||||
let(:for_individual) { true }
|
||||
let(:types_de_champ_public) do
|
||||
[
|
||||
{ type: :text, libelle: "first champ", mandatory: true, stable_id: 1 },
|
||||
{ type: :communes, libelle: "Commune", mandatory: true, stable_id: 17 },
|
||||
{ type: :piece_justificative, libelle: "PJ", stable_id: 30 },
|
||||
{
|
||||
type: :repetition, mandatory: true, stable_id: 7, libelle: "Champ répétable", children:
|
||||
[
|
||||
{ type: 'text', libelle: 'child first champ', stable_id: 8 },
|
||||
{ type: 'text', libelle: 'child second champ', stable_id: 9 }
|
||||
]
|
||||
}
|
||||
]
|
||||
end
|
||||
let(:exported_columns) { [] }
|
||||
|
||||
describe 'to_xlsx' do
|
||||
subject do
|
||||
service
|
||||
.to_xlsx
|
||||
.open { |f| SimpleXlsxReader.open(f.path) }
|
||||
end
|
||||
|
||||
let(:kind) { 'xlsx' }
|
||||
let(:dossiers_sheet) { subject.sheets.first }
|
||||
let(:etablissements_sheet) { subject.sheets.second }
|
||||
let(:avis_sheet) { subject.sheets.third }
|
||||
let(:repetition_sheet) { subject.sheets.fourth }
|
||||
|
||||
describe 'sheets' do
|
||||
it 'should have a sheet for each record type' do
|
||||
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis'])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Dossiers sheet' do
|
||||
let(:exported_columns) do
|
||||
[
|
||||
ExportedColumn.new(libelle: 'Date du dernier évènement', column: procedure.find_column(label: 'Date du dernier évènement')),
|
||||
ExportedColumn.new(libelle: 'Email', column: procedure.find_column(label: 'Email')),
|
||||
ExportedColumn.new(libelle: 'Groupe instructeur', column: procedure.find_column(label: 'Groupe instructeur')),
|
||||
ExportedColumn.new(libelle: 'État du dossier', column: procedure.dossier_state_column),
|
||||
ExportedColumn.new(libelle: 'first champ', column: procedure.find_column(label: 'first champ')),
|
||||
ExportedColumn.new(libelle: 'Commune (Code INSEE)', column: procedure.find_column(label: 'Commune (Code INSEE)')),
|
||||
ExportedColumn.new(libelle: 'PJ', column: procedure.find_column(label: 'PJ'))
|
||||
]
|
||||
end
|
||||
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure) }
|
||||
let(:selected_headers) { ["Email", "first champ", "Commune (Code INSEE)", "Groupe instructeur", "Date du dernier évènement", "État du dossier", "PJ"] }
|
||||
|
||||
it 'should have only headers from export template' do
|
||||
expect(dossiers_sheet.headers).to match_array(selected_headers)
|
||||
end
|
||||
|
||||
it 'should have data' do
|
||||
expect(procedure.dossiers.count).to eq 1
|
||||
expect(dossiers_sheet.data.size).to eq 1
|
||||
|
||||
expect(dossiers_sheet.data).to match_array([[anything, dossier.user_email_for_display, "défaut", "En instruction", "text", "60172", "toto.txt"]])
|
||||
end
|
||||
|
||||
context 'with a procedure routee' do
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:) }
|
||||
before { create(:groupe_instructeur, label: '2', procedure:) }
|
||||
|
||||
it 'find groupe instructeur data' do
|
||||
expect(dossiers_sheet.headers).to include('Groupe instructeur')
|
||||
expect(dossiers_sheet.data[0][dossiers_sheet.headers.index('Groupe instructeur')]).to eq('défaut')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a dossier having multiple pjs' do
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, types_de_champ_public:) }
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure:) }
|
||||
let!(:dossier_2) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure:) }
|
||||
before do
|
||||
dossier_2.filled_champs_public
|
||||
.find { _1.is_a? Champs::PieceJustificativeChamp }
|
||||
.piece_justificative_file
|
||||
.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
end
|
||||
it { expect(dossiers_sheet.data.last.last).to eq "toto.txt, toto.txt" }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Etablissement sheet' do
|
||||
let(:types_de_champ_public) { [{ type: :siret, libelle: 'siret', stable_id: 40 }] }
|
||||
let(:exported_columns) do
|
||||
[
|
||||
ExportedColumn.new(libelle: "Nº dossier", column: procedure.find_column(label: "Nº dossier")),
|
||||
ExportedColumn.new(libelle: "Demandeur", column: procedure.find_column(label: "Demandeur")),
|
||||
ExportedColumn.new(libelle: "siret", column: procedure.find_column(label: "siret"))
|
||||
]
|
||||
end
|
||||
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_entreprise, procedure: procedure) }
|
||||
|
||||
let(:dossier_etablissement) { etablissements_sheet.data[1] }
|
||||
let(:champ_etablissement) { etablissements_sheet.data[0] }
|
||||
|
||||
it 'should have siret header in dossiers sheet' do
|
||||
expect(dossiers_sheet.headers).to include('siret')
|
||||
end
|
||||
|
||||
it 'should have headers in etablissement sheet' do
|
||||
expect(etablissements_sheet.headers).to eq([
|
||||
"Dossier ID",
|
||||
"Champ",
|
||||
"Établissement SIRET",
|
||||
"Etablissement enseigne",
|
||||
"É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 état administratif",
|
||||
"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"
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Avis sheet' do
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure) }
|
||||
let!(:avis) { create(:avis, :with_answer, dossier: dossier) }
|
||||
|
||||
it 'should have headers and data' do
|
||||
expect(avis_sheet.headers).to eq([
|
||||
"Dossier ID",
|
||||
"Introduction",
|
||||
"Réponse",
|
||||
"Question",
|
||||
"Réponse oui/non",
|
||||
"Créé le",
|
||||
"Répondu le",
|
||||
"Instructeur",
|
||||
"Expert"
|
||||
])
|
||||
expect(avis_sheet.data.size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Repetitions sheet' do
|
||||
let(:exported_columns) do
|
||||
[
|
||||
ExportedColumn.new(libelle: "Champ répétable – child second champ", column: procedure.find_column(label: "Champ répétable – child second champ"))
|
||||
]
|
||||
end
|
||||
let!(:dossiers) do
|
||||
[
|
||||
create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure),
|
||||
create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure)
|
||||
]
|
||||
end
|
||||
|
||||
describe 'sheets' do
|
||||
it 'should have a sheet for repetition' do
|
||||
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', '(7) Champ repetable'])
|
||||
end
|
||||
end
|
||||
|
||||
it 'should have headers' do
|
||||
expect(repetition_sheet.headers).to eq([
|
||||
"Dossier ID", "Ligne", "Champ répétable – child second champ"
|
||||
])
|
||||
end
|
||||
|
||||
it 'should have data' do
|
||||
expect(repetition_sheet.data.size).to eq 4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,7 +41,10 @@ describe 'Creating a new procedure', js: true do
|
|||
click_on "Télécharger tous les dossiers"
|
||||
|
||||
expect {
|
||||
click_on "Demander un export au format .xlsx"
|
||||
within(:css, '#tabpanel-standard-panel') do
|
||||
choose "Fichier xlsx", allow_label_click: true
|
||||
click_on "Demander l'export"
|
||||
end
|
||||
expect(page).to have_content("Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger.")
|
||||
}.to have_enqueued_job(ExportJob).with(an_instance_of(Export))
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue