diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index 9be16c708..6d8a3cd9e 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -217,6 +217,15 @@ class Admin::ProceduresController < AdminController render json: json_path_list end + def delete_deliberation + procedure = Procedure.find(params[:id]) + + procedure.deliberation.purge_later + + flash.notice = 'la délibération a bien été supprimée' + redirect_to edit_admin_procedure_path(procedure) + end + private def cloned_from_library? @@ -224,7 +233,7 @@ class Admin::ProceduresController < AdminController end def procedure_params - editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on] + editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on] if @procedure&.locked? params.require(:procedure).permit(*editable_params) else diff --git a/app/controllers/manager/dossiers_controller.rb b/app/controllers/manager/dossiers_controller.rb new file mode 100644 index 000000000..d42d335ce --- /dev/null +++ b/app/controllers/manager/dossiers_controller.rb @@ -0,0 +1,4 @@ +module Manager + class DossiersController < Manager::ApplicationController + end +end diff --git a/app/controllers/manager/gestionnaires_controller.rb b/app/controllers/manager/gestionnaires_controller.rb new file mode 100644 index 000000000..859bf2749 --- /dev/null +++ b/app/controllers/manager/gestionnaires_controller.rb @@ -0,0 +1,4 @@ +module Manager + class GestionnairesController < Manager::ApplicationController + end +end diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb new file mode 100644 index 000000000..4cde73804 --- /dev/null +++ b/app/controllers/manager/users_controller.rb @@ -0,0 +1,4 @@ +module Manager + class UsersController < Manager::ApplicationController + end +end diff --git a/app/controllers/new_user/dossiers_controller.rb b/app/controllers/new_user/dossiers_controller.rb index f710fe14f..fcca742c6 100644 --- a/app/controllers/new_user/dossiers_controller.rb +++ b/app/controllers/new_user/dossiers_controller.rb @@ -73,7 +73,7 @@ module NewUser @dossier.en_construction! NotificationMailer.send_initiated_notification(@dossier).deliver_later redirect_to merci_dossier_path(@dossier) - elsif owns_dossier? + elsif current_user.owns?(dossier) redirect_to users_dossier_recapitulatif_path(@dossier) else redirect_to users_dossiers_invite_path(@dossier.invite_for_user(current_user)) @@ -142,19 +142,19 @@ module NewUser end def ensure_ownership! - if !owns_dossier? + if !current_user.owns?(dossier) forbidden! end end def ensure_ownership_or_invitation! - if !dossier.owner_or_invite?(current_user) + if !current_user.owns_or_invite?(dossier) forbidden! end end def forbid_invite_submission! - if passage_en_construction? && !owns_dossier? + if passage_en_construction? && !current_user.owns?(dossier) forbidden! end end @@ -172,10 +172,6 @@ module NewUser params.require(:dossier).permit(:autorisation_donnees) end - def owns_dossier? - dossier.user_id == current_user.id - end - def passage_en_construction? dossier.brouillon? && !draft? end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 26b3f1d44..b3ba3b69b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -10,7 +10,7 @@ class UsersController < ApplicationController dossier = Dossier.find(dossier_id) - if !dossier.owner_or_invite?(current_user) + if !current_user.owns_or_invite?(dossier) raise ActiveRecord::RecordNotFound end diff --git a/app/dashboards/dossier_dashboard.rb b/app/dashboards/dossier_dashboard.rb new file mode 100644 index 000000000..734b4fe25 --- /dev/null +++ b/app/dashboards/dossier_dashboard.rb @@ -0,0 +1,54 @@ +require "administrate/base_dashboard" + +class DossierDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + procedure: Field::HasOne, + state: Field::String, + text_summary: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + types_de_champ: TypesDeChampCollectionField, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :id, + :procedure, + :created_at, + :state + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :text_summary, + :state, + :procedure, + :types_de_champ, + :created_at, + :updated_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [].freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + # def display_resource(user) + # "User ##{user.id}" + # end +end diff --git a/app/dashboards/gestionnaire_dashboard.rb b/app/dashboards/gestionnaire_dashboard.rb new file mode 100644 index 000000000..db1d6727b --- /dev/null +++ b/app/dashboards/gestionnaire_dashboard.rb @@ -0,0 +1,50 @@ +require "administrate/base_dashboard" + +class GestionnaireDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + email: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + current_sign_in_at: Field::DateTime, + dossiers: Field::HasMany, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :email, + :created_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :dossiers, + :id, + :email, + :current_sign_in_at, + :created_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [].freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + def display_resource(gestionnaire) + gestionnaire.email + end +end diff --git a/app/dashboards/procedure_dashboard.rb b/app/dashboards/procedure_dashboard.rb index dc7c3681d..af16cfc04 100644 --- a/app/dashboards/procedure_dashboard.rb +++ b/app/dashboards/procedure_dashboard.rb @@ -74,7 +74,7 @@ class ProcedureDashboard < Administrate::BaseDashboard # Overwrite this method to customize how procedures are displayed # across all pages of the admin dashboard. # - # def display_resource(procedure) - # "Procedure ##{procedure.id}" - # end + def display_resource(procedure) + "#{procedure.libelle} ##{procedure.id}" + end end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb new file mode 100644 index 000000000..19fcb2e54 --- /dev/null +++ b/app/dashboards/user_dashboard.rb @@ -0,0 +1,50 @@ +require "administrate/base_dashboard" + +class UserDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + email: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + current_sign_in_at: Field::DateTime, + dossiers: Field::HasMany, + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = [ + :email, + :created_at, + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = [ + :dossiers, + :id, + :email, + :current_sign_in_at, + :created_at, + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = [].freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + def display_resource(user) + user.email + end +end diff --git a/app/helpers/dossier_helper.rb b/app/helpers/dossier_helper.rb index 7cddd4bac..bb90efa41 100644 --- a/app/helpers/dossier_helper.rb +++ b/app/helpers/dossier_helper.rb @@ -16,10 +16,12 @@ module DossierHelper end def delete_dossier_confirm(dossier) - message = "Vous vous apprêtez à supprimer votre dossier ainsi que les informations qu’il contient. " + message = ["Vous vous apprêtez à supprimer votre dossier ainsi que les informations qu’il contient."] if dossier.en_construction_ou_instruction? - message += "Nous vous rappelons que toute suppression entraine l’annulation de la démarche en cours. " + message << "Nous vous rappelons que toute suppression entraine l’annulation de la démarche en cours." end - message += "Confirmer la suppression ?" + message << "Confirmer la suppression ?" + + message.join(" ") end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index ef2351dd4..3747e8f84 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -163,10 +163,6 @@ class Dossier < ApplicationRecord en_instruction? || accepte? || refuse? || sans_suite? end - def owner_or_invite?(user) - self.user == user || invite_for_user(user).present? - end - def invite_for_user(user) invites_user.find_by(user_id: user.id) end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index fb88eed0f..32c90e489 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -24,6 +24,7 @@ class Procedure < ApplicationRecord has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy has_one_attached :notice + has_one_attached :deliberation delegate :use_api_carto, to: :module_api_carto @@ -45,6 +46,7 @@ class Procedure < ApplicationRecord validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false + validate :check_juridique include AASM @@ -198,15 +200,7 @@ class Procedure < ApplicationRecord procedure.logo_secure_token = nil procedure.remote_logo_url = self.logo_url - if notice.attached? - response = Typhoeus.get(notice.service_url, timeout: 5) - if response.success? - procedure.notice.attach( - io: StringIO.new(response.body), - filename: notice.filename - ) - end - end + %i(notice deliberation).each { |attachment| clone_attachment(procedure, attachment) } procedure.administrateur = admin procedure.initiated_mail = initiated_mail&.dup @@ -349,6 +343,25 @@ class Procedure < ApplicationRecord private + def clone_attachment(cloned_procedure, attachment_symbol) + attachment = send(attachment_symbol) + if attachment.attached? + response = Typhoeus.get(attachment.service_url, timeout: 5) + if response.success? + cloned_procedure.send(attachment_symbol).attach( + io: StringIO.new(response.body), + filename: attachment.filename + ) + end + end + end + + def check_juridique + if cadre_juridique.blank? && !deliberation.attached? + errors.add(:cadre_juridique, " : veuillez remplir le texte de loi ou la délibération") + end + end + def field_hash(label, table, column) { 'label' => label, diff --git a/app/models/user.rb b/app/models/user.rb index 2de403c64..7ecbac5ff 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -38,7 +38,15 @@ class User < ApplicationRecord loged_in_with_france_connect.present? end + def owns?(dossier) + dossier.user_id == id + end + def invite?(dossier_id) invites.pluck(:dossier_id).include?(dossier_id.to_i) end + + def owns_or_invite?(dossier) + owns?(dossier) || invite?(dossier.id) + end end diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index eeadb6cb3..9187a4540 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -21,6 +21,27 @@ Un lien de rappel HTTP (aussi appelé webhook) est utilisé pour notifier un service tiers du changement de l'état d’un dossier sur demarches-simplifiees.fr. À chaque changement d’état d'un dossier, notre site va effectuer une requête sur le lien renseigné avec en paramètres : le nouvel état du dossier, l’identifiant de la procédure, l'identifiant dossier et la date du changement. Vous pourrez alors utiliser notre API pour récupérer les nouvelles informations du dossier concerné. = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/' +.form-group + %h4 Cadre juridique * + %p Indiquez la référence ou l'URL du texte juridique ou chargez la délibération qui justifie cette procédure + = f.label :cadre_juridique, 'Référence ou texte de loi' + = f.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/' + + = f.label :deliberation, 'Délibération' + - deliberation = @procedure.deliberation + - if !deliberation.attached? + = f.file_field :deliberation, + direct_upload: true + - else + %a{ href: url_for(deliberation), target: '_blank' } + = deliberation.filename.to_s + = link_to 'supprimer', delete_deliberation_admin_procedure_path(@procedure), + method: :delete + %br + Modifier : + = f.file_field :deliberation, + direct_upload: true + .form-group %h4 Notice explicative de la procédure - notice = @procedure.notice diff --git a/app/views/dossiers/_edit_carto.html.haml b/app/views/dossiers/_edit_carto.html.haml index 85567d5b2..d0f57a8a9 100644 --- a/app/views/dossiers/_edit_carto.html.haml +++ b/app/views/dossiers/_edit_carto.html.haml @@ -1,5 +1,5 @@ - if !@facade.dossier.read_only? - - if user_signed_in? && (@facade.dossier.owner_or_invite?(current_user)) + - if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier)) %a#maj_carte.action{ href: "/users/dossiers/#{@facade.dossier.id}/carte" } .col-lg-2.col-md-2.col-sm-2.col-xs-2.action = 'ÉDITER' diff --git a/app/views/dossiers/_edit_dossier.html.haml b/app/views/dossiers/_edit_dossier.html.haml index 14e3800cd..ecbed3cca 100644 --- a/app/views/dossiers/_edit_dossier.html.haml +++ b/app/views/dossiers/_edit_dossier.html.haml @@ -1,5 +1,5 @@ - if !@facade.dossier.read_only? - - if user_signed_in? && (@facade.dossier.owner_or_invite?(current_user)) + - if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier)) = link_to modifier_dossier_path(@facade.dossier), class: 'action', id: 'maj_infos' do #edit-dossier.col-lg-2.col-md-2.col-sm-2.col-xs-2.action = "ÉDITER" diff --git a/app/views/dossiers/_edit_pieces_jointes.html.haml b/app/views/dossiers/_edit_pieces_jointes.html.haml index 41dac0f2a..497f941a4 100644 --- a/app/views/dossiers/_edit_pieces_jointes.html.haml +++ b/app/views/dossiers/_edit_pieces_jointes.html.haml @@ -1,5 +1,5 @@ - if !@facade.dossier.read_only? - - if user_signed_in? && (@facade.dossier.owner_or_invite?(current_user)) + - if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier)) - if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0 .col-lg-4.col-md-4.col-sm-4.col-xs-4.action %a#maj_pj.action{ "data-target" => "#upload-pj-modal", diff --git a/app/views/dossiers/_infos_dossier.html.haml b/app/views/dossiers/_infos_dossier.html.haml index 0677e67e3..a14e46c4b 100644 --- a/app/views/dossiers/_infos_dossier.html.haml +++ b/app/views/dossiers/_infos_dossier.html.haml @@ -101,7 +101,7 @@ Pièce non fournie - if !@facade.dossier.read_only? - - if user_signed_in? && (@facade.dossier.owner_or_invite?(current_user)) + - if user_signed_in? && (current_user.owns_or_invite?(@facade.dossier)) - if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0 .row .col-xs-4 diff --git a/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml index 1e5a3a253..6c3499cd4 100644 --- a/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_users_recapitulatifcontroller_show.html.haml @@ -14,7 +14,7 @@ .dossier-state= @facade.dossier.display_state .split-hr-left - - if @facade.dossier.user == current_user + - if current_user.owns?(@facade.dossier) .text-center.mt-1 = link_to ask_deletion_dossier_path(@facade.dossier), method: :post, class: "btn btn-danger", data: { confirm: delete_dossier_confirm(@facade.dossier) } do Supprimer définitivement diff --git a/app/views/manager/application/_navigation.html.erb b/app/views/manager/application/_navigation.html.erb index 20b3b7aa9..60c28e051 100644 --- a/app/views/manager/application/_navigation.html.erb +++ b/app/views/manager/application/_navigation.html.erb @@ -12,7 +12,8 @@ as defined by the routes in the `admin/` namespace