5f9a9d059e
When receiving a request that expects JSON, return a simple '200'. This avoids the unecessary work of rendering all the HTML page (which ultimately will not be used).
375 lines
11 KiB
Ruby
375 lines
11 KiB
Ruby
module Users
|
||
class DossiersController < UserController
|
||
include Devise::StoreLocationExtension
|
||
include DossierHelper
|
||
|
||
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
||
|
||
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new]
|
||
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire]
|
||
|
||
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
|
||
before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update_brouillon, :modifier, :update]
|
||
before_action :forbid_invite_submission!, only: [:update_brouillon]
|
||
before_action :forbid_closed_submission!, only: [:update_brouillon]
|
||
before_action :show_demarche_en_test_banner
|
||
before_action :store_user_location!, only: :new
|
||
|
||
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)
|
||
|
||
@current_tab = current_tab(@user_dossiers.count, @dossiers_invites.count)
|
||
|
||
@dossiers = case @current_tab
|
||
when 'mes-dossiers'
|
||
@user_dossiers
|
||
when 'dossiers-invites'
|
||
@dossiers_invites
|
||
end
|
||
end
|
||
|
||
def show
|
||
if dossier.brouillon?
|
||
redirect_to brouillon_dossier_path(dossier)
|
||
end
|
||
|
||
@dossier = dossier
|
||
end
|
||
|
||
def demande
|
||
@dossier = dossier
|
||
end
|
||
|
||
def messagerie
|
||
@dossier = dossier
|
||
@commentaire = Commentaire.new
|
||
end
|
||
|
||
def attestation
|
||
if dossier.attestation&.pdf&.attached?
|
||
redirect_to url_for(dossier.attestation.pdf)
|
||
else
|
||
flash.notice = "L'attestation n'est plus disponible sur ce dossier."
|
||
redirect_to dossier_path(dossier)
|
||
end
|
||
end
|
||
|
||
def identite
|
||
@dossier = dossier
|
||
@user = current_user
|
||
end
|
||
|
||
def update_identite
|
||
@dossier = dossier
|
||
|
||
if @dossier.individual.update(individual_params)
|
||
@dossier.update!(autorisation_donnees: true)
|
||
flash.notice = "Identité enregistrée"
|
||
|
||
redirect_to brouillon_dossier_path(@dossier)
|
||
else
|
||
flash.now.alert = @dossier.individual.errors.full_messages
|
||
render :identite
|
||
end
|
||
end
|
||
|
||
def siret
|
||
@dossier = dossier
|
||
end
|
||
|
||
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
|
||
begin
|
||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
|
||
rescue RestClient::RequestFailed
|
||
return render_siret_error(t('errors.messages.siret_network_error'))
|
||
end
|
||
if etablissement_attributes.blank?
|
||
return render_siret_error(t('errors.messages.siret_unknown'))
|
||
end
|
||
|
||
etablissement = @dossier.build_etablissement(etablissement_attributes)
|
||
etablissement.save!
|
||
current_user.update!(siret: sanitized_siret)
|
||
@dossier.update!(autorisation_donnees: true)
|
||
|
||
redirect_to etablissement_dossier_path
|
||
end
|
||
|
||
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
|
||
|
||
def brouillon
|
||
@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
|
||
redirect_to siret_dossier_path(@dossier)
|
||
end
|
||
end
|
||
end
|
||
|
||
# FIXME:
|
||
# - delegate draft save logic to champ ?
|
||
def update_brouillon
|
||
@dossier = dossier_with_champs
|
||
|
||
errors = update_dossier_and_compute_errors
|
||
|
||
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
|
||
else
|
||
flash.now.notice = 'Votre brouillon a bien été sauvegardé.'
|
||
end
|
||
|
||
respond_to do |format|
|
||
format.html { render :brouillon }
|
||
format.json { head :ok }
|
||
end
|
||
end
|
||
|
||
def modifier
|
||
@dossier = dossier_with_champs
|
||
end
|
||
|
||
def update
|
||
@dossier = dossier_with_champs
|
||
|
||
errors = update_dossier_and_compute_errors
|
||
|
||
if errors.present?
|
||
flash.now.alert = errors
|
||
render :modifier
|
||
else
|
||
redirect_to demande_dossier_path(@dossier)
|
||
end
|
||
end
|
||
|
||
def merci
|
||
@dossier = current_user.dossiers.includes(:procedure).find(params[:id])
|
||
end
|
||
|
||
def create_commentaire
|
||
@commentaire = CommentaireService.build(current_user, dossier, commentaire_params)
|
||
|
||
if @commentaire.save
|
||
flash.notice = "Votre message a bien été envoyé à l’instructeur en charge de votre dossier."
|
||
redirect_to messagerie_dossier_path(dossier)
|
||
else
|
||
flash.now.alert = @commentaire.errors.full_messages
|
||
render :messagerie
|
||
end
|
||
end
|
||
|
||
def ask_deletion
|
||
dossier = current_user.dossiers.includes(:user, procedure: :administrateurs).find(params[:id])
|
||
|
||
if dossier.can_be_deleted_by_user?
|
||
dossier.delete_and_keep_track(current_user)
|
||
flash.notice = 'Votre dossier a bien été supprimé.'
|
||
redirect_to dossiers_path
|
||
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."
|
||
redirect_to dossier_path(dossier)
|
||
end
|
||
end
|
||
|
||
def recherche
|
||
@dossier_id = params[:dossier_id]
|
||
dossier = current_user.dossiers.find_by(id: @dossier_id)
|
||
|
||
if dossier
|
||
redirect_to url_for_dossier(dossier)
|
||
else
|
||
flash.alert = "Vous n’avez pas de dossier avec le nº #{@dossier_id}."
|
||
redirect_to dossiers_path
|
||
end
|
||
end
|
||
|
||
def new
|
||
erase_user_location!
|
||
|
||
if params[:brouillon]
|
||
procedure = Procedure.brouillon.find(params[:procedure_id])
|
||
else
|
||
procedure = Procedure.publiees.find(params[:procedure_id])
|
||
end
|
||
|
||
dossier = Dossier.create!(groupe_instructeur: procedure.defaut_groupe_instructeur, user: current_user, state: Dossier.states.fetch(:brouillon))
|
||
|
||
if dossier.procedure.for_individual
|
||
if current_user.france_connect_information.present?
|
||
dossier.update_with_france_connect(current_user.france_connect_information)
|
||
end
|
||
|
||
redirect_to identite_dossier_path(dossier)
|
||
else
|
||
redirect_to siret_dossier_path(id: dossier.id)
|
||
end
|
||
rescue ActiveRecord::RecordNotFound
|
||
flash.alert = t('errors.messages.procedure_not_found')
|
||
|
||
redirect_to url_for dossiers_path
|
||
end
|
||
|
||
def dossier_for_help
|
||
dossier_id = params[:id] || params[:dossier_id]
|
||
@dossier || (dossier_id.present? && Dossier.find_by(id: dossier_id.to_i))
|
||
end
|
||
|
||
private
|
||
|
||
def store_user_location!
|
||
store_location_for(:user, request.fullpath)
|
||
end
|
||
|
||
def erase_user_location!
|
||
clear_stored_location_for(:user)
|
||
end
|
||
|
||
def show_demarche_en_test_banner
|
||
if @dossier.present? && @dossier.procedure.brouillon?
|
||
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...) entrainera sa suppression."
|
||
end
|
||
end
|
||
|
||
def ensure_dossier_can_be_updated
|
||
if !dossier.can_be_updated_by_user?
|
||
flash.alert = 'Votre dossier ne peut plus être modifié'
|
||
redirect_to dossiers_path
|
||
end
|
||
end
|
||
|
||
def page
|
||
[params[:page].to_i, 1].max
|
||
end
|
||
|
||
def current_tab(mes_dossiers_count, dossiers_invites_count)
|
||
if dossiers_invites_count == 0
|
||
'mes-dossiers'
|
||
elsif mes_dossiers_count == 0
|
||
'dossiers-invites'
|
||
else
|
||
params[:current_tab].presence || 'mes-dossiers'
|
||
end
|
||
end
|
||
|
||
# FIXME: require(:dossier) when all the champs are united
|
||
def champs_and_groupe_instructeurs_params
|
||
params.permit(dossier: [
|
||
:groupe_instructeur_id,
|
||
champs_attributes: [
|
||
:id, :value, :primary_value, :secondary_value, :piece_justificative_file, value: [],
|
||
champs_attributes: [:id, :_destroy, :value, :primary_value, :secondary_value, :piece_justificative_file, value: []]
|
||
]
|
||
])
|
||
end
|
||
|
||
def dossier
|
||
@dossier ||= Dossier.find(params[:id] || params[:dossier_id])
|
||
end
|
||
|
||
def dossier_with_champs
|
||
Dossier.with_champs.find(params[:id])
|
||
end
|
||
|
||
def update_dossier_and_compute_errors
|
||
errors = []
|
||
|
||
if champs_and_groupe_instructeurs_params[:dossier] && !@dossier.update(champs_and_groupe_instructeurs_params[:dossier])
|
||
errors += @dossier.errors.full_messages
|
||
end
|
||
|
||
if !save_draft?
|
||
errors += @dossier.check_mandatory_champs
|
||
end
|
||
|
||
errors
|
||
end
|
||
|
||
def ensure_ownership!
|
||
if !current_user.owns?(dossier)
|
||
forbidden!
|
||
end
|
||
end
|
||
|
||
def ensure_ownership_or_invitation!
|
||
if !current_user.owns_or_invite?(dossier)
|
||
forbidden!
|
||
end
|
||
end
|
||
|
||
def forbid_invite_submission!
|
||
if passage_en_construction? && !current_user.owns?(dossier)
|
||
forbidden!
|
||
end
|
||
end
|
||
|
||
def forbid_closed_submission!
|
||
if passage_en_construction? && !dossier.can_transition_to_en_construction?
|
||
forbidden!
|
||
end
|
||
end
|
||
|
||
def forbidden!
|
||
flash[:alert] = "Vous n'avez pas accès à ce dossier"
|
||
redirect_to root_path
|
||
end
|
||
|
||
def render_siret_error(error_message)
|
||
flash.alert = error_message
|
||
render :siret
|
||
end
|
||
|
||
def individual_params
|
||
params.require(:individual).permit(:gender, :nom, :prenom, :birthdate)
|
||
end
|
||
|
||
def siret_params
|
||
params.require(:user).permit(:siret)
|
||
end
|
||
|
||
def commentaire_params
|
||
params.require(:commentaire).permit(:body, :piece_jointe)
|
||
end
|
||
|
||
def passage_en_construction?
|
||
dossier.brouillon? && !save_draft?
|
||
end
|
||
|
||
def save_draft?
|
||
dossier.brouillon? && !params[:submit_draft]
|
||
end
|
||
end
|
||
end
|