Merge pull request #6019 from betagouv/main

This commit is contained in:
Pierre de La Morinerie 2021-03-25 12:54:17 +01:00 committed by GitHub
commit a7e919c184
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 70 additions and 63 deletions

View file

@ -113,11 +113,12 @@ type Association {
type Avis { type Avis {
attachment: File attachment: File
claimant: Profile
dateQuestion: ISO8601DateTime! dateQuestion: ISO8601DateTime!
dateReponse: ISO8601DateTime dateReponse: ISO8601DateTime
expert: Profile expert: Profile
id: ID! id: ID!
instructeur: Profile! instructeur: Profile! @deprecated(reason: "Utilisez le champ claimant à la place.")
question: String! question: String!
reponse: String reponse: String
} }

View file

@ -11,7 +11,8 @@ module Types
{ Extensions::Attachment => { attachment: :piece_justificative_file } } { Extensions::Attachment => { attachment: :piece_justificative_file } }
] ]
field :instructeur, Types::ProfileType, null: false, method: :claimant field :instructeur, Types::ProfileType, null: false, method: :claimant, deprecation_reason: "Utilisez le champ claimant à la place."
field :claimant, Types::ProfileType, null: true
field :expert, Types::ProfileType, null: true field :expert, Types::ProfileType, null: true
end end
end end

View file

@ -90,10 +90,10 @@ module Types
def avis(id: nil) def avis(id: nil)
if id.present? if id.present?
Loaders::Record Loaders::Record
.for(Avis, where: { dossier: object }, includes: [:instructeur, :claimant], array: true) .for(Avis, where: { dossier: object }, includes: [:expert, :claimant], array: true)
.load(ApplicationRecord.id_from_typed_id(id)) .load(ApplicationRecord.id_from_typed_id(id))
else else
Loaders::Association.for(object.class, avis: [:instructeur, :claimant]).load(object) Loaders::Association.for(object.class, avis: [:expert, :claimant]).load(object)
end end
end end

View file

@ -21,9 +21,8 @@ class Avis < ApplicationRecord
include EmailSanitizableConcern include EmailSanitizableConcern
belongs_to :dossier, inverse_of: :avis, touch: true, optional: false belongs_to :dossier, inverse_of: :avis, touch: true, optional: false
belongs_to :instructeur, optional: true
belongs_to :experts_procedure, optional: false belongs_to :experts_procedure, optional: false
belongs_to :claimant, class_name: 'Instructeur', optional: false belongs_to :claimant, polymorphic: true, optional: false
has_one_attached :piece_justificative_file has_one_attached :piece_justificative_file
has_one_attached :introduction_file has_one_attached :introduction_file
@ -57,26 +56,7 @@ class Avis < ApplicationRecord
attr_accessor :emails attr_accessor :emails
attr_accessor :invite_linked_dossiers attr_accessor :invite_linked_dossiers
def claimant self.ignored_columns = [:instructeur_id, :tmp_expert_migrated]
claimant_id = read_attribute(:claimant_id)
claimant_type = read_attribute(:claimant_type)
if claimant_type == 'Instructeur' || !tmp_expert_migrated
Instructeur.find(claimant_id)
else
Expert.find(claimant_id)
end
end
def claimant=(claimant)
self.claimant_id = claimant.id
if claimant.is_a? Instructeur
self.claimant_type = 'Instructeur'
else
self.claimant_type = 'Expert'
self.tmp_expert_migrated = true
end
end
def email_to_display def email_to_display
expert&.email expert&.email

View file

@ -23,8 +23,6 @@ class Instructeur < ApplicationRecord
has_many :previous_follows, -> { inactive }, class_name: 'Follow', inverse_of: :instructeur has_many :previous_follows, -> { inactive }, class_name: 'Follow', inverse_of: :instructeur
has_many :followed_dossiers, through: :follows, source: :dossier has_many :followed_dossiers, through: :follows, source: :dossier
has_many :previously_followed_dossiers, -> { distinct }, through: :previous_follows, source: :dossier has_many :previously_followed_dossiers, -> { distinct }, through: :previous_follows, source: :dossier
has_many :avis
has_many :dossiers_from_avis, through: :avis, source: :dossier
has_many :trusted_device_tokens, dependent: :destroy has_many :trusted_device_tokens, dependent: :destroy
has_one :user, dependent: :nullify has_one :user, dependent: :nullify

View file

@ -21,7 +21,7 @@ class DossierSearchService
end end
def self.dossiers_by_id(id, instructeur) def self.dossiers_by_id(id, instructeur)
(instructeur.dossiers.where(id: id) + instructeur.dossiers_from_avis.where(id: id)).uniq instructeur.dossiers.where(id: id).uniq
end end
def self.id_compatible?(number) def self.id_compatible?(number)

View file

@ -109,7 +109,7 @@ class SerializerService
reponse reponse
dateQuestion dateQuestion
dateReponse dateReponse
instructeur { claimant {
email email
} }
expert { expert {

View file

@ -32,11 +32,13 @@
- if current_instructeur.procedures.count > 0 - if current_instructeur.procedures.count > 0
%li %li
= active_link_to "Démarches", instructeur_procedures_path, active: ['dossiers','procedures'].include?(controller_name), class: 'tab-link' = active_link_to "Démarches", instructeur_procedures_path, active: ['dossiers','procedures'].include?(controller_name), class: 'tab-link'
- if current_instructeur.avis.count > 0 - if nav_bar_profile == :expert && expert_signed_in?
- if current_expert.avis.count > 0
%ul.header-tabs
%li %li
= active_link_to instructeur_all_avis_path, active: controller_name == 'avis', class: 'tab-link' do = active_link_to expert_all_avis_path, active: controller_name == 'avis', class: 'tab-link' do
Avis Avis
- avis_counter = current_instructeur.avis.without_answer.count - avis_counter = current_expert.avis.without_answer.count
- if avis_counter > 0 - if avis_counter > 0
%span.badge.warning= avis_counter %span.badge.warning= avis_counter

View file

@ -2,8 +2,8 @@
= image_tag "landing/hero/dematerialiser.svg", class: "paperless-logo", alt: "moins de papier" = image_tag "landing/hero/dematerialiser.svg", class: "paperless-logo", alt: "moins de papier"
.baseline.center .baseline.center
%p %p
%span.simple Un outil simple %span.simple= t('views.commencer.no_procedure.ligne1')
%br %br
pour gérer les formulaires = t('views.commencer.no_procedure.ligne2')
%br %br
administratifs dématérialisés. = t('views.commencer.no_procedure.ligne3')

View file

@ -3,29 +3,29 @@
.auth-form.sign-in-form .auth-form.sign-in-form
= form_for User.new, url: user_session_path, html: { class: "form" } do |f| = form_for User.new, url: user_session_path, html: { class: "form" } do |f|
%h1.huge-title Connectez-vous %h1.huge-title= t('views.sessions.new.title')
= render partial: 'shared/france_connect_login', locals: { url: france_connect_particulier_path } = render partial: 'shared/france_connect_login', locals: { url: france_connect_particulier_path }
= f.label :email, "Email (nom@site.com)" = f.label :email, t('views.sessions.new.email')
= f.text_field :email, type: :email, autocomplete: 'username', autofocus: true = f.text_field :email, type: :email, autocomplete: 'username', autofocus: true
= f.label :password, "Mot de passe (#{PASSWORD_MIN_LENGTH} caractères minimum)" = f.label :password, t('views.sessions.new.password', min_length: PASSWORD_MIN_LENGTH)
= f.password_field :password, autocomplete: 'current-password' = f.password_field :password, autocomplete: 'current-password'
.auth-options .auth-options
%div %div
= f.check_box :remember_me = f.check_box :remember_me
= f.label :remember_me, "Se souvenir de moi", class: 'remember-me' = f.label :remember_me, t('views.sessions.new.remember_me'), class: 'remember-me'
.text-right .text-right
= link_to "Mot de passe oublié ?", new_user_password_path, class: "link" = link_to t('views.sessions.new.reset_password'), new_user_password_path, class: "link"
= f.submit "Se connecter", class: "button large primary expand" = f.submit t('views.sessions.new.connection'), class: "button large primary expand"
%hr %hr
%p.center %p.center
%span Vous êtes nouveau sur #{APPLICATION_NAME.gsub("-","&#8209;").html_safe} ? %span= t('views.sessions.new.are_you_new', app_name: APPLICATION_NAME.gsub("-","&#8209;")).html_safe
%br %br
%br %br
= link_to "Trouvez votre démarche", COMMENT_TROUVER_MA_DEMARCHE_URL, target: "_blank", class: "button expend secondary" = link_to t('views.sessions.new.find_procedure'), COMMENT_TROUVER_MA_DEMARCHE_URL, target: "_blank", class: "button expend secondary"

View file

@ -35,7 +35,21 @@ en:
previous: Previous previous: Previous
first: First first: First
truncate: '&hellip;' truncate: '&hellip;'
sessions:
new:
title: Sign in
email: Email address (name@site.com)
password: Password (minimum length %{min_length} characters)
remember_me: Remember me
reset_password: Forgot password?
connection: Sign in
are_you_new: First time on %{app_name} ?
find_procedure: Find your procedure
commencer:
no_procedure:
ligne1: A simple tool
ligne2: to manage dematerialized
ligne3: administrative forms.
modal: modal:
publish: publish:
title: title:
@ -47,7 +61,6 @@ en:
submit: submit:
publish: Publish publish: Publish
reopen: Reopen reopen: Reopen
activerecord: activerecord:
attributes: attributes:
user: user:
@ -91,7 +104,6 @@ en:
taken: is already used for procedure. You cannot use it because it belongs to another administrator. taken: is already used for procedure. You cannot use it because it belongs to another administrator.
# taken_can_be_claimed: est identique à celui dune autre de vos procedures publiées. Si vous publiez cette procedure, lancienne sera dépubliée et ne sera plus accessible au public. Les utilisateurs qui ont commencé un brouillon vont pouvoir le déposer. # taken_can_be_claimed: est identique à celui dune autre de vos procedures publiées. Si vous publiez cette procedure, lancienne sera dépubliée et ne sera plus accessible au public. Les utilisateurs qui ont commencé un brouillon vont pouvoir le déposer.
invalid: is not valid. It must countain between 3 and 50 characters among a-z, 0-9, '_' and '-'. invalid: is not valid. It must countain between 3 and 50 characters among a-z, 0-9, '_' and '-'.
errors: errors:
messages: messages:
dossier_not_found: "The file does not exist or you do not have access to it." dossier_not_found: "The file does not exist or you do not have access to it."
@ -111,7 +123,6 @@ en:
# other: "Aucune parcelle cadastrale sur les zones sélectionnées" # other: "Aucune parcelle cadastrale sur les zones sélectionnées"
not_an_integer: "must be an integer (without decimal)" not_an_integer: "must be an integer (without decimal)"
blank: "can't be blank" blank: "can't be blank"
time: time:
formats: formats:
default: "%B %d %Y %R" default: "%B %d %Y %R"

View file

@ -35,7 +35,21 @@ fr:
previous: Précédent previous: Précédent
first: Premier first: Premier
truncate: '&hellip;' truncate: '&hellip;'
sessions:
new:
title: Connectez-vous
email: Email (nom@site.com)
password: Mot de passe (%{min_length} caractères minimum)
remember_me: Se souvenir de moi
reset_password: Mot de passe oublié ?
connection: Se connecter
are_you_new: Vous êtes nouveau sur %{app_name} ?
find_procedure: Trouvez votre démarche
commencer:
no_procedure:
ligne1: Un outil simple
ligne2: pour gérer les formulaires
ligne3: administratifs dématérialisés.
modal: modal:
publish: publish:
title: title:
@ -47,7 +61,6 @@ fr:
submit: submit:
publish: Publier publish: Publier
reopen: Réactiver reopen: Réactiver
activerecord: activerecord:
attributes: attributes:
default_attributes: &default_attributes default_attributes: &default_attributes
@ -100,7 +113,6 @@ fr:
taken: est déjà utilisé par une démarche. Vous ne pouvez pas lutiliser car il appartient à un autre administrateur. taken: est déjà utilisé par une démarche. Vous ne pouvez pas lutiliser car il appartient à un autre administrateur.
taken_can_be_claimed: est identique à celui dune autre de vos démarches publiées. Si vous publiez cette démarche, lancienne sera dépubliée et ne sera plus accessible au public. Les utilisateurs qui ont commencé un brouillon vont pouvoir le déposer. taken_can_be_claimed: est identique à celui dune autre de vos démarches publiées. Si vous publiez cette démarche, lancienne sera dépubliée et ne sera plus accessible au public. Les utilisateurs qui ont commencé un brouillon vont pouvoir le déposer.
invalid: nest pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés. invalid: nest pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés.
errors: errors:
messages: messages:
saml_not_authorized: "Vous n'êtes pas autorisé à accéder à ce service." saml_not_authorized: "Vous n'êtes pas autorisé à accéder à ce service."
@ -122,7 +134,6 @@ fr:
other: "Aucune parcelle cadastrale sur les zones sélectionnées" other: "Aucune parcelle cadastrale sur les zones sélectionnées"
not_an_integer: "doit être un nombre entier (sans chiffres après la virgule)" not_an_integer: "doit être un nombre entier (sans chiffres après la virgule)"
blank: "doit être rempli" blank: "doit être rempli"
time: time:
formats: formats:
default: "%d %B %Y %R" default: "%d %B %Y %R"

View file

@ -0,0 +1,9 @@
en:
views:
shared:
france_connect_login:
title: "With FranceConnect"
description: "France connect is a solution proposed by the government to secure and simplify the connection to web services."
login_button: "Sign in with FranceConnect"
help_link: What is FranceConnect ?
separator: or

View file

@ -320,8 +320,6 @@ Rails.application.routes.draw do
# #
scope module: 'instructeurs', as: 'instructeur' do scope module: 'instructeurs', as: 'instructeur' do
get 'avis', to: 'avis#index', as: 'all_avis'
# this redirections are ephemeral, to ensure that emails sent to experts before are still valid # this redirections are ephemeral, to ensure that emails sent to experts before are still valid
# TODO : they will be removed in September, 2020 # TODO : they will be removed in September, 2020
get 'avis/:id', to: redirect('/procedures/old/avis/%{id}') get 'avis/:id', to: redirect('/procedures/old/avis/%{id}')
@ -339,12 +337,8 @@ Rails.application.routes.draw do
resources :avis, only: [:show, :update] do resources :avis, only: [:show, :update] do
get '', action: 'procedure', on: :collection, as: :procedure get '', action: 'procedure', on: :collection, as: :procedure
member do member do
get 'messagerie'
post 'commentaire' => 'avis#create_commentaire'
post 'avis' => 'avis#create_avis'
patch 'revoquer' patch 'revoquer'
get 'revive' get 'revive'
get 'bilans_bdf'
end end
end end

View file

@ -345,9 +345,9 @@ describe Dossier do
end end
context 'when they are a lot of advice' do context 'when they are a lot of advice' do
let!(:avis_1) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('10/01/2010'), tmp_expert_migrated: true) } let!(:avis_1) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('10/01/2010')) }
let!(:avis_2) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('9/01/2010'), tmp_expert_migrated: true) } let!(:avis_2) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('9/01/2010')) }
let!(:avis_3) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('11/01/2010'), tmp_expert_migrated: true) } let!(:avis_3) { create(:avis, dossier: dossier, claimant: expert_1, experts_procedure: experts_procedure_2, confidentiel: false, created_at: Time.zone.parse('11/01/2010')) }
it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis_2, avis_1, avis_3]) } it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis_2, avis_1, avis_3]) }
it { expect(dossier.avis_for_expert(expert_1)).to match([avis_2, avis_1, avis_3]) } it { expect(dossier.avis_for_expert(expert_1)).to match([avis_2, avis_1, avis_3]) }