2018-03-06 13:44:29 +01:00
|
|
|
class Gestionnaire < ApplicationRecord
|
2018-03-14 17:25:43 +01:00
|
|
|
include CredentialsSyncableConcern
|
|
|
|
include EmailSanitizableConcern
|
|
|
|
|
2018-05-26 00:06:40 +02:00
|
|
|
devise :database_authenticatable, :registerable, :async,
|
2017-06-12 13:49:51 +02:00
|
|
|
:recoverable, :rememberable, :trackable, :validatable
|
2015-11-10 10:23:15 +01:00
|
|
|
|
2016-05-20 15:39:17 +02:00
|
|
|
has_and_belongs_to_many :administrateurs
|
2015-11-16 18:08:19 +01:00
|
|
|
|
2018-03-14 17:25:43 +01:00
|
|
|
before_validation -> { sanitize_email(:email) }
|
|
|
|
|
2016-06-20 17:37:04 +02:00
|
|
|
has_many :assign_to, dependent: :destroy
|
2018-02-19 19:25:34 +01:00
|
|
|
has_many :procedures, through: :assign_to
|
2019-03-18 14:43:05 +01:00
|
|
|
|
|
|
|
has_many :assign_to_with_email_notifications, -> { with_email_notifications }, class_name: 'AssignTo'
|
|
|
|
has_many :procedures_with_email_notifications, through: :assign_to_with_email_notifications, source: :procedure
|
|
|
|
|
2017-07-10 16:11:12 +02:00
|
|
|
has_many :dossiers, -> { state_not_brouillon }, through: :procedures
|
2019-06-07 14:59:49 +02:00
|
|
|
has_many :follows, -> { active }
|
2019-06-07 14:59:49 +02:00
|
|
|
has_many :previous_follows, -> { inactive }, class_name: 'Follow'
|
2018-01-23 18:23:07 +01:00
|
|
|
has_many :followed_dossiers, through: :follows, source: :dossier
|
2019-06-07 14:59:49 +02:00
|
|
|
has_many :previously_followed_dossiers, -> { distinct }, through: :previous_follows, source: :dossier
|
2017-04-25 12:09:11 +02:00
|
|
|
has_many :avis
|
2018-01-16 09:23:20 +01:00
|
|
|
has_many :dossiers_from_avis, through: :avis, source: :dossier
|
2019-02-01 18:11:55 +01:00
|
|
|
has_many :trusted_device_tokens
|
2016-03-14 16:49:12 +01:00
|
|
|
|
2018-02-19 19:25:34 +01:00
|
|
|
def visible_procedures
|
2018-12-03 13:57:59 +01:00
|
|
|
procedures.merge(Procedure.avec_lien.or(Procedure.archivees))
|
2018-02-19 19:25:34 +01:00
|
|
|
end
|
2017-01-05 12:44:15 +01:00
|
|
|
|
2017-07-17 11:28:14 +02:00
|
|
|
def follow(dossier)
|
2019-04-09 11:00:13 +02:00
|
|
|
begin
|
|
|
|
followed_dossiers << dossier
|
2019-06-07 14:59:14 +02:00
|
|
|
# If the user tries to follow a dossier she already follows,
|
|
|
|
# we just fail silently: it means the goal is already reached.
|
2019-04-09 11:00:13 +02:00
|
|
|
rescue ActiveRecord::RecordNotUnique
|
2019-06-07 14:59:14 +02:00
|
|
|
# Database uniqueness constraint
|
|
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
|
|
# ActiveRecord validation
|
|
|
|
raise unless e.record.errors.details.dig(:gestionnaire_id, 0, :error) == :taken
|
2019-04-09 11:00:13 +02:00
|
|
|
end
|
2017-07-17 11:28:14 +02:00
|
|
|
end
|
|
|
|
|
2017-10-05 14:10:49 +02:00
|
|
|
def unfollow(dossier)
|
2019-06-07 14:59:49 +02:00
|
|
|
f = follows.find_by(dossier: dossier)
|
|
|
|
if f.present?
|
|
|
|
f.update(unfollowed_at: Time.zone.now)
|
|
|
|
end
|
2017-10-05 14:10:49 +02:00
|
|
|
end
|
|
|
|
|
2017-07-17 13:13:20 +02:00
|
|
|
def follow?(dossier)
|
|
|
|
followed_dossiers.include?(dossier)
|
2016-07-18 18:24:29 +02:00
|
|
|
end
|
2016-08-02 14:49:41 +02:00
|
|
|
|
2018-02-19 11:20:57 +01:00
|
|
|
def assign_to_procedure(procedure)
|
2018-02-20 11:24:32 +01:00
|
|
|
begin
|
|
|
|
procedures << procedure
|
|
|
|
true
|
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
false
|
|
|
|
end
|
2018-02-19 11:20:57 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def remove_from_procedure(procedure)
|
2018-02-20 11:24:32 +01:00
|
|
|
!!(procedure.in?(procedures) && procedures.destroy(procedure))
|
2018-02-19 11:20:57 +01:00
|
|
|
end
|
|
|
|
|
2017-05-12 16:47:18 +02:00
|
|
|
def last_week_overview
|
2018-10-25 15:07:15 +02:00
|
|
|
start_date = Time.zone.now.beginning_of_week
|
2017-05-12 16:47:18 +02:00
|
|
|
|
|
|
|
active_procedure_overviews = procedures
|
2018-01-15 19:34:08 +01:00
|
|
|
.publiees
|
|
|
|
.map { |procedure| procedure.procedure_overview(start_date) }
|
|
|
|
.select(&:had_some_activities?)
|
2017-05-12 16:47:18 +02:00
|
|
|
|
2017-06-27 18:00:05 +02:00
|
|
|
if active_procedure_overviews.count == 0
|
2017-05-12 16:47:18 +02:00
|
|
|
nil
|
|
|
|
else
|
|
|
|
{
|
|
|
|
start_date: start_date,
|
2018-10-01 14:06:08 +02:00
|
|
|
procedure_overviews: active_procedure_overviews
|
2017-05-12 16:47:18 +02:00
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-10-23 11:39:54 +02:00
|
|
|
def procedure_presentation_and_errors_for_procedure_id(procedure_id)
|
|
|
|
assign_to.find_by(procedure_id: procedure_id).procedure_presentation_or_default_and_errors
|
2017-10-02 17:03:38 +02:00
|
|
|
end
|
|
|
|
|
2017-10-05 16:10:00 +02:00
|
|
|
def notifications_for_dossier(dossier)
|
|
|
|
follow = Follow
|
|
|
|
.includes(dossier: [:champs, :avis, :commentaires])
|
|
|
|
.find_by(gestionnaire: self, dossier: dossier)
|
|
|
|
|
|
|
|
if follow.present?
|
2019-06-07 14:41:24 +02:00
|
|
|
champs_publiques = follow.dossier.champs.updated_since?(follow.demande_seen_at).any?
|
2017-10-05 16:10:00 +02:00
|
|
|
|
2019-06-07 14:41:24 +02:00
|
|
|
pieces_justificatives = follow.dossier.pieces_justificatives.updated_since?(follow.demande_seen_at).any?
|
2017-10-05 16:10:00 +02:00
|
|
|
|
|
|
|
demande = champs_publiques || pieces_justificatives
|
|
|
|
|
2019-06-07 14:41:24 +02:00
|
|
|
annotations_privees = follow.dossier.champs_private.updated_since?(follow.annotations_privees_seen_at).any?
|
2017-10-05 16:10:00 +02:00
|
|
|
|
2019-06-07 14:41:24 +02:00
|
|
|
avis_notif = follow.dossier.avis.updated_since?(follow.avis_seen_at).any?
|
2017-10-05 16:10:00 +02:00
|
|
|
|
2019-06-07 14:41:24 +02:00
|
|
|
messagerie = dossier.commentaires
|
2019-06-07 17:09:19 +02:00
|
|
|
.where.not(email: OLD_CONTACT_EMAIL)
|
|
|
|
.where.not(email: CONTACT_EMAIL)
|
|
|
|
.updated_since?(follow.messagerie_seen_at).any?
|
2017-10-05 16:10:00 +02:00
|
|
|
|
|
|
|
annotations_hash(demande, annotations_privees, avis_notif, messagerie)
|
|
|
|
else
|
|
|
|
annotations_hash(false, false, false, false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-20 12:09:25 +01:00
|
|
|
def notifications_for_procedure(procedure, state = :en_cours)
|
|
|
|
dossiers = case state
|
|
|
|
when :termine
|
|
|
|
procedure.dossiers.termine
|
|
|
|
when :not_archived
|
|
|
|
procedure.dossiers.not_archived
|
2019-04-17 15:20:10 +02:00
|
|
|
when :all
|
|
|
|
procedure.dossiers
|
2018-02-20 12:09:25 +01:00
|
|
|
else
|
|
|
|
procedure.dossiers.en_cours
|
2018-10-23 18:45:21 +02:00
|
|
|
end
|
2017-10-05 16:10:00 +02:00
|
|
|
|
|
|
|
dossiers_id_with_notifications(dossiers)
|
|
|
|
end
|
|
|
|
|
2018-02-20 12:09:25 +01:00
|
|
|
def notifications_per_procedure(state = :en_cours)
|
|
|
|
dossiers = case state
|
|
|
|
when :termine
|
|
|
|
Dossier.termine
|
|
|
|
when :not_archived
|
|
|
|
Dossier.not_archived
|
|
|
|
else
|
|
|
|
Dossier.en_cours
|
2018-10-23 18:45:21 +02:00
|
|
|
end
|
2017-10-05 16:10:00 +02:00
|
|
|
|
|
|
|
Dossier.where(id: dossiers_id_with_notifications(dossiers)).group(:procedure_id).count
|
|
|
|
end
|
|
|
|
|
2019-02-18 17:05:30 +01:00
|
|
|
def create_trusted_device_token
|
2019-02-01 18:11:55 +01:00
|
|
|
trusted_device_token = trusted_device_tokens.create
|
|
|
|
trusted_device_token.token
|
2018-10-03 11:11:02 +02:00
|
|
|
end
|
|
|
|
|
2017-10-05 16:10:00 +02:00
|
|
|
def dossiers_id_with_notifications(dossiers)
|
2018-10-23 18:45:21 +02:00
|
|
|
dossiers = dossiers.followed_by(self)
|
|
|
|
|
2017-10-05 16:10:00 +02:00
|
|
|
updated_demandes = dossiers
|
|
|
|
.joins(:champs)
|
|
|
|
.where('champs.updated_at > follows.demande_seen_at')
|
|
|
|
|
|
|
|
updated_pieces_justificatives = dossiers
|
|
|
|
.joins(:pieces_justificatives)
|
|
|
|
.where('pieces_justificatives.updated_at > follows.demande_seen_at')
|
|
|
|
|
|
|
|
updated_annotations = dossiers
|
|
|
|
.joins(:champs_private)
|
|
|
|
.where('champs.updated_at > follows.annotations_privees_seen_at')
|
|
|
|
|
|
|
|
updated_avis = dossiers
|
|
|
|
.joins(:avis)
|
|
|
|
.where('avis.updated_at > follows.avis_seen_at')
|
|
|
|
|
|
|
|
updated_messagerie = dossiers
|
|
|
|
.joins(:commentaires)
|
|
|
|
.where('commentaires.updated_at > follows.messagerie_seen_at')
|
2018-05-31 15:43:57 +02:00
|
|
|
.where.not(commentaires: { email: OLD_CONTACT_EMAIL })
|
|
|
|
.where.not(commentaires: { email: CONTACT_EMAIL })
|
2017-10-05 16:10:00 +02:00
|
|
|
|
2018-01-15 14:42:48 +01:00
|
|
|
[
|
|
|
|
updated_demandes,
|
|
|
|
updated_pieces_justificatives,
|
|
|
|
updated_annotations,
|
|
|
|
updated_avis,
|
|
|
|
updated_messagerie
|
2018-01-15 21:34:32 +01:00
|
|
|
].flat_map { |query| query.distinct.ids }.uniq
|
2017-10-05 16:10:00 +02:00
|
|
|
end
|
2018-10-23 18:46:45 +02:00
|
|
|
|
|
|
|
def mark_tab_as_seen(dossier, tab)
|
|
|
|
attributes = {}
|
2018-10-25 15:07:15 +02:00
|
|
|
attributes["#{tab}_seen_at"] = Time.zone.now
|
2018-10-23 18:46:45 +02:00
|
|
|
Follow.where(gestionnaire: self, dossier: dossier).update_all(attributes)
|
|
|
|
end
|
|
|
|
|
|
|
|
def invite!
|
|
|
|
reset_password_token = set_reset_password_token
|
|
|
|
|
|
|
|
GestionnaireMailer.invite_gestionnaire(self, reset_password_token).deliver_later
|
|
|
|
end
|
|
|
|
|
2018-11-08 17:13:48 +01:00
|
|
|
def feature_enabled?(feature)
|
|
|
|
Flipflop.feature_set.feature(feature)
|
|
|
|
features[feature.to_s]
|
|
|
|
end
|
|
|
|
|
|
|
|
def disable_feature(feature)
|
|
|
|
Flipflop.feature_set.feature(feature)
|
|
|
|
features.delete(feature.to_s)
|
|
|
|
save
|
|
|
|
end
|
|
|
|
|
|
|
|
def enable_feature(feature)
|
|
|
|
Flipflop.feature_set.feature(feature)
|
|
|
|
features[feature.to_s] = true
|
|
|
|
save
|
|
|
|
end
|
|
|
|
|
2019-01-10 10:41:03 +01:00
|
|
|
def young_login_token?
|
2019-02-01 18:11:55 +01:00
|
|
|
trusted_device_token = trusted_device_tokens.order(created_at: :desc).first
|
2019-02-04 11:04:55 +01:00
|
|
|
trusted_device_token&.token_young?
|
2019-01-10 10:41:03 +01:00
|
|
|
end
|
|
|
|
|
2019-03-13 17:59:33 +01:00
|
|
|
def email_notification_data
|
|
|
|
procedures_with_email_notifications
|
|
|
|
.reduce([]) do |acc, procedure|
|
|
|
|
|
|
|
|
h = {
|
|
|
|
nb_en_construction: procedure.dossiers.en_construction.count,
|
2019-04-17 15:20:10 +02:00
|
|
|
nb_notification: notifications_for_procedure(procedure, :all).count
|
2019-03-13 17:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if h[:nb_en_construction] > 0 || h[:nb_notification] > 0
|
|
|
|
h[:procedure_id] = procedure.id
|
|
|
|
h[:procedure_libelle] = procedure.libelle
|
|
|
|
acc << h
|
|
|
|
end
|
|
|
|
|
|
|
|
acc
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-10-23 18:46:45 +02:00
|
|
|
private
|
|
|
|
|
|
|
|
def annotations_hash(demande, annotations_privees, avis, messagerie)
|
|
|
|
{
|
|
|
|
demande: demande,
|
|
|
|
annotations_privees: annotations_privees,
|
|
|
|
avis: avis,
|
|
|
|
messagerie: messagerie
|
|
|
|
}
|
|
|
|
end
|
2015-09-22 10:15:12 +02:00
|
|
|
end
|