From a007d6e3eb93c109e49583e7f9714f403cc2cd1c Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Wed, 30 May 2018 18:19:40 +0200 Subject: [PATCH 1/8] Avoid trailing spaces in strings --- app/helpers/dossier_helper.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 From 4e9565a5df30400b67ab8085871627e75ac0211b Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Wed, 30 May 2018 18:26:23 +0200 Subject: [PATCH 2/8] Adds User#owns? --- .../new_user/dossiers_controller.rb | 10 ++---- app/models/user.rb | 4 +++ ...ers_recapitulatifcontroller_show.html.haml | 2 +- app/views/shared/dossiers/_edit.html.haml | 2 +- spec/models/user_spec.rb | 31 +++++++++++++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/app/controllers/new_user/dossiers_controller.rb b/app/controllers/new_user/dossiers_controller.rb index f710fe14f..ebac58847 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,7 +142,7 @@ module NewUser end def ensure_ownership! - if !owns_dossier? + if !current_user.owns?(dossier) forbidden! end end @@ -154,7 +154,7 @@ module NewUser 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/models/user.rb b/app/models/user.rb index 2de403c64..57c049ade 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -38,6 +38,10 @@ 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 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/shared/dossiers/_edit.html.haml b/app/views/shared/dossiers/_edit.html.haml index f9df14445..79de4e7f4 100644 --- a/app/views/shared/dossiers/_edit.html.haml +++ b/app/views/shared/dossiers/_edit.html.haml @@ -58,7 +58,7 @@ class: 'button send', data: { action: 'draft', disable_with: 'Envoi...' } - - if dossier.user == current_user + - if current_user.owns?(dossier) = f.button 'Soumettre le dossier', class: 'button send primary', data: { action: 'submit', disable_with: 'Envoi...' } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 848909a51..a9a2e24fa 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -31,6 +31,37 @@ describe User, type: :model do end end + describe '#owns?' do + let(:owner) { create(:user) } + let(:dossier) { create(:dossier, user: owner) } + let(:invite_user) { create(:user) } + let(:invite_gestionnaire) { create(:user) } + + subject { user.owns?(dossier) } + + context 'when user is owner' do + let(:user) { owner } + + it { is_expected.to be_truthy } + end + + context 'when user was invited by user' do + before do + create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') + end + + let(:user) { invite_user } + + it { is_expected.to be_falsy } + end + + context 'when user is quidam' do + let(:user) { create(:user) } + + it { is_expected.to be_falsey } + end + end + describe '#invite?' do let(:dossier) { create :dossier } let(:user) { dossier.user } From 0329b1db68832c2cce021694e1942d2aaf8c1e92 Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Wed, 30 May 2018 18:31:02 +0200 Subject: [PATCH 3/8] Use User#owns_or_invite? instead of Dossier#owner_or_invite? --- .../new_user/dossiers_controller.rb | 2 +- app/controllers/users_controller.rb | 2 +- app/models/dossier.rb | 4 -- app/models/user.rb | 4 ++ app/views/dossiers/_edit_carto.html.haml | 2 +- app/views/dossiers/_edit_dossier.html.haml | 2 +- .../dossiers/_edit_pieces_jointes.html.haml | 2 +- app/views/dossiers/_infos_dossier.html.haml | 2 +- spec/models/dossier_spec.rb | 38 ----------- spec/models/user_spec.rb | 31 +++++++++ .../recapitulatif/show.html.haml_spec.rb | 65 +++++-------------- 11 files changed, 58 insertions(+), 96 deletions(-) diff --git a/app/controllers/new_user/dossiers_controller.rb b/app/controllers/new_user/dossiers_controller.rb index ebac58847..fcca742c6 100644 --- a/app/controllers/new_user/dossiers_controller.rb +++ b/app/controllers/new_user/dossiers_controller.rb @@ -148,7 +148,7 @@ module NewUser end def ensure_ownership_or_invitation! - if !dossier.owner_or_invite?(current_user) + if !current_user.owns_or_invite?(dossier) forbidden! end 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/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/user.rb b/app/models/user.rb index 57c049ade..7ecbac5ff 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -45,4 +45,8 @@ class User < ApplicationRecord 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/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/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 924aed3a5..dac882796 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -397,44 +397,6 @@ describe Dossier do end end - describe '#owner_or_invite?' do - let(:owner) { create(:user) } - let(:dossier) { create(:dossier, user: owner) } - let(:invite_user) { create(:user) } - let(:invite_gestionnaire) { create(:user) } - - before do - create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') - create(:invite, dossier: dossier, user: invite_gestionnaire, type: 'InviteGestionnaire') - end - - subject { dossier.owner_or_invite?(user) } - - context 'when user is owner' do - let(:user) { owner } - - it { is_expected.to be_truthy } - end - - context 'when user was invited by user' do - let(:user) { invite_user } - - it { is_expected.to be_truthy } - end - - context 'when user was invited by gestionnaire (legacy, no new invitations happen)' do - let(:user) { invite_gestionnaire } - - it { is_expected.to be_falsey } - end - - context 'when user is quidam' do - let(:user) { create(:user) } - - it { is_expected.to be_falsey } - end - end - describe "#text_summary" do let(:procedure) { create(:procedure, libelle: "Procédure", organisation: "Organisme") } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a9a2e24fa..0175811f2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -81,6 +81,37 @@ describe User, type: :model do end end + describe '#owns_or_invite?' do + let(:owner) { create(:user) } + let(:dossier) { create(:dossier, user: owner) } + let(:invite_user) { create(:user) } + let(:invite_gestionnaire) { create(:user) } + + subject { user.owns_or_invite?(dossier) } + + context 'when user is owner' do + let(:user) { owner } + + it { is_expected.to be_truthy } + end + + context 'when user was invited by user' do + before do + create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') + end + + let(:user) { invite_user } + + it { is_expected.to be_truthy } + end + + context 'when user is quidam' do + let(:user) { create(:user) } + + it { is_expected.to be_falsey } + end + end + context 'unified login' do it 'syncs credentials to associated gestionnaire' do user = create(:user) diff --git a/spec/views/users/recapitulatif/show.html.haml_spec.rb b/spec/views/users/recapitulatif/show.html.haml_spec.rb index 0681bd895..67995d93d 100644 --- a/spec/views/users/recapitulatif/show.html.haml_spec.rb +++ b/spec/views/users/recapitulatif/show.html.haml_spec.rb @@ -72,61 +72,30 @@ describe 'users/recapitulatif/show.html.haml', type: :view do end context 'when invite is logged' do - context 'when invite is by Gestionnaire' do - let!(:invite_user) { create(:user, email: 'invite@octo.com') } + let!(:invite_user) { create(:user, email: 'invite@octo.com') } - before do - create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) } - sign_out dossier.user - sign_in invite_user - render - end - - describe 'les liens de modifications' do - it 'describe link is not present' do - expect(rendered).not_to have_css('#maj_infos') - end - - it 'map link is not present' do - expect(rendered).not_to have_css('#maj_carte') - end - - it 'PJ link is not present' do - expect(rendered).not_to have_css('#maj_pj') - end - - it 'archive link is not present' do - expect(rendered).not_to have_content('Archiver') - end - end + before do + create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') } + sign_out dossier.user + sign_in invite_user + render end - context 'invite is by User' do - let!(:invite_user) { create(:user, email: 'invite@octo.com') } - - before do - create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') } - sign_out dossier.user - sign_in invite_user - render + describe 'les liens de modifications' do + it 'describe link is not present' do + expect(rendered).to have_css('#maj_infos') end - describe 'les liens de modifications' do - it 'describe link is not present' do - expect(rendered).to have_css('#maj_infos') - end + it 'map link is present' do + expect(rendered).to have_css('#maj_carte') + end - it 'map link is present' do - expect(rendered).to have_css('#maj_carte') - end + it 'PJ link is present' do + expect(rendered).to have_css('#maj_pj') + end - it 'PJ link is present' do - expect(rendered).to have_css('#maj_pj') - end - - it 'archive link is present' do - expect(rendered).not_to have_content('Archiver') - end + it 'archive link is present' do + expect(rendered).not_to have_content('Archiver') end end end From e2a126e37a608e85c38dc301af4b5ad33623fb00 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 31 May 2018 15:18:06 +0200 Subject: [PATCH 4/8] Add users and gestionnaires to manager --- .../manager/dossiers_controller.rb | 4 ++ .../manager/gestionnaires_controller.rb | 4 ++ app/controllers/manager/users_controller.rb | 4 ++ app/dashboards/dossier_dashboard.rb | 54 +++++++++++++++++++ app/dashboards/gestionnaire_dashboard.rb | 50 +++++++++++++++++ app/dashboards/procedure_dashboard.rb | 6 +-- app/dashboards/user_dashboard.rb | 50 +++++++++++++++++ .../manager/application/_navigation.html.erb | 3 +- config/routes.rb | 4 ++ 9 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 app/controllers/manager/dossiers_controller.rb create mode 100644 app/controllers/manager/gestionnaires_controller.rb create mode 100644 app/controllers/manager/users_controller.rb create mode 100644 app/dashboards/dossier_dashboard.rb create mode 100644 app/dashboards/gestionnaire_dashboard.rb create mode 100644 app/dashboards/user_dashboard.rb 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/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/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
- <% Administrate::Namespace.new(namespace).resources.each do |resource| %> + <% Administrate::Namespace.new(namespace).resources.reject { |resource| resource.resource == 'dossiers'}.each do |resource| %> + <%= link_to( display_resource_name(resource), [namespace, resource.path], diff --git a/config/routes.rb b/config/routes.rb index 106e1002d..be7433006 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,10 @@ Rails.application.routes.draw do put 'enable_feature', on: :member end + resources :users, only: [:index, :show] + resources :gestionnaires, only: [:index, :show] + resources :dossiers, only: [:show] + resources :demandes, only: [:index] post 'demandes/create_administrateur' post 'demandes/refuse_administrateur' From a96889310ba82530ea2b14ada1913fc787eed1f7 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Wed, 2 May 2018 15:41:43 +0200 Subject: [PATCH 5/8] Procedure: add legal reference --- app/controllers/admin/procedures_controller.rb | 2 +- app/models/procedure.rb | 1 + app/views/admin/procedures/_informations.html.haml | 4 ++++ config/locales/models/procedure/fr.yml | 14 ++++++++++++++ ...80502104006_add_cadre_juridique_to_procedure.rb | 5 +++++ db/schema.rb | 1 + .../admin/procedures_controller_spec.rb | 2 ++ spec/factories/procedure.rb | 1 + spec/features/admin/procedure_cloning_spec.rb | 1 + spec/features/admin/procedure_creation_spec.rb | 4 +++- 10 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20180502104006_add_cadre_juridique_to_procedure.rb diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index 9be16c708..10949c077 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -224,7 +224,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, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on] if @procedure&.locked? params.require(:procedure).permit(*editable_params) else diff --git a/app/models/procedure.rb b/app/models/procedure.rb index fb88eed0f..176076bcd 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -45,6 +45,7 @@ class Procedure < ApplicationRecord validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false + validates :cadre_juridique, presence: true, allow_blank: false, allow_nil: false include AASM diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index eeadb6cb3..0b5bdbd2f 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -21,6 +21,10 @@ 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 : indiquez la référence ou l'URL du texte juridique ou chargez la délibération qui justifie cette procédure * + = f.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/' + .form-group %h4 Notice explicative de la procédure - notice = @procedure.notice diff --git a/config/locales/models/procedure/fr.yml b/config/locales/models/procedure/fr.yml index 1066ffc86..ef28b30a9 100644 --- a/config/locales/models/procedure/fr.yml +++ b/config/locales/models/procedure/fr.yml @@ -3,3 +3,17 @@ fr: attributes: procedure: organisation: Organisme + errors: + models: + procedure: + attributes: + libelle: + blank: Attribut manquant + description: + blank: Attribut manquant + lien_demarche: + blank: Attribut manquant + organisation: + blank: Attribut manquant + 'cadre_juridique': + blank: Attribut manquant diff --git a/db/migrate/20180502104006_add_cadre_juridique_to_procedure.rb b/db/migrate/20180502104006_add_cadre_juridique_to_procedure.rb new file mode 100644 index 000000000..91cd50287 --- /dev/null +++ b/db/migrate/20180502104006_add_cadre_juridique_to_procedure.rb @@ -0,0 +1,5 @@ +class AddCadreJuridiqueToProcedure < ActiveRecord::Migration[5.2] + def change + add_column :procedures, :cadre_juridique, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 69ee7bffb..92e8ce361 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -481,6 +481,7 @@ ActiveRecord::Schema.define(version: 2018_05_30_095508) do t.bigint "service_id" t.integer "duree_conservation_dossiers_dans_ds" t.integer "duree_conservation_dossiers_hors_ds" + t.string "cadre_juridique" t.index ["hidden_at"], name: "index_procedures_on_hidden_at" t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id" t.index ["service_id"], name: "index_procedures_on_service_id" diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index cd6947cee..db8026e2d 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -15,6 +15,7 @@ describe Admin::ProceduresController, type: :controller do let(:quartiers_prioritaires) { '0' } let(:cadastre) { '0' } let(:cerfa_flag) { true } + let(:cadre_juridique) { 'cadre juridique' } let(:procedure_params) { { @@ -24,6 +25,7 @@ describe Admin::ProceduresController, type: :controller do direction: direction, lien_demarche: lien_demarche, cerfa_flag: cerfa_flag, + cadre_juridique: cadre_juridique, module_api_carto_attributes: { use_api_carto: use_api_carto, quartiers_prioritaires: quartiers_prioritaires, diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 233d655a0..39f77d9d7 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -6,6 +6,7 @@ FactoryBot.define do description "Demande de subvention à l'intention des associations" organisation "Orga DINSIC" direction "direction DINSIC" + cadre_juridique "un cadre juridique important" published_at nil cerfa_flag false administrateur { create(:administrateur) } diff --git a/spec/features/admin/procedure_cloning_spec.rb b/spec/features/admin/procedure_cloning_spec.rb index 6cb94edf7..bfa32d8c1 100644 --- a/spec/features/admin/procedure_cloning_spec.rb +++ b/spec/features/admin/procedure_cloning_spec.rb @@ -14,6 +14,7 @@ feature 'As an administrateur I wanna clone a procedure', js: true do page.find_by_id('from-scratch').click fill_in 'procedure_libelle', with: 'libelle de la procedure' page.execute_script("$('#procedure_description').val('description de la procedure')") + fill_in 'procedure_cadre_juridique', with: 'cadre juridique' page.find_by_id('save-procedure').click end diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 9523f3681..9528b1cd0 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -32,13 +32,14 @@ feature 'As an administrateur I wanna create a new procedure', js: true do expect(page).to have_current_path(new_admin_procedure_path) end - scenario 'Finding save button for new procedure, libelle and description required' do + scenario 'Finding save button for new procedure, libelle, description and cadre_juridique required' do page.find_by_id('new-procedure').click page.find_by_id('from-scratch').click page.find_by_id('save-procedure').click page.find_by_id('flash_message').visible? fill_in 'procedure_libelle', with: 'libelle de la procedure' page.execute_script("$('#procedure_description').val('description de la procedure')") + fill_in 'procedure_cadre_juridique', with: 'cadre juridique' page.find_by_id('save-procedure').click expect(page).to have_current_path(admin_procedure_types_de_champ_path(Procedure.first.id.to_s)) end @@ -50,6 +51,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do page.find_by_id('from-scratch').click fill_in 'procedure_libelle', with: 'libelle de la procedure' page.execute_script("$('#procedure_description').val('description de la procedure')") + fill_in 'procedure_cadre_juridique', with: 'cadre juridique' page.find_by_id('save-procedure').click procedure = Procedure.last From fa14db1cbffcb7c8946b4b478ec4c446cd75bf1a Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Thu, 31 May 2018 10:59:38 +0200 Subject: [PATCH 6/8] Procedure: add deliberation --- .../admin/procedures_controller.rb | 2 +- app/models/procedure.rb | 9 ++++++++- .../admin/procedures/_informations.html.haml | 17 +++++++++++++++- spec/models/procedure_spec.rb | 20 +++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index 10949c077..bd1c3c38d 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -224,7 +224,7 @@ class Admin::ProceduresController < AdminController end def procedure_params - editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :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/models/procedure.rb b/app/models/procedure.rb index 176076bcd..dc9d15065 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,7 +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 - validates :cadre_juridique, presence: true, allow_blank: false, allow_nil: false + validate :check_juridique include AASM @@ -350,6 +351,12 @@ class Procedure < ApplicationRecord private + 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/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index 0b5bdbd2f..9270d749f 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -22,9 +22,24 @@ = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/' .form-group - %h4 Cadre juridique : indiquez la référence ou l'URL du texte juridique ou chargez la délibération qui justifie cette procédure * + %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 + %br + Modifier : + = f.file_field :deliberation, + direct_upload: true + .form-group %h4 Notice explicative de la procédure - notice = @procedure.notice diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 15efdf5e2..ac091cb6d 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -173,6 +173,26 @@ describe Procedure do context 'organisation' do it { is_expected.to allow_value('URRSAF').for(:organisation) } end + + context 'juridique' do + it { is_expected.not_to allow_value(nil).for(:cadre_juridique) } + it { is_expected.to allow_value('text').for(:cadre_juridique) } + + context 'with deliberation' do + let(:procedure) { build(:procedure, cadre_juridique: nil) } + + it { expect(procedure.valid?).to eq(false) } + + context 'when the deliberation is uploaded ' do + before do + allow(procedure).to receive(:deliberation) + .and_return(double('attached?': true)) + end + + it { expect(procedure.valid?).to eq(true) } + end + end + end end describe '#types_de_champ_ordered' do From 0e690c90ccb977e0d445ec60a35d1b7dce1db556 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Thu, 31 May 2018 11:00:22 +0200 Subject: [PATCH 7/8] Procedure: clone the deliberation --- app/models/procedure.rb | 23 +++++++++++-------- .../admin/procedures_controller_spec.rb | 3 ++- spec/factories/procedure.rb | 9 ++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/app/models/procedure.rb b/app/models/procedure.rb index dc9d15065..32c90e489 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -200,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 @@ -351,6 +343,19 @@ 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") diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index db8026e2d..9c790afdd 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -473,7 +473,7 @@ describe Admin::ProceduresController, type: :controller do end describe 'PUT #clone' do - let!(:procedure) { create(:procedure, :with_notice, administrateur: admin) } + let!(:procedure) { create(:procedure, :with_notice, :with_deliberation, administrateur: admin) } let(:params) { { procedure_id: procedure.id } } subject { put :clone, params: params } @@ -491,6 +491,7 @@ describe Admin::ProceduresController, type: :controller do expect(response).to redirect_to edit_admin_procedure_path(id: Procedure.last.id) expect(Procedure.last.cloned_from_library).to be_falsey expect(Procedure.last.notice.attached?).to be_truthy + expect(Procedure.last.deliberation.attached?).to be_truthy expect(flash[:notice]).to have_content 'Procédure clonée' end diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 39f77d9d7..2ef30a635 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -135,6 +135,15 @@ FactoryBot.define do end end + trait :with_deliberation do + after(:create) do |procedure, _evaluator| + procedure.deliberation.attach( + io: StringIO.new('Hello World'), + filename: 'hello.txt' + ) + end + end + trait :with_all_champs_mandatory do after(:build) do |procedure, _evaluator| tdcs = [] From 18ad227df5b4f80ee853a32d1d956dba30b90c46 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Thu, 31 May 2018 11:15:44 +0200 Subject: [PATCH 8/8] [fix #1897] Procedure: can delete a deliberation --- app/controllers/admin/procedures_controller.rb | 9 +++++++++ app/views/admin/procedures/_informations.html.haml | 2 ++ config/routes.rb | 1 + spec/controllers/admin/procedures_controller_spec.rb | 12 ++++++++++++ 4 files changed, 24 insertions(+) diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index bd1c3c38d..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? diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index 9270d749f..9187a4540 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -35,6 +35,8 @@ - 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, diff --git a/config/routes.rb b/config/routes.rb index be7433006..a6816f131 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -147,6 +147,7 @@ Rails.application.routes.draw do member do post :hide + delete :delete_deliberation end resources :types_de_champ, only: [:destroy] diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index 9c790afdd..900f5eaf2 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -637,4 +637,16 @@ describe Admin::ProceduresController, type: :controller do end end end + + describe "DELETE #delete_deliberation" do + let(:procedure) { create(:procedure, :with_deliberation) } + + before do + delete :delete_deliberation, params: { id: procedure.id } + procedure.reload + end + + it { expect(procedure.deliberation.attached?).to eq(false) } + it { expect(response).to redirect_to(edit_admin_procedure_path(procedure)) } + end end