2021-11-25 16:26:55 +01:00
module Administrateurs
2019-10-17 15:13:50 +02:00
class GroupeInstructeursController < AdministrateurController
2021-06-09 17:51:35 +02:00
include ActiveSupport :: NumberHelper
2023-04-26 17:33:14 +02:00
include Logic
2022-07-21 18:56:01 +02:00
before_action :ensure_not_super_admin! , only : [ :add_instructeur ]
2019-10-17 15:13:50 +02:00
ITEMS_PER_PAGE = 25
2021-06-09 17:51:35 +02:00
CSV_MAX_SIZE = 1 . megabytes
2021-07-15 15:52:51 +02:00
CSV_ACCEPTED_CONTENT_TYPES = [
" text/csv " ,
" application/vnd.ms-excel "
]
2019-10-17 15:13:50 +02:00
def index
@procedure = procedure
2022-10-14 17:10:42 +02:00
@groupes_instructeurs = paginated_groupe_instructeurs
2019-10-17 15:13:50 +02:00
2022-10-17 11:01:55 +02:00
@instructeurs = paginated_instructeurs
@available_instructeur_emails = available_instructeur_emails
2019-10-17 15:13:50 +02:00
end
2023-04-26 17:31:05 +02:00
def options
@procedure = procedure
end
2023-04-26 17:31:49 +02:00
def ajout
redirect_to admin_procedure_groupe_instructeurs_path ( procedure ) if procedure . groupe_instructeurs . one?
@procedure = procedure
@groupes_instructeurs = paginated_groupe_instructeurs
end
2023-04-26 17:33:14 +02:00
def simple_routing
@procedure = procedure
end
def create_simple_routing
@procedure = procedure
stable_id = params [ :create_simple_routing ] [ :stable_id ] . to_i
tdc = @procedure . active_revision . routable_types_de_champ . find { | tdc | tdc . stable_id == stable_id }
tdc_options = tdc . options [ " drop_down_options " ] . reject ( & :empty? )
tdc_options . each do | option_label |
2023-06-27 10:08:53 +02:00
gi = @procedure . groupe_instructeurs . find_by ( { label : option_label } ) || @procedure . groupe_instructeurs
2023-04-26 17:33:14 +02:00
. create ( { label : option_label , instructeurs : [ current_administrateur . instructeur ] } )
gi . update ( routing_rule : ds_eq ( champ_value ( stable_id ) , constant ( gi . label ) ) )
end
2023-06-28 11:00:25 +02:00
@procedure . toggle_routing
2023-04-26 17:33:14 +02:00
defaut = @procedure . defaut_groupe_instructeur
if ! tdc_options . include? ( defaut . label )
new_defaut = @procedure . reload . groupe_instructeurs_but_defaut . first
@procedure . update! ( defaut_groupe_instructeur : new_defaut )
reaffecter_all_dossiers_to_defaut_groupe
defaut . instructeurs . each { new_defaut . add ( _1 ) }
defaut . destroy!
end
flash . notice = 'Les groupes instructeurs ont été ajoutés'
2023-06-27 10:08:53 +02:00
redirect_to admin_procedure_groupe_instructeurs_path ( @procedure )
2023-04-26 17:33:14 +02:00
end
2023-04-27 10:10:57 +02:00
def wizard
if params [ :choice ] [ :state ] == 'routage_custom'
new_label = procedure . defaut_groupe_instructeur . label + ' bis'
procedure . groupe_instructeurs
. create ( { label : new_label , instructeurs : [ current_administrateur . instructeur ] } )
2023-06-28 11:00:25 +02:00
procedure . toggle_routing
2023-04-27 10:10:57 +02:00
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
elsif params [ :choice ] [ :state ] == 'routage_simple'
redirect_to simple_routing_admin_procedure_groupe_instructeurs_path
end
end
2023-04-27 10:11:27 +02:00
def destroy_all_groups_but_defaut
reaffecter_all_dossiers_to_defaut_groupe
procedure . groupe_instructeurs_but_defaut . each ( & :destroy! )
2023-06-27 10:58:41 +02:00
procedure . update! ( routing_enabled : false )
2023-04-27 10:11:27 +02:00
procedure . defaut_groupe_instructeur . update! (
routing_rule : nil ,
label : GroupeInstructeur :: DEFAUT_LABEL ,
closed : false
)
flash . notice = 'Tous les groupes instructeurs ont été supprimés'
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
end
2019-10-23 20:22:56 +02:00
def show
@procedure = procedure
@groupe_instructeur = groupe_instructeur
2019-10-23 20:54:59 +02:00
@instructeurs = paginated_instructeurs
2019-11-04 14:49:53 +01:00
@available_instructeur_emails = available_instructeur_emails
2019-10-23 20:22:56 +02:00
end
2019-10-23 20:51:25 +02:00
def create
@groupe_instructeur = procedure
. groupe_instructeurs
2022-06-20 16:14:27 +02:00
. new ( { instructeurs : [ current_administrateur . instructeur ] } . merge ( groupe_instructeur_params ) )
2019-10-23 20:51:25 +02:00
2023-01-12 14:09:43 +01:00
if @groupe_instructeur . save
2023-06-28 11:00:25 +02:00
procedure . toggle_routing
2023-01-06 16:52:58 +01:00
routing_notice = " et le routage a été activé " if procedure . groupe_instructeurs . active . size == 2
redirect_to admin_procedure_groupe_instructeur_path ( procedure , @groupe_instructeur ) ,
2023-01-12 15:17:42 +01:00
notice : " Le groupe d’ instructeurs « #{ @groupe_instructeur . label } » a été créé#{ routing_notice } . "
2023-01-12 14:09:43 +01:00
else
2019-10-23 20:51:25 +02:00
@procedure = procedure
2022-10-14 17:10:42 +02:00
@instructeurs = paginated_instructeurs
2019-10-23 20:51:25 +02:00
@groupes_instructeurs = paginated_groupe_instructeurs
2023-01-04 17:21:28 +01:00
flash . now [ :alert ] = @groupe_instructeur . errors . full_messages
2019-10-23 20:51:25 +02:00
render :index
end
end
2019-10-23 20:54:59 +02:00
def update
@groupe_instructeur = groupe_instructeur
2023-04-24 15:47:46 +02:00
if @groupe_instructeur . update ( groupe_instructeur_params )
2023-06-28 11:00:25 +02:00
procedure . toggle_routing
2023-01-06 16:52:58 +01:00
redirect_to admin_procedure_groupe_instructeur_path ( procedure , groupe_instructeur ) ,
2023-01-12 15:17:42 +01:00
notice : " Le nom est à présent « #{ @groupe_instructeur . label } ». "
2023-01-12 14:09:43 +01:00
else
2019-10-23 20:54:59 +02:00
@procedure = procedure
@instructeurs = paginated_instructeurs
2019-11-04 14:49:53 +01:00
@available_instructeur_emails = available_instructeur_emails
2019-10-23 20:54:59 +02:00
2023-01-04 17:21:28 +01:00
flash . now [ :alert ] = @groupe_instructeur . errors . full_messages
2019-10-23 20:54:59 +02:00
render :show
end
end
2023-04-24 15:47:46 +02:00
def update_state
@groupe_instructeur = procedure . groupe_instructeurs . find ( params [ :groupe_instructeur_id ] )
if closed_params? && @groupe_instructeur . id == procedure . defaut_groupe_instructeur . id
redirect_to admin_procedure_groupe_instructeur_path ( procedure , @groupe_instructeur ) ,
alert : " Il est impossible de désactiver le groupe d’ instructeurs par défaut. "
elsif @groupe_instructeur . update ( closed : params [ :closed ] )
state_for_notice = @groupe_instructeur . closed ? 'désactivé' : 'activé'
redirect_to admin_procedure_groupe_instructeur_path ( procedure , @groupe_instructeur ) ,
notice : " Le groupe #{ @groupe_instructeur . label } est #{ state_for_notice } . "
else
@procedure = procedure
@instructeurs = paginated_instructeurs
@available_instructeur_emails = available_instructeur_emails
flash . now [ :alert ] = @groupe_instructeur . errors . full_messages
render :show
end
end
2020-01-06 17:09:08 +01:00
def destroy
2022-06-20 16:14:27 +02:00
@groupe_instructeur = groupe_instructeur
2022-12-01 18:14:08 +01:00
if @groupe_instructeur . dossiers . present?
2023-01-12 14:02:01 +01:00
flash [ :alert ] = " Impossible de supprimer un groupe avec des dossiers. Il faut le réaffecter avant "
2020-01-20 11:27:41 +01:00
elsif procedure . groupe_instructeurs . one?
2023-01-12 14:02:01 +01:00
flash [ :alert ] = " Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure "
2023-04-18 16:40:53 +02:00
elsif @groupe_instructeur . id == procedure . defaut_groupe_instructeur . id
flash [ :alert ] = " Suppression impossible : le groupe « #{ @groupe_instructeur . label } » est le groupe par défaut. "
2020-01-06 17:09:08 +01:00
else
2023-01-12 15:33:56 +01:00
@groupe_instructeur . destroy!
if procedure . groupe_instructeurs . active . one?
2023-06-28 11:00:25 +02:00
procedure . toggle_routing
2023-04-27 10:11:27 +02:00
procedure . defaut_groupe_instructeur . update! (
routing_rule : nil ,
label : GroupeInstructeur :: DEFAUT_LABEL ,
closed : false
)
2023-01-12 15:33:56 +01:00
routing_notice = " et le routage a été désactivé "
2022-10-14 17:10:42 +02:00
end
2023-01-12 14:02:01 +01:00
flash [ :notice ] = " le groupe « #{ @groupe_instructeur . label } » a été supprimé #{ routing_notice } . "
2020-01-06 17:09:08 +01:00
end
2020-07-07 12:03:32 +02:00
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
2020-01-06 17:09:08 +01:00
end
2020-01-07 17:39:50 +01:00
def reaffecter_dossiers
@procedure = procedure
@groupe_instructeur = groupe_instructeur
@groupes_instructeurs = paginated_groupe_instructeurs
. without_group ( @groupe_instructeur )
end
2021-07-26 16:06:09 +02:00
def reaffecter_bulk_messages ( target_group )
bulk_messages = BulkMessage . joins ( :groupe_instructeurs ) . where ( groupe_instructeurs : { id : groupe_instructeur . id } )
bulk_messages . each do | bulk_message |
bulk_message . groupe_instructeurs . delete ( groupe_instructeur )
if ! bulk_message . groupe_instructeur_ids . include? ( target_group . id )
bulk_message . groupe_instructeurs << target_group
end
end
end
2020-01-07 17:39:50 +01:00
def reaffecter
2020-01-20 11:27:41 +01:00
target_group = procedure . groupe_instructeurs . find ( params [ :target_group ] )
2021-07-26 16:06:09 +02:00
reaffecter_bulk_messages ( target_group )
2022-03-09 10:27:43 +01:00
groupe_instructeur . dossiers . find_each do | dossier |
2023-07-05 17:48:18 +02:00
dossier . assign_to_groupe_instructeur ( target_group , DossierAssignment . modes . fetch ( :manual ) , current_administrateur )
2020-02-26 12:30:52 +01:00
end
2020-01-20 11:27:41 +01:00
flash [ :notice ] = " Les dossiers du groupe « #{ groupe_instructeur . label } » ont été réaffectés au groupe « #{ target_group . label } ». "
2020-07-07 12:03:32 +02:00
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
2020-01-07 17:39:50 +01:00
end
2023-04-27 10:11:27 +02:00
def reaffecter_all_dossiers_to_defaut_groupe
procedure . groupe_instructeurs_but_defaut . each do | gi |
gi . dossiers . find_each do | dossier |
2023-07-05 17:48:18 +02:00
dossier . assign_to_groupe_instructeur ( procedure . defaut_groupe_instructeur , DossierAssignment . modes . fetch ( :manual ) , current_administrateur )
2023-04-27 10:11:27 +02:00
end
end
end
2019-10-10 19:36:56 +02:00
def add_instructeur
2021-02-11 15:36:11 +01:00
emails = params [ 'emails' ] . presence || [ ] . to_json
2023-01-10 17:20:22 +01:00
emails = JSON . parse ( emails ) . map { EmailSanitizableConcern :: EmailSanitizer . sanitize ( _1 ) }
2019-10-10 19:36:56 +02:00
2023-02-21 16:37:26 +01:00
instructeurs , invalid_emails = groupe_instructeur . add_instructeurs ( emails : )
2019-11-04 14:49:53 +01:00
2022-12-01 18:14:08 +01:00
if invalid_emails . present?
2019-11-04 14:49:53 +01:00
flash [ :alert ] = t ( '.wrong_address' ,
2022-12-01 18:14:08 +01:00
count : invalid_emails . size ,
emails : invalid_emails . join ( ', ' ) )
2019-11-04 14:49:53 +01:00
end
2022-12-01 18:14:08 +01:00
if instructeurs . present?
flash [ :notice ] = if procedure . routing_enabled?
t ( '.assignment' ,
count : instructeurs . size ,
emails : instructeurs . map ( & :email ) . join ( ', ' ) ,
2020-06-12 18:16:07 +02:00
groupe : groupe_instructeur . label )
else
2022-12-01 18:14:08 +01:00
" Les instructeurs ont bien été affectés à la démarche "
2020-06-12 18:16:07 +02:00
end
2023-02-17 15:24:12 +01:00
GroupeInstructeurMailer
. notify_added_instructeurs ( groupe_instructeur , instructeurs , current_administrateur . email )
. deliver_later
2019-10-10 19:36:56 +02:00
end
2022-11-04 10:10:57 +01:00
if procedure . routing_enabled?
2021-09-14 19:54:35 +02:00
redirect_to admin_procedure_groupe_instructeur_path ( procedure , groupe_instructeur )
else
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
end
2019-10-10 19:36:56 +02:00
end
2019-10-09 18:23:29 +02:00
def remove_instructeur
if groupe_instructeur . instructeurs . one?
flash [ :alert ] = " Suppression impossible : il doit y avoir au moins un instructeur dans le groupe "
else
2022-12-01 18:14:08 +01:00
instructeur = groupe_instructeur . instructeurs . find_by ( id : instructeur_id )
if groupe_instructeur . remove ( instructeur )
2023-02-15 11:57:35 +01:00
flash [ :notice ] = if instructeur . in? ( procedure . instructeurs )
2022-12-01 18:14:08 +01:00
" L’ instructeur « #{ instructeur . email } » a été retiré du groupe. "
2021-10-26 22:40:48 +02:00
else
2022-12-01 18:14:08 +01:00
" L’ instructeur a bien été désaffecté de la démarche "
2021-10-26 22:40:48 +02:00
end
2023-02-15 11:57:35 +01:00
GroupeInstructeurMailer
. notify_removed_instructeur ( groupe_instructeur , instructeur , current_administrateur . email )
. deliver_later
2020-06-12 18:16:07 +02:00
else
2022-12-01 18:14:08 +01:00
flash [ :alert ] = if procedure . routing_enabled?
if instructeur . present?
" L’ instructeur « #{ instructeur . email } » n’ est pas dans le groupe. "
else
" L’ instructeur n’ est pas dans le groupe. "
end
2020-06-12 18:16:07 +02:00
else
2022-12-01 18:14:08 +01:00
" L’ instructeur n’ est pas affecté à la démarche "
2020-06-12 18:16:07 +02:00
end
end
2019-10-09 18:23:29 +02:00
end
2021-09-14 19:54:35 +02:00
2022-11-04 10:10:57 +01:00
if procedure . routing_enabled?
2021-09-14 19:54:35 +02:00
redirect_to admin_procedure_groupe_instructeur_path ( procedure , groupe_instructeur )
else
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
end
2019-10-09 18:23:29 +02:00
end
2021-09-15 10:37:19 +02:00
def update_instructeurs_self_management_enabled
procedure . update! ( instructeurs_self_management_enabled_params )
2023-04-26 17:31:05 +02:00
redirect_to options_admin_procedure_groupe_instructeurs_path ( procedure ) ,
2021-09-15 10:37:19 +02:00
notice : " L’ autogestion des instructeurs est #{ procedure . instructeurs_self_management_enabled? ? " activée " : " désactivée " } . "
end
2021-06-09 17:51:35 +02:00
def import
2023-02-09 09:44:06 +01:00
if procedure . publiee_or_close?
2023-01-10 14:36:56 +01:00
if ! CSV_ACCEPTED_CONTENT_TYPES . include? ( csv_file . content_type ) && ! CSV_ACCEPTED_CONTENT_TYPES . include? ( marcel_content_type )
2022-01-17 12:22:21 +01:00
flash [ :alert ] = " Importation impossible : veuillez importer un fichier CSV "
2021-06-09 17:51:35 +02:00
2023-01-10 14:36:56 +01:00
elsif csv_file . size > CSV_MAX_SIZE
2022-01-17 12:22:21 +01:00
flash [ :alert ] = " Importation impossible : le poids du fichier est supérieur à #{ number_to_human_size ( CSV_MAX_SIZE ) } "
2021-06-09 17:51:35 +02:00
else
2023-01-10 14:36:56 +01:00
file = csv_file . read
2022-01-17 12:22:21 +01:00
base_encoding = CharlockHolmes :: EncodingDetector . detect ( file )
2021-06-22 14:30:02 +02:00
2023-03-02 18:07:05 +01:00
csv_content = ACSV :: CSV . new_for_ruby3 ( file . encode ( " UTF-8 " , base_encoding [ :encoding ] , invalid : :replace , replace : " " ) , headers : true , header_converters : :downcase ) . map ( & :to_h )
2022-01-17 12:22:21 +01:00
2023-03-02 18:07:05 +01:00
if csv_content . first . has_key? ( " groupe " ) && csv_content . first . has_key? ( " email " )
groupes_emails = csv_content . map { | r | r . to_h . slice ( 'groupe' , 'email' ) }
2022-01-17 12:22:21 +01:00
2023-03-02 18:07:05 +01:00
added_instructeurs_by_group , invalid_emails = InstructeursImportService . import_groupes ( procedure , groupes_emails )
2023-02-22 18:05:20 +01:00
2023-03-02 18:07:05 +01:00
added_instructeurs_by_group . each do | groupe , added_instructeurs |
2023-03-08 10:47:22 +01:00
if added_instructeurs . present?
GroupeInstructeurMailer
. notify_added_instructeurs ( groupe , added_instructeurs , current_administrateur . email )
. deliver_later
end
2023-02-22 18:05:20 +01:00
flash_message_for_import ( invalid_emails )
2023-01-10 14:36:56 +01:00
end
2023-03-02 18:07:05 +01:00
elsif csv_content . first . has_key? ( " email " ) && ! csv_content . map ( & :to_h ) . first . keys . many? && procedure . groupe_instructeurs . one?
instructors_emails = csv_content . map ( & :to_h )
2023-01-10 14:36:56 +01:00
2023-03-02 18:07:05 +01:00
added_instructeurs , invalid_emails = InstructeursImportService . import_instructeurs ( procedure , instructors_emails )
2023-03-08 10:47:22 +01:00
if added_instructeurs . present?
GroupeInstructeurMailer
. notify_added_instructeurs ( groupe_instructeur , added_instructeurs , current_administrateur . email )
. deliver_later
end
2023-03-02 18:07:05 +01:00
flash_message_for_import ( invalid_emails )
else
flash_message_for_invalid_csv
2021-06-22 14:30:02 +02:00
end
2023-01-10 14:36:56 +01:00
redirect_to admin_procedure_groupe_instructeurs_path ( procedure )
2021-06-09 17:51:35 +02:00
end
end
end
2021-10-04 16:02:19 +02:00
def export_groupe_instructeurs
groupe_instructeurs = procedure . groupe_instructeurs
data = CSV . generate ( headers : true ) do | csv |
column_names = [ " Groupe " , " Email " ]
csv << column_names
groupe_instructeurs . each do | gi |
gi . instructeurs . each do | instructeur |
csv << [ gi . label , instructeur . email ]
end
end
end
respond_to do | format |
format . csv { send_data data , filename : " #{ procedure . id } -groupe-instructeurs- #{ Date . today } .csv " }
end
end
2019-10-17 15:13:50 +02:00
private
2023-04-18 17:15:04 +02:00
def closed_params?
2023-04-24 15:47:46 +02:00
params [ :closed ] == " 1 "
2023-04-18 17:15:04 +02:00
end
2019-10-17 15:13:50 +02:00
def procedure
current_administrateur
. procedures
. includes ( :groupe_instructeurs )
. find ( params [ :procedure_id ] )
end
2019-10-23 20:22:56 +02:00
def groupe_instructeur
2021-09-14 19:54:35 +02:00
if params [ :id ] . present?
procedure . groupe_instructeurs . find ( params [ :id ] )
else
procedure . defaut_groupe_instructeur
end
2019-10-23 20:22:56 +02:00
end
2019-10-23 20:51:25 +02:00
2019-10-09 18:23:29 +02:00
def instructeur_id
params [ :instructeur ] [ :id ]
end
2022-06-20 16:14:27 +02:00
def groupe_instructeur_params
2023-04-24 15:47:46 +02:00
params . require ( :groupe_instructeur ) . permit ( :label )
2019-10-23 20:51:25 +02:00
end
def paginated_groupe_instructeurs
2023-05-09 11:15:02 +02:00
groupes = if params [ :q ] . present?
query = ActiveRecord :: Base . sanitize_sql_like ( params [ :q ] )
procedure
. groupe_instructeurs
. where ( 'unaccent(label) ILIKE unaccent(?)' , " % #{ query } % " )
else
procedure . groupe_instructeurs
end
2023-07-03 18:21:50 +02:00
if params [ :filter ] == '1'
groupes = Kaminari . paginate_array ( groupes . filter ( & :routing_to_configure? ) )
end
2023-05-09 11:15:02 +02:00
groupes
2019-10-23 20:51:25 +02:00
. page ( params [ :page ] )
. per ( ITEMS_PER_PAGE )
end
2019-10-23 20:54:59 +02:00
def paginated_instructeurs
groupe_instructeur
. instructeurs
. page ( params [ :page ] )
. per ( ITEMS_PER_PAGE )
. order ( :email )
end
2019-10-17 10:57:58 +02:00
2019-11-04 14:49:53 +01:00
def available_instructeur_emails
2019-12-02 14:52:01 +01:00
all = current_administrateur . instructeurs . map ( & :email )
assigned = groupe_instructeur . instructeurs . map ( & :email )
2019-11-04 14:49:53 +01:00
( all - assigned ) . sort
end
2021-06-09 17:51:35 +02:00
2023-01-10 14:36:56 +01:00
def csv_file
2023-03-02 18:07:05 +01:00
params [ :csv_file ]
2021-06-09 17:51:35 +02:00
end
def marcel_content_type
2023-01-10 14:36:56 +01:00
Marcel :: MimeType . for ( csv_file . read , name : csv_file . original_filename , declared_type : csv_file . content_type )
2021-06-09 17:51:35 +02:00
end
2021-09-15 10:37:19 +02:00
def instructeurs_self_management_enabled_params
params . require ( :procedure ) . permit ( :instructeurs_self_management_enabled )
end
2021-11-11 13:25:47 +01:00
def routing_enabled_params
{ routing_enabled : params . require ( :routing ) == 'enable' }
end
2023-01-18 17:48:42 +01:00
def flash_message_for_import ( result )
if result . blank?
flash [ :notice ] = " La liste des instructeurs a été importée avec succès "
else
flash [ :alert ] = " Import terminé. Cependant les emails suivants ne sont pas pris en compte: #{ result . join ( ', ' ) } "
end
end
2023-03-02 18:07:05 +01:00
def flash_message_for_invalid_csv
flash [ :alert ] = " Importation impossible, veuillez importer un csv suivant #{ view_context . link_to ( 'ce modèle' , " /csv/import-instructeurs-test.csv " ) } pour une procédure sans routage ou #{ view_context . link_to ( 'celui-ci' , " /csv/ #{ I18n . locale } /import-groupe-test.csv " ) } pour une procédure routée "
end
2019-10-17 15:13:50 +02:00
end
end