2024-04-29 00:17:15 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-04-25 12:09:11 +02:00
|
|
|
class Avis < ApplicationRecord
|
2018-02-28 15:46:27 +01:00
|
|
|
include EmailSanitizableConcern
|
|
|
|
|
2020-07-20 16:32:22 +02:00
|
|
|
belongs_to :dossier, inverse_of: :avis, touch: true, optional: false
|
2021-03-23 12:25:57 +01:00
|
|
|
belongs_to :experts_procedure, optional: false
|
2021-03-22 10:05:04 +01:00
|
|
|
belongs_to :claimant, polymorphic: true, optional: false
|
2017-04-25 17:02:54 +02:00
|
|
|
|
2019-03-01 17:16:56 +01:00
|
|
|
has_one_attached :piece_justificative_file
|
2020-03-03 12:52:35 +01:00
|
|
|
has_one_attached :introduction_file
|
2021-01-15 16:39:07 +01:00
|
|
|
has_one :expert, through: :experts_procedure
|
2021-02-25 09:30:16 +01:00
|
|
|
has_one :procedure, through: :experts_procedure
|
2019-03-01 17:16:56 +01:00
|
|
|
|
2023-01-31 16:06:31 +01:00
|
|
|
has_many :targeted_user_links, as: :target_model, dependent: :destroy, inverse_of: :target_model
|
2022-05-23 15:09:22 +02:00
|
|
|
|
2021-09-14 18:03:40 +02:00
|
|
|
FILE_MAX_SIZE = 20.megabytes
|
2021-01-18 13:50:24 +01:00
|
|
|
validates :piece_justificative_file,
|
|
|
|
content_type: AUTHORIZED_CONTENT_TYPES,
|
2021-11-24 10:04:20 +01:00
|
|
|
size: { less_than: FILE_MAX_SIZE }
|
2021-01-18 13:50:24 +01:00
|
|
|
|
|
|
|
validates :introduction_file,
|
|
|
|
content_type: AUTHORIZED_CONTENT_TYPES,
|
2021-11-24 10:04:20 +01:00
|
|
|
size: { less_than: FILE_MAX_SIZE }
|
2021-01-18 13:50:24 +01:00
|
|
|
|
2024-02-13 10:37:03 +01:00
|
|
|
validates :email, strict_email: true, allow_nil: true
|
2023-03-21 17:07:05 +01:00
|
|
|
validates :question_answer, inclusion: { in: [true, false] }, on: :update, if: -> { question_label.present? }
|
2021-11-24 10:04:20 +01:00
|
|
|
validates :piece_justificative_file, size: { less_than: FILE_MAX_SIZE }
|
|
|
|
validates :introduction_file, size: { less_than: FILE_MAX_SIZE }
|
2018-02-28 15:46:27 +01:00
|
|
|
before_validation -> { sanitize_email(:email) }
|
2023-03-28 15:38:13 +02:00
|
|
|
before_validation -> { strip_attribute(:question_label) }
|
2017-05-02 15:37:06 +02:00
|
|
|
|
2021-02-25 09:53:09 +01:00
|
|
|
default_scope { joins(:dossier) }
|
2017-04-27 12:17:50 +02:00
|
|
|
scope :with_answer, -> { where.not(answer: nil) }
|
|
|
|
scope :without_answer, -> { where(answer: nil) }
|
2018-01-15 21:53:30 +01:00
|
|
|
scope :for_dossier, -> (dossier_id) { where(dossier_id: dossier_id) }
|
2017-05-02 13:54:57 +02:00
|
|
|
scope :by_latest, -> { order(updated_at: :desc) }
|
2017-10-05 16:10:00 +02:00
|
|
|
scope :updated_since?, -> (date) { where('avis.updated_at > ?', date) }
|
2022-03-09 10:27:43 +01:00
|
|
|
scope :termine_expired, -> { unscope(:joins).where(dossier: Dossier.termine_expired) }
|
|
|
|
scope :en_construction_expired, -> { unscope(:joins).where(dossier: Dossier.en_construction_expired) }
|
2021-12-14 15:21:03 +01:00
|
|
|
scope :not_hidden_by_administration, -> { where(dossiers: { hidden_by_administration_at: nil }) }
|
2022-11-28 15:14:35 +01:00
|
|
|
scope :not_revoked, -> { where(revoked_at: nil) }
|
2023-04-03 17:05:17 +02:00
|
|
|
scope :not_termine, -> { where.not(dossiers: { state: Dossier::TERMINE }) }
|
|
|
|
|
2018-10-31 16:09:11 +01:00
|
|
|
# The form allows subtmitting avis requests to several emails at once,
|
|
|
|
# hence this virtual attribute.
|
|
|
|
attr_accessor :emails
|
2019-08-21 09:09:20 +02:00
|
|
|
attr_accessor :invite_linked_dossiers
|
2018-10-31 16:09:11 +01:00
|
|
|
|
2017-04-25 17:02:54 +02:00
|
|
|
def email_to_display
|
2021-02-28 22:19:49 +01:00
|
|
|
expert&.email
|
2017-04-25 17:02:54 +02:00
|
|
|
end
|
2017-05-02 15:37:06 +02:00
|
|
|
|
2019-04-03 14:29:30 +02:00
|
|
|
def spreadsheet_columns
|
|
|
|
[
|
|
|
|
['Dossier ID', dossier_id.to_s],
|
2023-03-10 14:38:37 +01:00
|
|
|
['Introduction', :introduction],
|
2019-04-03 14:29:30 +02:00
|
|
|
['Réponse', :answer],
|
2023-03-10 14:38:37 +01:00
|
|
|
['Question', :question_label],
|
|
|
|
['Réponse oui/non', :question_answer],
|
2019-04-03 14:29:30 +02:00
|
|
|
['Créé le', :created_at],
|
2020-01-28 12:42:30 +01:00
|
|
|
['Répondu le', :updated_at],
|
|
|
|
['Instructeur', claimant&.email],
|
2021-02-25 09:37:28 +01:00
|
|
|
['Expert', expert&.email]
|
2019-04-03 14:29:30 +02:00
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2022-08-30 21:41:36 +02:00
|
|
|
def updated_recently?
|
|
|
|
updated_at > 30.minutes.ago
|
|
|
|
end
|
|
|
|
|
2020-07-16 11:14:37 +02:00
|
|
|
def revoked?
|
|
|
|
revoked_at.present?
|
|
|
|
end
|
|
|
|
|
2023-01-26 16:19:06 +01:00
|
|
|
def remindable_by?(reminder)
|
|
|
|
revokable_by?(reminder)
|
2020-07-21 13:14:07 +02:00
|
|
|
end
|
|
|
|
|
2020-07-16 20:42:50 +02:00
|
|
|
def revokable_by?(revocator)
|
|
|
|
revocator.dossiers.include?(dossier) || revocator == claimant
|
|
|
|
end
|
|
|
|
|
|
|
|
def revoke_by!(revocator)
|
|
|
|
return false if !revokable_by?(revocator)
|
|
|
|
|
2020-07-16 11:14:37 +02:00
|
|
|
if answer.present?
|
|
|
|
update!(revoked_at: Time.zone.now)
|
|
|
|
else
|
|
|
|
destroy!
|
|
|
|
end
|
|
|
|
end
|
2023-01-23 21:02:59 +01:00
|
|
|
|
|
|
|
def remind_by!(revocator)
|
2023-01-26 16:19:06 +01:00
|
|
|
return false if !remindable_by?(revocator) || answer.present?
|
2023-04-26 07:45:11 +02:00
|
|
|
update_column(:reminded_at, Time.zone.now)
|
2023-01-23 21:02:59 +01:00
|
|
|
end
|
2023-03-28 15:38:13 +02:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def strip_attribute(attribute)
|
|
|
|
self[attribute] = self[attribute]&.strip&.presence
|
|
|
|
end
|
2017-04-25 12:09:11 +02:00
|
|
|
end
|