commit
85accfd389
33 changed files with 501 additions and 1008 deletions
|
@ -130,6 +130,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.state-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
@ -213,10 +217,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.selected,
|
||||
&:hover:not(.inactive) {
|
||||
background: $light-grey;
|
||||
&:not(.inactive) {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.selected {
|
||||
background: $light-grey;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
|
|
|
@ -150,6 +150,8 @@ $header-mobile-breakpoint: 550px;
|
|||
}
|
||||
|
||||
button {
|
||||
@extend %outline;
|
||||
|
||||
padding: 9px;
|
||||
border: none;
|
||||
background: none;
|
||||
|
|
|
@ -56,6 +56,7 @@ module Instructeurs
|
|||
recipients = Instructeur.find(params[:recipients])
|
||||
|
||||
recipients.each do |recipient|
|
||||
recipient.follow(dossier)
|
||||
InstructeurMailer.send_dossier(current_instructeur, dossier, recipient).deliver_later
|
||||
end
|
||||
|
||||
|
|
|
@ -185,21 +185,19 @@ module Instructeurs
|
|||
end
|
||||
|
||||
def download_dossiers
|
||||
options = params.permit(:version, :limit, :since, tables: [])
|
||||
|
||||
dossiers = current_instructeur.dossiers.for_procedure(procedure)
|
||||
|
||||
respond_to do |format|
|
||||
format.csv do
|
||||
send_data(procedure.to_csv(dossiers, options),
|
||||
send_data(procedure.to_csv(dossiers),
|
||||
filename: procedure.export_filename(:csv))
|
||||
end
|
||||
format.xlsx do
|
||||
send_data(procedure.to_xlsx(dossiers, options),
|
||||
send_data(procedure.to_xlsx(dossiers),
|
||||
filename: procedure.export_filename(:xlsx))
|
||||
end
|
||||
format.ods do
|
||||
send_data(procedure.to_ods(dossiers, options),
|
||||
send_data(procedure.to_ods(dossiers),
|
||||
filename: procedure.export_filename(:ods))
|
||||
end
|
||||
end
|
||||
|
@ -210,12 +208,13 @@ module Instructeurs
|
|||
notice_message = "Nous générons cet export. Lorsque celui-ci sera disponible, vous recevrez une notification par email accompagnée d'un lien de téléchargement."
|
||||
if procedure.should_generate_export?(export_format)
|
||||
procedure.queue_export(current_instructeur, export_format)
|
||||
flash.notice = notice_message
|
||||
|
||||
respond_to do |format|
|
||||
format.js do
|
||||
flash.notice = notice_message
|
||||
@procedure = procedure
|
||||
end
|
||||
format.all { redirect_to procedure }
|
||||
end
|
||||
elsif procedure.export_queued?(export_format)
|
||||
flash.notice = notice_message
|
||||
|
|
|
@ -143,18 +143,19 @@ module Users
|
|||
|
||||
errors = update_dossier_and_compute_errors
|
||||
|
||||
if errors.present?
|
||||
if passage_en_construction? && errors.blank?
|
||||
@dossier.en_construction!
|
||||
NotificationMailer.send_initiated_notification(@dossier).deliver_later
|
||||
return redirect_to(merci_dossier_path(@dossier))
|
||||
elsif errors.present?
|
||||
flash.now.alert = errors
|
||||
render :brouillon
|
||||
else
|
||||
if save_draft?
|
||||
flash.now.notice = 'Votre brouillon a bien été sauvegardé.'
|
||||
render :brouillon
|
||||
else
|
||||
@dossier.en_construction!
|
||||
NotificationMailer.send_initiated_notification(@dossier).deliver_later
|
||||
redirect_to merci_dossier_path(@dossier)
|
||||
end
|
||||
flash.now.notice = 'Votre brouillon a bien été sauvegardé.'
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :brouillon }
|
||||
format.json { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -368,7 +369,7 @@ module Users
|
|||
end
|
||||
|
||||
def save_draft?
|
||||
dossier.brouillon? && params[:save_draft]
|
||||
dossier.brouillon? && !params[:submit_draft]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,13 +38,6 @@ module ProcedureHelper
|
|||
}
|
||||
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
|
||||
|
||||
TOGGLES = {
|
||||
|
|
|
@ -5,16 +5,16 @@ import debounce from 'debounce';
|
|||
export { debounce };
|
||||
export const { fire, ajax } = Rails;
|
||||
|
||||
export function show({ classList }) {
|
||||
classList.remove('hidden');
|
||||
export function show(el) {
|
||||
el && el.classList.remove('hidden');
|
||||
}
|
||||
|
||||
export function hide({ classList }) {
|
||||
classList.add('hidden');
|
||||
export function hide(el) {
|
||||
el && el.classList.add('hidden');
|
||||
}
|
||||
|
||||
export function toggle({ classList }) {
|
||||
classList.toggle('hidden');
|
||||
export function toggle(el) {
|
||||
el && el.classList.toggle('hidden');
|
||||
}
|
||||
|
||||
export function delegate(eventNames, selector, callback) {
|
||||
|
|
|
@ -193,7 +193,7 @@ class Procedure < ApplicationRecord
|
|||
end
|
||||
|
||||
def prepare_export_download(format)
|
||||
service = ProcedureExportV2Service.new(self, self.dossiers)
|
||||
service = ProcedureExportService.new(self, self.dossiers)
|
||||
filename = export_filename(format)
|
||||
|
||||
case format.to_sym
|
||||
|
@ -440,26 +440,20 @@ class Procedure < ApplicationRecord
|
|||
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
|
||||
end
|
||||
|
||||
def export(dossiers, options = {})
|
||||
version = options.delete(:version)
|
||||
if version == 'v2'
|
||||
options.delete(:tables)
|
||||
ProcedureExportV2Service.new(self, dossiers)
|
||||
else
|
||||
ProcedureExportService.new(self, dossiers, **options.to_h.symbolize_keys)
|
||||
end
|
||||
def export(dossiers)
|
||||
ProcedureExportService.new(self, dossiers)
|
||||
end
|
||||
|
||||
def to_csv(dossiers, options = {})
|
||||
export(dossiers, options).to_csv
|
||||
def to_csv(dossiers)
|
||||
export(dossiers).to_csv
|
||||
end
|
||||
|
||||
def to_xlsx(dossiers, options = {})
|
||||
export(dossiers, options).to_xlsx
|
||||
def to_xlsx(dossiers)
|
||||
export(dossiers).to_xlsx
|
||||
end
|
||||
|
||||
def to_ods(dossiers, options = {})
|
||||
export(dossiers, options).to_ods
|
||||
def to_ods(dossiers)
|
||||
export(dossiers).to_ods
|
||||
end
|
||||
|
||||
def procedure_overview(start_date)
|
||||
|
|
|
@ -1,238 +1,76 @@
|
|||
class ProcedureExportService
|
||||
include DossierHelper
|
||||
attr_reader :dossiers
|
||||
|
||||
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, dossiers, tables: [])
|
||||
def initialize(procedure, dossiers)
|
||||
@procedure = procedure
|
||||
|
||||
@attributes = ATTRIBUTES.dup
|
||||
|
||||
if procedure.routee?
|
||||
@attributes << :groupe_instructeur_label
|
||||
end
|
||||
|
||||
@dossiers = dossiers.downloadable_sorted
|
||||
@dossiers = @dossiers.to_a
|
||||
@tables = tables.map(&:to_sym)
|
||||
@tables = [:dossiers, :etablissements, :avis] + champs_repetables_options
|
||||
end
|
||||
|
||||
def to_csv
|
||||
SpreadsheetArchitect.to_csv(to_data(:dossiers))
|
||||
SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv))
|
||||
end
|
||||
|
||||
def to_xlsx
|
||||
package = SpreadsheetArchitect.to_axlsx_package(to_data(:dossiers))
|
||||
|
||||
# Next we recursively build multi page spreadsheet
|
||||
@tables.reduce(package) do |package, table|
|
||||
SpreadsheetArchitect.to_axlsx_package(to_data(table), package)
|
||||
# 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
|
||||
spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet(to_data(:dossiers))
|
||||
|
||||
# Next we recursively build multi page spreadsheet
|
||||
@tables.reduce(spreadsheet) do |spreadsheet, table|
|
||||
SpreadsheetArchitect.to_rodf_spreadsheet(to_data(table), spreadsheet)
|
||||
# We recursively build multi page spreadsheet
|
||||
@tables.reduce(nil) do |spreadsheet, table|
|
||||
SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet)
|
||||
end.bytes
|
||||
end
|
||||
|
||||
def to_data(table)
|
||||
case table
|
||||
when :dossiers
|
||||
dossiers_table_data
|
||||
when :etablissements
|
||||
etablissements_table_data
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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|
|
||||
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
|
||||
|
||||
if @etablissements.any?
|
||||
{
|
||||
sheet_name: 'Etablissements',
|
||||
headers: etablissements_headers,
|
||||
data: etablissements_data
|
||||
}
|
||||
else
|
||||
empty_table_data('Etablissements', etablissements_headers)
|
||||
end
|
||||
end.map(&:etablissement).compact + dossiers.map(&:etablissement).compact
|
||||
end
|
||||
|
||||
def dossiers_headers
|
||||
headers = @attributes.map(&:to_s) +
|
||||
@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) }
|
||||
def avis
|
||||
@avis ||= dossiers.flat_map(&:avis)
|
||||
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_instructeurs.map(&:email).join(' ')
|
||||
when :groupe_instructeur_label
|
||||
dossier.groupe_instructeur.label
|
||||
else
|
||||
dossier.read_attribute(key)
|
||||
end
|
||||
end
|
||||
|
||||
normalize_values(values) +
|
||||
dossier.champs.reject(&:exclude_from_export?).map(&:for_export) +
|
||||
dossier.champs_private.reject(&:exclude_from_export?).map(&:for_export) +
|
||||
etablissement_data(dossier.etablissement)
|
||||
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 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|
|
||||
def champs_repetables_options
|
||||
champs_repetables.map do |libelle, champs|
|
||||
[
|
||||
etablissement.champ.dossier_id,
|
||||
label_for_export(etablissement.champ.libelle).to_s
|
||||
] + etablissement_data(etablissement)
|
||||
libelle,
|
||||
champs.flat_map(&:rows_for_export)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def etablissement_data(etablissement)
|
||||
data = ETABLISSEMENT_ATTRIBUTES.map do |key|
|
||||
if etablissement.present?
|
||||
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
|
||||
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 label_for_export(label)
|
||||
label.parameterize.underscore.to_sym
|
||||
end
|
||||
|
||||
def normalize_values(values)
|
||||
values.map do |value|
|
||||
case value
|
||||
when TrueClass, FalseClass
|
||||
value.to_s
|
||||
else
|
||||
value.blank? ? nil : value.to_s
|
||||
end
|
||||
end
|
||||
def options_for(table, format)
|
||||
case table
|
||||
when :dossiers
|
||||
{ instances: dossiers.to_a, sheet_name: 'Dossiers', spreadsheet_columns: :"spreadsheet_columns_#{format}" }
|
||||
when :etablissements
|
||||
{ instances: etablissements.to_a, sheet_name: 'Etablissements' }
|
||||
when :avis
|
||||
{ instances: avis.to_a, sheet_name: 'Avis' }
|
||||
when Array
|
||||
{ instances: table.last, sheet_name: table.first }
|
||||
end.merge(DEFAULT_STYLES)
|
||||
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
|
|
@ -4,6 +4,8 @@
|
|||
%p.tab-paragraph
|
||||
Vous êtes le seul instructeur assigné sur cette démarche
|
||||
- else
|
||||
%p.tab-paragrah.mb-1
|
||||
Le destinataire suivra automatiquement le dossier
|
||||
= form_for dossier, url: send_to_instructeurs_instructeur_dossier_path(dossier.procedure, dossier), method: :post, html: { class: 'form recipients-form' } do |f|
|
||||
.flex.justify-start.align-start
|
||||
= select_tag(:recipients,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%span.dropdown.print-menu-opener
|
||||
%button.button.dropdown-button.icon-only
|
||||
%button.button.dropdown-button.icon-only{ title: 'imprimer' }
|
||||
%span.icon.printer
|
||||
%ul.print-menu.dropdown-content
|
||||
%li
|
||||
|
@ -20,5 +20,5 @@
|
|||
|
||||
= render partial: "instructeurs/procedures/dossier_actions", locals: { procedure: dossier.procedure, dossier: dossier, dossier_is_followed: current_instructeur&.follow?(dossier) }
|
||||
|
||||
%span.state-button
|
||||
.state-button
|
||||
= render partial: "state_button", locals: { dossier: dossier }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%span.dropdown
|
||||
.dropdown
|
||||
-# Dropdown button title
|
||||
%button.button.primary.dropdown-button{ class: button_or_label_class(dossier) }
|
||||
= dossier_display_state dossier
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
%span.dropdown
|
||||
%button.button.dropdown-button
|
||||
Télécharger tous les dossiers
|
||||
- old_format_limit_date = Date.parse("Nov 15 2019")
|
||||
- export_v1_enabled = old_format_limit_date > Time.zone.today
|
||||
.dropdown-content.fade-in-down{ style: !export_v1_enabled ? 'width: 330px' : '' }
|
||||
.dropdown-content.fade-in-down{ style: 'width: 330px' }
|
||||
%ul.dropdown-items
|
||||
%li
|
||||
- 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
|
||||
- else
|
||||
= 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"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%span.dropdown.invite-user-action
|
||||
.dropdown.invite-user-action
|
||||
%button.button.dropdown-button
|
||||
%span.icon.person
|
||||
- if dossier.invites.count > 0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%span.dropdown.header-menu-opener
|
||||
.dropdown.header-menu-opener
|
||||
%button.button.dropdown-button.header-menu-button
|
||||
= image_tag "icons/account-circle.svg", title: "Mon compte"
|
||||
%ul.header-menu.dropdown-content
|
||||
|
@ -8,30 +8,30 @@
|
|||
- if administration_signed_in?
|
||||
%li
|
||||
= link_to manager_root_path, class: "menu-item menu-link" do
|
||||
= image_tag "icons/super-admin.svg"
|
||||
= image_tag "icons/super-admin.svg", alt: ''
|
||||
Passer en super-admin
|
||||
- if multiple_devise_profile_connect?
|
||||
- if user_signed_in? && nav_bar_profile != :user
|
||||
%li
|
||||
= link_to dossiers_path, class: "menu-item menu-link" do
|
||||
= image_tag "icons/switch-profile.svg"
|
||||
= image_tag "icons/switch-profile.svg", alt: ''
|
||||
Passer en usager
|
||||
- if instructeur_signed_in? && nav_bar_profile != :instructeur
|
||||
%li
|
||||
= link_to instructeur_procedures_path, class: "menu-item menu-link" do
|
||||
= image_tag "icons/switch-profile.svg"
|
||||
= image_tag "icons/switch-profile.svg", alt: ''
|
||||
Passer en instructeur
|
||||
- if administrateur_signed_in? && nav_bar_profile != :administrateur
|
||||
%li
|
||||
= link_to admin_procedures_path, class: "menu-item menu-link" do
|
||||
= image_tag "icons/switch-profile.svg"
|
||||
= image_tag "icons/switch-profile.svg", alt: ''
|
||||
Passer en administrateur
|
||||
|
||||
%li
|
||||
= link_to profil_path, class: "menu-item menu-link" do
|
||||
= image_tag "icons/switch-profile.svg"
|
||||
= image_tag "icons/switch-profile.svg", alt: ''
|
||||
Voir mon profil
|
||||
%li
|
||||
= link_to destroy_user_session_path, method: :delete, class: "menu-item menu-link" do
|
||||
= image_tag "icons/sign-out.svg"
|
||||
= image_tag "icons/sign-out.svg", alt: ''
|
||||
Se déconnecter
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
= form_tag instructeur_recherche_path, method: :get, class: "form" do
|
||||
= text_field_tag "q", "#{@search_terms if @search_terms.present?}", placeholder: "Rechercher un dossier"
|
||||
%button{ title: "Rechercher" }
|
||||
= image_tag "icons/search-blue.svg"
|
||||
= image_tag "icons/search-blue.svg", alt: ''
|
||||
|
||||
- if nav_bar_profile == :user && user_signed_in? && current_user.dossiers.count > 2
|
||||
%li
|
||||
|
@ -46,7 +46,7 @@
|
|||
= form_tag recherche_dossiers_path, method: :post, class: "form" do
|
||||
= text_field_tag :dossier_id, "", placeholder: "Numéro de dossier"
|
||||
%button{ title: "Rechercher" }
|
||||
= image_tag "icons/search-blue.svg"
|
||||
= image_tag "icons/search-blue.svg", alt: ''
|
||||
|
||||
- if instructeur_signed_in? || user_signed_in?
|
||||
%li
|
||||
|
@ -60,15 +60,14 @@
|
|||
= link_to "Connexion", new_user_session_path, class: "button secondary"
|
||||
|
||||
%li
|
||||
.header-help
|
||||
- if dossier.present? && nav_bar_profile == :user
|
||||
= render partial: 'shared/help/help_dropdown_dossier', locals: { dossier: dossier }
|
||||
- if dossier.present? && nav_bar_profile == :user
|
||||
= render partial: 'shared/help/help_dropdown_dossier', locals: { dossier: dossier }
|
||||
|
||||
- elsif procedure.present? && (nav_bar_profile == :user || nav_bar_profile == :guest)
|
||||
= render partial: 'shared/help/help_dropdown_procedure', locals: { procedure: procedure }
|
||||
- elsif procedure.present? && (nav_bar_profile == :user || nav_bar_profile == :guest)
|
||||
= render partial: 'shared/help/help_dropdown_procedure', locals: { procedure: procedure }
|
||||
|
||||
- elsif nav_bar_profile == :instructeur
|
||||
= render partial: 'shared/help/help_dropdown_instructeur'
|
||||
- elsif nav_bar_profile == :instructeur
|
||||
= render partial: 'shared/help/help_dropdown_instructeur'
|
||||
|
||||
- else
|
||||
= render partial: 'shared/help/help_button'
|
||||
- else
|
||||
= render partial: 'shared/help/help_button'
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
%th.libelle{ class: repetition ? 'padded' : '' }
|
||||
= "#{c.libelle} :"
|
||||
%td.rich-text
|
||||
%span{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
|
||||
%div{ class: highlight_if_unseen_class(demande_seen_at, c.updated_at) }
|
||||
- case c.type_champ
|
||||
- when TypeDeChamp.type_champs.fetch(:carte)
|
||||
= render partial: "shared/champs/carte/show", locals: { champ: c }
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: dossier }
|
||||
|
||||
- if apercu
|
||||
- form_options = { url: '', method: :get, html: { class: 'form', multipart: true } }
|
||||
- form_options = { url: '', method: :get }
|
||||
- elsif dossier.brouillon?
|
||||
- form_options = { url: brouillon_dossier_url(dossier), method: :patch, html: { class: 'form', multipart: true } }
|
||||
- form_options = { url: brouillon_dossier_url(dossier), method: :patch }
|
||||
- else
|
||||
- form_options = { url: modifier_dossier_url(dossier), method: :patch, html: { class: 'form', multipart: true } }
|
||||
- form_options = { url: modifier_dossier_url(dossier), method: :patch }
|
||||
|
||||
= form_for dossier, form_options do |f|
|
||||
= form_for dossier, form_options.merge({ html: { id: 'dossier-edit-form', class: 'form', multipart: true } }) do |f|
|
||||
|
||||
.prologue
|
||||
%p.mandatory-explanation
|
||||
|
@ -43,13 +43,14 @@
|
|||
- if dossier.brouillon?
|
||||
= f.button 'Enregistrer le brouillon',
|
||||
formnovalidate: true,
|
||||
name: :save_draft,
|
||||
value: true,
|
||||
class: 'button send secondary',
|
||||
data: { 'disable-with': "Envoi en cours…" }
|
||||
|
||||
- if dossier.can_transition_to_en_construction?
|
||||
= f.button 'Déposer le dossier',
|
||||
name: :submit_draft,
|
||||
value: true,
|
||||
class: 'button send primary',
|
||||
disabled: !current_user.owns?(dossier),
|
||||
data: { 'disable-with': "Envoi en cours…" }
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%div
|
||||
= f.file_field :piece_jointe, id: 'piece_jointe', direct_upload: true
|
||||
%label{ for: :piece_jointe }
|
||||
.notice
|
||||
%span.notice
|
||||
(taille max : 20 Mo)
|
||||
|
||||
%div
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- if commentaire.sent_by_system?
|
||||
= image_tag('icons/mail.svg', class: 'person-icon')
|
||||
= image_tag('icons/mail.svg', class: 'person-icon', alt: '')
|
||||
- elsif commentaire.sent_by?(connected_user)
|
||||
= image_tag('icons/account-circle.svg', class: 'person-icon')
|
||||
= image_tag('icons/account-circle.svg', class: 'person-icon', alt: '')
|
||||
- else
|
||||
= image_tag('icons/blue-person.svg', class: 'person-icon')
|
||||
= image_tag('icons/blue-person.svg', class: 'person-icon', alt: '')
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.dropdown.help-dropdown
|
||||
.button.primary.dropdown-button Aide
|
||||
%button.button.primary.dropdown-button Aide
|
||||
.dropdown-content.fade-in-down
|
||||
%ul.dropdown-items
|
||||
- title = dossier.brouillon? ? "Besoin d’aide pour remplir votre dossier ?" : "Une question sur votre dossier ?"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.dropdown.help-dropdown
|
||||
.button.primary.dropdown-button Aide
|
||||
%button.button.primary.dropdown-button Aide
|
||||
.dropdown-content.fade-in-down
|
||||
%ul.dropdown-items
|
||||
= render partial: 'shared/help/dropdown_items/faq_item'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
- has_actions = has_delete_action || has_new_dossier_action
|
||||
|
||||
- if has_actions
|
||||
%span.dropdown.user-dossier-actions
|
||||
.dropdown.user-dossier-actions
|
||||
%button.button.dropdown-button
|
||||
Actions
|
||||
.dropdown-content.fade-in-down
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
- content_for :footer do
|
||||
= render partial: "users/procedure_footer", locals: { procedure: @dossier.procedure, dossier: @dossier }
|
||||
|
||||
.dossier-header.sub-header
|
||||
.container
|
||||
= render partial: "shared/dossiers/header", locals: { dossier: @dossier, apercu: false }
|
||||
#dossier-draft
|
||||
.dossier-header.sub-header
|
||||
.container
|
||||
= render partial: "shared/dossiers/header", locals: { dossier: @dossier, apercu: false }
|
||||
|
||||
= render partial: "shared/dossiers/edit", locals: { dossier: @dossier, apercu: false }
|
||||
= render partial: "shared/dossiers/edit", locals: { dossier: @dossier, apercu: false }
|
||||
|
|
|
@ -30,26 +30,26 @@
|
|||
%th.status-col Statut
|
||||
%th.updated-at-col Mis à jour
|
||||
%th
|
||||
%tbody
|
||||
- @dossiers.each do |dossier|
|
||||
%tr{ data: { 'dossier-id': dossier.id } }
|
||||
%td.folder-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
%span.icon.folder
|
||||
%td.number-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= dossier.id
|
||||
%td
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= procedure_libelle(dossier.procedure)
|
||||
%td.status-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= render partial: 'shared/dossiers/status_badge', locals: { dossier: dossier }
|
||||
%td.updated-at-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= try_format_date(dossier.updated_at)
|
||||
%td.action-col.action-col
|
||||
= render partial: 'dossier_actions', locals: { dossier: dossier }
|
||||
%tbody
|
||||
- @dossiers.each do |dossier|
|
||||
%tr{ data: { 'dossier-id': dossier.id } }
|
||||
%td.folder-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
%span.icon.folder
|
||||
%td.number-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= dossier.id
|
||||
%td
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= procedure_libelle(dossier.procedure)
|
||||
%td.status-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= render partial: 'shared/dossiers/status_badge', locals: { dossier: dossier }
|
||||
%td.updated-at-col
|
||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||
= try_format_date(dossier.updated_at)
|
||||
%td.action-col.action-col
|
||||
= render partial: 'dossier_actions', locals: { dossier: dossier }
|
||||
= paginate(@dossiers)
|
||||
|
||||
- if current_user.feedbacks.empty? || current_user.feedbacks.last.created_at < 1.month.ago
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.auth-options
|
||||
%div
|
||||
= f.check_box :remember_me, as: :boolean
|
||||
= f.check_box :remember_me
|
||||
= f.label :remember_me, "Se souvenir de moi", class: 'remember-me'
|
||||
|
||||
.text-right
|
||||
|
|
|
@ -1,20 +1,35 @@
|
|||
# 3 valeurs:
|
||||
# * tps: environnement de production
|
||||
# * tps_dev: environnement de pre-production
|
||||
# * tps_local: machine de développeur
|
||||
APP_NAME="tps_local"
|
||||
|
||||
# Nom d'hôte de l'appli
|
||||
# * Pour du dev local: localhost:3000
|
||||
# * pour de la preprod: preprod.ds.organisme.fr (par exemple)
|
||||
# * pour de la prod: www.demarches-simplifiees.fr
|
||||
APP_HOST="localhost:3000"
|
||||
|
||||
# Utilisé pour les logs LogRage
|
||||
SOURCE="tps_local"
|
||||
|
||||
# Clé de chiffrement de rails, cf https://api.rubyonrails.org/classes/Rails/Application.html
|
||||
SECRET_KEY_BASE="05a2d479d8e412198dabd08ef0eee9d6e180f5cbb48661a35fd1cae287f0a93d40b5f1da08f06780d698bbd458a0ea97f730f83ee780de5d4e31f649a0130cf0"
|
||||
SIGNING_KEY="aef3153a9829fa4ba10acb02927ac855df6b92795b1ad265d654443c4b14a017"
|
||||
|
||||
# Database
|
||||
DB_DATABASE="tps_development"
|
||||
DB_HOST="localhost"
|
||||
DB_POOL=""
|
||||
DB_USERNAME="tps_development"
|
||||
DB_PASSWORD="tps_development"
|
||||
|
||||
# Protection simple de l'instance par mot de passe (utile pour la pre-prod)
|
||||
BASIC_AUTH_ENABLED="disabled"
|
||||
BASIC_AUTH_USERNAME=""
|
||||
BASIC_AUTH_PASSWORD=""
|
||||
|
||||
# Object Storage pour les pièces jointes
|
||||
FOG_OPENSTACK_TENANT=""
|
||||
FOG_OPENSTACK_API_KEY=""
|
||||
FOG_OPENSTACK_USERNAME=""
|
||||
|
@ -22,29 +37,36 @@ FOG_OPENSTACK_URL=""
|
|||
FOG_OPENSTACK_IDENTITY_API_VERSION=""
|
||||
FOG_OPENSTACK_REGION=""
|
||||
FOG_DIRECTORY=""
|
||||
FOG_ENABLED=""
|
||||
FOG_ENABLED="" # valeur attendue: enabled
|
||||
DS_PROXY_URL=""
|
||||
|
||||
# Service externe: authentification France Connect
|
||||
FC_PARTICULIER_ID=""
|
||||
FC_PARTICULIER_SECRET=""
|
||||
FC_PARTICULIER_BASE_URL=""
|
||||
|
||||
# Service externe: Authentification pour manager (auth Github obligatoire), permet d'accéder à /manager
|
||||
GITHUB_CLIENT_ID=""
|
||||
GITHUB_CLIENT_SECRET=""
|
||||
|
||||
# Service externe: Support Utilisateur HelpScout | Spécifique démarches-simplifiées.fr
|
||||
HELPSCOUT_MAILBOX_ID=""
|
||||
HELPSCOUT_CLIENT_ID=""
|
||||
HELPSCOUT_CLIENT_SECRET=""
|
||||
HELPSCOUT_WEBHOOK_SECRET=""
|
||||
|
||||
# Service externe: Supervision exterieure | Spécifique démarches-simplifiées.fr
|
||||
SENTRY_ENABLED="disabled"
|
||||
SENTRY_CURRENT_ENV="development"
|
||||
SENTRY_DSN_RAILS=""
|
||||
SENTRY_DSN_JS=""
|
||||
|
||||
# Statistiques web
|
||||
MATOMO_ENABLED="disabled"
|
||||
MATOMO_ID="73"
|
||||
# Missing MATOMO_HOST (thus hardcoded)
|
||||
|
||||
# SMTP Provider: Send In Blue
|
||||
SENDINBLUE_BALANCING=""
|
||||
SENDINBLUE_BALANCING_VALUE=""
|
||||
SENDINBLUE_ENABLED=""
|
||||
|
@ -52,26 +74,34 @@ SENDINBLUE_CLIENT_KEY=""
|
|||
SENDINBLUE_SMTP_KEY=""
|
||||
SENDINBLUE_USER_NAME=""
|
||||
|
||||
|
||||
# Service externe: Fournisseur de tchat pour administrateur | Spécifique démarches-simplifiées.fr
|
||||
CRISP_ENABLED="disabled"
|
||||
CRISP_CLIENT_KEY=""
|
||||
|
||||
# Service externe: rattrapage de mails envoyés, utile en préprod | Spécifique démarches-simplifiées.fr
|
||||
MAILTRAP_ENABLED="disabled"
|
||||
MAILTRAP_USERNAME=""
|
||||
MAILTRAP_PASSWORD=""
|
||||
|
||||
# SMTP Provider: Mailjet
|
||||
MAILJET_API_KEY=""
|
||||
MAILJET_SECRET_KEY=""
|
||||
|
||||
# API Entreprise https://api.gouv.fr/api/api-entreprise.html
|
||||
API_ENTREPRISE_KEY=""
|
||||
|
||||
# Service externe: CRM de suivi de création d'administrateur | Spécifique démarches-simplifiées.fr
|
||||
PIPEDRIVE_KEY=""
|
||||
|
||||
# Liste des réseaux qui passent outre la génération de token pour identifier un device, ainsi que le throttling par rack-attack
|
||||
TRUSTED_NETWORKS=""
|
||||
|
||||
# Service externe: mesure de performance d'appli Rails | Spécifique démarches-simplifiées.fr
|
||||
SKYLIGHT_AUTHENTICATION_KEY=""
|
||||
|
||||
# Activer ou non les logs LogRage
|
||||
LOGRAGE_ENABLED="disabled"
|
||||
|
||||
# Service externe d'horodatage des changements de statut des dossiers (effectué quotidiennement)
|
||||
UNIVERSIGN_API_URL=""
|
||||
UNIVERSIGN_USERPWD=""
|
||||
|
|
|
@ -48,6 +48,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
end
|
||||
|
||||
it { expect(response).to redirect_to(personnes_impliquees_instructeur_dossier_url) }
|
||||
it { expect(recipient.followed_dossiers).to include(dossier) }
|
||||
end
|
||||
|
||||
describe '#follow' do
|
||||
|
|
|
@ -426,7 +426,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
context "csv" do
|
||||
before do
|
||||
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'
|
||||
end
|
||||
|
|
|
@ -100,38 +100,38 @@ describe Users::DossiersController, type: :controller do
|
|||
let(:user) { create(:user) }
|
||||
let(:asked_dossier) { create(:dossier) }
|
||||
let(:ensure_authorized) { :forbid_invite_submission! }
|
||||
let(:draft) { false }
|
||||
let(:submit) { true }
|
||||
|
||||
before do
|
||||
@controller.params = @controller.params.merge(dossier_id: asked_dossier.id, save_draft: draft)
|
||||
@controller.params = @controller.params.merge(dossier_id: asked_dossier.id, submit_draft: submit)
|
||||
allow(@controller).to receive(:current_user).and_return(user)
|
||||
allow(@controller).to receive(:redirect_to)
|
||||
end
|
||||
|
||||
context 'when a user save their own draft' do
|
||||
let(:asked_dossier) { create(:dossier, user: user) }
|
||||
let(:draft) { true }
|
||||
let(:submit) { false }
|
||||
|
||||
it_behaves_like 'does not redirect nor flash'
|
||||
end
|
||||
|
||||
context 'when a user submit their own dossier' do
|
||||
let(:asked_dossier) { create(:dossier, user: user) }
|
||||
let(:draft) { false }
|
||||
let(:submit) { true }
|
||||
|
||||
it_behaves_like 'does not redirect nor flash'
|
||||
end
|
||||
|
||||
context 'when an invite save the draft for a dossier where they where invited' do
|
||||
before { create(:invite, dossier: asked_dossier, user: user) }
|
||||
let(:draft) { true }
|
||||
let(:submit) { false }
|
||||
|
||||
it_behaves_like 'does not redirect nor flash'
|
||||
end
|
||||
|
||||
context 'when an invite submit a dossier where they where invited' do
|
||||
before { create(:invite, dossier: asked_dossier, user: user) }
|
||||
let(:draft) { false }
|
||||
let(:submit) { true }
|
||||
|
||||
it_behaves_like 'redirects and flashes'
|
||||
end
|
||||
|
@ -394,7 +394,7 @@ describe Users::DossiersController, type: :controller do
|
|||
}
|
||||
}
|
||||
end
|
||||
let(:payload) { submit_payload }
|
||||
let(:payload) { submit_payload.merge(submit_draft: true) }
|
||||
|
||||
subject do
|
||||
Timecop.freeze(now) do
|
||||
|
@ -480,7 +480,7 @@ describe Users::DossiersController, type: :controller do
|
|||
it { expect(flash.alert).to eq(['Le champ l doit être rempli.']) }
|
||||
|
||||
context 'and the user saves a draft' do
|
||||
let(:payload) { submit_payload.merge(save_draft: true) }
|
||||
let(:payload) { submit_payload.except(:submit_draft) }
|
||||
|
||||
it { expect(response).to render_template(:brouillon) }
|
||||
it { expect(flash.notice).to eq('Votre brouillon a bien été sauvegardé.') }
|
||||
|
@ -510,7 +510,7 @@ describe Users::DossiersController, type: :controller do
|
|||
let!(:invite) { create(:invite, dossier: dossier, user: user) }
|
||||
|
||||
context 'and the invite saves a draft' do
|
||||
let(:payload) { submit_payload.merge(save_draft: true) }
|
||||
let(:payload) { submit_payload.except(:submit_draft) }
|
||||
|
||||
before do
|
||||
first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
require 'spec_helper'
|
||||
require 'csv'
|
||||
|
||||
describe ProcedureExportService do
|
||||
describe 'to_data' do
|
||||
let(:procedure) { create(:procedure, :published, :with_all_champs) }
|
||||
let(:table) { :dossiers }
|
||||
subject { ProcedureExportService.new(procedure, procedure.dossiers).to_data(table) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) }
|
||||
subject do
|
||||
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(:data) { subject[:data] }
|
||||
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
|
||||
|
@ -19,269 +27,324 @@ describe ProcedureExportService do
|
|||
end
|
||||
|
||||
context 'dossiers' do
|
||||
let(:nominal_header) 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,
|
||||
: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
|
||||
"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(headers).to eq(nominal_header)
|
||||
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_header.insert(nominal_header.index(:textarea), :groupe_instructeur_label) }
|
||||
let(:routee_header) { nominal_headers.insert(nominal_headers.index('textarea'), 'Groupe instructeur') }
|
||||
|
||||
it { expect(headers).to eq(routee_header) }
|
||||
end
|
||||
|
||||
it 'should have empty values' do
|
||||
expect(data).to eq([[]])
|
||||
end
|
||||
|
||||
context 'with dossier' do
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :for_individual, procedure: procedure) }
|
||||
|
||||
let(:dossier_data) {
|
||||
[
|
||||
dossier.id.to_s,
|
||||
dossier.created_at.to_s,
|
||||
dossier.updated_at.to_s,
|
||||
"false",
|
||||
dossier.user.email,
|
||||
"received",
|
||||
dossier.en_construction_at.to_s,
|
||||
dossier.en_instruction_at.to_s,
|
||||
nil,
|
||||
nil,
|
||||
nil
|
||||
] + individual_data
|
||||
}
|
||||
|
||||
let(:individual_data) {
|
||||
[
|
||||
"M.",
|
||||
"Xavier",
|
||||
"Julien",
|
||||
"1991-11-01"
|
||||
]
|
||||
}
|
||||
|
||||
let(:champs_data) {
|
||||
dossier.reload.champs.reject(&:exclude_from_export?).map(&:for_export)
|
||||
}
|
||||
|
||||
let(:etablissement_data) {
|
||||
Array.new(24)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
context 'with a procedure routee' do
|
||||
before { procedure.groupe_instructeurs.create(label: '2') }
|
||||
|
||||
it { expect(data.first[15]).to eq('défaut') }
|
||||
it { expect(data.first.count).to eq(dossier_data.count + champs_data.count + etablissement_data.count + 1) }
|
||||
end
|
||||
|
||||
context 'and etablissement' do
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, :with_entreprise, procedure: procedure) }
|
||||
|
||||
let(:etablissement_data) {
|
||||
[
|
||||
dossier.etablissement.siret,
|
||||
dossier.etablissement.siege_social.to_s,
|
||||
dossier.etablissement.naf,
|
||||
dossier.etablissement.libelle_naf,
|
||||
dossier.etablissement.adresse&.chomp&.gsub("\r\n", ' ')&.delete("\r"),
|
||||
dossier.etablissement.numero_voie,
|
||||
dossier.etablissement.type_voie,
|
||||
dossier.etablissement.nom_voie,
|
||||
dossier.etablissement.complement_adresse,
|
||||
dossier.etablissement.code_postal,
|
||||
dossier.etablissement.localite,
|
||||
dossier.etablissement.code_insee_localite,
|
||||
dossier.etablissement.entreprise_siren,
|
||||
dossier.etablissement.entreprise_capital_social.to_s,
|
||||
dossier.etablissement.entreprise_numero_tva_intracommunautaire,
|
||||
dossier.etablissement.entreprise_forme_juridique,
|
||||
dossier.etablissement.entreprise_forme_juridique_code,
|
||||
dossier.etablissement.entreprise_nom_commercial,
|
||||
dossier.etablissement.entreprise_raison_sociale,
|
||||
dossier.etablissement.entreprise_siret_siege_social,
|
||||
dossier.etablissement.entreprise_code_effectif_entreprise,
|
||||
dossier.etablissement.entreprise_date_creation.to_datetime.to_s,
|
||||
dossier.etablissement.entreprise_nom,
|
||||
dossier.etablissement.entreprise_prenom
|
||||
]
|
||||
}
|
||||
|
||||
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
|
||||
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 'etablissements' do
|
||||
let(:table) { :etablissements }
|
||||
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 << ProcedureExportService.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(headers).to eq([
|
||||
:dossier_id,
|
||||
:libelle,
|
||||
: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
|
||||
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 empty values' do
|
||||
expect(data).to eq([[]])
|
||||
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
|
||||
|
||||
context 'with dossier containing champ siret' do
|
||||
let!(:dossier) { create(:dossier, :en_instruction, :with_all_champs, procedure: procedure) }
|
||||
let(:etablissement) { dossier.champs.find { |champ| champ.type_champ == 'siret' }.etablissement }
|
||||
it 'should have data' do
|
||||
expect(avis_sheet.data.size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
let(:etablissement_data) {
|
||||
[
|
||||
dossier.id,
|
||||
'siret',
|
||||
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
|
||||
]
|
||||
}
|
||||
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 values' do
|
||||
expect(data.first).to eq(etablissement_data)
|
||||
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
|
||||
|
|
|
@ -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