diff --git a/app/components/types_de_champ_editor/champ_component.rb b/app/components/types_de_champ_editor/champ_component.rb index 87fcd2fdf..3b8eca491 100644 --- a/app/components/types_de_champ_editor/champ_component.rb +++ b/app/components/types_de_champ_editor/champ_component.rb @@ -82,6 +82,14 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent } end + def notice_explicative_options + { + attached_file: type_de_champ.notice_explicative, + auto_attach_url: helpers.auto_attach_url(type_de_champ), + view_as: :download + } + end + EXCLUDE_FROM_BLOCK = [ TypeDeChamp.type_champs.fetch(:carte), TypeDeChamp.type_champs.fetch(:dossier_link), diff --git a/app/components/types_de_champ_editor/champ_component/champ_component.html.haml b/app/components/types_de_champ_editor/champ_component/champ_component.html.haml index 187234bcc..de9480aae 100644 --- a/app/components/types_de_champ_editor/champ_component/champ_component.html.haml +++ b/app/components/types_de_champ_editor/champ_component/champ_component.html.haml @@ -97,6 +97,11 @@ %p Dans le cadre de la RGPD, le titre d’identité sera supprimé lors de l’acceptation du dossier - elsif procedure.piece_justificative_multiple? %p Les usagers pourront envoyer plusieurs fichiers si nécessaire. + - if type_de_champ.explication? + .cell + = form.label :notice_explicative, "Notice explicative", for: dom_id(type_de_champ, :notice_explicative) + = render Attachment::EditComponent.new(**notice_explicative_options) + - if type_de_champ.carte? - type_de_champ.editable_options.each do |slice| .cell diff --git a/app/controllers/administrateurs/types_de_champ_controller.rb b/app/controllers/administrateurs/types_de_champ_controller.rb index 73d41b37f..88aa11a95 100644 --- a/app/controllers/administrateurs/types_de_champ_controller.rb +++ b/app/controllers/administrateurs/types_de_champ_controller.rb @@ -44,6 +44,19 @@ module Administrateurs end end + def notice_explicative + type_de_champ = draft.find_and_ensure_exclusive_use(params[:stable_id]) + byebug + if type_de_champ.notice_explicative.attach(params[:blob_signed_id]) + @coordinate = draft.coordinate_for(type_de_champ) + @morphed = [champ_component_from(@coordinate)] + + render :create + else + render json: { errors: @champ.errors.full_messages }, status: 422 + end + end + def move draft.move_type_de_champ(params[:stable_id], params[:position].to_i) end diff --git a/app/helpers/champ_helper.rb b/app/helpers/champ_helper.rb index 2e7971a85..61c988788 100644 --- a/app/helpers/champ_helper.rb +++ b/app/helpers/champ_helper.rb @@ -10,8 +10,10 @@ module ChampHelper def auto_attach_url(object, params = {}) if object.is_a?(Champ) champs_attach_piece_justificative_url(object.id, params) - elsif object.is_a?(TypeDeChamp) + elsif object.is_a?(TypeDeChamp) && object.piece_justificative? piece_justificative_template_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id: object.procedure.id, **params) + elsif object.is_a?(TypeDeChamp) && object.explication? + notice_explicative_admin_procedure_type_de_champ_url(stable_id: object.stable_id, procedure_id: object.procedure.id, **params) end end end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index a29369b95..602b33d17 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -193,6 +193,21 @@ class TypeDeChamp < ApplicationRecord validates :piece_justificative_template, size: { less_than: FILE_MAX_SIZE } validates :piece_justificative_template, content_type: AUTHORIZED_CONTENT_TYPES + has_one_attached :notice_explicative + validates :notice_explicative, content_type: [ + "application/msword", + "application/pdf", + "application/vnd.ms-powerpoint", + "application/vnd.oasis.opendocument.presentation", + "application/vnd.oasis.opendocument.text", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "image/jpeg", + "image/jpg", + "image/png", + "text/plain" + ], size: { less_than: 20.megabytes } + validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false validates :character_limit, numericality: { diff --git a/config/routes.rb b/config/routes.rb index aaa75f6ac..245ad19f4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -625,6 +625,7 @@ Rails.application.routes.draw do patch :move_up patch :move_down put :piece_justificative_template + put :notice_explicative end end diff --git a/spec/components/types_de_champ_editor/champ_component_spec.rb b/spec/components/types_de_champ_editor/champ_component_spec.rb index 40d1250ac..2ec4a9342 100644 --- a/spec/components/types_de_champ_editor/champ_component_spec.rb +++ b/spec/components/types_de_champ_editor/champ_component_spec.rb @@ -50,5 +50,14 @@ describe TypesDeChampEditor::ChampComponent, type: :component do end end end + + describe 'tdc explication' do + let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :explication }]) } + let(:coordinate) { procedure.draft_revision.revision_types_de_champ_public.first } + it 'includes an uploader for notice_explicative' do + expect(page).to have_css('label', text: 'Notice explicative') + expect(page).to have_css('input[type=file]') + end + end end end diff --git a/spec/controllers/administrateurs/types_de_champ_controller_spec.rb b/spec/controllers/administrateurs/types_de_champ_controller_spec.rb index 4b26f71bb..8c2db31a2 100644 --- a/spec/controllers/administrateurs/types_de_champ_controller_spec.rb +++ b/spec/controllers/administrateurs/types_de_champ_controller_spec.rb @@ -188,4 +188,20 @@ describe Administrateurs::TypesDeChampController, type: :controller do end end end + + describe '#notice_explicative' do + let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :explication }]) } + let(:coordinate) { procedure.draft_revision.types_de_champ.first } + let(:file) { Tempfile.new } + let(:blob) { ActiveStorage::Blob.create_before_direct_upload!(filename: File.basename(file.path), byte_size: file.size, checksum: Digest::SHA256.file(file.path), content_type: 'text/plain') } + + context 'when sending a valid blob' do + it 'attaches the blob and responds with 200' do + expect { put :notice_explicative, format: :turbo_stream, params: { stable_id: coordinate.stable_id, procedure_id: procedure.id, blob_signed_id: blob.signed_id } } + .to change { coordinate.reload.notice_explicative.attached? } + .from(false).to(true) + expect(response).to have_http_status(:success) + end + end + end end