Merge pull request #3991 from tchak/cleanup-old-export
Supprimer le code du vieux export de xls (15/11/2019)
This commit is contained in:
commit
6f2779a312
9 changed files with 363 additions and 916 deletions
|
@ -185,21 +185,19 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def download_dossiers
|
def download_dossiers
|
||||||
options = params.permit(:version, :limit, :since, tables: [])
|
|
||||||
|
|
||||||
dossiers = current_instructeur.dossiers.for_procedure(procedure)
|
dossiers = current_instructeur.dossiers.for_procedure(procedure)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.csv do
|
format.csv do
|
||||||
send_data(procedure.to_csv(dossiers, options),
|
send_data(procedure.to_csv(dossiers),
|
||||||
filename: procedure.export_filename(:csv))
|
filename: procedure.export_filename(:csv))
|
||||||
end
|
end
|
||||||
format.xlsx do
|
format.xlsx do
|
||||||
send_data(procedure.to_xlsx(dossiers, options),
|
send_data(procedure.to_xlsx(dossiers),
|
||||||
filename: procedure.export_filename(:xlsx))
|
filename: procedure.export_filename(:xlsx))
|
||||||
end
|
end
|
||||||
format.ods do
|
format.ods do
|
||||||
send_data(procedure.to_ods(dossiers, options),
|
send_data(procedure.to_ods(dossiers),
|
||||||
filename: procedure.export_filename(:ods))
|
filename: procedure.export_filename(:ods))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,13 +38,6 @@ module ProcedureHelper
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_dossiers_download_path(procedure, format:, version:)
|
|
||||||
download_dossiers_instructeur_procedure_path(format: format,
|
|
||||||
procedure_id: procedure.id,
|
|
||||||
tables: [:etablissements],
|
|
||||||
version: version)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
TOGGLES = {
|
TOGGLES = {
|
||||||
|
|
|
@ -193,7 +193,7 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_export_download(format)
|
def prepare_export_download(format)
|
||||||
service = ProcedureExportV2Service.new(self, self.dossiers)
|
service = ProcedureExportService.new(self, self.dossiers)
|
||||||
filename = export_filename(format)
|
filename = export_filename(format)
|
||||||
|
|
||||||
case format.to_sym
|
case format.to_sym
|
||||||
|
@ -440,26 +440,20 @@ class Procedure < ApplicationRecord
|
||||||
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
|
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def export(dossiers, options = {})
|
def export(dossiers)
|
||||||
version = options.delete(:version)
|
ProcedureExportService.new(self, dossiers)
|
||||||
if version == 'v2'
|
|
||||||
options.delete(:tables)
|
|
||||||
ProcedureExportV2Service.new(self, dossiers)
|
|
||||||
else
|
|
||||||
ProcedureExportService.new(self, dossiers, **options.to_h.symbolize_keys)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_csv(dossiers, options = {})
|
def to_csv(dossiers)
|
||||||
export(dossiers, options).to_csv
|
export(dossiers).to_csv
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_xlsx(dossiers, options = {})
|
def to_xlsx(dossiers)
|
||||||
export(dossiers, options).to_xlsx
|
export(dossiers).to_xlsx
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ods(dossiers, options = {})
|
def to_ods(dossiers)
|
||||||
export(dossiers, options).to_ods
|
export(dossiers).to_ods
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_overview(start_date)
|
def procedure_overview(start_date)
|
||||||
|
|
|
@ -1,238 +1,76 @@
|
||||||
class ProcedureExportService
|
class ProcedureExportService
|
||||||
include DossierHelper
|
attr_reader :dossiers
|
||||||
|
|
||||||
ATTRIBUTES = [
|
def initialize(procedure, dossiers)
|
||||||
: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, dossiers, tables: [])
|
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
|
|
||||||
@attributes = ATTRIBUTES.dup
|
|
||||||
|
|
||||||
if procedure.routee?
|
|
||||||
@attributes << :groupe_instructeur_label
|
|
||||||
end
|
|
||||||
|
|
||||||
@dossiers = dossiers.downloadable_sorted
|
@dossiers = dossiers.downloadable_sorted
|
||||||
@dossiers = @dossiers.to_a
|
@tables = [:dossiers, :etablissements, :avis] + champs_repetables_options
|
||||||
@tables = tables.map(&:to_sym)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_csv
|
def to_csv
|
||||||
SpreadsheetArchitect.to_csv(to_data(:dossiers))
|
SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv))
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_xlsx
|
def to_xlsx
|
||||||
package = SpreadsheetArchitect.to_axlsx_package(to_data(:dossiers))
|
# We recursively build multi page spreadsheet
|
||||||
|
@tables.reduce(nil) do |package, table|
|
||||||
# Next we recursively build multi page spreadsheet
|
SpreadsheetArchitect.to_axlsx_package(options_for(table, :xlsx), package)
|
||||||
@tables.reduce(package) do |package, table|
|
|
||||||
SpreadsheetArchitect.to_axlsx_package(to_data(table), package)
|
|
||||||
end.to_stream.read
|
end.to_stream.read
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ods
|
def to_ods
|
||||||
spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet(to_data(:dossiers))
|
# We recursively build multi page spreadsheet
|
||||||
|
@tables.reduce(nil) do |spreadsheet, table|
|
||||||
# Next we recursively build multi page spreadsheet
|
SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet)
|
||||||
@tables.reduce(spreadsheet) do |spreadsheet, table|
|
|
||||||
SpreadsheetArchitect.to_rodf_spreadsheet(to_data(table), spreadsheet)
|
|
||||||
end.bytes
|
end.bytes
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_data(table)
|
|
||||||
case table
|
|
||||||
when :dossiers
|
|
||||||
dossiers_table_data
|
|
||||||
when :etablissements
|
|
||||||
etablissements_table_data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def empty_table_data(sheet_name, headers = [])
|
def etablissements
|
||||||
{
|
@etablissements ||= dossiers.flat_map do |dossier|
|
||||||
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, dossier.champs_private]
|
[dossier.champs, dossier.champs_private]
|
||||||
.flatten
|
.flatten
|
||||||
.filter { |champ| champ.is_a?(Champs::SiretChamp) }
|
.filter { |champ| champ.is_a?(Champs::SiretChamp) }
|
||||||
end.map(&:etablissement).compact
|
end.map(&:etablissement).compact + dossiers.map(&:etablissement).compact
|
||||||
|
|
||||||
if @etablissements.any?
|
|
||||||
{
|
|
||||||
sheet_name: 'Etablissements',
|
|
||||||
headers: etablissements_headers,
|
|
||||||
data: etablissements_data
|
|
||||||
}
|
|
||||||
else
|
|
||||||
empty_table_data('Etablissements', etablissements_headers)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def dossiers_headers
|
def avis
|
||||||
headers = @attributes.map(&:to_s) +
|
@avis ||= dossiers.flat_map(&:avis)
|
||||||
@procedure.types_de_champ.reject(&:exclude_from_export?).map(&:libelle) +
|
|
||||||
@procedure.types_de_champ_private.reject(&:exclude_from_export?).map(&:libelle) +
|
|
||||||
ETABLISSEMENT_ATTRIBUTES.map { |key| "etablissement.#{key}" } +
|
|
||||||
ENTREPRISE_ATTRIBUTES.map { |key| "entreprise.#{key}" }
|
|
||||||
|
|
||||||
headers.map { |header| label_for_export(header) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def dossiers_data
|
def champs_repetables
|
||||||
@dossiers.map do |dossier|
|
@champs_repetables ||= dossiers.flat_map do |dossier|
|
||||||
values = @attributes.map do |key|
|
[dossier.champs, dossier.champs_private]
|
||||||
case key
|
.flatten
|
||||||
when :email
|
.filter { |champ| champ.is_a?(Champs::RepetitionChamp) }
|
||||||
dossier.user.email
|
end.group_by(&:libelle_for_export)
|
||||||
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_instructeurs.map(&:email).join(' ')
|
|
||||||
when :groupe_instructeur_label
|
|
||||||
dossier.groupe_instructeur.label
|
|
||||||
else
|
|
||||||
dossier.read_attribute(key)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
normalize_values(values) +
|
def champs_repetables_options
|
||||||
dossier.champs.reject(&:exclude_from_export?).map(&:for_export) +
|
champs_repetables.map do |libelle, champs|
|
||||||
dossier.champs_private.reject(&:exclude_from_export?).map(&:for_export) +
|
|
||||||
etablissement_data(dossier.etablissement)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def etablissements_headers
|
|
||||||
headers = ["dossier_id", "libelle"] +
|
|
||||||
ETABLISSEMENT_ATTRIBUTES.map { |key| "etablissement.#{key}" } +
|
|
||||||
ENTREPRISE_ATTRIBUTES.map { |key| "entreprise.#{key}" }
|
|
||||||
|
|
||||||
headers.map { |header| label_for_export(header) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def etablissements_data
|
|
||||||
@etablissements.map do |etablissement|
|
|
||||||
[
|
[
|
||||||
etablissement.champ.dossier_id,
|
libelle,
|
||||||
label_for_export(etablissement.champ.libelle).to_s
|
champs.flat_map(&:rows_for_export)
|
||||||
] + etablissement_data(etablissement)
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def etablissement_data(etablissement)
|
DEFAULT_STYLES = {
|
||||||
data = ETABLISSEMENT_ATTRIBUTES.map do |key|
|
header_style: { background_color: "000000", color: "FFFFFF", font_size: 12, bold: true },
|
||||||
if etablissement.present?
|
row_style: { background_color: nil, color: "000000", font_size: 12 }
|
||||||
case key
|
}
|
||||||
when :adresse
|
|
||||||
etablissement.adresse&.chomp&.gsub("\r\n", ' ')&.delete("\r")
|
|
||||||
else
|
|
||||||
etablissement.read_attribute(key)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
data += ENTREPRISE_ATTRIBUTES.map do |key|
|
|
||||||
if etablissement.present?
|
|
||||||
case key
|
|
||||||
when :date_creation
|
|
||||||
etablissement.entreprise_date_creation&.to_datetime
|
|
||||||
else
|
|
||||||
etablissement.read_attribute(:"entreprise_#{key}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
normalize_values(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def label_for_export(label)
|
def options_for(table, format)
|
||||||
label.parameterize.underscore.to_sym
|
case table
|
||||||
end
|
when :dossiers
|
||||||
|
{ instances: dossiers.to_a, sheet_name: 'Dossiers', spreadsheet_columns: :"spreadsheet_columns_#{format}" }
|
||||||
def normalize_values(values)
|
when :etablissements
|
||||||
values.map do |value|
|
{ instances: etablissements.to_a, sheet_name: 'Etablissements' }
|
||||||
case value
|
when :avis
|
||||||
when TrueClass, FalseClass
|
{ instances: avis.to_a, sheet_name: 'Avis' }
|
||||||
value.to_s
|
when Array
|
||||||
else
|
{ instances: table.last, sheet_name: table.first }
|
||||||
value.blank? ? nil : value.to_s
|
end.merge(DEFAULT_STYLES)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
class ProcedureExportV2Service
|
|
||||||
attr_reader :dossiers
|
|
||||||
|
|
||||||
def initialize(procedure, dossiers)
|
|
||||||
@procedure = procedure
|
|
||||||
@dossiers = dossiers.downloadable_sorted
|
|
||||||
@tables = [:dossiers, :etablissements, :avis] + champs_repetables_options
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_csv
|
|
||||||
SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv))
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_xlsx
|
|
||||||
# We recursively build multi page spreadsheet
|
|
||||||
@tables.reduce(nil) do |package, table|
|
|
||||||
SpreadsheetArchitect.to_axlsx_package(options_for(table, :xlsx), package)
|
|
||||||
end.to_stream.read
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_ods
|
|
||||||
# We recursively build multi page spreadsheet
|
|
||||||
@tables.reduce(nil) do |spreadsheet, table|
|
|
||||||
SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet)
|
|
||||||
end.bytes
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def etablissements
|
|
||||||
@etablissements ||= dossiers.flat_map do |dossier|
|
|
||||||
[dossier.champs, dossier.champs_private]
|
|
||||||
.flatten
|
|
||||||
.filter { |champ| champ.is_a?(Champs::SiretChamp) }
|
|
||||||
end.map(&:etablissement).compact + dossiers.map(&:etablissement).compact
|
|
||||||
end
|
|
||||||
|
|
||||||
def avis
|
|
||||||
@avis ||= dossiers.flat_map(&:avis)
|
|
||||||
end
|
|
||||||
|
|
||||||
def champs_repetables
|
|
||||||
@champs_repetables ||= dossiers.flat_map do |dossier|
|
|
||||||
[dossier.champs, dossier.champs_private]
|
|
||||||
.flatten
|
|
||||||
.filter { |champ| champ.is_a?(Champs::RepetitionChamp) }
|
|
||||||
end.group_by(&:libelle_for_export)
|
|
||||||
end
|
|
||||||
|
|
||||||
def champs_repetables_options
|
|
||||||
champs_repetables.map do |libelle, champs|
|
|
||||||
[
|
|
||||||
libelle,
|
|
||||||
champs.flat_map(&:rows_for_export)
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
DEFAULT_STYLES = {
|
|
||||||
header_style: { background_color: "000000", color: "FFFFFF", font_size: 12, bold: true },
|
|
||||||
row_style: { background_color: nil, color: "000000", font_size: 12 }
|
|
||||||
}
|
|
||||||
|
|
||||||
def options_for(table, format)
|
|
||||||
case table
|
|
||||||
when :dossiers
|
|
||||||
{ instances: dossiers.to_a, sheet_name: 'Dossiers', spreadsheet_columns: :"spreadsheet_columns_#{format}" }.merge(DEFAULT_STYLES)
|
|
||||||
when :etablissements
|
|
||||||
{ instances: etablissements.to_a, sheet_name: 'Etablissements' }.merge(DEFAULT_STYLES)
|
|
||||||
when :avis
|
|
||||||
{ instances: avis.to_a, sheet_name: 'Avis' }.merge(DEFAULT_STYLES)
|
|
||||||
when Array
|
|
||||||
{ instances: table.last, sheet_name: table.first }.merge(DEFAULT_STYLES)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,9 +2,7 @@
|
||||||
%span.dropdown
|
%span.dropdown
|
||||||
%button.button.dropdown-button
|
%button.button.dropdown-button
|
||||||
Télécharger tous les dossiers
|
Télécharger tous les dossiers
|
||||||
- old_format_limit_date = Date.parse("Nov 15 2019")
|
.dropdown-content.fade-in-down{ style: 'width: 330px' }
|
||||||
- export_v1_enabled = old_format_limit_date > Time.zone.today
|
|
||||||
.dropdown-content.fade-in-down{ style: !export_v1_enabled ? 'width: 330px' : '' }
|
|
||||||
%ul.dropdown-items
|
%ul.dropdown-items
|
||||||
%li
|
%li
|
||||||
- if procedure.xlsx_export_stale?
|
- if procedure.xlsx_export_stale?
|
||||||
|
@ -30,12 +28,3 @@
|
||||||
= link_to "Exporter au format .csv", download_export_instructeur_procedure_path(procedure, export_format: :csv), remote: true
|
= link_to "Exporter au format .csv", download_export_instructeur_procedure_path(procedure, export_format: :csv), remote: true
|
||||||
- else
|
- else
|
||||||
= link_to "Au format .csv", url_for(procedure.csv_export_file), target: "_blank", rel: "noopener"
|
= link_to "Au format .csv", url_for(procedure.csv_export_file), target: "_blank", rel: "noopener"
|
||||||
|
|
||||||
- if export_v1_enabled
|
|
||||||
- old_format_message = "(ancien format, jusqu’au #{old_format_limit_date.strftime('%d/%m/%Y')})"
|
|
||||||
%li
|
|
||||||
= link_to "Au format .xlsx #{old_format_message}", procedure_dossiers_download_path(procedure, format: :xlsx, version: 'v1'), target: "_blank", rel: "noopener"
|
|
||||||
%li
|
|
||||||
= link_to "Au format .ods #{old_format_message}", procedure_dossiers_download_path(procedure, format: :ods, version: 'v1'), target: "_blank", rel: "noopener"
|
|
||||||
%li
|
|
||||||
= link_to "Au format .csv #{old_format_message}", procedure_dossiers_download_path(procedure, format: :csv, version: 'v1'), target: "_blank", rel: "noopener"
|
|
||||||
|
|
|
@ -426,7 +426,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
||||||
context "csv" do
|
context "csv" do
|
||||||
before do
|
before do
|
||||||
expect_any_instance_of(Procedure).to receive(:to_csv)
|
expect_any_instance_of(Procedure).to receive(:to_csv)
|
||||||
.with(instructeur.dossiers.for_procedure(procedure), {})
|
.with(instructeur.dossiers.for_procedure(procedure))
|
||||||
|
|
||||||
get :download_dossiers, params: { procedure_id: procedure.id }, format: 'csv'
|
get :download_dossiers, params: { procedure_id: procedure.id }, format: 'csv'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'csv'
|
||||||
|
|
||||||
describe ProcedureExportService do
|
describe ProcedureExportService do
|
||||||
describe 'to_data' do
|
describe 'to_data' do
|
||||||
let(:procedure) { create(:procedure, :published, :with_all_champs) }
|
let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) }
|
||||||
let(:table) { :dossiers }
|
subject do
|
||||||
subject { ProcedureExportService.new(procedure, procedure.dossiers).to_data(table) }
|
Tempfile.create do |f|
|
||||||
|
f << ProcedureExportService.new(procedure, procedure.dossiers).to_xlsx
|
||||||
|
f.rewind
|
||||||
|
SimpleXlsxReader.open(f.path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
let(:headers) { subject[:headers] }
|
let(:dossiers_sheet) { subject.sheets.first }
|
||||||
let(:data) { subject[:data] }
|
let(:etablissements_sheet) { subject.sheets.second }
|
||||||
|
let(:avis_sheet) { subject.sheets.third }
|
||||||
|
let(:repetition_sheet) { subject.sheets.fourth }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
# change one tdc place to check if the header is ordered
|
# change one tdc place to check if the header is ordered
|
||||||
|
@ -19,269 +27,324 @@ describe ProcedureExportService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'dossiers' do
|
context 'dossiers' do
|
||||||
let(:nominal_header) do
|
it 'should have sheets' do
|
||||||
[
|
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis'])
|
||||||
: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,
|
|
||||||
|
|
||||||
: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,
|
|
||||||
|
|
||||||
:etablissement_siret,
|
|
||||||
:etablissement_siege_social,
|
|
||||||
:etablissement_naf,
|
|
||||||
:etablissement_libelle_naf,
|
|
||||||
:etablissement_adresse,
|
|
||||||
:etablissement_numero_voie,
|
|
||||||
:etablissement_type_voie,
|
|
||||||
:etablissement_nom_voie,
|
|
||||||
:etablissement_complement_adresse,
|
|
||||||
:etablissement_code_postal,
|
|
||||||
:etablissement_localite,
|
|
||||||
:etablissement_code_insee_localite,
|
|
||||||
:entreprise_siren,
|
|
||||||
:entreprise_capital_social,
|
|
||||||
:entreprise_numero_tva_intracommunautaire,
|
|
||||||
:entreprise_forme_juridique,
|
|
||||||
:entreprise_forme_juridique_code,
|
|
||||||
:entreprise_nom_commercial,
|
|
||||||
:entreprise_raison_sociale,
|
|
||||||
:entreprise_siret_siege_social,
|
|
||||||
:entreprise_code_effectif_entreprise,
|
|
||||||
:entreprise_date_creation,
|
|
||||||
:entreprise_nom,
|
|
||||||
:entreprise_prenom
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should have headers' do
|
|
||||||
expect(headers).to eq(nominal_header)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a procedure routee' do
|
|
||||||
before { procedure.groupe_instructeurs.create(label: '2') }
|
|
||||||
|
|
||||||
let(:routee_header) { nominal_header.insert(nominal_header.index(:textarea), :groupe_instructeur_label) }
|
|
||||||
|
|
||||||
it { expect(headers).to eq(routee_header) }
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have empty values' do
|
|
||||||
expect(data).to eq([[]])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with dossier' do
|
context 'with dossier' do
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
||||||
|
|
||||||
let(:dossier_data) {
|
let(:nominal_headers) do
|
||||||
[
|
[
|
||||||
dossier.id.to_s,
|
"ID",
|
||||||
dossier.created_at.to_s,
|
"Email",
|
||||||
dossier.updated_at.to_s,
|
"Civilité",
|
||||||
"false",
|
"Nom",
|
||||||
dossier.user.email,
|
"Prénom",
|
||||||
"received",
|
"Date de naissance",
|
||||||
dossier.en_construction_at.to_s,
|
"Archivé",
|
||||||
dossier.en_instruction_at.to_s,
|
"État du dossier",
|
||||||
nil,
|
"Dernière mise à jour le",
|
||||||
nil,
|
"Déposé le",
|
||||||
nil
|
"Passé en instruction le",
|
||||||
] + individual_data
|
"Traité le",
|
||||||
}
|
"Motivation de la décision",
|
||||||
|
"Instructeurs",
|
||||||
let(:individual_data) {
|
"textarea",
|
||||||
[
|
"date",
|
||||||
"M.",
|
"datetime",
|
||||||
"Xavier",
|
"number",
|
||||||
"Julien",
|
"decimal_number",
|
||||||
"1991-11-01"
|
"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(:champs_data) {
|
it 'should have headers' do
|
||||||
dossier.reload.champs.reject(&:exclude_from_export?).map(&:for_export)
|
expect(dossiers_sheet.headers).to match(nominal_headers)
|
||||||
}
|
end
|
||||||
|
|
||||||
let(:etablissement_data) {
|
it 'should have data' do
|
||||||
Array.new(24)
|
expect(dossiers_sheet.data.size).to eq(1)
|
||||||
}
|
expect(etablissements_sheet.data.size).to eq(1)
|
||||||
|
|
||||||
it 'should have values' do
|
# SimpleXlsxReader is transforming datetimes in utc... It is only used in test so we just hack around.
|
||||||
expect(data.first[0..14]).to eq(dossier_data)
|
offset = dossier.en_construction_at.utc_offset
|
||||||
expect(data.first[15..38]).to eq(champs_data)
|
en_construction_at = Time.zone.at(dossiers_sheet.data[0][9] - offset.seconds)
|
||||||
expect(data.first[39..62]).to eq(etablissement_data)
|
en_instruction_at = Time.zone.at(dossiers_sheet.data[0][10] - offset.seconds)
|
||||||
|
expect(en_construction_at).to eq(dossier.en_construction_at.round)
|
||||||
expect(data).to eq([
|
expect(en_instruction_at).to eq(dossier.en_instruction_at.round)
|
||||||
dossier_data + champs_data + etablissement_data
|
|
||||||
])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a procedure routee' do
|
context 'with a procedure routee' do
|
||||||
before { procedure.groupe_instructeurs.create(label: '2') }
|
before { procedure.groupe_instructeurs.create(label: '2') }
|
||||||
|
|
||||||
it { expect(data.first[15]).to eq('défaut') }
|
let(:routee_header) { nominal_headers.insert(nominal_headers.index('textarea'), 'Groupe instructeur') }
|
||||||
it { expect(data.first.count).to eq(dossier_data.count + champs_data.count + etablissement_data.count + 1) }
|
|
||||||
|
it { expect(dossiers_sheet.headers).to match(routee_header) }
|
||||||
|
it { expect(dossiers_sheet.data[0][dossiers_sheet.headers.index('Groupe instructeur')]).to eq('défaut') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and etablissement' do
|
context 'with etablissement' do
|
||||||
|
let(:procedure) { create(:procedure, :published, :with_all_champs) }
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :with_entreprise, procedure: procedure) }
|
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :with_entreprise, procedure: procedure) }
|
||||||
|
|
||||||
let(:etablissement_data) {
|
let(:dossier_etablissement) { etablissements_sheet.data[1] }
|
||||||
|
let(:champ_etablissement) { etablissements_sheet.data[0] }
|
||||||
|
|
||||||
|
let(:nominal_headers) do
|
||||||
[
|
[
|
||||||
dossier.etablissement.siret,
|
"ID",
|
||||||
dossier.etablissement.siege_social.to_s,
|
"Email",
|
||||||
dossier.etablissement.naf,
|
"Entreprise raison sociale",
|
||||||
dossier.etablissement.libelle_naf,
|
"Archivé",
|
||||||
dossier.etablissement.adresse&.chomp&.gsub("\r\n", ' ')&.delete("\r"),
|
"État du dossier",
|
||||||
dossier.etablissement.numero_voie,
|
"Dernière mise à jour le",
|
||||||
dossier.etablissement.type_voie,
|
"Déposé le",
|
||||||
dossier.etablissement.nom_voie,
|
"Passé en instruction le",
|
||||||
dossier.etablissement.complement_adresse,
|
"Traité le",
|
||||||
dossier.etablissement.code_postal,
|
"Motivation de la décision",
|
||||||
dossier.etablissement.localite,
|
"Instructeurs",
|
||||||
dossier.etablissement.code_insee_localite,
|
"textarea",
|
||||||
dossier.etablissement.entreprise_siren,
|
"date",
|
||||||
dossier.etablissement.entreprise_capital_social.to_s,
|
"datetime",
|
||||||
dossier.etablissement.entreprise_numero_tva_intracommunautaire,
|
"number",
|
||||||
dossier.etablissement.entreprise_forme_juridique,
|
"decimal_number",
|
||||||
dossier.etablissement.entreprise_forme_juridique_code,
|
"integer_number",
|
||||||
dossier.etablissement.entreprise_nom_commercial,
|
"checkbox",
|
||||||
dossier.etablissement.entreprise_raison_sociale,
|
"civilite",
|
||||||
dossier.etablissement.entreprise_siret_siege_social,
|
"email",
|
||||||
dossier.etablissement.entreprise_code_effectif_entreprise,
|
"phone",
|
||||||
dossier.etablissement.entreprise_date_creation.to_datetime.to_s,
|
"address",
|
||||||
dossier.etablissement.entreprise_nom,
|
"yes_no",
|
||||||
dossier.etablissement.entreprise_prenom
|
"simple_drop_down_list",
|
||||||
|
"multiple_drop_down_list",
|
||||||
|
"linked_drop_down_list",
|
||||||
|
"pays",
|
||||||
|
"regions",
|
||||||
|
"departements",
|
||||||
|
"engagement",
|
||||||
|
"dossier_link",
|
||||||
|
"piece_justificative",
|
||||||
|
"siret",
|
||||||
|
"carte",
|
||||||
|
"text"
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
let(:individual_data) {
|
|
||||||
Array.new(4)
|
|
||||||
}
|
|
||||||
|
|
||||||
it 'should have values' do
|
|
||||||
expect(data.first[0..14]).to eq(dossier_data)
|
|
||||||
expect(data.first[15..38]).to eq(champs_data)
|
|
||||||
expect(data.first[39..62]).to eq(etablissement_data)
|
|
||||||
|
|
||||||
expect(data).to eq([
|
|
||||||
dossier_data + champs_data + etablissement_data
|
|
||||||
])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'as csv' do
|
||||||
|
subject do
|
||||||
|
Tempfile.create do |f|
|
||||||
|
f << ProcedureExportService.new(procedure, procedure.dossiers).to_csv
|
||||||
|
f.rewind
|
||||||
|
CSV.read(f.path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'etablissements' do
|
let(:nominal_headers) do
|
||||||
let(:table) { :etablissements }
|
[
|
||||||
|
"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
|
it 'should have headers' do
|
||||||
expect(headers).to eq([
|
expect(dossiers_sheet_headers).to match(nominal_headers)
|
||||||
:dossier_id,
|
end
|
||||||
:libelle,
|
end
|
||||||
:etablissement_siret,
|
|
||||||
:etablissement_siege_social,
|
it 'should have headers' do
|
||||||
:etablissement_naf,
|
expect(dossiers_sheet.headers).to match(nominal_headers)
|
||||||
:etablissement_libelle_naf,
|
|
||||||
:etablissement_adresse,
|
expect(etablissements_sheet.headers).to eq([
|
||||||
:etablissement_numero_voie,
|
"Dossier ID",
|
||||||
:etablissement_type_voie,
|
"Champ",
|
||||||
:etablissement_nom_voie,
|
"Établissement SIRET",
|
||||||
:etablissement_complement_adresse,
|
"Établissement siège social",
|
||||||
:etablissement_code_postal,
|
"Établissement NAF",
|
||||||
:etablissement_localite,
|
"Établissement libellé NAF",
|
||||||
:etablissement_code_insee_localite,
|
"Établissement Adresse",
|
||||||
:entreprise_siren,
|
"Établissement numero voie",
|
||||||
:entreprise_capital_social,
|
"Établissement type voie",
|
||||||
:entreprise_numero_tva_intracommunautaire,
|
"Établissement nom voie",
|
||||||
:entreprise_forme_juridique,
|
"Établissement complément adresse",
|
||||||
:entreprise_forme_juridique_code,
|
"Établissement code postal",
|
||||||
:entreprise_nom_commercial,
|
"Établissement localité",
|
||||||
:entreprise_raison_sociale,
|
"Établissement code INSEE localité",
|
||||||
:entreprise_siret_siege_social,
|
"Entreprise SIREN",
|
||||||
:entreprise_code_effectif_entreprise,
|
"Entreprise capital social",
|
||||||
:entreprise_date_creation,
|
"Entreprise numero TVA intracommunautaire",
|
||||||
:entreprise_nom,
|
"Entreprise forme juridique",
|
||||||
:entreprise_prenom
|
"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"
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should have empty values' do
|
it 'should have data' do
|
||||||
expect(data).to eq([[]])
|
expect(etablissements_sheet.data.size).to eq(2)
|
||||||
|
expect(dossier_etablissement[1]).to eq("Dossier")
|
||||||
|
expect(champ_etablissement[1]).to eq("siret")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with dossier containing champ siret' do
|
context 'with avis' do
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, procedure: procedure) }
|
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
||||||
let(:etablissement) { dossier.champs.find { |champ| champ.type_champ == 'siret' }.etablissement }
|
let!(:avis) { create(:avis, :with_answer, dossier: dossier) }
|
||||||
|
|
||||||
let(:etablissement_data) {
|
it 'should have headers' do
|
||||||
|
expect(avis_sheet.headers).to eq([
|
||||||
|
"Dossier ID",
|
||||||
|
"Question / Introduction",
|
||||||
|
"Réponse",
|
||||||
|
"Créé le",
|
||||||
|
"Répondu le"
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have data' do
|
||||||
|
expect(avis_sheet.data.size).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with repetitions' do
|
||||||
|
let!(:dossiers) do
|
||||||
[
|
[
|
||||||
dossier.id,
|
create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure),
|
||||||
'siret',
|
create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure)
|
||||||
etablissement.siret,
|
|
||||||
etablissement.siege_social.to_s,
|
|
||||||
etablissement.naf,
|
|
||||||
etablissement.libelle_naf,
|
|
||||||
etablissement.adresse&.chomp&.gsub("\r\n", ' ')&.delete("\r"),
|
|
||||||
etablissement.numero_voie,
|
|
||||||
etablissement.type_voie,
|
|
||||||
etablissement.nom_voie,
|
|
||||||
etablissement.complement_adresse,
|
|
||||||
etablissement.code_postal,
|
|
||||||
etablissement.localite,
|
|
||||||
etablissement.code_insee_localite,
|
|
||||||
etablissement.entreprise_siren,
|
|
||||||
etablissement.entreprise_capital_social.to_s,
|
|
||||||
etablissement.entreprise_numero_tva_intracommunautaire,
|
|
||||||
etablissement.entreprise_forme_juridique,
|
|
||||||
etablissement.entreprise_forme_juridique_code,
|
|
||||||
etablissement.entreprise_nom_commercial,
|
|
||||||
etablissement.entreprise_raison_sociale,
|
|
||||||
etablissement.entreprise_siret_siege_social,
|
|
||||||
etablissement.entreprise_code_effectif_entreprise,
|
|
||||||
etablissement.entreprise_date_creation.to_datetime.to_s,
|
|
||||||
etablissement.entreprise_nom,
|
|
||||||
etablissement.entreprise_prenom
|
|
||||||
]
|
]
|
||||||
}
|
end
|
||||||
|
let(:champ_repetition) { dossiers.first.champs.find { |champ| champ.type_champ == 'repetition' } }
|
||||||
|
|
||||||
it 'should have values' do
|
it 'should have sheets' do
|
||||||
expect(data.first).to eq(etablissement_data)
|
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have headers' do
|
||||||
|
expect(repetition_sheet.headers).to eq([
|
||||||
|
"Dossier ID",
|
||||||
|
"Ligne",
|
||||||
|
"Nom",
|
||||||
|
"Age"
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have data' do
|
||||||
|
expect(repetition_sheet.data.size).to eq(4)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid characters' do
|
||||||
|
before do
|
||||||
|
champ_repetition.type_de_champ.update(libelle: 'A / B \ C')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have valid sheet name' do
|
||||||
|
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
|
||||||
|
|
|
@ -1,352 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
require 'csv'
|
|
||||||
|
|
||||||
describe ProcedureExportV2Service do
|
|
||||||
describe 'to_data' do
|
|
||||||
let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) }
|
|
||||||
subject do
|
|
||||||
Tempfile.create do |f|
|
|
||||||
f << ProcedureExportV2Service.new(procedure, procedure.dossiers).to_xlsx
|
|
||||||
f.rewind
|
|
||||||
SimpleXlsxReader.open(f.path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:dossiers_sheet) { subject.sheets.first }
|
|
||||||
let(:etablissements_sheet) { subject.sheets.second }
|
|
||||||
let(:avis_sheet) { subject.sheets.third }
|
|
||||||
let(:repetition_sheet) { subject.sheets.fourth }
|
|
||||||
|
|
||||||
before do
|
|
||||||
# change one tdc place to check if the header is ordered
|
|
||||||
tdc_first = procedure.types_de_champ.first
|
|
||||||
tdc_last = procedure.types_de_champ.last
|
|
||||||
|
|
||||||
tdc_first.update(order_place: tdc_last.order_place + 1)
|
|
||||||
procedure.reload
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'dossiers' do
|
|
||||||
it 'should have sheets' do
|
|
||||||
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis'])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with dossier' do
|
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
|
||||||
|
|
||||||
let(:nominal_headers) do
|
|
||||||
[
|
|
||||||
"ID",
|
|
||||||
"Email",
|
|
||||||
"Civilité",
|
|
||||||
"Nom",
|
|
||||||
"Prénom",
|
|
||||||
"Date de naissance",
|
|
||||||
"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
|
|
||||||
|
|
||||||
it 'should have headers' do
|
|
||||||
expect(dossiers_sheet.headers).to match(nominal_headers)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have data' do
|
|
||||||
expect(dossiers_sheet.data.size).to eq(1)
|
|
||||||
expect(etablissements_sheet.data.size).to eq(1)
|
|
||||||
|
|
||||||
# SimpleXlsxReader is transforming datetimes in utc... It is only used in test so we just hack around.
|
|
||||||
offset = dossier.en_construction_at.utc_offset
|
|
||||||
en_construction_at = Time.zone.at(dossiers_sheet.data[0][9] - offset.seconds)
|
|
||||||
en_instruction_at = Time.zone.at(dossiers_sheet.data[0][10] - offset.seconds)
|
|
||||||
expect(en_construction_at).to eq(dossier.en_construction_at.round)
|
|
||||||
expect(en_instruction_at).to eq(dossier.en_instruction_at.round)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a procedure routee' do
|
|
||||||
before { procedure.groupe_instructeurs.create(label: '2') }
|
|
||||||
|
|
||||||
let(:routee_header) { nominal_headers.insert(nominal_headers.index('textarea'), 'Groupe instructeur') }
|
|
||||||
|
|
||||||
it { expect(dossiers_sheet.headers).to match(routee_header) }
|
|
||||||
it { expect(dossiers_sheet.data[0][dossiers_sheet.headers.index('Groupe instructeur')]).to eq('défaut') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with etablissement' do
|
|
||||||
let(:procedure) { create(:procedure, :published, :with_all_champs) }
|
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :with_entreprise, procedure: procedure) }
|
|
||||||
|
|
||||||
let(:dossier_etablissement) { etablissements_sheet.data[1] }
|
|
||||||
let(:champ_etablissement) { etablissements_sheet.data[0] }
|
|
||||||
|
|
||||||
let(:nominal_headers) do
|
|
||||||
[
|
|
||||||
"ID",
|
|
||||||
"Email",
|
|
||||||
"Entreprise raison sociale",
|
|
||||||
"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
|
|
||||||
|
|
||||||
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
|
|
||||||
expect(dossiers_sheet.headers).to match(nominal_headers)
|
|
||||||
|
|
||||||
expect(etablissements_sheet.headers).to eq([
|
|
||||||
"Dossier ID",
|
|
||||||
"Champ",
|
|
||||||
"É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"
|
|
||||||
])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have data' do
|
|
||||||
expect(etablissements_sheet.data.size).to eq(2)
|
|
||||||
expect(dossier_etablissement[1]).to eq("Dossier")
|
|
||||||
expect(champ_etablissement[1]).to eq("siret")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with avis' do
|
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
|
||||||
let!(:avis) { create(:avis, :with_answer, dossier: dossier) }
|
|
||||||
|
|
||||||
it 'should have headers' do
|
|
||||||
expect(avis_sheet.headers).to eq([
|
|
||||||
"Dossier ID",
|
|
||||||
"Question / Introduction",
|
|
||||||
"Réponse",
|
|
||||||
"Créé le",
|
|
||||||
"Répondu le"
|
|
||||||
])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have data' do
|
|
||||||
expect(avis_sheet.data.size).to eq(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with repetitions' do
|
|
||||||
let!(:dossiers) do
|
|
||||||
[
|
|
||||||
create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure),
|
|
||||||
create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure)
|
|
||||||
]
|
|
||||||
end
|
|
||||||
let(:champ_repetition) { dossiers.first.champs.find { |champ| champ.type_champ == 'repetition' } }
|
|
||||||
|
|
||||||
it 'should have sheets' do
|
|
||||||
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have headers' do
|
|
||||||
expect(repetition_sheet.headers).to eq([
|
|
||||||
"Dossier ID",
|
|
||||||
"Ligne",
|
|
||||||
"Nom",
|
|
||||||
"Age"
|
|
||||||
])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have data' do
|
|
||||||
expect(repetition_sheet.data.size).to eq(4)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with invalid characters' do
|
|
||||||
before do
|
|
||||||
champ_repetition.type_de_champ.update(libelle: 'A / B \ C')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have valid sheet name' do
|
|
||||||
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
|
|
Loading…
Reference in a new issue