2016-03-22 17:36:36 +01:00
|
|
|
|
class PiecesJustificativesService
|
2024-03-08 17:14:21 +01:00
|
|
|
|
def initialize(user_profile:, export_template:)
|
2024-02-07 17:33:34 +01:00
|
|
|
|
@user_profile = user_profile
|
2024-03-08 17:14:21 +01:00
|
|
|
|
@export_template = export_template
|
2024-02-07 17:33:34 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def liste_documents(dossiers)
|
2022-04-05 15:30:23 +02:00
|
|
|
|
bill_ids = []
|
|
|
|
|
|
|
|
|
|
docs = dossiers.in_batches.flat_map do |batch|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
pjs = pjs_for_champs(batch) +
|
2022-04-04 23:53:29 +02:00
|
|
|
|
pjs_for_commentaires(batch) +
|
2023-10-03 17:07:25 +02:00
|
|
|
|
pjs_for_dossier(batch) +
|
2024-02-07 17:33:34 +01:00
|
|
|
|
pjs_for_avis(batch)
|
2022-04-05 15:10:22 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
if liste_documents_allows?(:with_bills)
|
2022-04-05 15:30:23 +02:00
|
|
|
|
# some bills are shared among operations
|
|
|
|
|
# so first, all the bill_ids are fetched
|
|
|
|
|
operation_logs, some_bill_ids = operation_logs_and_signature_ids(batch)
|
|
|
|
|
|
|
|
|
|
pjs += operation_logs
|
|
|
|
|
bill_ids += some_bill_ids
|
2022-04-05 15:10:22 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
pjs
|
2022-04-04 23:53:29 +02:00
|
|
|
|
end
|
2022-04-05 15:30:23 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
if liste_documents_allows?(:with_bills)
|
2022-04-05 15:30:23 +02:00
|
|
|
|
# then the bills are retrieved without duplication
|
|
|
|
|
docs += signatures(bill_ids.uniq)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
docs
|
2019-07-01 15:55:37 +02:00
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def generate_dossiers_export(dossiers)
|
2022-04-06 00:20:52 +02:00
|
|
|
|
return [] if dossiers.empty?
|
|
|
|
|
|
2022-04-07 15:23:18 +02:00
|
|
|
|
pdfs = []
|
|
|
|
|
|
2022-04-06 00:20:52 +02:00
|
|
|
|
procedure = dossiers.first.procedure
|
2024-03-05 14:00:54 +01:00
|
|
|
|
dossiers = dossiers.includes(:individual, :traitement, :etablissement, user: :france_connect_informations, avis: :expert, commentaires: [:instructeur, :expert])
|
2022-07-21 13:05:30 +02:00
|
|
|
|
dossiers = DossierPreloader.new(dossiers).in_batches
|
|
|
|
|
dossiers.each do |dossier|
|
|
|
|
|
dossier.association(:procedure).target = procedure
|
|
|
|
|
|
2022-04-07 15:23:18 +02:00
|
|
|
|
pdf = ApplicationController
|
|
|
|
|
.render(template: 'dossiers/show', formats: [:pdf],
|
|
|
|
|
assigns: {
|
2024-03-07 08:39:32 +01:00
|
|
|
|
acls: acl_for_dossier_export(procedure),
|
2022-07-21 13:05:30 +02:00
|
|
|
|
dossier: dossier
|
2022-04-07 15:23:18 +02:00
|
|
|
|
})
|
|
|
|
|
|
2022-11-18 11:30:21 +01:00
|
|
|
|
a = ActiveStorage::FakeAttachment.new(
|
2022-04-07 15:23:18 +02:00
|
|
|
|
file: StringIO.new(pdf),
|
|
|
|
|
filename: "export-#{dossier.id}.pdf",
|
|
|
|
|
name: 'pdf_export_for_instructeur',
|
|
|
|
|
id: dossier.id,
|
|
|
|
|
created_at: dossier.updated_at
|
|
|
|
|
)
|
|
|
|
|
|
2024-03-08 17:14:21 +01:00
|
|
|
|
if @export_template
|
|
|
|
|
pdfs << @export_template.attachment_and_path(dossier, a)
|
|
|
|
|
else
|
|
|
|
|
pdfs << ActiveStorage::DownloadableFile.pj_and_path(dossier.id, a)
|
|
|
|
|
end
|
2022-04-07 15:23:18 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
pdfs
|
2021-04-29 17:29:47 +02:00
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def self.serialize_types_de_champ_as_type_pj(revision)
|
|
|
|
|
tdcs = revision.types_de_champ_public.filter { |type_champ| type_champ.old_pj.present? }
|
|
|
|
|
tdcs.map.with_index do |type_champ, order_place|
|
|
|
|
|
description = type_champ.description
|
|
|
|
|
if /^(?<original_description>.*?)(?:[\r\n]+)Récupérer le formulaire vierge pour mon dossier : (?<lien_demarche>http.*)$/m =~ description
|
|
|
|
|
description = original_description
|
|
|
|
|
end
|
|
|
|
|
{
|
|
|
|
|
id: type_champ.old_pj[:stable_id],
|
|
|
|
|
libelle: type_champ.libelle,
|
|
|
|
|
description: description,
|
|
|
|
|
order_place: order_place,
|
|
|
|
|
lien_demarche: lien_demarche
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-03-07 08:39:32 +01:00
|
|
|
|
def acl_for_dossier_export(procedure)
|
2024-02-07 17:33:34 +01:00
|
|
|
|
case @user_profile
|
|
|
|
|
when Expert
|
2024-02-19 16:21:26 +01:00
|
|
|
|
{
|
2024-03-07 08:39:32 +01:00
|
|
|
|
include_messagerie: procedure.allow_expert_messaging,
|
2024-03-06 17:28:47 +01:00
|
|
|
|
include_infos_administration: false,
|
2024-02-19 16:21:26 +01:00
|
|
|
|
include_avis_for_expert: true,
|
|
|
|
|
only_for_expert: @user_profile
|
|
|
|
|
}
|
2024-02-07 17:33:34 +01:00
|
|
|
|
when Instructeur, Administrateur
|
2024-02-19 16:21:26 +01:00
|
|
|
|
{
|
2024-03-07 08:39:32 +01:00
|
|
|
|
include_messagerie: true,
|
2024-02-19 16:21:26 +01:00
|
|
|
|
include_infos_administration: true,
|
|
|
|
|
include_avis_for_expert: true,
|
|
|
|
|
only_for_export: false
|
|
|
|
|
}
|
2024-02-07 17:33:34 +01:00
|
|
|
|
when User
|
2024-02-19 16:21:26 +01:00
|
|
|
|
{
|
2024-03-07 08:39:32 +01:00
|
|
|
|
include_messagerie: true,
|
2024-02-19 16:21:26 +01:00
|
|
|
|
include_infos_administration: false,
|
|
|
|
|
include_avis_for_expert: false, # should be true, expert can use the messagerie, why not provide avis ?
|
|
|
|
|
only_for_expert: false
|
|
|
|
|
}
|
2024-02-07 17:33:34 +01:00
|
|
|
|
else
|
|
|
|
|
raise 'not supported'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2021-04-29 16:16:12 +02:00
|
|
|
|
private
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def liste_documents_allows?(scope)
|
|
|
|
|
case @user_profile
|
|
|
|
|
when Expert
|
|
|
|
|
{
|
|
|
|
|
with_bills: false,
|
|
|
|
|
with_champs_private: false,
|
|
|
|
|
with_avis_piece_justificative: false
|
|
|
|
|
}
|
|
|
|
|
when Instructeur
|
|
|
|
|
{
|
|
|
|
|
with_bills: false,
|
|
|
|
|
with_champs_private: true,
|
|
|
|
|
with_avis_piece_justificative: true
|
|
|
|
|
}
|
|
|
|
|
when Administrateur
|
|
|
|
|
{
|
|
|
|
|
with_bills: true,
|
|
|
|
|
with_champs_private: true,
|
|
|
|
|
with_avis_piece_justificative: true
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
raise 'not supported'
|
|
|
|
|
end.fetch(scope)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def pjs_for_champs(dossiers)
|
2022-04-01 15:26:03 +02:00
|
|
|
|
champs = Champ
|
2022-10-20 10:14:47 +02:00
|
|
|
|
.joins(:piece_justificative_file_attachments)
|
2022-04-04 23:08:01 +02:00
|
|
|
|
.where(type: "Champs::PieceJustificativeChamp", dossier: dossiers)
|
2020-06-24 12:56:58 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
if !liste_documents_allows?(:with_champs_private)
|
2022-04-01 15:26:03 +02:00
|
|
|
|
champs = champs.where(private: false)
|
|
|
|
|
end
|
2020-06-24 12:56:58 +02:00
|
|
|
|
|
2022-04-04 23:08:01 +02:00
|
|
|
|
champ_id_dossier_id = champs
|
|
|
|
|
.pluck(:id, :dossier_id)
|
|
|
|
|
.to_h
|
|
|
|
|
|
2022-04-01 15:26:03 +02:00
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:08:01 +02:00
|
|
|
|
.where(record_type: "Champ", record_id: champ_id_dossier_id.keys)
|
2022-04-08 14:45:51 +02:00
|
|
|
|
.filter { |a| safe_attachment(a) }
|
2024-05-01 21:23:41 +02:00
|
|
|
|
.group_by(&:record_id)
|
|
|
|
|
.flat_map do |champ_id, attachments|
|
|
|
|
|
dossier_id = champ_id_dossier_id[champ_id]
|
|
|
|
|
|
|
|
|
|
attachments.map.with_index do |attachment, index|
|
|
|
|
|
if @export_template
|
|
|
|
|
@export_template.attachment_and_path(Dossier.find(dossier_id), attachment, index: index, row_index: attachment.record.row_index)
|
|
|
|
|
else
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, attachment)
|
|
|
|
|
end
|
2024-03-08 17:14:21 +01:00
|
|
|
|
end
|
2022-04-04 23:08:01 +02:00
|
|
|
|
end
|
2019-09-03 15:17:19 +02:00
|
|
|
|
end
|
2020-06-24 12:56:58 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def pjs_for_commentaires(dossiers)
|
2022-04-04 23:15:10 +02:00
|
|
|
|
commentaire_id_dossier_id = Commentaire
|
2024-02-13 08:10:22 +01:00
|
|
|
|
.joins(:piece_jointe_attachments)
|
2022-04-04 23:15:10 +02:00
|
|
|
|
.where(dossier: dossiers)
|
|
|
|
|
.pluck(:id, :dossier_id)
|
|
|
|
|
.to_h
|
2022-04-01 15:22:19 +02:00
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:15:10 +02:00
|
|
|
|
.where(record_type: "Commentaire", record_id: commentaire_id_dossier_id.keys)
|
2022-04-08 14:45:51 +02:00
|
|
|
|
.filter { |a| safe_attachment(a) }
|
2022-04-04 23:15:10 +02:00
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = commentaire_id_dossier_id[a.record_id]
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2020-06-24 12:56:58 +02:00
|
|
|
|
end
|
2020-12-08 16:34:38 +01:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def pjs_for_dossier(dossiers)
|
2022-04-05 15:10:22 +02:00
|
|
|
|
motivations(dossiers) +
|
2022-04-04 23:40:20 +02:00
|
|
|
|
attestations(dossiers) +
|
|
|
|
|
etablissements(dossiers)
|
2020-12-08 16:34:38 +01:00
|
|
|
|
end
|
2022-04-01 16:21:38 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def etablissements(dossiers)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
etablissement_id_dossier_id = Etablissement
|
|
|
|
|
.where(dossier: dossiers)
|
|
|
|
|
.pluck(:id, :dossier_id)
|
|
|
|
|
.to_h
|
2022-04-04 14:40:49 +02:00
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(record_type: "Etablissement", record_id: etablissement_id_dossier_id.keys)
|
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = etablissement_id_dossier_id[a.record_id]
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2022-04-04 14:40:49 +02:00
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def motivations(dossiers)
|
2022-04-04 14:40:49 +02:00
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(record_type: "Dossier", name: "justificatif_motivation", record_id: dossiers)
|
2022-04-08 14:45:51 +02:00
|
|
|
|
.filter { |a| safe_attachment(a) }
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = a.record_id
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2022-04-04 14:40:49 +02:00
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def attestations(dossiers)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
attestation_id_dossier_id = Attestation
|
2022-04-04 14:40:49 +02:00
|
|
|
|
.joins(:pdf_attachment)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(dossier: dossiers)
|
|
|
|
|
.pluck(:id, :dossier_id)
|
|
|
|
|
.to_h
|
2022-04-04 14:40:49 +02:00
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(record_type: "Attestation", record_id: attestation_id_dossier_id.keys)
|
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = attestation_id_dossier_id[a.record_id]
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2022-04-04 14:40:49 +02:00
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def pjs_for_avis(dossiers)
|
|
|
|
|
avis_ids_dossier_id_query = Avis.joins(:dossier).where(dossier: dossiers)
|
2024-02-19 16:22:08 +01:00
|
|
|
|
if !liste_documents_allows?(:with_avis_piece_justificative)
|
|
|
|
|
avis_ids_dossier_id_query = avis_ids_dossier_id_query.where(confidentiel: false)
|
|
|
|
|
end
|
|
|
|
|
if @user_profile.is_a?(Expert)
|
|
|
|
|
avis_ids = Avis.joins(:dossier, experts_procedure: :expert)
|
|
|
|
|
.where(experts_procedure: { expert: @user_profile })
|
|
|
|
|
.where(dossier: dossiers)
|
|
|
|
|
.pluck(:id)
|
|
|
|
|
avis_ids_dossier_id_query = avis_ids_dossier_id_query.or(Avis.where(id: avis_ids))
|
|
|
|
|
end
|
2023-10-03 17:07:25 +02:00
|
|
|
|
avis_ids_dossier_id = avis_ids_dossier_id_query.pluck(:id, :dossier_id).to_h
|
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2024-02-19 16:21:26 +01:00
|
|
|
|
.where(record_type: "Avis", record_id: avis_ids_dossier_id.keys)
|
2023-10-03 17:07:25 +02:00
|
|
|
|
.filter { |a| safe_attachment(a) }
|
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = avis_ids_dossier_id[a.record_id]
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def operation_logs_and_signature_ids(dossiers)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
dol_id_dossier_id_bill_id = DossierOperationLog
|
2022-11-18 11:31:23 +01:00
|
|
|
|
.where(dossier: dossiers, data: nil)
|
|
|
|
|
.pluck(:bill_signature_id, :id, :dossier_id)
|
|
|
|
|
dol_id_data_bill_id = DossierOperationLog
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(dossier: dossiers)
|
2022-11-18 11:31:23 +01:00
|
|
|
|
.with_data
|
|
|
|
|
.pluck(:bill_signature_id, :id, :dossier_id, :data, :digest, :created_at)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
|
|
|
|
|
dol_id_dossier_id = dol_id_dossier_id_bill_id
|
2022-11-18 11:31:23 +01:00
|
|
|
|
.map { |_, dol_id, dossier_id| [dol_id, dossier_id] }
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.to_h
|
2022-04-01 16:21:38 +02:00
|
|
|
|
|
2022-11-18 11:31:23 +01:00
|
|
|
|
bill_ids = (dol_id_dossier_id_bill_id + dol_id_data_bill_id)
|
|
|
|
|
.map(&:first)
|
|
|
|
|
.uniq
|
|
|
|
|
.compact
|
2022-04-01 18:01:48 +02:00
|
|
|
|
|
|
|
|
|
serialized_dols = ActiveStorage::Attachment
|
|
|
|
|
.includes(:blob)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.where(record_type: "DossierOperationLog", record_id: dol_id_dossier_id.keys)
|
|
|
|
|
.map do |a|
|
|
|
|
|
dossier_id = dol_id_dossier_id[a.record_id]
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2022-11-18 11:31:23 +01:00
|
|
|
|
serialized_dols += dol_id_data_bill_id.map do |_, id, dossier_id, data, digest, created_at|
|
|
|
|
|
a = ActiveStorage::FakeAttachment.new(
|
|
|
|
|
file: StringIO.new(data.to_json),
|
|
|
|
|
filename: "operation-#{digest}.json",
|
|
|
|
|
name: 'serialized',
|
|
|
|
|
id: id,
|
|
|
|
|
created_at: created_at,
|
|
|
|
|
record_type: 'DossierOperationLog'
|
|
|
|
|
)
|
|
|
|
|
ActiveStorage::DownloadableFile.pj_and_path(dossier_id, a)
|
|
|
|
|
end
|
2022-04-01 18:01:48 +02:00
|
|
|
|
|
2022-04-05 15:30:23 +02:00
|
|
|
|
[serialized_dols, bill_ids]
|
|
|
|
|
end
|
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def signatures(bill_ids)
|
2022-04-05 15:30:23 +02:00
|
|
|
|
ActiveStorage::Attachment
|
2022-04-01 18:01:48 +02:00
|
|
|
|
.includes(:blob)
|
|
|
|
|
.where(record_type: "BillSignature", record_id: bill_ids)
|
2022-04-04 23:40:20 +02:00
|
|
|
|
.map { |bill| ActiveStorage::DownloadableFile.bill_and_path(bill) }
|
2022-04-01 16:21:38 +02:00
|
|
|
|
end
|
2022-04-08 14:45:51 +02:00
|
|
|
|
|
2024-02-07 17:33:34 +01:00
|
|
|
|
def safe_attachment(attachment)
|
2022-04-08 14:45:51 +02:00
|
|
|
|
attachment
|
|
|
|
|
.blob
|
2023-01-06 10:54:27 +01:00
|
|
|
|
.virus_scan_result == ActiveStorage::VirusScanner::SAFE
|
2022-04-08 14:45:51 +02:00
|
|
|
|
end
|
2017-04-04 15:27:04 +02:00
|
|
|
|
end
|