demarches-normaliennes/app/models/dossier.rb

354 lines
11 KiB
Ruby
Raw Normal View History

2015-08-10 11:05:06 +02:00
class Dossier < ActiveRecord::Base
include SpreadsheetArchitect
2016-02-19 16:59:18 +01:00
enum state: {draft: 'draft',
initiated: 'initiated',
replied: 'replied', #action utilisateur demandé
updated: 'updated', #etude par l'administration en cours
validated: 'validated',
2015-11-19 18:04:09 +01:00
submitted: 'submitted',
received: 'received',
closed: 'closed',
refused: 'refused',
without_continuation: 'without_continuation'
}
2015-09-24 11:45:00 +02:00
has_one :etablissement, dependent: :destroy
has_one :entreprise, dependent: :destroy
2016-08-30 11:18:43 +02:00
has_one :individual, dependent: :destroy
has_many :cerfa, dependent: :destroy
2015-09-24 11:45:00 +02:00
has_many :pieces_justificatives, dependent: :destroy
has_many :champs, class_name: 'ChampPublic', dependent: :destroy
has_many :champs_private, class_name: 'ChampPrivate', dependent: :destroy
has_many :quartier_prioritaires, dependent: :destroy
2016-01-18 12:03:18 +01:00
has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :follows
2016-12-21 17:26:31 +01:00
has_many :notifications, dependent: :destroy
belongs_to :procedure
2015-09-23 12:16:21 +02:00
belongs_to :user
2016-08-30 11:18:43 +02:00
accepts_nested_attributes_for :individual
delegate :siren, to: :entreprise
delegate :siret, to: :etablissement, allow_nil: true
delegate :types_de_piece_justificative, to: :procedure
2015-11-05 11:21:44 +01:00
delegate :types_de_champ, to: :procedure
delegate :france_connect_information, to: :user
after_save :build_default_champs, if: Proc.new { procedure_id_changed? }
2016-08-30 11:18:43 +02:00
after_save :build_default_individual, if: Proc.new { procedure.for_individual? }
2016-12-26 11:57:08 +01:00
after_save :internal_notification
validates :user, presence: true
2015-08-21 11:37:13 +02:00
BROUILLON = %w(draft)
NOUVEAUX = %w(initiated)
OUVERT = %w(updated replied)
WAITING_FOR_GESTIONNAIRE = %w(updated)
2015-11-30 14:48:37 +01:00
WAITING_FOR_USER = %w(replied validated)
EN_CONSTRUCTION = %w(initiated updated replied)
VALIDES = %w(validated)
DEPOSES = %w(submitted)
EN_INSTRUCTION = %w(submitted received)
A_INSTRUIRE = %w(received)
TERMINE = %w(closed refused without_continuation)
2016-12-01 19:18:15 +01:00
ALL_STATE = %w(initiated updated replied validated submitted received closed refused without_continuation)
2015-11-19 18:04:09 +01:00
def unreaded_notifications
@unreaded_notif ||= notifications.where(already_read: false)
end
def first_unread_notification
unreaded_notifications.order("created_at ASC").first
end
2016-03-17 14:50:10 +01:00
def retrieve_last_piece_justificative_by_type(type)
pieces_justificatives.where(type_de_piece_justificative_id: type).last
end
2016-03-17 14:50:10 +01:00
def retrieve_all_piece_justificative_by_type(type)
pieces_justificatives.where(type_de_piece_justificative_id: type).order(created_at: :DESC)
end
def build_default_champs
2015-11-05 11:21:44 +01:00
procedure.types_de_champ.each do |type_de_champ|
ChampPublic.create(type_de_champ_id: type_de_champ.id, dossier_id: id)
end
procedure.types_de_champ_private.each do |type_de_champ|
ChampPrivate.create(type_de_champ_id: type_de_champ.id, dossier_id: id)
end
end
2016-08-30 11:18:43 +02:00
def build_default_individual
if Individual.where(dossier_id: self.id).count == 0
Individual.create(dossier: self)
end
2016-08-30 11:18:43 +02:00
end
def ordered_champs
2016-06-21 12:41:28 +02:00
champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place')
end
def ordered_champs_private
champs_private.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place')
end
2016-10-07 15:16:03 +02:00
def ordered_pieces_justificatives
champs.joins(', types_de_piece_justificative').where("pieces_justificatives.type_de_piece_justificative_id = types_de_piece_justificative.id AND types_de_piece_justificative.procedure_id = #{procedure.id}").order('order_place ASC')
end
def ordered_commentaires
commentaires.order(created_at: :desc)
end
def next_step! role, action
unless %w(initiate follow update comment valid submit receive refuse without_continuation close).include?(action)
fail 'action is not valid'
end
2015-10-05 16:42:29 +02:00
unless %w(user gestionnaire).include?(role)
fail 'role is not valid'
end
if role == 'user'
case action
when 'initiate'
if draft?
initiated!
end
when 'submit'
if validated?
submitted!
end
when 'update'
if replied?
updated!
end
when 'comment'
if replied?
updated!
end
end
elsif role == 'gestionnaire'
case action
when 'comment'
if updated?
replied!
elsif initiated?
replied!
end
when 'follow'
if initiated?
updated!
end
when 'valid'
if updated?
validated!
elsif replied?
validated!
elsif initiated?
validated!
end
when 'receive'
if submitted?
received!
end
when 'close'
if received?
closed!
end
when 'refuse'
if received?
refused!
end
when 'without_continuation'
if received?
without_continuation!
end
end
end
state
end
def brouillon?
BROUILLON.include?(state)
end
def self.all_state order = 'ASC'
where(state: ALL_STATE, archived: false).order("updated_at #{order}")
end
def self.brouillon order = 'ASC'
where(state: BROUILLON, archived: false).order("updated_at #{order}")
end
def self.nouveaux order = 'ASC'
where(state: NOUVEAUX, archived: false).order("updated_at #{order}")
end
def self.waiting_for_gestionnaire order = 'ASC'
where(state: WAITING_FOR_GESTIONNAIRE, archived: false).order("updated_at #{order}")
end
def self.waiting_for_user order = 'ASC'
where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}")
end
def self.en_construction order = 'ASC'
where(state: EN_CONSTRUCTION, archived: false).order("updated_at #{order}")
2016-08-22 16:10:48 +02:00
end
def self.ouvert order = 'ASC'
where(state: OUVERT, archived: false).order("updated_at #{order}")
end
def self.valides order = 'ASC'
where(state: VALIDES, archived: false).order("updated_at #{order}")
end
def self.fige order = 'ASC'
where(state: VALIDES, archived: false).order("updated_at #{order}")
end
def self.deposes order = 'ASC'
where(state: DEPOSES, archived: false).order("updated_at #{order}")
end
def self.a_instruire order = 'ASC'
where(state: A_INSTRUIRE, archived: false).order("updated_at #{order}")
end
def self.en_instruction order = 'ASC'
where(state: EN_INSTRUCTION, archived: false).order("updated_at #{order}")
end
def self.termine order = 'ASC'
where(state: TERMINE, archived: false).order("updated_at #{order}")
end
2016-02-02 18:37:38 +01:00
def cerfa_available?
procedure.cerfa_flag? && cerfa.size != 0
2016-02-02 18:37:38 +01:00
end
2016-11-14 17:43:34 +01:00
def convert_specific_hash_values_to_string(hash_to_convert)
hash = {}
hash_to_convert.each do |key, value|
value = value.to_s if !value.kind_of?(Time) && !value.nil?
hash.store(key, value)
end
return hash
end
2016-11-14 17:43:34 +01:00
def convert_specific_array_values_to_string(array_to_convert)
array = []
array_to_convert.each do |value|
value = value.to_s if !value.kind_of?(Time) && !value.nil?
array << value
end
return array
end
def export_entreprise_data
2016-10-07 15:34:10 +02:00
unless entreprise.nil?
etablissement_attr = EtablissementCsvSerializer.new(self.etablissement).attributes.map { |k, v| ["etablissement.#{k}".parameterize.underscore.to_sym, v] }.to_h
entreprise_attr = EntrepriseSerializer.new(self.entreprise).attributes.map { |k, v| ["entreprise.#{k}".parameterize.underscore.to_sym, v] }.to_h
else
etablissement_attr = EtablissementSerializer.new(Etablissement.new).attributes.map { |k, v| ["etablissement.#{k}".parameterize.underscore.to_sym, v] }.to_h
entreprise_attr = EntrepriseSerializer.new(Entreprise.new).attributes.map { |k, v| ["entreprise.#{k}".parameterize.underscore.to_sym, v] }.to_h
2016-10-07 15:34:10 +02:00
end
2016-11-14 17:43:34 +01:00
return convert_specific_hash_values_to_string(etablissement_attr.merge(entreprise_attr))
end
2016-10-07 15:34:10 +02:00
def export_default_columns
dossier_attr = DossierSerializer.new(self).attributes
2016-11-14 17:43:34 +01:00
dossier_attr = convert_specific_hash_values_to_string(dossier_attr)
dossier_attr = dossier_attr.merge(self.export_entreprise_data)
return dossier_attr
2016-02-19 16:59:18 +01:00
end
def spreadsheet_columns
self.export_default_columns.to_a
end
def data_with_champs
serialized_dossier = DossierProcedureSerializer.new(self)
data = serialized_dossier.attributes.values
data += self.champs.order('type_de_champ_id ASC').map(&:value)
data += self.export_entreprise_data.values
return data
end
def export_headers
serialized_dossier = DossierProcedureSerializer.new(self)
headers = serialized_dossier.attributes.keys
headers += self.procedure.types_de_champ.order('id ASC').map { |types_de_champ| types_de_champ.libelle.parameterize.underscore.to_sym }
headers += self.export_entreprise_data.keys
return headers
end
def self.export_full_generation(dossiers, format)
if dossiers && !dossiers.empty?
data = []
headers = dossiers.first.export_headers
dossiers.each do |dossier|
data << dossier.convert_specific_array_values_to_string(dossier.data_with_champs)
end
if ["csv"].include?(format)
return SpreadsheetArchitect.to_csv(data: data, headers: headers)
elsif ["xlsx"].include?(format)
return SpreadsheetArchitect.to_xlsx(data: data, headers: headers)
elsif ["ods"].include?(format)
return SpreadsheetArchitect.to_ods(data: data, headers: headers)
end
end
end
2017-01-26 17:54:04 +01:00
def followers_gestionnaires_emails
follows.includes(:gestionnaire).map { |f| f.gestionnaire }.pluck(:email).join(' ')
end
def reset!
etablissement.destroy
2016-10-05 15:01:31 +02:00
entreprise.destroy
update_attributes(autorisation_donnees: false)
end
def total_follow
follows.size
end
2016-08-08 14:12:16 +02:00
def submit!
self.deposit_datetime= DateTime.now
next_step! 'user', 'submit'
NotificationMailer.dossier_submitted(self).deliver_now!
end
2016-09-13 12:17:56 +02:00
def read_only?
validated? || received? || submitted? || closed? || refused? || without_continuation?
end
def owner? email
user.email == email
end
def invite_by_user? email
(invites_user.pluck :email).include? email
end
2016-12-26 11:57:08 +01:00
private
def internal_notification
if state_changed? && state == 'submitted'
NotificationService.new('submitted', self.id).notify
end
end
2015-08-10 11:05:06 +02:00
end