Merge branch 'dev'
This commit is contained in:
commit
d28d467aea
34 changed files with 402 additions and 124 deletions
|
@ -217,6 +217,15 @@ class Admin::ProceduresController < AdminController
|
||||||
render json: json_path_list
|
render json: json_path_list
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def cloned_from_library?
|
def cloned_from_library?
|
||||||
|
@ -224,7 +233,7 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_params
|
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?
|
if @procedure&.locked?
|
||||||
params.require(:procedure).permit(*editable_params)
|
params.require(:procedure).permit(*editable_params)
|
||||||
else
|
else
|
||||||
|
|
4
app/controllers/manager/dossiers_controller.rb
Normal file
4
app/controllers/manager/dossiers_controller.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module Manager
|
||||||
|
class DossiersController < Manager::ApplicationController
|
||||||
|
end
|
||||||
|
end
|
4
app/controllers/manager/gestionnaires_controller.rb
Normal file
4
app/controllers/manager/gestionnaires_controller.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module Manager
|
||||||
|
class GestionnairesController < Manager::ApplicationController
|
||||||
|
end
|
||||||
|
end
|
4
app/controllers/manager/users_controller.rb
Normal file
4
app/controllers/manager/users_controller.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module Manager
|
||||||
|
class UsersController < Manager::ApplicationController
|
||||||
|
end
|
||||||
|
end
|
|
@ -73,7 +73,7 @@ module NewUser
|
||||||
@dossier.en_construction!
|
@dossier.en_construction!
|
||||||
NotificationMailer.send_initiated_notification(@dossier).deliver_later
|
NotificationMailer.send_initiated_notification(@dossier).deliver_later
|
||||||
redirect_to merci_dossier_path(@dossier)
|
redirect_to merci_dossier_path(@dossier)
|
||||||
elsif owns_dossier?
|
elsif current_user.owns?(dossier)
|
||||||
redirect_to users_dossier_recapitulatif_path(@dossier)
|
redirect_to users_dossier_recapitulatif_path(@dossier)
|
||||||
else
|
else
|
||||||
redirect_to users_dossiers_invite_path(@dossier.invite_for_user(current_user))
|
redirect_to users_dossiers_invite_path(@dossier.invite_for_user(current_user))
|
||||||
|
@ -142,19 +142,19 @@ module NewUser
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_ownership!
|
def ensure_ownership!
|
||||||
if !owns_dossier?
|
if !current_user.owns?(dossier)
|
||||||
forbidden!
|
forbidden!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_ownership_or_invitation!
|
def ensure_ownership_or_invitation!
|
||||||
if !dossier.owner_or_invite?(current_user)
|
if !current_user.owns_or_invite?(dossier)
|
||||||
forbidden!
|
forbidden!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def forbid_invite_submission!
|
def forbid_invite_submission!
|
||||||
if passage_en_construction? && !owns_dossier?
|
if passage_en_construction? && !current_user.owns?(dossier)
|
||||||
forbidden!
|
forbidden!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -172,10 +172,6 @@ module NewUser
|
||||||
params.require(:dossier).permit(:autorisation_donnees)
|
params.require(:dossier).permit(:autorisation_donnees)
|
||||||
end
|
end
|
||||||
|
|
||||||
def owns_dossier?
|
|
||||||
dossier.user_id == current_user.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def passage_en_construction?
|
def passage_en_construction?
|
||||||
dossier.brouillon? && !draft?
|
dossier.brouillon? && !draft?
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
dossier = Dossier.find(dossier_id)
|
dossier = Dossier.find(dossier_id)
|
||||||
|
|
||||||
if !dossier.owner_or_invite?(current_user)
|
if !current_user.owns_or_invite?(dossier)
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
54
app/dashboards/dossier_dashboard.rb
Normal file
54
app/dashboards/dossier_dashboard.rb
Normal file
|
@ -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
|
50
app/dashboards/gestionnaire_dashboard.rb
Normal file
50
app/dashboards/gestionnaire_dashboard.rb
Normal file
|
@ -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
|
|
@ -74,7 +74,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
# Overwrite this method to customize how procedures are displayed
|
# Overwrite this method to customize how procedures are displayed
|
||||||
# across all pages of the admin dashboard.
|
# across all pages of the admin dashboard.
|
||||||
#
|
#
|
||||||
# def display_resource(procedure)
|
def display_resource(procedure)
|
||||||
# "Procedure ##{procedure.id}"
|
"#{procedure.libelle} ##{procedure.id}"
|
||||||
# end
|
end
|
||||||
end
|
end
|
||||||
|
|
50
app/dashboards/user_dashboard.rb
Normal file
50
app/dashboards/user_dashboard.rb
Normal file
|
@ -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
|
|
@ -16,10 +16,12 @@ module DossierHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_dossier_confirm(dossier)
|
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?
|
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
|
end
|
||||||
message += "Confirmer la suppression ?"
|
message << "Confirmer la suppression ?"
|
||||||
|
|
||||||
|
message.join(" ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -163,10 +163,6 @@ class Dossier < ApplicationRecord
|
||||||
en_instruction? || accepte? || refuse? || sans_suite?
|
en_instruction? || accepte? || refuse? || sans_suite?
|
||||||
end
|
end
|
||||||
|
|
||||||
def owner_or_invite?(user)
|
|
||||||
self.user == user || invite_for_user(user).present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def invite_for_user(user)
|
def invite_for_user(user)
|
||||||
invites_user.find_by(user_id: user.id)
|
invites_user.find_by(user_id: user.id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,7 @@ class Procedure < ApplicationRecord
|
||||||
has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy
|
has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy
|
||||||
|
|
||||||
has_one_attached :notice
|
has_one_attached :notice
|
||||||
|
has_one_attached :deliberation
|
||||||
|
|
||||||
delegate :use_api_carto, to: :module_api_carto
|
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 :libelle, presence: true, allow_blank: false, allow_nil: false
|
||||||
validates :description, presence: true, allow_blank: false, allow_nil: false
|
validates :description, presence: true, allow_blank: false, allow_nil: false
|
||||||
|
validate :check_juridique
|
||||||
|
|
||||||
include AASM
|
include AASM
|
||||||
|
|
||||||
|
@ -198,15 +200,7 @@ class Procedure < ApplicationRecord
|
||||||
procedure.logo_secure_token = nil
|
procedure.logo_secure_token = nil
|
||||||
procedure.remote_logo_url = self.logo_url
|
procedure.remote_logo_url = self.logo_url
|
||||||
|
|
||||||
if notice.attached?
|
%i(notice deliberation).each { |attachment| clone_attachment(procedure, attachment) }
|
||||||
response = Typhoeus.get(notice.service_url, timeout: 5)
|
|
||||||
if response.success?
|
|
||||||
procedure.notice.attach(
|
|
||||||
io: StringIO.new(response.body),
|
|
||||||
filename: notice.filename
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
procedure.administrateur = admin
|
procedure.administrateur = admin
|
||||||
procedure.initiated_mail = initiated_mail&.dup
|
procedure.initiated_mail = initiated_mail&.dup
|
||||||
|
@ -349,6 +343,25 @@ class Procedure < ApplicationRecord
|
||||||
|
|
||||||
private
|
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)
|
def field_hash(label, table, column)
|
||||||
{
|
{
|
||||||
'label' => label,
|
'label' => label,
|
||||||
|
|
|
@ -38,7 +38,15 @@ class User < ApplicationRecord
|
||||||
loged_in_with_france_connect.present?
|
loged_in_with_france_connect.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def owns?(dossier)
|
||||||
|
dossier.user_id == id
|
||||||
|
end
|
||||||
|
|
||||||
def invite?(dossier_id)
|
def invite?(dossier_id)
|
||||||
invites.pluck(:dossier_id).include?(dossier_id.to_i)
|
invites.pluck(:dossier_id).include?(dossier_id.to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def owns_or_invite?(dossier)
|
||||||
|
owns?(dossier) || invite?(dossier.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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é.
|
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/'
|
= 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
|
.form-group
|
||||||
%h4 Notice explicative de la procédure
|
%h4 Notice explicative de la procédure
|
||||||
- notice = @procedure.notice
|
- notice = @procedure.notice
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- if !@facade.dossier.read_only?
|
- 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" }
|
%a#maj_carte.action{ href: "/users/dossiers/#{@facade.dossier.id}/carte" }
|
||||||
.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
|
.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
|
||||||
= 'ÉDITER'
|
= 'ÉDITER'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- if !@facade.dossier.read_only?
|
- 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
|
= 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
|
#edit-dossier.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
|
||||||
= "ÉDITER"
|
= "ÉDITER"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- if !@facade.dossier.read_only?
|
- 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
|
- 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
|
.col-lg-4.col-md-4.col-sm-4.col-xs-4.action
|
||||||
%a#maj_pj.action{ "data-target" => "#upload-pj-modal",
|
%a#maj_pj.action{ "data-target" => "#upload-pj-modal",
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
Pièce non fournie
|
Pièce non fournie
|
||||||
|
|
||||||
- if !@facade.dossier.read_only?
|
- 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
|
- if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0
|
||||||
.row
|
.row
|
||||||
.col-xs-4
|
.col-xs-4
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
.dossier-state= @facade.dossier.display_state
|
.dossier-state= @facade.dossier.display_state
|
||||||
.split-hr-left
|
.split-hr-left
|
||||||
|
|
||||||
- if @facade.dossier.user == current_user
|
- if current_user.owns?(@facade.dossier)
|
||||||
.text-center.mt-1
|
.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
|
= 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
|
Supprimer définitivement
|
||||||
|
|
|
@ -12,7 +12,8 @@ as defined by the routes in the `admin/` namespace
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<% Administrate::Namespace.new(namespace).resources.each do |resource| %>
|
<% Administrate::Namespace.new(namespace).resources.reject { |resource| resource.resource == 'dossiers'}.each do |resource| %>
|
||||||
|
|
||||||
<%= link_to(
|
<%= link_to(
|
||||||
display_resource_name(resource),
|
display_resource_name(resource),
|
||||||
[namespace, resource.path],
|
[namespace, resource.path],
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
class: 'button send',
|
class: 'button send',
|
||||||
data: { action: 'draft', disable_with: 'Envoi...' }
|
data: { action: 'draft', disable_with: 'Envoi...' }
|
||||||
|
|
||||||
- if dossier.user == current_user
|
- if current_user.owns?(dossier)
|
||||||
= f.button 'Soumettre le dossier',
|
= f.button 'Soumettre le dossier',
|
||||||
class: 'button send primary',
|
class: 'button send primary',
|
||||||
data: { action: 'submit', disable_with: 'Envoi...' }
|
data: { action: 'submit', disable_with: 'Envoi...' }
|
||||||
|
|
|
@ -3,3 +3,17 @@ fr:
|
||||||
attributes:
|
attributes:
|
||||||
procedure:
|
procedure:
|
||||||
organisation: Organisme
|
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
|
||||||
|
|
|
@ -11,6 +11,10 @@ Rails.application.routes.draw do
|
||||||
put 'enable_feature', on: :member
|
put 'enable_feature', on: :member
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :users, only: [:index, :show]
|
||||||
|
resources :gestionnaires, only: [:index, :show]
|
||||||
|
resources :dossiers, only: [:show]
|
||||||
|
|
||||||
resources :demandes, only: [:index]
|
resources :demandes, only: [:index]
|
||||||
post 'demandes/create_administrateur'
|
post 'demandes/create_administrateur'
|
||||||
post 'demandes/refuse_administrateur'
|
post 'demandes/refuse_administrateur'
|
||||||
|
@ -143,6 +147,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
member do
|
member do
|
||||||
post :hide
|
post :hide
|
||||||
|
delete :delete_deliberation
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :types_de_champ, only: [:destroy]
|
resources :types_de_champ, only: [:destroy]
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddCadreJuridiqueToProcedure < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :cadre_juridique, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -481,6 +481,7 @@ ActiveRecord::Schema.define(version: 2018_05_30_095508) do
|
||||||
t.bigint "service_id"
|
t.bigint "service_id"
|
||||||
t.integer "duree_conservation_dossiers_dans_ds"
|
t.integer "duree_conservation_dossiers_dans_ds"
|
||||||
t.integer "duree_conservation_dossiers_hors_ds"
|
t.integer "duree_conservation_dossiers_hors_ds"
|
||||||
|
t.string "cadre_juridique"
|
||||||
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
||||||
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
||||||
t.index ["service_id"], name: "index_procedures_on_service_id"
|
t.index ["service_id"], name: "index_procedures_on_service_id"
|
||||||
|
|
|
@ -15,6 +15,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
let(:quartiers_prioritaires) { '0' }
|
let(:quartiers_prioritaires) { '0' }
|
||||||
let(:cadastre) { '0' }
|
let(:cadastre) { '0' }
|
||||||
let(:cerfa_flag) { true }
|
let(:cerfa_flag) { true }
|
||||||
|
let(:cadre_juridique) { 'cadre juridique' }
|
||||||
|
|
||||||
let(:procedure_params) {
|
let(:procedure_params) {
|
||||||
{
|
{
|
||||||
|
@ -24,6 +25,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
direction: direction,
|
direction: direction,
|
||||||
lien_demarche: lien_demarche,
|
lien_demarche: lien_demarche,
|
||||||
cerfa_flag: cerfa_flag,
|
cerfa_flag: cerfa_flag,
|
||||||
|
cadre_juridique: cadre_juridique,
|
||||||
module_api_carto_attributes: {
|
module_api_carto_attributes: {
|
||||||
use_api_carto: use_api_carto,
|
use_api_carto: use_api_carto,
|
||||||
quartiers_prioritaires: quartiers_prioritaires,
|
quartiers_prioritaires: quartiers_prioritaires,
|
||||||
|
@ -471,7 +473,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'PUT #clone' do
|
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 } }
|
let(:params) { { procedure_id: procedure.id } }
|
||||||
subject { put :clone, params: params }
|
subject { put :clone, params: params }
|
||||||
|
|
||||||
|
@ -489,6 +491,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
expect(response).to redirect_to edit_admin_procedure_path(id: Procedure.last.id)
|
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.cloned_from_library).to be_falsey
|
||||||
expect(Procedure.last.notice.attached?).to be_truthy
|
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'
|
expect(flash[:notice]).to have_content 'Procédure clonée'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -634,4 +637,16 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@ FactoryBot.define do
|
||||||
description "Demande de subvention à l'intention des associations"
|
description "Demande de subvention à l'intention des associations"
|
||||||
organisation "Orga DINSIC"
|
organisation "Orga DINSIC"
|
||||||
direction "direction DINSIC"
|
direction "direction DINSIC"
|
||||||
|
cadre_juridique "un cadre juridique important"
|
||||||
published_at nil
|
published_at nil
|
||||||
cerfa_flag false
|
cerfa_flag false
|
||||||
administrateur { create(:administrateur) }
|
administrateur { create(:administrateur) }
|
||||||
|
@ -134,6 +135,15 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
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
|
trait :with_all_champs_mandatory do
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
tdcs = []
|
tdcs = []
|
||||||
|
|
|
@ -14,6 +14,7 @@ feature 'As an administrateur I wanna clone a procedure', js: true do
|
||||||
page.find_by_id('from-scratch').click
|
page.find_by_id('from-scratch').click
|
||||||
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
||||||
page.execute_script("$('#procedure_description').val('description 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
|
page.find_by_id('save-procedure').click
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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)
|
expect(page).to have_current_path(new_admin_procedure_path)
|
||||||
end
|
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('new-procedure').click
|
||||||
page.find_by_id('from-scratch').click
|
page.find_by_id('from-scratch').click
|
||||||
page.find_by_id('save-procedure').click
|
page.find_by_id('save-procedure').click
|
||||||
page.find_by_id('flash_message').visible?
|
page.find_by_id('flash_message').visible?
|
||||||
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
||||||
page.execute_script("$('#procedure_description').val('description 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
|
page.find_by_id('save-procedure').click
|
||||||
expect(page).to have_current_path(admin_procedure_types_de_champ_path(Procedure.first.id.to_s))
|
expect(page).to have_current_path(admin_procedure_types_de_champ_path(Procedure.first.id.to_s))
|
||||||
end
|
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
|
page.find_by_id('from-scratch').click
|
||||||
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
fill_in 'procedure_libelle', with: 'libelle de la procedure'
|
||||||
page.execute_script("$('#procedure_description').val('description 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
|
page.find_by_id('save-procedure').click
|
||||||
|
|
||||||
procedure = Procedure.last
|
procedure = Procedure.last
|
||||||
|
|
|
@ -397,44 +397,6 @@ describe Dossier do
|
||||||
end
|
end
|
||||||
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
|
describe "#text_summary" do
|
||||||
let(:procedure) { create(:procedure, libelle: "Procédure", organisation: "Organisme") }
|
let(:procedure) { create(:procedure, libelle: "Procédure", organisation: "Organisme") }
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,26 @@ describe Procedure do
|
||||||
context 'organisation' do
|
context 'organisation' do
|
||||||
it { is_expected.to allow_value('URRSAF').for(:organisation) }
|
it { is_expected.to allow_value('URRSAF').for(:organisation) }
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe '#types_de_champ_ordered' do
|
describe '#types_de_champ_ordered' do
|
||||||
|
|
|
@ -31,6 +31,37 @@ describe User, type: :model do
|
||||||
end
|
end
|
||||||
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
|
describe '#invite?' do
|
||||||
let(:dossier) { create :dossier }
|
let(:dossier) { create :dossier }
|
||||||
let(:user) { dossier.user }
|
let(:user) { dossier.user }
|
||||||
|
@ -50,6 +81,37 @@ describe User, type: :model do
|
||||||
end
|
end
|
||||||
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
|
context 'unified login' do
|
||||||
it 'syncs credentials to associated gestionnaire' do
|
it 'syncs credentials to associated gestionnaire' do
|
||||||
user = create(:user)
|
user = create(:user)
|
||||||
|
|
|
@ -72,61 +72,30 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when invite is logged' do
|
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
|
before do
|
||||||
create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) }
|
create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') }
|
||||||
sign_out dossier.user
|
sign_out dossier.user
|
||||||
sign_in invite_user
|
sign_in invite_user
|
||||||
render
|
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'invite is by User' do
|
describe 'les liens de modifications' do
|
||||||
let!(:invite_user) { create(:user, email: 'invite@octo.com') }
|
it 'describe link is not present' do
|
||||||
|
expect(rendered).to have_css('#maj_infos')
|
||||||
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
|
end
|
||||||
|
|
||||||
describe 'les liens de modifications' do
|
it 'map link is present' do
|
||||||
it 'describe link is not present' do
|
expect(rendered).to have_css('#maj_carte')
|
||||||
expect(rendered).to have_css('#maj_infos')
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it 'map link is present' do
|
it 'PJ link is present' do
|
||||||
expect(rendered).to have_css('#maj_carte')
|
expect(rendered).to have_css('#maj_pj')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'PJ link is present' do
|
it 'archive link is present' do
|
||||||
expect(rendered).to have_css('#maj_pj')
|
expect(rendered).not_to have_content('Archiver')
|
||||||
end
|
|
||||||
|
|
||||||
it 'archive link is present' do
|
|
||||||
expect(rendered).not_to have_content('Archiver')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue