feat(procedure): update archiving to add closing reason and closing details

This commit is contained in:
Eric Leroy-Terquem 2024-02-15 10:54:19 +01:00
parent 6651b36fe4
commit 74903d79bf
8 changed files with 136 additions and 21 deletions

View file

@ -194,16 +194,19 @@ module Administrateurs
def archive
procedure = current_administrateur.procedures.find(params[:procedure_id])
if params[:new_procedure].present?
new_procedure = current_administrateur.procedures.find(params[:new_procedure])
procedure.update!(replaced_by_procedure_id: new_procedure.id)
if procedure.update(closing_params)
procedure.close!
if (procedure.dossiers.not_archived.state_brouillon.present? || procedure.dossiers.not_archived.state_en_construction_ou_instruction.present?)
redirect_to admin_procedure_closing_notification_path
else
flash.notice = "Démarche close"
redirect_to admin_procedure_path(id: procedure.id)
end
else
flash.alert = procedure.errors.full_messages
redirect_to admin_procedure_close_path
end
procedure.close!
flash.notice = "Démarche close"
redirect_to admin_procedures_path
rescue ActiveRecord::RecordNotFound
flash.alert = 'Démarche inexistante'
redirect_to admin_procedures_path
@ -327,6 +330,7 @@ module Administrateurs
def close
@published_procedures = current_administrateur.procedures.publiees.to_h { |p| ["#{p.libelle} (#{p.id})", p.id] }
@closing_reason_options = Procedure.closing_reasons.values.map { |reason| [I18n.t("activerecord.attributes.procedure.closing_reasons.#{reason}"), reason] }
end
def confirmation
@ -493,6 +497,18 @@ module Administrateurs
params.permit(:path, :lien_site_web)
end
def closing_params
closing_params = params.require(:procedure).permit(:closing_details, :closing_reason, :replaced_by_procedure_id)
replaced_by_procedure_id = closing_params[:replaced_by_procedure_id]
if replaced_by_procedure_id.present?
if current_administrateur.procedures.find_by(id: replaced_by_procedure_id).blank?
closing_params.delete(:replaced_by_procedure_id)
end
end
closing_params
end
def allow_decision_access_params
params.require(:experts_procedure).permit(:allow_decision_access)
end

View file

@ -0,0 +1,44 @@
import { ApplicationController } from './application_controller';
import { hide, show } from '@utils';
export class ClosingReasonController extends ApplicationController {
static targets = ['closingReason', 'replacedByProcedureId', 'closingDetails'];
declare closingReasonTarget: HTMLSelectElement;
declare replacedByProcedureIdTarget: HTMLInputElement;
declare closingDetailsTarget: HTMLInputElement;
connect() {
this.displayInput();
this.on('change', () => this.onChange());
}
onChange() {
this.displayInput();
}
displayInput() {
const closingReasonSelect = this.closingReasonTarget as HTMLSelectElement;
Array.from(closingReasonSelect.options).forEach((option) => {
if (option.selected && option.value == 'internal_procedure') {
show(this.replacedByProcedureIdTarget);
hide(this.closingDetailsTarget);
this.emptyValue(this.closingDetailsTarget.querySelector('input'));
} else if (option.selected && option.value == 'other') {
hide(this.replacedByProcedureIdTarget);
this.emptyValue(
this.replacedByProcedureIdTarget.querySelector('select')
);
show(this.closingDetailsTarget);
this.emptyValue(this.closingDetailsTarget.querySelector('input'));
}
});
}
emptyValue(field: HTMLInputElement | HTMLSelectElement | null) {
if (field) {
field.value = '';
}
}
}

View file

@ -8,15 +8,21 @@
.fr-col-12.fr-col-offset-md-2.fr-col-md-8
%h1= t('administrateurs.procedures.close.page_title')
%p= t('administrateurs.procedures.close.replacement_procedure_title')
= render Dsfr::CalloutComponent.new(title: t("administrateurs.procedures.close.replacement_procedure_callout_title"), icon: "fr-fi-information-line") do |c|
- c.with_body do
= t('administrateurs.procedures.close.replacement_procedure_callout_content')
= form_tag admin_procedure_archive_path(@procedure), method: :put do
= form_for @procedure, url: admin_procedure_archive_path(@procedure), method: :put, html: { "data-controller" => "closing-reason" } do |f|
.fr-select-group
= f.label :closing_reason, class: 'fr-label'
= f.select :closing_reason, options_for_select(@closing_reason_options), {}, { class: 'fr-select', "data-closing-reason-target" => "closingReason" }
- if @published_procedures.present?
.fr-select-group
= label_tag :new_procedure, class: 'fr-label' do
= t('activerecord.attributes.procedure.new_procedure')
= t('utils.no_mandatory')
= select_tag :new_procedure, options_for_select(@published_procedures), include_blank: true, class: 'fr-select'
.fr-select-group#js_replaced_by_procedure_id{ "data-closing-reason-target" => "replacedByProcedureId" }
= f.label :replaced_by_procedure_id, class: 'fr-label'
= f.select :replaced_by_procedure_id, options_for_select(@published_procedures), { include_blank: "Sélectionnez la nouvelle démarche" }, { class: 'fr-select' }
.fr-input-group#js_closing_details{ "data-closing-reason-target" => "closingDetails" }
= render Dsfr::InputComponent.new(form: f, attribute: :closing_details, input_type: :text_area, opts: { rows: '10', placeholder: t('activerecord.attributes.procedure.hints.closing_details_placeholder')}, required: false)
= submit_tag t('administrateurs.procedures.close.actions.close_procedure'), { class: "fr-btn", id: 'publish', data: { confirm: "Voulez-vous vraiment clore la démarche ? \nLes dossiers en cours pourront être instruits, mais aucun nouveau dossier ne pourra plus être déposé.", disable_with: "Archivage..."} }

View file

@ -14,6 +14,8 @@ en:
cadre_juridique: "Exemple: 'https://www.legifrance.gouv.fr/'"
old_procedure: This procedure replaces a close? If yes, please indicate the number of the replaced procedure
procedure_path: "Personalize if needed the rest of the URL to facilitate access to the procedure. From 3 to 200 characters: lowercase letters, numbers and dashes only"
closing_details: Give as many explanations as possible to users about the reason for closing the process
closing_details_placeholder: "This procedure has been replaced by the page…\n\nThe guide to the new procedure is available here\n\nFor any further information, contact…\n\nSincerely,"
path: Public link
organisation: Service
description: What is the purpose of this procedure?
@ -23,6 +25,12 @@ en:
lien_site_web: Where will users find the link to the procedure?
old_procedure: Replaced procedure number
new_procedure: New procedure number
replaced_by_procedure_id: New procedure
closing_details: Information message on the process closing page
closing_reason: Closing reason
closing_reasons:
other: Other
internal_procedure: I replace my procedure with another in Démarches Simplifiées
procedure_path: Procedure link to disseminate to users
procedure_path_placeholder: procedure-name
cadre_juridique: Link to the legal text

View file

@ -14,6 +14,8 @@ fr:
cadre_juridique: "Exemple: 'https://www.legifrance.gouv.fr/'"
old_procedure: Cette démarche remplace une close ? Si oui, veuillez indiquer le n° de la démarche remplacée
procedure_path: "Personnalisez si besoin la suite de lURL, pour faciliter l'accès à la démarche. De 3 à 200 caractères : minuscules, chiffres et tiret seulement"
closing_details: Donnez le plus d'explication possible aux usagers sur la raison de la fermeture de la démarche
closing_details_placeholder: "Cette démarche a été remplacée par la page…\n\nLe guide de la nouvelle démarche est disponible ici\n\nPour toute information complémentaire, contactez…\n\nCordialement,"
path: Lien public
organisation: Organisme
duree_conservation_dossiers_dans_ds: Durée de conservation des dossiers sur demarches-simplifiees.fr (choisi par un usager)
@ -27,6 +29,12 @@ fr:
lien_site_web: Où les usagers trouveront-ils le lien vers la démarche ?
old_procedure: Numéro de la démarche remplacée
new_procedure: Numéro de la nouvelle démarche
replaced_by_procedure_id: Nouvelle démarche
closing_details: Message d'information remplaçant la démarche
closing_reason: Raison de la clôture
closing_reasons:
other: Autre
internal_procedure: Je remplace ma démarche par une autre dans Démarches simplifiées
procedure_path: Lien de la démarche à diffuser aux usagers
procedure_path_placeholder: nom-de-la-demarche
cadre_juridique: Lien vers le texte

View file

@ -3,7 +3,8 @@ en:
procedures:
close:
page_title: Close the procedure
replacement_procedure_title: Is this procedure replaced by an existing one? If yes, please indicate the number of the new procedure
replacement_procedure_callout_title: You are about to close a procedure
replacement_procedure_callout_content: Files « in construction » or « instructing » can be instructed, but no new files can be filed.
actions:
close_procedure: Close the procedure
preview_unavailable: Preview is unavailable due to procedure misconfiguration

View file

@ -3,7 +3,8 @@ fr:
procedures:
close:
page_title: Clore la démarche
replacement_procedure_title: Cette démarche est-elle remplacée par une existante ? Si oui, veuillez indiquer le n° de la nouvelle démarche
replacement_procedure_callout_title: Vous êtes sur le point de clore une démarche
replacement_procedure_callout_content: Les dossiers en cours pourront être instruits, mais aucun nouveau dossier ne pourra plus être déposé.
actions:
close_procedure: Clore la démarche
preview_unavailable: Aperçu non disponible car la démarche est mal configurée

View file

@ -690,7 +690,7 @@ describe Administrateurs::ProceduresController, type: :controller do
context 'when the admin is an owner of the procedure without procedure replacement' do
before do
put :archive, params: { procedure_id: procedure.id }
put :archive, params: { procedure_id: procedure.id, procedure: { closing_reason: 'other' } }
procedure.reload
end
@ -702,13 +702,23 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'does not have any replacement procedure' do
expect(procedure.replaced_by_procedure).to be_nil
expect(procedure.closing_reason).to eq('other')
end
context 'the admin can notify users if there are file in brouillon or en_cours' do
let!(:procedure) { create(:procedure_with_dossiers, :published, dossiers_count: 2, administrateur: admin, lien_site_web: lien_site_web) }
it 'archives the procedure and redirects to page to notify users' do
expect(procedure.close?).to be_truthy
expect(response).to redirect_to :admin_procedure_closing_notification
end
end
end
context 'when the admin is an owner of the procedure with procedure replacement' do
context 'when the admin is an owner of the procedure with procedure replacement in DS' do
let(:procedure) { create(:procedure_with_dossiers, :published, administrateur: admin, lien_site_web: lien_site_web) }
let(:new_procedure) { create(:procedure, :published, administrateur: admin, lien_site_web: lien_site_web) }
before do
put :archive, params: { procedure_id: procedure.id, new_procedure: new_procedure }
put :archive, params: { procedure_id: procedure.id, procedure: { closing_reason: 'internal_procedure', replaced_by_procedure_id: new_procedure.id } }
procedure.reload
end
@ -720,6 +730,27 @@ describe Administrateurs::ProceduresController, type: :controller do
it 'does have a replacement procedure' do
expect(procedure.replaced_by_procedure).to eq(new_procedure)
expect(procedure.closing_reason).to eq('internal_procedure')
end
end
context 'when the admin is an owner of the procedure with procedure replacement outside DS' do
let(:new_procedure) { create(:procedure, :published, administrateur: admin, lien_site_web: lien_site_web) }
before do
put :archive, params: { procedure_id: procedure.id, procedure: { closing_reason: 'other', closing_details: "Sorry it's closed" } }
procedure.reload
end
it 'archives the procedure' do
expect(procedure.close?).to be_truthy
expect(response).to redirect_to :admin_procedures
expect(flash[:notice]).to have_content 'Démarche close'
end
it 'does have a replacement procedure' do
expect(procedure.replaced_by_procedure).to eq(nil)
expect(procedure.replaced_by_external_url).to eq('new_url.com')
expect(procedure.closing_reason).to eq('external_procedure')
end
end
@ -730,7 +761,7 @@ describe Administrateurs::ProceduresController, type: :controller do
sign_out(admin.user)
sign_in(admin_2.user)
put :archive, params: { procedure_id: procedure.id }
put :archive, params: { procedure_id: procedure.id, procedure: { closing_reason: 'other' } }
procedure.reload
end