2019-03-25 10:53:45 +01:00
module Users
2017-06-29 14:18:12 +02:00
class DossiersController < UserController
2018-07-17 11:40:19 +02:00
include DossierHelper
2019-01-07 12:17:11 +01:00
layout 'procedure_context' , only : [ :identite , :update_identite , :siret , :update_siret ]
2018-11-01 13:00:35 +01:00
ACTIONS_ALLOWED_TO_ANY_USER = [ :index , :recherche , :new ]
2019-05-29 12:05:28 +02:00
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [ :show , :demande , :messagerie , :brouillon , :update_brouillon , :modifier , :update , :create_commentaire ]
2018-09-20 17:39:15 +02:00
before_action :ensure_ownership! , except : ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
before_action :ensure_ownership_or_invitation! , only : ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
2019-05-29 12:05:28 +02:00
before_action :ensure_dossier_can_be_updated , only : [ :update_identite , :update_brouillon , :modifier , :update ]
2018-09-06 10:49:26 +02:00
before_action :forbid_invite_submission! , only : [ :update_brouillon ]
2018-09-06 13:29:56 +02:00
before_action :forbid_closed_submission! , only : [ :update_brouillon ]
2018-10-25 18:05:47 +02:00
before_action :show_demarche_en_test_banner
2018-11-01 13:00:35 +01:00
before_action :store_user_location! , only : :new
2017-06-29 14:18:12 +02:00
2018-07-04 11:49:24 +02:00
def index
@user_dossiers = current_user . dossiers . includes ( :procedure ) . order_by_updated_at . page ( page )
@dossiers_invites = current_user . dossiers_invites . includes ( :procedure ) . order_by_updated_at . page ( page )
2020-12-07 15:10:26 +01:00
@dossiers_supprimes = current_user . deleted_dossiers . order_by_updated_at . page ( page )
@statut = statut ( @user_dossiers , @dossiers_invites , @dossiers_supprimes , params [ :statut ] )
2018-07-04 11:49:24 +02:00
end
2018-08-07 11:58:10 +02:00
def show
if dossier . brouillon?
2018-09-06 09:09:23 +02:00
redirect_to brouillon_dossier_path ( dossier )
2020-01-29 10:26:26 +01:00
return
2018-08-07 11:58:10 +02:00
end
2018-08-07 16:32:11 +02:00
@dossier = dossier
2019-12-15 22:10:35 +01:00
respond_to do | format |
format . pdf do
@include_infos_administration = false
2021-02-17 19:02:31 +01:00
render ( template : 'dossiers/show' , formats : [ :pdf ] )
2019-12-15 22:10:35 +01:00
end
format . all
end
2018-08-07 11:58:10 +02:00
end
2018-08-29 16:57:01 +02:00
def demande
2018-08-14 15:06:44 +02:00
@dossier = dossier
end
2018-09-05 13:56:12 +02:00
def messagerie
@dossier = dossier
@commentaire = Commentaire . new
end
2017-06-29 14:18:59 +02:00
def attestation
2019-11-05 16:44:28 +01:00
if dossier . attestation & . pdf & . attached?
2019-12-19 18:15:37 +01:00
redirect_to dossier . attestation . pdf . service_url
2019-11-05 16:44:28 +01:00
else
flash . notice = " L'attestation n'est plus disponible sur ce dossier. "
redirect_to dossier_path ( dossier )
2019-08-27 17:43:33 +02:00
end
2017-06-29 14:18:59 +02:00
end
2018-02-08 17:13:15 +01:00
def identite
@dossier = dossier
@user = current_user
end
2018-02-08 17:13:15 +01:00
def update_identite
@dossier = dossier
2018-10-02 13:51:56 +02:00
if @dossier . individual . update ( individual_params )
@dossier . update! ( autorisation_donnees : true )
2018-02-08 17:13:15 +01:00
flash . notice = " Identité enregistrée "
2018-11-27 15:56:14 +01:00
redirect_to brouillon_dossier_path ( @dossier )
2018-02-08 17:13:15 +01:00
else
2018-10-02 13:51:56 +02:00
flash . now . alert = @dossier . individual . errors . full_messages
2018-02-08 17:13:15 +01:00
render :identite
end
end
2018-10-04 09:43:19 +02:00
def siret
@dossier = dossier
end
2018-10-15 18:41:53 +02:00
def update_siret
@dossier = dossier
# We use the user as the holder model object for the siret value
# (so that we can restore it on the form in case of error).
#
# This is the only remaining use of User#siret: it could be refactored away.
# However some existing users have a siret but no associated etablissement,
# so we would need to analyze the legacy data and decide what to do with it.
current_user . siret = siret_params [ :siret ]
siret_model = Siret . new ( siret : siret_params [ :siret ] )
if ! siret_model . valid?
return render_siret_error ( siret_model . errors . full_messages )
end
sanitized_siret = siret_model . siret
2019-05-02 11:24:22 +02:00
begin
2020-08-05 18:40:47 +02:00
etablissement = APIEntrepriseService . create_etablissement ( @dossier , sanitized_siret , current_user . id )
rescue APIEntreprise :: API :: Error :: RequestFailed , APIEntreprise :: API :: Error :: BadGateway , APIEntreprise :: API :: Error :: TimedOut
2019-05-02 11:24:22 +02:00
return render_siret_error ( t ( 'errors.messages.siret_network_error' ) )
end
2020-05-18 10:30:08 +02:00
if etablissement . nil?
2018-10-15 18:41:53 +02:00
return render_siret_error ( t ( 'errors.messages.siret_unknown' ) )
end
current_user . update! ( siret : sanitized_siret )
@dossier . update! ( autorisation_donnees : true )
redirect_to etablissement_dossier_path
end
2018-10-15 12:25:25 +02:00
def etablissement
@dossier = dossier
# Redirect if the user attempts to access the page URL directly
if ! @dossier . etablissement
flash . alert = 'Aucun établissement n’ est associé à ce dossier'
return redirect_to siret_dossier_path ( @dossier )
end
end
2018-09-06 09:09:23 +02:00
def brouillon
2018-02-21 18:32:07 +01:00
@dossier = dossier_with_champs
# TODO: remove when the champs are unifed
if ! @dossier . autorisation_donnees
if dossier . procedure . for_individual
redirect_to identite_dossier_path ( @dossier )
else
2018-10-04 09:43:19 +02:00
redirect_to siret_dossier_path ( @dossier )
2018-02-21 18:32:07 +01:00
end
end
end
2018-09-05 19:05:43 +02:00
# FIXME:
# - delegate draft save logic to champ ?
2018-09-06 10:49:26 +02:00
def update_brouillon
2018-02-21 18:32:07 +01:00
@dossier = dossier_with_champs
2018-09-06 13:35:59 +02:00
errors = update_dossier_and_compute_errors
2018-02-21 18:32:07 +01:00
2019-11-07 16:11:24 +01:00
if passage_en_construction? && errors . blank?
2020-07-01 17:31:08 +02:00
@dossier . passer_en_construction!
2021-04-29 19:10:22 +02:00
NotificationMailer . send_en_construction_notification ( @dossier ) . deliver_later
2020-04-23 11:52:21 +02:00
@dossier . groupe_instructeur . instructeurs . with_instant_email_dossier_notifications . each do | instructeur |
2020-04-09 09:22:37 +02:00
DossierMailer . notify_new_dossier_depose_to_instructeur ( @dossier , instructeur . email ) . deliver_later
end
2019-11-07 16:11:24 +01:00
return redirect_to ( merci_dossier_path ( @dossier ) )
elsif errors . present?
2018-02-21 18:32:07 +01:00
flash . now . alert = errors
else
2019-11-07 16:11:24 +01:00
flash . now . notice = 'Votre brouillon a bien été sauvegardé.'
end
respond_to do | format |
format . html { render :brouillon }
2020-08-20 15:56:41 +02:00
format . js { render :brouillon }
2018-02-21 18:32:07 +01:00
end
end
2020-03-19 14:47:09 +01:00
def extend_conservation
2021-05-04 16:29:29 +02:00
dossier . update ( conservation_extension : dossier . conservation_extension + 1 . month )
2020-03-19 14:47:09 +01:00
flash [ :notice ] = 'Votre dossier sera conservé un mois supplémentaire'
redirect_to dossier_path ( @dossier )
end
2018-09-05 18:23:10 +02:00
def modifier
@dossier = dossier_with_champs
end
2018-09-06 11:39:46 +02:00
def update
@dossier = dossier_with_champs
2018-09-06 13:35:59 +02:00
errors = update_dossier_and_compute_errors
2018-09-06 11:39:46 +02:00
if errors . present?
flash . now . alert = errors
render :modifier
2018-09-06 13:31:29 +02:00
else
2018-10-02 12:23:53 +02:00
redirect_to demande_dossier_path ( @dossier )
2018-09-06 11:39:46 +02:00
end
end
2018-02-27 09:49:58 +01:00
def merci
@dossier = current_user . dossiers . includes ( :procedure ) . find ( params [ :id ] )
end
2018-09-05 13:56:12 +02:00
def create_commentaire
2018-11-29 15:00:26 +01:00
@commentaire = CommentaireService . build ( current_user , dossier , commentaire_params )
2018-09-05 13:56:12 +02:00
if @commentaire . save
2020-07-22 16:34:33 +02:00
@commentaire . dossier . update! ( last_commentaire_updated_at : Time . zone . now )
2020-04-02 10:18:23 +02:00
dossier . followers_instructeurs
. with_instant_email_message_notifications
. each do | instructeur |
2020-04-01 16:23:03 +02:00
DossierMailer . notify_new_commentaire_to_instructeur ( dossier , instructeur . email ) . deliver_later
end
2018-09-04 18:27:34 +02:00
flash . notice = " Votre message a bien été envoyé à l’ instructeur en charge de votre dossier. "
2018-09-05 13:56:12 +02:00
redirect_to messagerie_dossier_path ( dossier )
else
flash . now . alert = @commentaire . errors . full_messages
render :messagerie
end
end
2018-05-24 15:55:47 +02:00
def ask_deletion
2019-02-26 16:18:04 +01:00
dossier = current_user . dossiers . includes ( :user , procedure : :administrateurs ) . find ( params [ :id ] )
2018-06-13 13:58:14 +02:00
2019-02-06 19:11:55 +01:00
if dossier . can_be_deleted_by_user?
2020-03-25 18:08:32 +01:00
dossier . discard_and_keep_track! ( current_user , :user_request )
2018-06-13 13:58:14 +02:00
flash . notice = 'Votre dossier a bien été supprimé.'
2018-06-27 14:47:02 +02:00
redirect_to dossiers_path
2018-06-13 13:58:14 +02:00
else
flash . notice = " L'instruction de votre dossier a commencé, il n'est plus possible de supprimer votre dossier. Si vous souhaitez annuler l'instruction contactez votre administration par la messagerie de votre dossier. "
2018-11-01 13:00:35 +01:00
redirect_to dossier_path ( dossier )
2018-06-13 13:58:14 +02:00
end
2018-05-24 15:55:47 +02:00
end
2018-07-17 11:40:19 +02:00
def recherche
2020-04-03 16:07:18 +02:00
@search_terms = params [ :q ]
2020-04-03 17:15:01 +02:00
return redirect_to dossiers_path if @search_terms . blank?
@dossiers = DossierSearchService . matching_dossiers_for_user ( @search_terms , current_user ) . page ( page )
2018-07-17 11:40:19 +02:00
2020-04-03 16:07:18 +02:00
if @dossiers . present?
2020-04-03 17:15:01 +02:00
# we need the page condition when accessing page n with n>1 when the page has only 1 result
# in order to avoid an unpleasant redirection when changing page
if @dossiers . count == 1 && page == 1
redirect_to url_for_dossier ( @dossiers . first )
else
render :index
end
2018-07-17 11:40:19 +02:00
else
2020-04-03 17:15:01 +02:00
flash . alert = " Vous n’ avez pas de dossiers contenant « #{ @search_terms } ». "
2018-07-17 11:40:19 +02:00
redirect_to dossiers_path
end
end
2018-11-01 13:00:35 +01:00
def new
erase_user_location!
2020-01-06 12:53:20 +01:00
begin
if params [ :brouillon ]
procedure = Procedure . brouillon . find ( params [ :procedure_id ] )
else
procedure = Procedure . publiees . find ( params [ :procedure_id ] )
end
rescue ActiveRecord :: RecordNotFound
flash . alert = t ( 'errors.messages.procedure_not_found' )
return redirect_to url_for dossiers_path
2018-11-01 13:00:35 +01:00
end
2020-01-07 17:59:11 +01:00
dossier = Dossier . new (
2020-06-26 12:00:21 +02:00
revision : procedure . active_revision ,
2021-03-09 11:21:30 +01:00
groupe_instructeur : procedure . defaut_groupe_instructeur_for_new_dossier ,
2020-01-06 12:55:22 +01:00
user : current_user ,
state : Dossier . states . fetch ( :brouillon )
)
2020-01-07 17:59:11 +01:00
dossier . build_default_individual
dossier . save!
2018-11-01 13:00:35 +01:00
if dossier . procedure . for_individual
redirect_to identite_dossier_path ( dossier )
else
redirect_to siret_dossier_path ( id : dossier . id )
end
end
2019-03-13 16:48:38 +01:00
def dossier_for_help
dossier_id = params [ :id ] || params [ :dossier_id ]
@dossier || ( dossier_id . present? && Dossier . find_by ( id : dossier_id . to_i ) )
end
2017-06-29 14:18:12 +02:00
private
2020-12-07 15:10:26 +01:00
# if the status tab is filled, then this tab
# else first filled tab
# else mes-dossiers
def statut ( mes_dossiers , dossiers_invites , dossiers_supprimes , params_statut )
tabs = {
'mes-dossiers' = > mes_dossiers . present? ,
'dossiers-invites' = > dossiers_invites . present? ,
'dossiers-supprimes' = > dossiers_supprimes . present?
}
if tabs [ params_statut ]
params_statut
2020-11-26 15:13:32 +01:00
else
2020-12-07 15:10:26 +01:00
tabs
. filter { | _tab , filled | filled }
. map { | tab , _ | tab }
. first || 'mes-dossiers'
2020-11-26 15:13:32 +01:00
end
2020-11-17 13:25:35 +01:00
end
2018-11-01 13:00:35 +01:00
def store_user_location!
store_location_for ( :user , request . fullpath )
end
def erase_user_location!
2019-01-14 16:16:23 +01:00
clear_stored_location_for ( :user )
2018-11-01 13:00:35 +01:00
end
2018-10-25 18:05:47 +02:00
def show_demarche_en_test_banner
if @dossier . present? && @dossier . procedure . brouillon?
2020-12-16 10:27:46 +01:00
flash . now . alert = " Ce dossier est déposé sur une démarche en test. Toute modification de la démarche par l'administrateur (ajout d'un champ, publication de la démarche...) entraînera sa suppression. "
2018-10-25 18:05:47 +02:00
end
end
2018-06-08 15:51:46 +02:00
def ensure_dossier_can_be_updated
2019-02-06 18:20:35 +01:00
if ! dossier . can_be_updated_by_user?
2018-06-08 15:51:46 +02:00
flash . alert = 'Votre dossier ne peut plus être modifié'
2018-06-27 14:47:02 +02:00
redirect_to dossiers_path
2018-06-08 15:51:46 +02:00
end
end
2018-03-30 18:17:47 +02:00
def page
[ params [ :page ] . to_i , 1 ] . max
end
2018-02-27 17:25:45 +01:00
# FIXME: require(:dossier) when all the champs are united
2020-02-26 12:30:52 +01:00
def champs_params
params . permit ( dossier : {
2018-04-03 17:53:14 +02:00
champs_attributes : [
2021-01-14 23:54:32 +01:00
:id , :value , :external_id , :primary_value , :secondary_value , :piece_justificative_file , value : [ ] ,
champs_attributes : [ :id , :_destroy , :value , :external_id , :primary_value , :secondary_value , :piece_justificative_file , value : [ ] ]
2018-04-03 17:53:14 +02:00
]
2020-02-26 12:30:52 +01:00
} )
2018-02-21 18:32:07 +01:00
end
2017-06-29 14:18:12 +02:00
def dossier
2018-09-04 17:47:34 +02:00
@dossier || = Dossier . find ( params [ :id ] || params [ :dossier_id ] )
2017-06-29 14:18:12 +02:00
end
2018-02-21 18:32:07 +01:00
def dossier_with_champs
2018-08-30 11:51:35 +02:00
Dossier . with_champs . find ( params [ :id ] )
2018-02-21 18:32:07 +01:00
end
2020-02-26 12:30:52 +01:00
def change_groupe_instructeur?
2021-03-09 11:21:30 +01:00
if params [ :dossier ] . key? ( :groupe_instructeur_id )
groupe_instructeur_id = params [ :dossier ] [ :groupe_instructeur_id ]
if groupe_instructeur_id . nil?
@dossier . groupe_instructeur_id . present?
else
@dossier . groupe_instructeur_id != groupe_instructeur_id . to_i
end
end
end
def groupe_instructeur_from_params
groupe_instructeur_id = params [ :dossier ] [ :groupe_instructeur_id ]
if groupe_instructeur_id . present?
@dossier . procedure . groupe_instructeurs . find ( groupe_instructeur_id )
end
2020-02-26 12:30:52 +01:00
end
2018-09-06 13:35:59 +02:00
def update_dossier_and_compute_errors
2019-07-24 14:41:56 +02:00
errors = [ ]
2018-09-06 13:35:59 +02:00
2020-02-26 12:30:52 +01:00
if champs_params [ :dossier ]
2020-07-22 17:11:33 +02:00
@dossier . assign_attributes ( champs_params [ :dossier ] )
2021-04-01 16:40:22 +02:00
# FIXME: in some cases a removed repetition bloc row is submitted.
# In this case it will be treated as a new record, and the action will fail.
2021-01-26 16:50:32 +01:00
@dossier . champs . filter ( & :repetition? ) . each do | champ |
champ . champs = champ . champs . filter ( & :persisted? )
end
2021-04-01 17:22:47 +02:00
if @dossier . champs . any? ( & :changed_for_autosave? )
2020-07-22 17:11:33 +02:00
@dossier . last_champ_updated_at = Time . zone . now
end
if ! @dossier . save
2020-02-26 12:30:52 +01:00
errors += @dossier . errors . full_messages
elsif change_groupe_instructeur?
2021-03-09 11:21:30 +01:00
@dossier . assign_to_groupe_instructeur ( groupe_instructeur_from_params )
2020-02-26 12:30:52 +01:00
end
2018-09-06 13:35:59 +02:00
end
if ! save_draft?
2019-01-30 16:14:15 +01:00
errors += @dossier . check_mandatory_champs
2021-03-09 11:21:30 +01:00
if @dossier . groupe_instructeur . nil?
errors << " Le champ « #{ @dossier . procedure . routing_criteria_name } » doit être rempli "
end
2018-09-06 13:35:59 +02:00
end
errors
end
2017-06-29 14:18:12 +02:00
def ensure_ownership!
2018-05-30 18:26:23 +02:00
if ! current_user . owns? ( dossier )
2018-03-29 15:25:05 +02:00
forbidden!
2017-06-29 14:18:12 +02:00
end
end
2018-02-08 17:13:15 +01:00
2018-03-29 15:25:05 +02:00
def ensure_ownership_or_invitation!
2018-05-30 18:31:02 +02:00
if ! current_user . owns_or_invite? ( dossier )
2018-03-29 15:25:05 +02:00
forbidden!
end
end
2018-03-29 16:49:01 +02:00
def forbid_invite_submission!
2018-05-30 18:26:23 +02:00
if passage_en_construction? && ! current_user . owns? ( dossier )
2018-03-29 16:49:01 +02:00
forbidden!
end
end
2018-09-06 13:29:56 +02:00
def forbid_closed_submission!
if passage_en_construction? && ! dossier . can_transition_to_en_construction?
forbidden!
end
end
2018-03-29 15:25:05 +02:00
def forbidden!
flash [ :alert ] = " Vous n'avez pas accès à ce dossier "
redirect_to root_path
end
2018-10-15 18:41:53 +02:00
def render_siret_error ( error_message )
flash . alert = error_message
render :siret
end
2018-02-08 17:13:15 +01:00
def individual_params
params . require ( :individual ) . permit ( :gender , :nom , :prenom , :birthdate )
end
2018-10-15 18:41:53 +02:00
def siret_params
params . require ( :user ) . permit ( :siret )
end
2018-09-05 13:56:12 +02:00
def commentaire_params
2019-06-25 17:12:44 +02:00
params . require ( :commentaire ) . permit ( :body , :piece_jointe )
2018-09-05 13:56:12 +02:00
end
2018-03-29 16:49:01 +02:00
def passage_en_construction?
2018-09-05 19:06:00 +02:00
dossier . brouillon? && ! save_draft?
2018-03-29 16:49:01 +02:00
end
2018-09-05 19:06:00 +02:00
def save_draft?
2019-11-06 16:54:14 +01:00
dossier . brouillon? && ! params [ :submit_draft ]
2018-02-21 18:32:07 +01:00
end
2017-06-29 14:18:12 +02:00
end
end