diff --git a/Gemfile b/Gemfile index b4bc529f6..cc43823e0 100644 --- a/Gemfile +++ b/Gemfile @@ -164,6 +164,7 @@ group :development do gem 'rubocop-rspec-focused', require: false gem 'haml-lint' gem 'scss_lint', require: false + gem 'letter_opener_web' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 4e0a85aed..83bec46a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -459,6 +459,12 @@ GEM leaflet-markercluster-rails (0.7.0) railties (>= 3.1) leaflet-rails (0.7.7) + letter_opener (1.6.0) + launchy (~> 2.2) + letter_opener_web (1.3.4) + actionmailer (>= 3.2) + letter_opener (~> 1.0) + railties (>= 3.2) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -855,6 +861,7 @@ DEPENDENCIES leaflet-draw-rails leaflet-markercluster-rails (~> 0.7.0) leaflet-rails + letter_opener_web lograge logstash-event mailjet @@ -906,4 +913,4 @@ DEPENDENCIES zxcvbn-ruby BUNDLED WITH - 1.16.4 + 1.16.5 diff --git a/Procfile b/Procfile index 6047f41fa..56e81cebf 100644 --- a/Procfile +++ b/Procfile @@ -1,3 +1,2 @@ server: bin/rails server jobs: bin/delayed_job run -mails: mailcatcher -f diff --git a/app/assets/stylesheets/new_design/dossiers_table.scss b/app/assets/stylesheets/new_design/dossiers_table.scss index 7c9b6d15d..b3cd92a4e 100644 --- a/app/assets/stylesheets/new_design/dossiers_table.scss +++ b/app/assets/stylesheets/new_design/dossiers_table.scss @@ -77,7 +77,3 @@ padding-right: $default-spacer; } } - -.dossiers-table-empty { - text-align: center; -} diff --git a/app/assets/stylesheets/new_design/layouts.scss b/app/assets/stylesheets/new_design/layouts.scss index ec83ec436..fda1ff4ad 100644 --- a/app/assets/stylesheets/new_design/layouts.scss +++ b/app/assets/stylesheets/new_design/layouts.scss @@ -45,3 +45,7 @@ margin: auto; max-width: $page-width / 2; } + +.blank-tab { + text-align: center; +} diff --git a/app/assets/stylesheets/new_design/utils.scss b/app/assets/stylesheets/new_design/utils.scss index 5b7d2856f..ef32f9f20 100644 --- a/app/assets/stylesheets/new_design/utils.scss +++ b/app/assets/stylesheets/new_design/utils.scss @@ -44,7 +44,6 @@ } } - .highlighted { background: $orange-bg; color: $black; diff --git a/app/controllers/new_gestionnaire/procedures_controller.rb b/app/controllers/new_gestionnaire/procedures_controller.rb index 2b5bd6464..5810348f9 100644 --- a/app/controllers/new_gestionnaire/procedures_controller.rb +++ b/app/controllers/new_gestionnaire/procedures_controller.rb @@ -67,10 +67,11 @@ module NewGestionnaire @archived_dossiers end - sorted_ids = DossierFieldService.sorted_ids(@dossiers, procedure_presentation, current_gestionnaire) + dossier_field_service = DossierFieldService.new + sorted_ids = dossier_field_service.sorted_ids(@dossiers, procedure_presentation, current_gestionnaire) if @current_filters.count > 0 - filtered_ids = DossierFieldService.filtered_ids(@dossiers, current_filters) + filtered_ids = dossier_field_service.filtered_ids(@dossiers, current_filters) filtered_sorted_ids = sorted_ids.select { |id| filtered_ids.include?(id) } else filtered_sorted_ids = sorted_ids diff --git a/app/lib/api_entreprise/adapter.rb b/app/lib/api_entreprise/adapter.rb index bf0645b0f..422509d88 100644 --- a/app/lib/api_entreprise/adapter.rb +++ b/app/lib/api_entreprise/adapter.rb @@ -1,4 +1,6 @@ class ApiEntreprise::Adapter + UNAVAILABLE = 'Donnée indisponible' + def initialize(siret, procedure_id) @siret = siret @procedure_id = procedure_id @@ -17,4 +19,8 @@ class ApiEntreprise::Adapter {} end end + + def valid_params?(params) + !params.has_value?(UNAVAILABLE) + end end diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index a722c29d7..0abc968da 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -34,10 +34,7 @@ class ApiEntreprise::API params: params, timeout: TIMEOUT) - # Responses with a 206 codes are sometimes not useable, - # as the RNA calls often return a 206 with an error message, - # not a partial response - if response.success? && response.code != 206 + if response.success? JSON.parse(response.body, symbolize_names: true) else raise RestClient::ResourceNotFound diff --git a/app/lib/api_entreprise/entreprise_adapter.rb b/app/lib/api_entreprise/entreprise_adapter.rb index b32305c47..0798a0d41 100644 --- a/app/lib/api_entreprise/entreprise_adapter.rb +++ b/app/lib/api_entreprise/entreprise_adapter.rb @@ -8,8 +8,13 @@ class ApiEntreprise::EntrepriseAdapter < ApiEntreprise::Adapter def process_params params = data_source[:entreprise].slice(*attr_to_fetch) - params[:date_creation] = Time.at(params[:date_creation]).to_datetime - params.transform_keys { |k| :"entreprise_#{k}" } + + if valid_params?(params) + params[:date_creation] = Time.at(params[:date_creation]).to_datetime + params.transform_keys { |k| :"entreprise_#{k}" } + else + {} + end end def attr_to_fetch diff --git a/app/lib/api_entreprise/etablissement_adapter.rb b/app/lib/api_entreprise/etablissement_adapter.rb index a1eacd7c6..58f63c689 100644 --- a/app/lib/api_entreprise/etablissement_adapter.rb +++ b/app/lib/api_entreprise/etablissement_adapter.rb @@ -7,10 +7,15 @@ class ApiEntreprise::EtablissementAdapter < ApiEntreprise::Adapter def process_params params = data_source[:etablissement].slice(*attr_to_fetch) - adresse_line = params[:adresse].slice(*address_lines_to_fetch).values.compact.join("\r\n") - params.merge!(params[:adresse].slice(*address_attr_to_fetch)) - params[:adresse] = adresse_line - params + + if valid_params?(params) + adresse_line = params[:adresse].slice(*address_lines_to_fetch).values.compact.join("\r\n") + params.merge!(params[:adresse].slice(*address_attr_to_fetch)) + params[:adresse] = adresse_line + params + else + {} + end end def attr_to_fetch diff --git a/app/lib/api_entreprise/exercices_adapter.rb b/app/lib/api_entreprise/exercices_adapter.rb index 4807e205f..0563f629a 100644 --- a/app/lib/api_entreprise/exercices_adapter.rb +++ b/app/lib/api_entreprise/exercices_adapter.rb @@ -10,7 +10,11 @@ class ApiEntreprise::ExercicesAdapter < ApiEntreprise::Adapter exercice.slice(*attr_to_fetch) end - { exercices_attributes: exercices_array } + if exercices_array.all? { |params| valid_params?(params) } + { exercices_attributes: exercices_array } + else + {} + end end def attr_to_fetch diff --git a/app/lib/api_entreprise/rna_adapter.rb b/app/lib/api_entreprise/rna_adapter.rb index 9d0612788..042b952ca 100644 --- a/app/lib/api_entreprise/rna_adapter.rb +++ b/app/lib/api_entreprise/rna_adapter.rb @@ -6,12 +6,23 @@ class ApiEntreprise::RNAAdapter < ApiEntreprise::Adapter end def process_params - if data_source[:association][:id].present? - params = data_source[:association].slice(*attr_to_fetch) - params[:rna] = data_source[:association][:id] - params.transform_keys { |k| :"association_#{k}" } - else + # Sometimes the associations endpoints responses with a 206, + # and these response are often useable as the they only + # contain an error message. + # Therefore here we make sure that our response seems valid + # by checking that there is an association attribute. + if !data_source.key?(:association) {} + else + association_id = data_source[:association][:id] + params = data_source[:association].slice(*attr_to_fetch) + + if association_id.present? && valid_params?(params) + params[:rna] = association_id + params.transform_keys { |k| :"association_#{k}" } + else + {} + end end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index db405b172..f4c28c44d 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -223,10 +223,6 @@ class Dossier < ApplicationRecord end end - def get_value(table, column) - DossierFieldService.get_value(self, table, column) - end - def owner_name if etablissement.present? etablissement.entreprise_raison_sociale diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 6ffe9a620..006a3bf3c 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -293,7 +293,7 @@ class Procedure < ApplicationRecord end def fields - DossierFieldService.fields(self) + DossierFieldService.new.fields(self) end def fields_for_select diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index b9fccc2d7..7b0c61479 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -16,7 +16,7 @@ class ProcedurePresentation < ApplicationRecord displayed_fields.each do |field| table = field['table'] column = field['column'] - if !DossierFieldService.valid_column?(procedure, table, column) + if !dossier_field_service.valid_column?(procedure, table, column) errors.add(:filters, "#{table}.#{column} n’est pas une colonne permise") end end @@ -35,7 +35,7 @@ class ProcedurePresentation < ApplicationRecord columns.each do |column| table = column['table'] column = column['column'] - if !DossierFieldService.valid_column?(procedure, table, column) + if !dossier_field_service.valid_column?(procedure, table, column) errors.add(:filters, "#{table}.#{column} n’est pas une colonne permise") end end @@ -44,7 +44,11 @@ class ProcedurePresentation < ApplicationRecord private + def dossier_field_service + @dossier_field_service ||= DossierFieldService.new + end + def valid_sort_column?(procedure, table, column) - DossierFieldService.valid_column?(procedure, table, column) || EXTRA_SORT_COLUMNS[table]&.include?(column) + dossier_field_service.valid_column?(procedure, table, column) || EXTRA_SORT_COLUMNS[table]&.include?(column) end end diff --git a/app/services/dossier_field_service.rb b/app/services/dossier_field_service.rb index dad49c2f9..4ca6028f0 100644 --- a/app/services/dossier_field_service.rb +++ b/app/services/dossier_field_service.rb @@ -1,172 +1,172 @@ class DossierFieldService - @@column_whitelist = {} + def initialize + @column_whitelist = {} + end - class << self - def fields(procedure) - fields = [ - field_hash('Créé le', 'self', 'created_at'), - field_hash('Mis à jour le', 'self', 'updated_at'), - field_hash('Demandeur', 'user', 'email') - ] + def fields(procedure) + fields = [ + field_hash('Créé le', 'self', 'created_at'), + field_hash('Mis à jour le', 'self', 'updated_at'), + field_hash('Demandeur', 'user', 'email') + ] - if !procedure.for_individual || (procedure.for_individual && procedure.individual_with_siret) - fields.push( - field_hash('SIREN', 'etablissement', 'entreprise_siren'), - field_hash('Forme juridique', 'etablissement', 'entreprise_forme_juridique'), - field_hash('Nom commercial', 'etablissement', 'entreprise_nom_commercial'), - field_hash('Raison sociale', 'etablissement', 'entreprise_raison_sociale'), - field_hash('SIRET siège social', 'etablissement', 'entreprise_siret_siege_social'), - field_hash('Date de création', 'etablissement', 'entreprise_date_creation') - ) + if !procedure.for_individual || (procedure.for_individual && procedure.individual_with_siret) + fields.push( + field_hash('SIREN', 'etablissement', 'entreprise_siren'), + field_hash('Forme juridique', 'etablissement', 'entreprise_forme_juridique'), + field_hash('Nom commercial', 'etablissement', 'entreprise_nom_commercial'), + field_hash('Raison sociale', 'etablissement', 'entreprise_raison_sociale'), + field_hash('SIRET siège social', 'etablissement', 'entreprise_siret_siege_social'), + field_hash('Date de création', 'etablissement', 'entreprise_date_creation') + ) - fields.push( - field_hash('SIRET', 'etablissement', 'siret'), - field_hash('Libellé NAF', 'etablissement', 'libelle_naf'), - field_hash('Code postal', 'etablissement', 'code_postal') - ) - end - - explanatory_types_de_champ = [:header_section, :explication].map{ |k| TypeDeChamp.type_champs.fetch(k) } - - fields.concat procedure.types_de_champ - .reject { |tdc| explanatory_types_de_champ.include?(tdc.type_champ) } - .map { |type_de_champ| field_hash(type_de_champ.libelle, 'type_de_champ', type_de_champ.id.to_s) } - - fields.concat procedure.types_de_champ_private - .reject { |tdc| explanatory_types_de_champ.include?(tdc.type_champ) } - .map { |type_de_champ| field_hash(type_de_champ.libelle, 'type_de_champ_private', type_de_champ.id.to_s) } - - fields + fields.push( + field_hash('SIRET', 'etablissement', 'siret'), + field_hash('Libellé NAF', 'etablissement', 'libelle_naf'), + field_hash('Code postal', 'etablissement', 'code_postal') + ) end - def get_value(dossier, table, column) - assert_valid_column(dossier.procedure, table, column) + explanatory_types_de_champ = [:header_section, :explication].map{ |k| TypeDeChamp.type_champs.fetch(k) } + fields.concat procedure.types_de_champ + .reject { |tdc| explanatory_types_de_champ.include?(tdc.type_champ) } + .map { |type_de_champ| field_hash(type_de_champ.libelle, 'type_de_champ', type_de_champ.id.to_s) } + + fields.concat procedure.types_de_champ_private + .reject { |tdc| explanatory_types_de_champ.include?(tdc.type_champ) } + .map { |type_de_champ| field_hash(type_de_champ.libelle, 'type_de_champ_private', type_de_champ.id.to_s) } + + fields + end + + def get_value(dossier, table, column) + assert_valid_column(dossier.procedure, table, column) + + case table + when 'self' + dossier.send(column) + when 'user' + dossier.user.send(column) + when 'etablissement' + dossier.etablissement&.send(column) + when 'type_de_champ' + dossier.champs.find { |c| c.type_de_champ_id == column.to_i }.value + when 'type_de_champ_private' + dossier.champs_private.find { |c| c.type_de_champ_id == column.to_i }.value + end + end + + def assert_valid_column(procedure, table, column) + if !valid_column?(procedure, table, column) + raise "Invalid column #{table}.#{column}" + end + end + + def valid_column?(procedure, table, column) + valid_columns_for_table(procedure, table).include?(column) + end + + def filtered_ids(dossiers, filters) + filters.map do |filter| + table = filter['table'] + column = sanitized_column(filter) case table when 'self' - dossier.send(column) - when 'user' - dossier.user.send(column) + dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%") + + when 'type_de_champ', 'type_de_champ_private' + relation = table == 'type_de_champ' ? :champs : :champs_private + dossiers + .includes(relation) + .where("champs.type_de_champ_id = ?", filter['column'].to_i) + .where("champs.value ILIKE ?", "%#{filter['value']}%") when 'etablissement' - dossier.etablissement&.send(column) - when 'type_de_champ' - dossier.champs.find { |c| c.type_de_champ_id == column.to_i }.value - when 'type_de_champ_private' - dossier.champs_private.find { |c| c.type_de_champ_id == column.to_i }.value - end - end - - def assert_valid_column(procedure, table, column) - if !valid_column?(procedure, table, column) - raise "Invalid column #{table}.#{column}" - end - end - - def valid_column?(procedure, table, column) - valid_columns_for_table(procedure, table).include?(column) - end - - def filtered_ids(dossiers, filters) - filters.map do |filter| - table = filter['table'] - column = sanitized_column(filter) - case table - when 'self' - dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%") - - when 'type_de_champ', 'type_de_champ_private' - relation = table == 'type_de_champ' ? :champs : :champs_private + if filter['column'] == 'entreprise_date_creation' + date = filter['value'].to_date rescue nil dossiers - .includes(relation) - .where("champs.type_de_champ_id = ?", filter['column'].to_i) - .where("champs.value ILIKE ?", "%#{filter['value']}%") - when 'etablissement' - if filter['column'] == 'entreprise_date_creation' - date = filter['value'].to_date rescue nil - dossiers - .includes(table) - .where("#{column} = ?", date) - else - dossiers - .includes(table) - .where("#{column} ILIKE ?", "%#{filter['value']}%") - end - when 'user' + .includes(table) + .where("#{column} = ?", date) + else dossiers .includes(table) .where("#{column} ILIKE ?", "%#{filter['value']}%") - end.pluck(:id) - end.reduce(:&) - end - - def sorted_ids(dossiers, procedure_presentation, gestionnaire) - table = procedure_presentation.sort['table'] - column = sanitized_column(procedure_presentation.sort) - order = procedure_presentation.sort['order'] - assert_valid_order(order) - - case table - when 'notifications' - procedure = procedure_presentation.assign_to.procedure - dossiers_id_with_notification = gestionnaire.notifications_for_procedure(procedure) - if order == 'desc' - return dossiers_id_with_notification + - (dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification) - else - return (dossiers.order('dossiers.updated_at asc').ids - dossiers_id_with_notification) + - dossiers_id_with_notification end - when 'self' - return dossiers - .order("#{column} #{order}") - .pluck(:id) - when 'type_de_champ', 'type_de_champ_private' - return dossiers - .includes(table == 'type_de_champ' ? :champs : :champs_private) - .where("champs.type_de_champ_id = #{procedure_presentation.sort['column'].to_i}") - .order("champs.value #{order}") - .pluck(:id) + when 'user' + dossiers + .includes(table) + .where("#{column} ILIKE ?", "%#{filter['value']}%") + end.pluck(:id) + end.reduce(:&) + end + + def sorted_ids(dossiers, procedure_presentation, gestionnaire) + table = procedure_presentation.sort['table'] + column = sanitized_column(procedure_presentation.sort) + order = procedure_presentation.sort['order'] + assert_valid_order(order) + + case table + when 'notifications' + procedure = procedure_presentation.assign_to.procedure + dossiers_id_with_notification = gestionnaire.notifications_for_procedure(procedure) + if order == 'desc' + return dossiers_id_with_notification + + (dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification) else - return dossiers - .includes(table) - .order("#{column} #{order}") - .pluck(:id) + return (dossiers.order('dossiers.updated_at asc').ids - dossiers_id_with_notification) + + dossiers_id_with_notification end - end - - private - - def valid_columns_for_table(procedure, table) - if !@@column_whitelist.key?(procedure.id) - @@column_whitelist[procedure.id] = fields(procedure) - .group_by { |field| field['table'] } - .map { |table, fields| [table, Set.new(fields.map { |field| field['column'] }) ] } - .to_h - end - - @@column_whitelist[procedure.id][table] || [] - end - - def sanitized_column(field) - table = field['table'] - table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize) - column = ActiveRecord::Base.connection.quote_column_name(field['column']) - - table + '.' + column - end - - def assert_valid_order(order) - if !["asc", "desc"].include?(order) - raise "Invalid order #{order}" - end - end - - def field_hash(label, table, column) - { - 'label' => label, - 'table' => table, - 'column' => column - } + when 'self' + return dossiers + .order("#{column} #{order}") + .pluck(:id) + when 'type_de_champ', 'type_de_champ_private' + return dossiers + .includes(table == 'type_de_champ' ? :champs : :champs_private) + .where("champs.type_de_champ_id = #{procedure_presentation.sort['column'].to_i}") + .order("champs.value #{order}") + .pluck(:id) + else + return dossiers + .includes(table) + .order("#{column} #{order}") + .pluck(:id) end end + + private + + def valid_columns_for_table(procedure, table) + if !@column_whitelist.key?(procedure.id) + @column_whitelist[procedure.id] = fields(procedure) + .group_by { |field| field['table'] } + .map { |table, fields| [table, Set.new(fields.map { |field| field['column'] }) ] } + .to_h + end + + @column_whitelist[procedure.id][table] || [] + end + + def sanitized_column(field) + table = field['table'] + table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize) + column = ActiveRecord::Base.connection.quote_column_name(field['column']) + + table + '.' + column + end + + def assert_valid_order(order) + if !["asc", "desc"].include?(order) + raise "Invalid order #{order}" + end + end + + def field_hash(label, table, column) + { + 'label' => label, + 'table' => table, + 'column' => column + } + end end diff --git a/app/views/new_gestionnaire/avis/instruction.html.haml b/app/views/new_gestionnaire/avis/instruction.html.haml index 1ff164457..5bef952d5 100644 --- a/app/views/new_gestionnaire/avis/instruction.html.haml +++ b/app/views/new_gestionnaire/avis/instruction.html.haml @@ -21,6 +21,8 @@ .send-wrapper = f.submit 'Envoyer votre avis', class: 'button send' - = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_avis_path(@avis), must_be_confidentiel: @avis.confidentiel?, avis: @new_avis } + - if !@dossier.termine? + = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_avis_path(@avis), must_be_confidentiel: @avis.confidentiel?, avis: @new_avis } - = render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis_for(current_gestionnaire), avis_seen_at: nil } + - if @dossier.avis_for(current_gestionnaire).present? + = render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis_for(current_gestionnaire), avis_seen_at: nil } diff --git a/app/views/new_gestionnaire/dossiers/avis.html.haml b/app/views/new_gestionnaire/dossiers/avis.html.haml index 67881abbb..eb59d5dbb 100644 --- a/app/views/new_gestionnaire/dossiers/avis.html.haml +++ b/app/views/new_gestionnaire/dossiers/avis.html.haml @@ -3,6 +3,13 @@ = render partial: "header", locals: { dossier: @dossier } .container - = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_dossier_path(@dossier.procedure, @dossier), must_be_confidentiel: false, avis: @avis } + - if !@dossier.termine? + = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_dossier_path(@dossier.procedure, @dossier), must_be_confidentiel: false, avis: @avis } - = render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis, avis_seen_at: @avis_seen_at } + - if @dossier.avis.present? + = render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis, avis_seen_at: @avis_seen_at } + + - if @dossier.termine? && !@dossier.avis.present? + .blank-tab + %h2.empty-text Aucun avis. + %p.empty-text-details Aucun avis n'a été demandé sur ce dossier. diff --git a/app/views/new_gestionnaire/procedures/show.html.haml b/app/views/new_gestionnaire/procedures/show.html.haml index ebcf41b7f..8b5054168 100644 --- a/app/views/new_gestionnaire/procedures/show.html.haml +++ b/app/views/new_gestionnaire/procedures/show.html.haml @@ -92,6 +92,7 @@ = submit_tag "Enregistrer", class: 'button' %tbody + - dossier_field_service = DossierFieldService.new - @dossiers.each do |dossier| %tr %td.folder-col @@ -107,7 +108,7 @@ - @displayed_fields.each do |field| %td = link_to(gestionnaire_dossier_path(@procedure, dossier), class: 'cell-link') do - = dossier.get_value(field['table'], field['column']) + = dossier_field_service.get_value(dossier, field['table'], field['column']) %td.status-col = link_to(gestionnaire_dossier_path(@procedure, dossier), class: 'cell-link') do diff --git a/app/views/new_gestionnaire/shared/avis/_list.html.haml b/app/views/new_gestionnaire/shared/avis/_list.html.haml index 03966b8e6..fb34568fb 100644 --- a/app/views/new_gestionnaire/shared/avis/_list.html.haml +++ b/app/views/new_gestionnaire/shared/avis/_list.html.haml @@ -1,32 +1,31 @@ -- if avis.present? - %section.list-avis - %h1.tab-title - Avis des invités - %span.count= avis.count +%section.list-avis + %h1.tab-title + Avis des invités + %span.count= avis.count - %ul - - avis.each do |avis| - %li.one-avis.flex.align-start - .width-100 - %h2.claimant - Demandeur : - %span.email= (avis.claimant.email == current_gestionnaire.email) ? 'Vous' : avis.claimant.email - - if avis.confidentiel? - %span.confidentiel - confidentiel - %span.icon.lock{ title: "Cet avis n'est pas affiché avec les autres experts consultés" } - %span.date{ class: highlight_if_unseen_class(avis_seen_at, avis.created_at) } - Demande d'avis envoyée le #{I18n.l(avis.created_at.localtime, format: '%d/%m/%y à %H:%M')} - %p= avis.introduction + %ul + - avis.each do |avis| + %li.one-avis.flex.align-start + .width-100 + %h2.claimant + Demandeur : + %span.email= (avis.claimant.email == current_gestionnaire.email) ? 'Vous' : avis.claimant.email + - if avis.confidentiel? + %span.confidentiel + confidentiel + %span.icon.lock{ title: "Cet avis n'est pas affiché avec les autres experts consultés" } + %span.date{ class: highlight_if_unseen_class(avis_seen_at, avis.created_at) } + Demande d'avis envoyée le #{I18n.l(avis.created_at.localtime, format: '%d/%m/%y à %H:%M')} + %p= avis.introduction - .answer.flex.align-start - %span.icon.bubble.avis-icon - .width-100 - %h2.gestionnaire - = (avis.email_to_display == current_gestionnaire.email) ? 'Vous' : avis.email_to_display - - if avis.answer.present? - %span.date{ class: highlight_if_unseen_class(avis_seen_at, avis.updated_at) } - Réponse donnée le #{I18n.l(avis.updated_at.localtime, format: '%d/%m/%y à %H:%M')} - - else - %span.waiting En attente de réponse - %p= avis.answer + .answer.flex.align-start + %span.icon.bubble.avis-icon + .width-100 + %h2.gestionnaire + = (avis.email_to_display == current_gestionnaire.email) ? 'Vous' : avis.email_to_display + - if avis.answer.present? + %span.date{ class: highlight_if_unseen_class(avis_seen_at, avis.updated_at) } + Réponse donnée le #{I18n.l(avis.updated_at.localtime, format: '%d/%m/%y à %H:%M')} + - else + %span.waiting En attente de réponse + %p= avis.answer diff --git a/app/views/new_user/dossiers/index.html.haml b/app/views/new_user/dossiers/index.html.haml index 40c6189c7..1f9be4d28 100644 --- a/app/views/new_user/dossiers/index.html.haml +++ b/app/views/new_user/dossiers/index.html.haml @@ -63,7 +63,7 @@ %span.icon.smile - else - .dossiers-table-empty + .blank-tab %h2.empty-text Aucun dossier. %p.empty-text-details Vous n’avez pas encore commencé de démarche. = link_to "Commencer une nouvelle démarche", demarches_url, class: "button primary" diff --git a/app/views/shared/champs/dossier_link/_help_block.html.haml b/app/views/shared/champs/dossier_link/_help_block.html.haml index ebf725a29..910eb2c52 100644 --- a/app/views/shared/champs/dossier_link/_help_block.html.haml +++ b/app/views/shared/champs/dossier_link/_help_block.html.haml @@ -1,7 +1,5 @@ - if id.present? - - dossier = current_user&.dossiers&.find_by(id: id) - - dossier ||= current_gestionnaire&.dossiers&.find_by(id: id) - - dossier ||= current_administrateur&.dossiers&.find_by(id: id) + - dossier = Dossier.find_by(id: id) - if dossier.blank? %p.text-warning Ce dossier est inconnu diff --git a/bin/setup b/bin/setup index 86ae494c9..3d592bcd5 100755 --- a/bin/setup +++ b/bin/setup @@ -13,9 +13,6 @@ chdir APP_ROOT do # This script is a starting point to setup your application. # Add necessary setup steps to this file. - puts '== Installing global tools ==' - system! 'gem install mailcatcher --conservative' - puts "\n== Installing dependencies ==" system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') diff --git a/config/deploy.rb b/config/deploy.rb index 3da042697..fa18dffb9 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -104,16 +104,6 @@ namespace :yarn do end end -namespace :rails do - desc "Run deploy tasks." - task :after_party do - queue %{ - echo "-----> Running deploy tasks" - #{echo_cmd %[bundle exec rake after_party:run]} - } - end -end - desc "Deploys the current version to the server." task :deploy => :environment do queue 'export PATH=$PATH:/usr/local/rbenv/bin:/usr/local/rbenv/shims' @@ -126,7 +116,7 @@ task :deploy => :environment do invoke :'bundle:install' invoke :'yarn:install' invoke :'rails:db_migrate' - invoke :'rails:after_party' + invoke :'rake[after_party:run]' invoke :'rails:assets_precompile:force' to :launch do diff --git a/config/environments/development.rb b/config/environments/development.rb index e906943f1..f600e1bba 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -45,17 +45,11 @@ Rails.application.configure do config.assets.raise_runtime_errors = true # Action Mailer settings - config.action_mailer.delivery_method = :smtp - config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } - # Config for mailcatcher https://mailcatcher.me/ - config.action_mailer.smtp_settings = { - address: 'localhost', - port: 1025, - locale: 'fr' - } + config.action_mailer.delivery_method = :letter_opener_web Rails.application.routes.default_url_options = { - host: 'localhost:3000' + host: 'localhost', + port: 3000 } # Raises error for missing translations diff --git a/config/routes.rb b/config/routes.rb index d61486811..e939134a9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,6 +45,14 @@ Rails.application.routes.draw do root to: "administrateurs#index" end + # + # Letter Opener + # + + if Rails.env.development? + mount LetterOpenerWeb::Engine, at: "/letter_opener" + end + # # Monitoring # diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 3d6960488..351a890d8 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -732,29 +732,6 @@ describe Dossier do end end - describe "#get_value" do - let(:dossier) { create(:dossier, :with_entreprise, user: user) } - - before do - FranceConnectInformation.create(france_connect_particulier_id: 123, user: user, gender: 'male') - - @champ_public = dossier.champs.first - @champ_public.value = "kiwi" - @champ_public.save - - @champ_private = dossier.champs_private.first - @champ_private.value = "banane" - @champ_private.save - end - - it { expect(dossier.get_value('self', 'created_at')).to eq(dossier.created_at) } - it { expect(dossier.get_value('user', 'email')).to eq(user.email) } - it { expect(dossier.get_value('etablissement', 'entreprise_siren')).to eq(dossier.etablissement.entreprise_siren) } - it { expect(dossier.get_value('etablissement', 'siret')).to eq(dossier.etablissement.siret) } - it { expect(dossier.get_value('type_de_champ', @champ_public.type_de_champ.id.to_s)).to eq(dossier.champs.first.value) } - it { expect(dossier.get_value('type_de_champ_private', @champ_private.type_de_champ.id.to_s)).to eq(dossier.champs_private.first.value) } - end - describe 'updated_at' do let!(:dossier) { create(:dossier) } let(:modif_date) { DateTime.parse('01/01/2100') } diff --git a/spec/services/dossier_field_service_spec.rb b/spec/services/dossier_field_service_spec.rb index 5f1a1a5fb..1d439c006 100644 --- a/spec/services/dossier_field_service_spec.rb +++ b/spec/services/dossier_field_service_spec.rb @@ -14,7 +14,7 @@ describe DossierFieldService do type_de_champ.champ.create(dossier: discarded_dossier, value: 'discard me') end - subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ', 'column' => type_de_champ.id, 'value' => 'keep' }]) } + subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ', 'column' => type_de_champ.id, 'value' => 'keep' }]) } it { is_expected.to contain_exactly(kept_dossier.id) } end @@ -29,7 +29,7 @@ describe DossierFieldService do type_de_champ_private.champ.create(dossier: discarded_dossier, value: 'discard me') end - subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ_private', 'column' => type_de_champ_private.id, 'value' => 'keep' }]) } + subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ_private', 'column' => type_de_champ_private.id, 'value' => 'keep' }]) } it { is_expected.to contain_exactly(kept_dossier.id) } end @@ -39,7 +39,7 @@ describe DossierFieldService do let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2018, 6, 21))) } let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2008, 6, 21))) } - subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }]) } + subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }]) } it { is_expected.to contain_exactly(kept_dossier.id) } end @@ -50,7 +50,7 @@ describe DossierFieldService do let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75017')) } let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '25000')) } - subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }]) } + subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }]) } it { is_expected.to contain_exactly(kept_dossier.id) } end @@ -60,7 +60,7 @@ describe DossierFieldService do let!(:kept_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@keepmail.com')) } let!(:discarded_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@discard.com')) } - subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'user', 'column' => 'email', 'value' => 'keepmail' }]) } + subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'user', 'column' => 'email', 'value' => 'keepmail' }]) } it { is_expected.to contain_exactly(kept_dossier.id) } end @@ -72,7 +72,7 @@ describe DossierFieldService do let(:sort) { { 'table' => table, 'column' => column, 'order' => order } } let(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to, sort: sort) } - subject { DossierFieldService.sorted_ids(procedure.dossiers, procedure_presentation, gestionnaire) } + subject { described_class.new.sorted_ids(procedure.dossiers, procedure_presentation, gestionnaire) } context 'for notifications table' do let(:table) { 'notifications' } @@ -164,7 +164,7 @@ describe DossierFieldService do end describe '#get_value' do - subject { DossierFieldService.get_value(dossier, table, column) } + subject { described_class.new.get_value(dossier, table, column) } context 'for self table' do let(:table) { 'self' }