2018-03-06 13:44:29 +01:00
class Dossier < ApplicationRecord
2019-09-17 10:16:52 +02:00
self . ignored_columns = [ 'json_latlngs' ]
2019-02-27 12:03:53 +01:00
include DossierFilteringConcern
2017-05-26 18:27:51 +02:00
enum state : {
2017-12-04 20:23:57 +01:00
brouillon : 'brouillon' ,
en_construction : 'en_construction' ,
en_instruction : 'en_instruction' ,
accepte : 'accepte' ,
refuse : 'refuse' ,
sans_suite : 'sans_suite'
2017-05-26 18:27:51 +02:00
}
2015-09-22 18:30:20 +02:00
2018-08-28 14:10:55 +02:00
EN_CONSTRUCTION_OU_INSTRUCTION = [ states . fetch ( :en_construction ) , states . fetch ( :en_instruction ) ]
TERMINE = [ states . fetch ( :accepte ) , states . fetch ( :refuse ) , states . fetch ( :sans_suite ) ]
INSTRUCTION_COMMENCEE = TERMINE + [ states . fetch ( :en_instruction ) ]
2018-01-18 11:39:05 +01:00
SOUMIS = EN_CONSTRUCTION_OU_INSTRUCTION + TERMINE
2017-05-26 18:22:31 +02:00
2019-07-18 16:47:59 +02:00
TAILLE_MAX_ZIP = 50 . megabytes
2015-09-24 11:45:00 +02:00
has_one :etablissement , dependent : :destroy
2016-08-30 11:18:43 +02:00
has_one :individual , dependent : :destroy
2018-11-28 16:13:58 +01:00
has_one :attestation , dependent : :destroy
2016-01-18 16:20:51 +01:00
2019-02-18 17:52:15 +01:00
has_one_attached :justificatif_motivation
2019-05-29 18:28:27 +02:00
has_many :champs , - > { root . public_only . ordered } , inverse_of : :dossier , dependent : :destroy
has_many :champs_private , - > { root . private_only . ordered } , class_name : 'Champ' , inverse_of : :dossier , dependent : :destroy
has_many :commentaires , inverse_of : :dossier , dependent : :destroy
2016-02-08 18:16:18 +01:00
has_many :invites , dependent : :destroy
2019-06-12 19:10:53 +02:00
has_many :follows , - > { active } , inverse_of : :dossier
has_many :previous_follows , - > { inactive } , class_name : 'Follow' , inverse_of : :dossier
2019-08-06 11:02:54 +02:00
has_many :followers_instructeurs , through : :follows , source : :instructeur
has_many :previous_followers_instructeurs , - > { distinct } , through : :previous_follows , source : :instructeur
2019-05-29 18:28:27 +02:00
has_many :avis , inverse_of : :dossier , dependent : :destroy
2016-01-18 16:20:51 +01:00
2018-11-28 16:39:14 +01:00
has_many :dossier_operation_logs , dependent : :destroy
2018-11-23 21:02:18 +01:00
2019-08-22 17:58:31 +02:00
belongs_to :groupe_instructeur
has_one :procedure , through : :groupe_instructeur
2015-09-23 12:16:21 +02:00
belongs_to :user
2015-08-12 10:09:52 +02:00
2017-08-02 14:56:08 +02:00
accepts_nested_attributes_for :champs
2017-08-02 15:33:23 +02:00
accepts_nested_attributes_for :champs_private
2017-08-02 14:56:08 +02:00
2019-07-02 15:38:23 +02:00
include AASM
aasm whiny_persistence : true , column : :state , enum : true do
state :brouillon , initial : true
state :en_construction
state :en_instruction
state :accepte
state :refuse
state :sans_suite
event :passer_en_construction , after : :after_passer_en_construction do
transitions from : :brouillon , to : :en_construction
end
event :passer_en_instruction , after : :after_passer_en_instruction do
transitions from : :en_construction , to : :en_instruction
end
event :passer_automatiquement_en_instruction , after : :after_passer_automatiquement_en_instruction do
transitions from : :en_construction , to : :en_instruction
end
event :repasser_en_construction , after : :after_repasser_en_construction do
transitions from : :en_instruction , to : :en_construction
end
event :accepter , after : :after_accepter do
transitions from : :en_instruction , to : :accepte
end
event :accepter_automatiquement , after : :after_accepter_automatiquement do
transitions from : :en_construction , to : :accepte
end
event :refuser , after : :after_refuser do
transitions from : :en_instruction , to : :refuse
end
event :classer_sans_suite , after : :after_classer_sans_suite do
transitions from : :en_instruction , to : :sans_suite
end
event :repasser_en_instruction , after : :after_repasser_en_instruction do
transitions from : :refuse , to : :en_instruction
transitions from : :sans_suite , to : :en_instruction
2019-07-29 10:57:21 +02:00
transitions from : :accepte , to : :en_instruction
2019-07-02 15:38:23 +02:00
end
end
2017-06-27 15:26:40 +02:00
default_scope { where ( hidden_at : nil ) }
2018-08-28 14:10:55 +02:00
scope :state_brouillon , - > { where ( state : states . fetch ( :brouillon ) ) }
scope :state_not_brouillon , - > { where . not ( state : states . fetch ( :brouillon ) ) }
scope :state_en_construction , - > { where ( state : states . fetch ( :en_construction ) ) }
scope :state_en_instruction , - > { where ( state : states . fetch ( :en_instruction ) ) }
2017-07-11 16:09:03 +02:00
scope :state_en_construction_ou_instruction , - > { where ( state : EN_CONSTRUCTION_OU_INSTRUCTION ) }
2018-06-13 17:32:50 +02:00
scope :state_instruction_commencee , - > { where ( state : INSTRUCTION_COMMENCEE ) }
2017-07-11 16:09:03 +02:00
scope :state_termine , - > { where ( state : TERMINE ) }
2017-05-26 18:23:16 +02:00
2017-06-01 11:05:51 +02:00
scope :archived , - > { where ( archived : true ) }
scope :not_archived , - > { where ( archived : false ) }
2017-05-26 18:23:16 +02:00
scope :order_by_updated_at , - > ( order = :desc ) { order ( updated_at : order ) }
2019-06-04 15:28:23 +02:00
scope :order_for_api , - > ( order = :asc ) { order ( en_construction_at : order , created_at : order , id : order ) }
2017-05-26 18:23:16 +02:00
2017-09-27 11:51:31 +02:00
scope :all_state , - > { not_archived . state_not_brouillon }
2017-12-05 16:14:02 +01:00
scope :en_construction , - > { not_archived . state_en_construction }
2017-09-27 11:51:31 +02:00
scope :en_instruction , - > { not_archived . state_en_instruction }
scope :termine , - > { not_archived . state_termine }
2019-07-30 15:39:20 +02:00
scope :downloadable_sorted , - > {
state_not_brouillon
. includes (
:user ,
:individual ,
2019-08-06 11:02:54 +02:00
:followers_instructeurs ,
2019-07-30 15:39:20 +02:00
:avis ,
etablissement : :champ ,
champs : {
etablissement : :champ ,
type_de_champ : :drop_down_list
} ,
champs_private : {
etablissement : :champ ,
type_de_champ : :drop_down_list
2019-09-19 12:20:23 +02:00
} ,
procedure : :groupe_instructeurs
2019-07-30 15:39:20 +02:00
) . order ( en_construction_at : 'asc' )
}
2017-09-27 11:51:31 +02:00
scope :en_cours , - > { not_archived . state_en_construction_ou_instruction }
2017-10-10 18:35:00 +02:00
scope :without_followers , - > { left_outer_joins ( :follows ) . where ( follows : { id : nil } ) }
2018-08-30 11:51:35 +02:00
scope :with_champs , - > { includes ( champs : :type_de_champ ) }
2018-08-31 12:56:30 +02:00
scope :nearing_end_of_retention , - > ( duration = '1 month' ) { joins ( :procedure ) . where ( " en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ? " , duration ) }
2018-11-22 00:14:16 +01:00
scope :since , - > ( since ) { where ( 'dossiers.en_construction_at >= ?' , since ) }
2018-11-01 14:04:32 +01:00
scope :for_api , - > {
2019-06-25 17:12:44 +02:00
includes ( commentaires : { piece_jointe_attachment : :blob } ,
2018-11-01 14:04:32 +01:00
champs : [
:geo_areas ,
:etablissement ,
2019-07-11 10:28:44 +02:00
piece_justificative_file_attachment : :blob ,
champs : [
piece_justificative_file_attachment : :blob
]
2018-11-01 14:04:32 +01:00
] ,
champs_private : [
:geo_areas ,
:etablissement ,
2019-07-11 10:28:44 +02:00
piece_justificative_file_attachment : :blob ,
champs : [
piece_justificative_file_attachment : :blob
]
2018-11-01 14:04:32 +01:00
] ,
2019-07-31 16:09:28 +02:00
justificatif_motivation_attachment : :blob ,
attestation : [ ] ,
avis : { piece_justificative_file_attachment : :blob } ,
2018-11-01 14:04:32 +01:00
etablissement : [ ] ,
individual : [ ] ,
user : [ ] )
}
2019-09-18 13:07:30 +02:00
scope :for_procedure , - > ( procedure ) { includes ( :user , :groupe_instructeur ) . where ( groupe_instructeurs : { procedure : procedure } ) }
2019-08-28 11:25:41 +02:00
scope :for_api_v2 , - > { includes ( procedure : [ :administrateurs ] , etablissement : [ ] , individual : [ ] ) }
2019-09-18 13:07:30 +02:00
2019-09-23 14:38:12 +02:00
scope :with_notifications , - > do
# This scope is meant to be composed, typically with Instructeur.followed_dossiers, which means that the :follows table is already INNER JOINed;
# it will fail otherwise
# Relations passed to #or must be “structurally compatible”, i.e. query the same tables.
joined_dossiers = left_outer_joins ( :champs , :champs_private , :avis , :commentaires )
updated_demandes = joined_dossiers
. where ( 'champs.updated_at > follows.demande_seen_at' )
# We join `:champs` twice, the second time with `has_many :champs_privates`. ActiveRecord generates the SQL: 'LEFT OUTER JOIN "champs" "champs_privates_dossiers" ON …'. We can then use this `champs_privates_dossiers` alias to disambiguate the table in this WHERE clause.
updated_annotations = joined_dossiers
. where ( 'champs_privates_dossiers.updated_at > follows.annotations_privees_seen_at' )
updated_avis = joined_dossiers
. where ( 'avis.updated_at > follows.avis_seen_at' )
updated_messagerie = joined_dossiers
. where ( 'commentaires.updated_at > follows.messagerie_seen_at' )
. where . not ( commentaires : { email : OLD_CONTACT_EMAIL } )
. where . not ( commentaires : { email : CONTACT_EMAIL } )
updated_demandes . or ( updated_annotations ) . or ( updated_avis ) . or ( updated_messagerie ) . distinct
end
2016-08-30 11:18:43 +02:00
accepts_nested_attributes_for :individual
2018-04-23 11:57:38 +02:00
delegate :siret , :siren , to : :etablissement , allow_nil : true
2015-11-05 11:21:44 +01:00
delegate :types_de_champ , to : :procedure
2016-08-01 18:10:32 +02:00
delegate :france_connect_information , to : :user
2015-08-13 15:55:19 +02:00
2017-03-01 09:51:55 +01:00
before_validation :update_state_dates , if : - > { state_changed? }
2018-08-22 17:16:06 +02:00
2019-08-22 17:58:31 +02:00
before_save :build_default_champs , if : Proc . new { groupe_instructeur_id_changed? }
2018-08-22 17:16:06 +02:00
before_save :build_default_individual , if : Proc . new { procedure . for_individual? }
2018-07-25 19:34:06 +02:00
before_save :update_search_terms
2017-03-01 09:51:55 +01:00
2017-10-13 18:35:12 +02:00
after_save :send_dossier_received
2018-03-01 17:04:05 +01:00
after_save :send_web_hook
2017-10-11 15:36:40 +02:00
after_create :send_draft_notification_email
2015-08-24 15:23:07 +02:00
2015-09-24 11:17:17 +02:00
validates :user , presence : true
2015-08-21 11:37:13 +02:00
2018-07-25 19:34:06 +02:00
def update_search_terms
self . search_terms = [
user & . email ,
2018-08-22 17:48:25 +02:00
* champs . flat_map ( & :search_terms ) ,
2018-07-25 19:34:06 +02:00
* etablissement & . search_terms ,
individual & . nom ,
individual & . prenom
] . compact . join ( ' ' )
2018-08-22 17:48:25 +02:00
self . private_search_terms = champs_private . flat_map ( & :search_terms ) . compact . join ( ' ' )
2018-07-25 19:34:06 +02:00
end
2015-11-03 15:27:49 +01:00
def build_default_champs
2019-02-07 10:44:15 +01:00
procedure . build_champs . each do | champ |
2019-01-30 16:14:15 +01:00
champs << champ
2018-08-22 17:16:06 +02:00
end
2019-02-07 10:44:15 +01:00
procedure . build_champs_private . each do | champ |
champs_private << champ
2015-11-03 15:27:49 +01:00
end
end
2016-08-30 11:18:43 +02:00
def build_default_individual
2016-12-21 15:39:41 +01:00
if Individual . where ( dossier_id : self . id ) . count == 0
2018-08-22 17:16:06 +02:00
build_individual
2016-12-21 15:39:41 +01:00
end
2016-08-30 11:18:43 +02:00
end
2017-07-11 15:58:31 +02:00
def en_construction_ou_instruction?
EN_CONSTRUCTION_OU_INSTRUCTION . include? ( state )
end
def termine?
TERMINE . include? ( state )
end
2018-06-13 13:58:14 +02:00
def instruction_commencee?
INSTRUCTION_COMMENCEE . include? ( state )
end
2016-06-20 13:57:57 +02:00
def reset!
2016-10-05 14:28:10 +02:00
etablissement . destroy
2016-06-20 13:57:57 +02:00
2018-02-08 17:13:15 +01:00
update_columns ( autorisation_donnees : false )
2016-06-20 13:57:57 +02:00
end
2016-07-19 16:44:26 +02:00
2016-09-13 12:17:56 +02:00
def read_only?
2017-12-04 20:23:57 +01:00
en_instruction? || accepte? || refuse? || sans_suite?
2016-09-13 12:17:56 +02:00
end
2018-06-25 18:07:16 +02:00
def can_transition_to_en_construction?
! procedure . archivee? && brouillon?
end
2019-02-06 18:20:35 +01:00
def can_be_updated_by_user?
2018-06-08 15:51:46 +02:00
brouillon? || en_construction?
end
2019-02-06 19:11:55 +01:00
def can_be_deleted_by_user?
brouillon? || en_construction?
end
2019-03-12 15:41:47 +01:00
def messagerie_available?
2019-07-11 15:37:04 +02:00
! brouillon? && ! archived
2019-03-12 15:41:47 +01:00
end
2018-08-31 15:44:07 +02:00
def retention_end_date
if instruction_commencee?
en_instruction_at + procedure . duree_conservation_dossiers_dans_ds . months
end
end
def retention_expired?
2018-10-25 15:07:15 +02:00
instruction_commencee? && retention_end_date < = Time . zone . now
2018-08-31 15:44:07 +02:00
end
2017-04-18 17:31:01 +02:00
def text_summary
if brouillon?
parts = [
2018-09-05 14:48:42 +02:00
" Dossier en brouillon répondant à la démarche " ,
2017-04-18 17:31:01 +02:00
procedure . libelle ,
2017-05-02 09:48:25 +02:00
" gérée par l'organisme " ,
2019-02-05 11:29:49 +01:00
procedure . organisation_name
2017-04-18 17:31:01 +02:00
]
else
parts = [
" Dossier déposé le " ,
2018-10-25 22:25:43 +02:00
en_construction_at . strftime ( " %d/%m/%Y " ) ,
2018-09-05 14:48:42 +02:00
" sur la démarche " ,
2017-04-18 17:31:01 +02:00
procedure . libelle ,
2017-05-02 09:48:25 +02:00
" gérée par l'organisme " ,
2019-02-05 11:29:49 +01:00
procedure . organisation_name
2017-04-18 17:31:01 +02:00
]
end
parts . join
end
2019-08-06 11:02:54 +02:00
def avis_for ( instructeur )
if instructeur . dossiers . include? ( self )
2017-09-08 11:52:20 +02:00
avis . order ( created_at : :asc )
else
avis
. where ( confidentiel : false )
2019-08-06 11:02:54 +02:00
. or ( avis . where ( claimant : instructeur ) )
. or ( avis . where ( instructeur : instructeur ) )
2017-09-08 11:52:20 +02:00
. order ( created_at : :asc )
end
end
2017-11-17 23:40:51 +01:00
def owner_name
2018-04-23 11:57:38 +02:00
if etablissement . present?
etablissement . entreprise_raison_sociale
2017-11-17 23:40:51 +01:00
elsif individual . present?
" #{ individual . nom } #{ individual . prenom } "
end
end
2018-10-31 13:28:39 +01:00
def expose_legacy_carto_api?
procedure . expose_legacy_carto_api?
end
2018-10-10 19:58:51 +02:00
def geo_position
if etablissement . present?
2018-10-15 21:48:17 +02:00
point = ApiAdresse :: PointAdapter . new ( etablissement . geo_adresse ) . geocode
2018-10-10 19:58:51 +02:00
end
lon = " 2.428462 "
lat = " 46.538192 "
zoom = " 13 "
if point . present?
lon = point . x . to_s
lat = point . y . to_s
end
{ lon : lon , lat : lat , zoom : zoom }
end
2018-04-06 13:09:37 +02:00
def unspecified_attestation_champs
attestation_template = procedure . attestation_template
2018-04-06 16:21:48 +02:00
if attestation_template & . activated?
2018-04-06 13:09:37 +02:00
attestation_template . unspecified_champs_for_dossier ( self )
else
[ ]
end
end
2017-06-08 14:04:47 +02:00
def build_attestation
2018-04-06 16:21:48 +02:00
if procedure . attestation_template & . activated?
2017-06-08 14:04:47 +02:00
procedure . attestation_template . attestation_for ( self )
end
end
2019-07-15 16:00:49 +02:00
def delete_and_keep_track ( author )
2019-02-13 16:13:37 +01:00
deleted_dossier = DeletedDossier . create_from_dossier ( self )
update ( hidden_at : deleted_dossier . deleted_at )
2018-07-23 15:06:06 +02:00
2018-08-02 16:36:50 +02:00
if en_construction?
2019-08-06 11:02:54 +02:00
administration_emails = followers_instructeurs . present? ? followers_instructeurs . pluck ( :email ) : procedure . administrateurs . pluck ( :email )
2018-08-02 16:36:50 +02:00
administration_emails . each do | email |
DossierMailer . notify_deletion_to_administration ( deleted_dossier , email ) . deliver_later
end
2018-07-23 15:06:06 +02:00
end
2018-06-13 13:59:02 +02:00
DossierMailer . notify_deletion_to_user ( deleted_dossier , user . email ) . deliver_later
2019-07-15 16:00:49 +02:00
log_dossier_operation ( author , :supprimer , self )
2018-05-30 11:36:48 +02:00
end
2019-08-06 11:02:54 +02:00
def after_passer_en_instruction ( instructeur )
instructeur . follow ( self )
2018-11-26 21:29:06 +01:00
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :passer_en_instruction )
2018-11-26 19:12:56 +01:00
end
2019-07-02 15:38:23 +02:00
def after_passer_automatiquement_en_instruction
2019-05-02 16:22:16 +02:00
log_automatic_dossier_operation ( :passer_en_instruction )
2019-01-10 17:23:48 +01:00
end
2019-08-06 11:02:54 +02:00
def after_repasser_en_construction ( instructeur )
2018-11-26 19:12:56 +01:00
self . en_instruction_at = nil
2018-11-26 21:29:06 +01:00
2019-07-02 15:38:23 +02:00
save!
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :repasser_en_construction )
2018-11-26 19:12:56 +01:00
end
2019-08-06 11:02:54 +02:00
def after_repasser_en_instruction ( instructeur )
2019-07-02 15:38:23 +02:00
self . processed_at = nil
self . motivation = nil
2019-07-01 17:45:03 +02:00
attestation & . destroy
2019-07-02 15:38:23 +02:00
save!
DossierMailer . notify_revert_to_instruction ( self ) . deliver_later
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :repasser_en_instruction )
2019-07-01 17:45:03 +02:00
end
2019-08-06 11:02:54 +02:00
def after_accepter ( instructeur , motivation , justificatif = nil )
2018-11-26 19:12:56 +01:00
self . motivation = motivation
2019-07-02 15:38:23 +02:00
2019-02-18 17:52:15 +01:00
if justificatif
self . justificatif_motivation . attach ( justificatif )
end
2018-11-26 19:12:56 +01:00
if attestation . nil?
2019-07-02 15:38:23 +02:00
self . attestation = build_attestation
2018-11-26 19:12:56 +01:00
end
2019-07-02 15:38:23 +02:00
save!
2018-11-26 19:12:56 +01:00
NotificationMailer . send_closed_notification ( self ) . deliver_later
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :accepter , self )
2018-11-26 19:12:56 +01:00
end
2019-07-02 15:38:23 +02:00
def after_accepter_automatiquement
2019-01-16 11:00:25 +01:00
self . en_instruction_at || = Time . zone . now
if attestation . nil?
2019-07-02 15:38:23 +02:00
self . attestation = build_attestation
2019-01-16 11:00:25 +01:00
end
2019-07-02 15:38:23 +02:00
save!
2019-01-16 11:00:25 +01:00
NotificationMailer . send_closed_notification ( self ) . deliver_later
2019-05-02 16:22:16 +02:00
log_automatic_dossier_operation ( :accepter , self )
2019-01-16 11:00:25 +01:00
end
2019-08-06 11:02:54 +02:00
def after_refuser ( instructeur , motivation , justificatif = nil )
2018-11-26 19:12:56 +01:00
self . motivation = motivation
2019-07-02 15:38:23 +02:00
2019-02-18 17:52:15 +01:00
if justificatif
self . justificatif_motivation . attach ( justificatif )
end
2018-11-26 19:12:56 +01:00
2019-07-02 15:38:23 +02:00
save!
2018-11-26 19:12:56 +01:00
NotificationMailer . send_refused_notification ( self ) . deliver_later
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :refuser , self )
2018-11-26 19:12:56 +01:00
end
2019-08-06 11:02:54 +02:00
def after_classer_sans_suite ( instructeur , motivation , justificatif = nil )
2018-11-26 19:12:56 +01:00
self . motivation = motivation
2019-07-02 15:38:23 +02:00
2019-02-18 17:52:15 +01:00
if justificatif
self . justificatif_motivation . attach ( justificatif )
end
2018-11-26 19:12:56 +01:00
2019-07-02 15:38:23 +02:00
save!
2018-11-26 19:12:56 +01:00
NotificationMailer . send_without_continuation_notification ( self ) . deliver_later
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :classer_sans_suite , self )
2018-11-26 19:12:56 +01:00
end
2019-01-30 16:14:15 +01:00
def check_mandatory_champs
2019-09-12 11:26:22 +02:00
( champs + champs . filter ( & :repetition? ) . flat_map ( & :champs ) )
. filter ( & :mandatory_and_blank? )
2019-01-30 16:14:15 +01:00
. map do | champ |
" Le champ #{ champ . libelle . truncate ( 200 ) } doit être rempli. "
end
end
2019-08-06 11:02:54 +02:00
def modifier_annotations! ( instructeur )
2019-09-12 11:26:22 +02:00
champs_private . filter ( & :value_previously_changed? ) . each do | champ |
2019-08-06 11:02:54 +02:00
log_dossier_operation ( instructeur , :modifier_annotation , champ )
2019-05-02 16:23:47 +02:00
end
end
2019-05-02 16:24:24 +02:00
def demander_un_avis! ( avis )
log_dossier_operation ( avis . claimant , :demander_un_avis , avis )
end
2019-04-03 14:29:30 +02:00
def spreadsheet_columns
2019-09-18 21:09:52 +02:00
columns = [
2019-04-03 14:29:30 +02:00
[ 'ID' , id . to_s ] ,
[ 'Email' , user . email ] ,
[ 'Civilité' , individual & . gender ] ,
[ 'Nom' , individual & . nom ] ,
[ 'Prénom' , individual & . prenom ] ,
[ 'Date de naissance' , individual & . birthdate ] ,
[ 'Archivé' , :archived ] ,
[ 'État du dossier' , I18n . t ( state , scope : [ :activerecord , :attributes , :dossier , :state ] ) ] ,
[ 'Dernière mise à jour le' , :updated_at ] ,
2019-09-10 14:52:05 +02:00
[ 'Déposé le' , :en_construction_at ] ,
2019-07-04 15:02:25 +02:00
[ 'Passé en instruction le' , :en_instruction_at ] ,
2019-04-03 14:29:30 +02:00
[ 'Traité le' , :processed_at ] ,
[ 'Motivation de la décision' , :motivation ] ,
2019-08-06 11:02:54 +02:00
[ 'Instructeurs' , followers_instructeurs . map ( & :email ) . join ( ' ' ) ]
2019-09-18 21:09:52 +02:00
]
if procedure . routee?
columns << [ 'Groupe instructeur' , groupe_instructeur . label ]
end
columns + champs_for_export + annotations_for_export
2019-04-03 14:29:30 +02:00
end
def champs_for_export
champs . reject ( & :exclude_from_export? ) . map do | champ |
[ champ . libelle , champ . for_export ]
end
end
def annotations_for_export
champs_private . reject ( & :exclude_from_export? ) . map do | champ |
[ champ . libelle , champ . for_export ]
end
end
2019-07-01 15:55:37 +02:00
def attachments_downloadable?
2019-07-18 16:47:59 +02:00
! PiecesJustificativesService . liste_pieces_justificatives ( self ) . empty? && PiecesJustificativesService . pieces_justificatives_total_size ( self ) < Dossier :: TAILLE_MAX_ZIP
2019-07-01 15:55:37 +02:00
end
2019-07-31 15:49:18 +02:00
def update_with_france_connect ( fc_information )
2019-08-01 09:34:26 +02:00
self . individual = Individual . create_from_france_connect ( fc_information )
2019-07-31 15:49:18 +02:00
end
2017-12-05 17:43:32 +01:00
private
2019-05-02 16:22:16 +02:00
def log_dossier_operation ( author , operation , subject = nil )
DossierOperationLog . create_and_serialize (
dossier : self ,
2019-01-10 17:23:48 +01:00
operation : DossierOperationLog . operations . fetch ( operation ) ,
2019-05-02 16:22:16 +02:00
author : author ,
subject : subject
2018-11-26 21:29:06 +01:00
)
end
2019-05-02 16:22:16 +02:00
def log_automatic_dossier_operation ( operation , subject = nil )
DossierOperationLog . create_and_serialize (
dossier : self ,
operation : DossierOperationLog . operations . fetch ( operation ) ,
automatic_operation : true ,
subject : subject
2019-02-13 16:13:37 +01:00
)
end
2017-03-01 09:51:55 +01:00
def update_state_dates
2017-12-14 15:51:45 +01:00
if en_construction? && ! self . en_construction_at
2018-10-25 15:07:15 +02:00
self . en_construction_at = Time . zone . now
2017-12-14 15:53:02 +01:00
elsif en_instruction? && ! self . en_instruction_at
2018-10-25 15:07:15 +02:00
self . en_instruction_at = Time . zone . now
2017-03-01 09:51:55 +01:00
elsif TERMINE . include? ( state )
2018-10-25 15:07:15 +02:00
self . processed_at = Time . zone . now
2017-03-01 09:51:55 +01:00
end
end
2017-03-06 17:54:45 +01:00
2017-10-13 18:35:12 +02:00
def send_dossier_received
2019-05-23 14:28:14 +02:00
if saved_change_to_state? && en_instruction? && ! procedure . declarative_accepte?
2018-05-30 23:55:34 +02:00
NotificationMailer . send_dossier_received ( self ) . deliver_later
2017-05-26 20:01:57 +02:00
end
end
2017-10-11 15:36:40 +02:00
def send_draft_notification_email
2019-05-23 14:28:14 +02:00
if brouillon? && ! procedure . declarative?
2018-11-20 11:50:25 +01:00
DossierMailer . notify_new_draft ( self ) . deliver_later
2017-10-11 15:36:40 +02:00
end
end
2018-03-01 17:04:05 +01:00
def send_web_hook
if saved_change_to_state? && ! brouillon? && procedure . web_hook_url
WebHookJob . perform_later (
procedure ,
self
)
end
end
2015-08-10 11:05:06 +02:00
end