commit
39a40c43e3
19 changed files with 212 additions and 214 deletions
|
@ -139,8 +139,6 @@ module Experts
|
|||
end
|
||||
|
||||
def telecharger_pjs
|
||||
return head(:forbidden) if !avis.dossier.export_and_attachments_downloadable?
|
||||
|
||||
files = ActiveStorage::DownloadableFile.create_list_from_dossier(@dossier, true)
|
||||
|
||||
zipline(files, "dossier-#{@dossier.id}.zip")
|
||||
|
|
|
@ -218,8 +218,6 @@ module Instructeurs
|
|||
end
|
||||
|
||||
def telecharger_pjs
|
||||
return head(:forbidden) if !dossier.export_and_attachments_downloadable?
|
||||
|
||||
files = ActiveStorage::DownloadableFile.create_list_from_dossier(dossier)
|
||||
|
||||
zipline(files, "dossier-#{dossier.id}.zip")
|
||||
|
|
|
@ -12,7 +12,9 @@ module Instructeurs
|
|||
.includes(:defaut_groupe_instructeur)
|
||||
.order(closed_at: :desc, unpublished_at: :desc, published_at: :desc, created_at: :desc)
|
||||
|
||||
dossiers = current_instructeur.dossiers.joins(:groupe_instructeur)
|
||||
dossiers = current_instructeur.dossiers
|
||||
.joins(groupe_instructeur: :procedure)
|
||||
.where(procedures: { hidden_at: nil })
|
||||
dossiers_visibles = dossiers.visible_by_administration
|
||||
@dossiers_count_per_procedure = dossiers_visibles.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||
@dossiers_a_suivre_count_per_procedure = dossiers_visibles.without_followers.en_cours.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||
|
@ -61,47 +63,29 @@ module Instructeurs
|
|||
@can_download_dossiers = (@tous_count + @archives_count) > 0
|
||||
|
||||
dossiers = Dossier.where(groupe_instructeur_id: groupe_instructeur_ids)
|
||||
dossiers_visibles = dossiers.visible_by_administration
|
||||
|
||||
@a_suivre_dossiers = dossiers_visibles
|
||||
.without_followers
|
||||
.en_cours
|
||||
|
||||
@followed_dossiers = current_instructeur
|
||||
@followed_dossiers_id = current_instructeur
|
||||
.followed_dossiers
|
||||
.en_cours
|
||||
.merge(dossiers_visibles)
|
||||
.merge(dossiers.visible_by_administration)
|
||||
.pluck(:id)
|
||||
|
||||
@followed_dossiers_id = @followed_dossiers.pluck(:id)
|
||||
|
||||
@termines_dossiers = dossiers_visibles.termine
|
||||
@all_state_dossiers = dossiers_visibles.all_state
|
||||
@archived_dossiers = dossiers_visibles.archived
|
||||
@expirant_dossiers = dossiers_visibles.termine_or_en_construction_close_to_expiration
|
||||
@supprimes_recemment_dossiers = dossiers.hidden_by_administration.termine
|
||||
|
||||
@dossiers = case statut
|
||||
@dossiers = dossiers.by_statut(current_instructeur, statut)
|
||||
dossiers_count = case statut
|
||||
when 'a-suivre'
|
||||
dossiers_count = @a_suivre_count
|
||||
@a_suivre_dossiers
|
||||
@a_suivre_count
|
||||
when 'suivis'
|
||||
dossiers_count = @suivis_count
|
||||
@followed_dossiers
|
||||
@suivis_count
|
||||
when 'traites'
|
||||
dossiers_count = @traites_count
|
||||
@termines_dossiers
|
||||
@traites_count
|
||||
when 'tous'
|
||||
dossiers_count = @tous_count
|
||||
@all_state_dossiers
|
||||
@tous_count
|
||||
when 'supprimes_recemment'
|
||||
dossiers_count = @supprimes_recemment_count
|
||||
@supprimes_recemment_dossiers
|
||||
@supprimes_recemment_count
|
||||
when 'archives'
|
||||
dossiers_count = @archives_count
|
||||
@archived_dossiers
|
||||
@archives_count
|
||||
when 'expirant'
|
||||
dossiers_count = @expirant_count
|
||||
@expirant_dossiers
|
||||
@expirant_count
|
||||
end
|
||||
|
||||
notifications = current_instructeur.notifications_for_groupe_instructeurs(groupe_instructeur_ids)
|
||||
|
@ -109,7 +93,7 @@ module Instructeurs
|
|||
@has_termine_notifications = notifications[:termines].present?
|
||||
@not_archived_notifications_dossier_ids = notifications[:en_cours] + notifications[:termines]
|
||||
|
||||
sorted_ids = procedure_presentation.sorted_ids(@dossiers, dossiers_count, current_instructeur)
|
||||
sorted_ids = procedure_presentation.sorted_ids(@dossiers, dossiers_count)
|
||||
|
||||
if @current_filters.count > 0
|
||||
filtered_ids = procedure_presentation.filtered_ids(@dossiers, statut)
|
||||
|
|
|
@ -11,6 +11,12 @@ class ActiveStorage::DownloadableFile
|
|||
end
|
||||
end
|
||||
|
||||
def self.create_list_from_dossiers(dossiers)
|
||||
dossiers.flat_map do |dossier|
|
||||
create_list_from_dossier(dossier)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.timestamped_filename(attachment)
|
||||
|
|
|
@ -56,8 +56,6 @@ class Dossier < ApplicationRecord
|
|||
INSTRUCTION_COMMENCEE = TERMINE + [states.fetch(:en_instruction)]
|
||||
SOUMIS = EN_CONSTRUCTION_OU_INSTRUCTION + TERMINE
|
||||
|
||||
TAILLE_MAX_ZIP = 100.megabytes
|
||||
|
||||
REMAINING_DAYS_BEFORE_CLOSING = 2
|
||||
INTERVAL_BEFORE_CLOSING = "#{REMAINING_DAYS_BEFORE_CLOSING} days"
|
||||
REMAINING_WEEKS_BEFORE_EXPIRATION = 2
|
||||
|
@ -235,10 +233,11 @@ class Dossier < ApplicationRecord
|
|||
scope :en_instruction, -> { not_archived.state_en_instruction }
|
||||
scope :termine, -> { not_archived.state_termine }
|
||||
|
||||
scope :processed_in_month, -> (month) do
|
||||
scope :processed_in_month, -> (date) do
|
||||
date = date.to_datetime
|
||||
state_termine
|
||||
.joins(:traitements)
|
||||
.where(traitements: { processed_at: month.beginning_of_month..month.end_of_month })
|
||||
.where(traitements: { processed_at: date.beginning_of_month..date.end_of_month })
|
||||
end
|
||||
scope :downloadable_sorted, -> {
|
||||
state_not_brouillon
|
||||
|
@ -301,18 +300,18 @@ class Dossier < ApplicationRecord
|
|||
scope :interval_brouillon_close_to_expiration, -> do
|
||||
state_brouillon
|
||||
.visible_by_user
|
||||
.where("dossiers.created_at + dossiers.conservation_extension + (duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
.where("dossiers.created_at + dossiers.conservation_extension + (procedures.duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
end
|
||||
scope :interval_en_construction_close_to_expiration, -> do
|
||||
state_en_construction
|
||||
.visible_by_user_or_administration
|
||||
.where("dossiers.en_construction_at + dossiers.conservation_extension + (duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
.where("dossiers.en_construction_at + dossiers.conservation_extension + (procedures.duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
end
|
||||
scope :interval_termine_close_to_expiration, -> do
|
||||
state_termine
|
||||
.visible_by_user_or_administration
|
||||
.where(procedures: { procedure_expires_when_termine_enabled: true })
|
||||
.where("dossiers.processed_at + dossiers.conservation_extension + (duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
.where("dossiers.processed_at + dossiers.conservation_extension + (procedures.duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
|
||||
end
|
||||
|
||||
scope :brouillon_close_to_expiration, -> do
|
||||
|
@ -395,6 +394,30 @@ class Dossier < ApplicationRecord
|
|||
.distinct
|
||||
end
|
||||
|
||||
scope :by_statut, -> (instructeur, statut = 'tous') do
|
||||
case statut
|
||||
when 'a-suivre'
|
||||
visible_by_administration
|
||||
.without_followers
|
||||
.en_cours
|
||||
when 'suivis'
|
||||
instructeur
|
||||
.followed_dossiers
|
||||
.en_cours
|
||||
.merge(visible_by_administration)
|
||||
when 'traites'
|
||||
visible_by_administration.termine
|
||||
when 'tous'
|
||||
visible_by_administration.all_state
|
||||
when 'supprimes_recemment'
|
||||
hidden_by_administration.termine
|
||||
when 'archives'
|
||||
visible_by_administration.archived
|
||||
when 'expirant'
|
||||
visible_by_administration.termine_or_en_construction_close_to_expiration
|
||||
end
|
||||
end
|
||||
|
||||
accepts_nested_attributes_for :individual
|
||||
|
||||
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
||||
|
@ -1084,10 +1107,6 @@ class Dossier < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def export_and_attachments_downloadable?
|
||||
PiecesJustificativesService.pieces_justificatives_total_size(self) < Dossier::TAILLE_MAX_ZIP
|
||||
end
|
||||
|
||||
def linked_dossiers_for(instructeur_or_expert)
|
||||
dossier_ids = champs.filter(&:dossier_link?).filter_map(&:value)
|
||||
instructeur_or_expert.dossiers.where(id: dossier_ids)
|
||||
|
|
|
@ -110,7 +110,11 @@ class Instructeur < ApplicationRecord
|
|||
end
|
||||
|
||||
def procedure_presentation_and_errors_for_procedure_id(procedure_id)
|
||||
assign_to.joins(:groupe_instructeur).find_by(groupe_instructeurs: { procedure_id: procedure_id }).procedure_presentation_or_default_and_errors
|
||||
assign_to
|
||||
.joins(:groupe_instructeur)
|
||||
.includes(:instructeur, :procedure)
|
||||
.find_by(groupe_instructeurs: { procedure_id: procedure_id })
|
||||
.procedure_presentation_or_default_and_errors
|
||||
end
|
||||
|
||||
def notifications_for_dossier(dossier)
|
||||
|
|
|
@ -513,27 +513,6 @@ class Procedure < ApplicationRecord
|
|||
self.dossiers.state_not_brouillon.size
|
||||
end
|
||||
|
||||
def export_filename(format)
|
||||
procedure_identifier = path || "procedure-#{id}"
|
||||
"dossiers_#{procedure_identifier}_#{Time.zone.now.strftime('%Y-%m-%d_%H-%M')}.#{format}"
|
||||
end
|
||||
|
||||
def export(dossiers)
|
||||
ProcedureExportService.new(self, dossiers)
|
||||
end
|
||||
|
||||
def to_csv(dossiers)
|
||||
export(dossiers).to_csv
|
||||
end
|
||||
|
||||
def to_xlsx(dossiers)
|
||||
export(dossiers).to_xlsx
|
||||
end
|
||||
|
||||
def to_ods(dossiers)
|
||||
export(dossiers).to_ods
|
||||
end
|
||||
|
||||
def procedure_overview(start_date, groups)
|
||||
ProcedureOverview.new(self, start_date, groups)
|
||||
end
|
||||
|
|
|
@ -25,8 +25,7 @@ class ProcedurePresentation < ApplicationRecord
|
|||
FILTERS_VALUE_MAX_LENGTH = 100
|
||||
|
||||
belongs_to :assign_to, optional: false
|
||||
|
||||
delegate :procedure, to: :assign_to
|
||||
delegate :procedure, :instructeur, to: :assign_to
|
||||
|
||||
validate :check_allowed_displayed_fields
|
||||
validate :check_allowed_sort_column
|
||||
|
@ -84,7 +83,7 @@ class ProcedurePresentation < ApplicationRecord
|
|||
]
|
||||
end
|
||||
|
||||
def sorted_ids(dossiers, count, instructeur)
|
||||
def sorted_ids(dossiers, count)
|
||||
table, column, order = sort.values_at(TABLE, COLUMN, 'order')
|
||||
|
||||
case table
|
||||
|
|
|
@ -4,19 +4,7 @@ class PiecesJustificativesService
|
|||
pjs_commentaires = pjs_for_commentaires(dossier)
|
||||
pjs_dossier = pjs_for_dossier(dossier, for_expert)
|
||||
|
||||
pjs_champs + pjs_commentaires + pjs_dossier.filter(&:attached?)
|
||||
end
|
||||
|
||||
def self.liste_pieces_justificatives(dossier)
|
||||
pjs_champs = pjs_for_champs(dossier)
|
||||
pjs_commentaires = pjs_for_commentaires(dossier)
|
||||
|
||||
pjs_champs + pjs_commentaires
|
||||
end
|
||||
|
||||
def self.pieces_justificatives_total_size(dossier)
|
||||
liste_pieces_justificatives(dossier)
|
||||
.sum(&:byte_size)
|
||||
pjs_champs + pjs_commentaires + pjs_dossier
|
||||
end
|
||||
|
||||
def self.serialize_types_de_champ_as_type_pj(revision)
|
||||
|
@ -143,21 +131,57 @@ class PiecesJustificativesService
|
|||
end
|
||||
|
||||
def self.pjs_for_dossier(dossier, for_expert = false)
|
||||
pjs = [
|
||||
dossier.justificatif_motivation,
|
||||
dossier.attestation&.pdf,
|
||||
dossier.etablissement&.entreprise_attestation_sociale,
|
||||
dossier.etablissement&.entreprise_attestation_fiscale
|
||||
].flatten.compact
|
||||
pjs = motivation(dossier) +
|
||||
attestation(dossier) +
|
||||
etablissement(dossier)
|
||||
|
||||
if !for_expert
|
||||
bill_signatures = dossier.dossier_operation_logs.filter_map(&:bill_signature).uniq
|
||||
pjs += [
|
||||
dossier.dossier_operation_logs.map(&:serialized),
|
||||
bill_signatures.map(&:serialized),
|
||||
bill_signatures.map(&:signature)
|
||||
].flatten.compact
|
||||
pjs += operation_logs_and_signatures(dossier)
|
||||
end
|
||||
|
||||
pjs
|
||||
end
|
||||
|
||||
def self.etablissement(dossier)
|
||||
etablissement = Etablissement.where(dossier: dossier)
|
||||
|
||||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Etablissement", record_id: etablissement)
|
||||
end
|
||||
|
||||
def self.motivation(dossier)
|
||||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Dossier", name: "justificatif_motivation", record_id: dossier)
|
||||
end
|
||||
|
||||
def self.attestation(dossier)
|
||||
attestation = Attestation
|
||||
.joins(:pdf_attachment)
|
||||
.where(dossier: dossier)
|
||||
|
||||
ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "Attestation", record_id: attestation)
|
||||
end
|
||||
|
||||
def self.operation_logs_and_signatures(dossier)
|
||||
dol_ids_bill_id = DossierOperationLog
|
||||
.where(dossier: dossier)
|
||||
.pluck(:id, :bill_signature_id)
|
||||
|
||||
dol_ids = dol_ids_bill_id.map(&:first)
|
||||
bill_ids = dol_ids_bill_id.map(&:second).uniq.compact
|
||||
|
||||
serialized_dols = ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "DossierOperationLog", record_id: dol_ids)
|
||||
|
||||
bill_docs = ActiveStorage::Attachment
|
||||
.includes(:blob)
|
||||
.where(record_type: "BillSignature", record_id: bill_ids)
|
||||
|
||||
serialized_dols + bill_docs
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,8 @@ class ProcedureArchiveService
|
|||
dossiers.processed_in_month(archive.month)
|
||||
end
|
||||
|
||||
attachments = create_list_of_attachments(dossiers)
|
||||
attachments = ActiveStorage::DownloadableFile.create_list_from_dossiers(dossiers)
|
||||
|
||||
download_and_zip(archive, attachments) do |zip_filepath|
|
||||
ArchiveUploader.new(procedure: @procedure, archive: archive, filepath: zip_filepath)
|
||||
.upload
|
||||
|
@ -72,12 +73,6 @@ class ProcedureArchiveService
|
|||
"procedure-#{@procedure.id}-#{archive.id}"
|
||||
end
|
||||
|
||||
def create_list_of_attachments(dossiers)
|
||||
dossiers.flat_map do |dossier|
|
||||
ActiveStorage::DownloadableFile.create_list_from_dossier(dossier)
|
||||
end
|
||||
end
|
||||
|
||||
def self.attachments_from_champs_piece_justificative(champs)
|
||||
champs
|
||||
.filter { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) }
|
||||
|
|
|
@ -9,11 +9,7 @@
|
|||
%button.button.dropdown-button.icon-only{ 'aria-expanded' => 'false', 'aria-controls' => 'print-pj-menu' }
|
||||
%span.icon.attached
|
||||
%ul#print-pj-menu.print-menu.dropdown-content
|
||||
%li
|
||||
- if dossier.export_and_attachments_downloadable?
|
||||
= link_to "Télécharger le dossier et toutes ses pièces jointes", telecharger_pjs_expert_avis_path(avis), target: "_blank", rel: "noopener", class: "menu-item menu-link"
|
||||
- else
|
||||
%p.menu-item Le téléchargement des pièces jointes est désactivé pour les dossiers de plus de #{number_to_human_size Dossier::TAILLE_MAX_ZIP}.
|
||||
%li= link_to "Télécharger le dossier et toutes ses pièces jointes", telecharger_pjs_expert_avis_path(avis), target: "_blank", rel: "noopener", class: "menu-item menu-link"
|
||||
|
||||
%nav.tabs
|
||||
%ul
|
||||
|
|
|
@ -16,11 +16,7 @@
|
|||
%button.button.dropdown-button.icon-only{ 'aria-expanded' => 'false', 'aria-controls' => 'print-pj-menu' }
|
||||
%span.icon.attached
|
||||
%ul#print-pj-menu.print-menu.dropdown-content
|
||||
%li
|
||||
- if dossier.export_and_attachments_downloadable?
|
||||
= link_to "Télécharger le dossier et toutes ses pièces jointes", telecharger_pjs_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link"
|
||||
- else
|
||||
%p.menu-item Le téléchargement des pièces jointes est désactivé pour les dossiers de plus de #{number_to_human_size Dossier::TAILLE_MAX_ZIP}.
|
||||
%li= link_to "Télécharger le dossier et toutes ses pièces jointes", telecharger_pjs_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link"
|
||||
|
||||
= render partial: "instructeurs/procedures/dossier_actions",
|
||||
locals: { procedure_id: dossier.procedure.id,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
namespace :after_party do
|
||||
desc 'Deployment task: remove_duplicate_attestations'
|
||||
task remove_duplicate_attestations: :environment do
|
||||
dossier_ids = Attestation
|
||||
.group(:dossier_id)
|
||||
.count
|
||||
.filter { |_, attestation_count| attestation_count > 1 }
|
||||
.map(&:first)
|
||||
|
||||
dossier_ids.each do |dossier_id|
|
||||
current_attestation, *old_attestations = Attestation.where(dossier_id: dossier_id).order(created_at: :desc)
|
||||
|
||||
old_attestations.each do |old|
|
||||
if current_attestation.created_at < old.created_at
|
||||
raise "something odd, old attestation #{old.id} is newer than the current attestation #{current_attestation.id}"
|
||||
end
|
||||
|
||||
old.destroy
|
||||
end
|
||||
end
|
||||
|
||||
AfterParty::TaskRecord
|
||||
.create version: AfterParty::TaskRecorder.new(__FILE__).timestamp
|
||||
end
|
||||
end
|
|
@ -155,6 +155,23 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
it { expect(assigns(:all_dossiers_counts)['archivés']).to eq(1 + 0) }
|
||||
it { expect(assigns(:all_dossiers_counts)['expirant']).to eq(2 + 0) }
|
||||
end
|
||||
|
||||
context 'with not draft state on discarded procedure' do
|
||||
let(:discarded_procedure) { create(:procedure, :discarded, :expirable) }
|
||||
let(:state) { Dossier.states.fetch(:en_construction) }
|
||||
before do
|
||||
create(:dossier, procedure: discarded_procedure, state: Dossier.states.fetch(:en_construction))
|
||||
instructeur.groupe_instructeurs << discarded_procedure.defaut_groupe_instructeur
|
||||
subject
|
||||
end
|
||||
|
||||
it { expect(assigns(:dossiers_count_per_procedure)[procedure.id]).to eq(1) }
|
||||
it { expect(assigns(:dossiers_a_suivre_count_per_procedure)[procedure.id]).to eq(1) }
|
||||
|
||||
it { expect(assigns(:dossiers_count_per_procedure)[discarded_procedure.id]).to be_nil }
|
||||
|
||||
it { expect(assigns(:all_dossiers_counts)['à suivre']).to eq(1) }
|
||||
end
|
||||
end
|
||||
|
||||
context "with a routed procedure" do
|
||||
|
@ -257,38 +274,34 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
let!(:new_unfollow_dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||
|
||||
before { subject }
|
||||
it { expect(assigns(:a_suivre_dossiers)).to match_array([new_unfollow_dossier]) }
|
||||
it { expect(assigns(:followed_dossiers)).to be_empty }
|
||||
it { expect(assigns(:termines_dossiers)).to be_empty }
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([new_unfollow_dossier]) }
|
||||
it { expect(assigns(:archived_dossiers)).to be_empty }
|
||||
it { expect(assigns(:dossiers)).to match_array([new_unfollow_dossier]) }
|
||||
|
||||
context 'with a dossier en contruction hidden by user' do
|
||||
let!(:hidden_dossier) { create(:dossier, groupe_instructeur: gi_2, state: Dossier.states.fetch(:en_construction), hidden_by_user_at: 1.hour.ago) }
|
||||
let!(:hidden_dossier) { create(:dossier, :en_construction, groupe_instructeur: gi_2, hidden_by_user_at: 1.hour.ago) }
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([new_unfollow_dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([new_unfollow_dossier]) }
|
||||
end
|
||||
|
||||
context 'with a dossier en contruction not hidden by user' do
|
||||
let!(:en_construction_dossier) { create(:dossier, groupe_instructeur: gi_2, state: Dossier.states.fetch(:en_construction)) }
|
||||
let!(:en_construction_dossier) { create(:dossier, :en_construction, groupe_instructeur: gi_2) }
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([new_unfollow_dossier, en_construction_dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([new_unfollow_dossier, en_construction_dossier]) }
|
||||
end
|
||||
|
||||
context 'and dossiers without follower on each of the others groups' do
|
||||
let!(:new_unfollow_dossier_on_gi_2) { create(:dossier, groupe_instructeur: gi_2, state: Dossier.states.fetch(:en_instruction)) }
|
||||
let!(:new_unfollow_dossier_on_gi_3) { create(:dossier, groupe_instructeur: gi_3, state: Dossier.states.fetch(:en_instruction)) }
|
||||
let!(:new_unfollow_dossier_on_gi_2) { create(:dossier, :en_instruction, groupe_instructeur: gi_2) }
|
||||
let!(:new_unfollow_dossier_on_gi_3) { create(:dossier, :en_instruction, groupe_instructeur: gi_3) }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:a_suivre_dossiers)).to match_array([new_unfollow_dossier, new_unfollow_dossier_on_gi_2]) }
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([new_unfollow_dossier, new_unfollow_dossier_on_gi_2]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([new_unfollow_dossier, new_unfollow_dossier_on_gi_2]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a new dossier with a follower' do
|
||||
let(:statut) { 'suivis' }
|
||||
let!(:new_followed_dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||
|
||||
before do
|
||||
|
@ -296,15 +309,11 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
subject
|
||||
end
|
||||
|
||||
it { expect(assigns(:a_suivre_dossiers)).to be_empty }
|
||||
it { expect(assigns(:followed_dossiers)).to match_array([new_followed_dossier]) }
|
||||
it { expect(assigns(:termines_dossiers)).to be_empty }
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([new_followed_dossier]) }
|
||||
it { expect(assigns(:archived_dossiers)).to be_empty }
|
||||
it { expect(assigns(:dossiers)).to match_array([new_followed_dossier]) }
|
||||
|
||||
context 'and dossier with a follower on each of the others groups' do
|
||||
let!(:new_follow_dossier_on_gi_2) { create(:dossier, groupe_instructeur: gi_2, state: Dossier.states.fetch(:en_instruction)) }
|
||||
let!(:new_follow_dossier_on_gi_3) { create(:dossier, groupe_instructeur: gi_3, state: Dossier.states.fetch(:en_instruction)) }
|
||||
let!(:new_follow_dossier_on_gi_2) { create(:dossier, :en_instruction, groupe_instructeur: gi_2) }
|
||||
let!(:new_follow_dossier_on_gi_3) { create(:dossier, :en_instruction, groupe_instructeur: gi_3) }
|
||||
|
||||
before do
|
||||
instructeur.followed_dossiers << new_follow_dossier_on_gi_2 << new_follow_dossier_on_gi_3
|
||||
|
@ -312,44 +321,36 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
end
|
||||
|
||||
# followed dossiers on another groupe should not be displayed
|
||||
it { expect(assigns(:followed_dossiers)).to contain_exactly(new_followed_dossier, new_follow_dossier_on_gi_2) }
|
||||
it { expect(assigns(:all_state_dossiers)).to contain_exactly(new_followed_dossier, new_follow_dossier_on_gi_2) }
|
||||
it { expect(assigns(:dossiers)).to contain_exactly(new_followed_dossier, new_follow_dossier_on_gi_2) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a termine dossier with a follower' do
|
||||
let(:statut) { 'traites' }
|
||||
let!(:termine_dossier) { create(:dossier, :accepte, procedure: procedure) }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:a_suivre_dossiers)).to be_empty }
|
||||
it { expect(assigns(:followed_dossiers)).to be_empty }
|
||||
it { expect(assigns(:termines_dossiers)).to match_array([termine_dossier]) }
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([termine_dossier]) }
|
||||
it { expect(assigns(:archived_dossiers)).to be_empty }
|
||||
it { expect(assigns(:dossiers)).to match_array([termine_dossier]) }
|
||||
|
||||
context 'and terminer dossiers on each of the others groups' do
|
||||
let!(:termine_dossier_on_gi_2) { create(:dossier, groupe_instructeur: gi_2, state: Dossier.states.fetch(:accepte)) }
|
||||
let!(:termine_dossier_on_gi_3) { create(:dossier, groupe_instructeur: gi_3, state: Dossier.states.fetch(:accepte)) }
|
||||
let!(:termine_dossier_on_gi_2) { create(:dossier, :accepte, groupe_instructeur: gi_2) }
|
||||
let!(:termine_dossier_on_gi_3) { create(:dossier, :accepte, groupe_instructeur: gi_3) }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:termines_dossiers)).to match_array([termine_dossier, termine_dossier_on_gi_2]) }
|
||||
it { expect(assigns(:all_state_dossiers)).to match_array([termine_dossier, termine_dossier_on_gi_2]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([termine_dossier, termine_dossier_on_gi_2]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an archived dossier' do
|
||||
let(:statut) { 'archives' }
|
||||
let!(:archived_dossier) { create(:dossier, :en_instruction, procedure: procedure, archived: true) }
|
||||
let!(:archived_dossier_deleted) { create(:dossier, :en_instruction, procedure: procedure, archived: true, hidden_by_administration_at: 2.days.ago) }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:a_suivre_dossiers)).to be_empty }
|
||||
it { expect(assigns(:followed_dossiers)).to be_empty }
|
||||
it { expect(assigns(:termines_dossiers)).to be_empty }
|
||||
it { expect(assigns(:all_state_dossiers)).to be_empty }
|
||||
it { expect(assigns(:archived_dossiers)).to match_array([archived_dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([archived_dossier]) }
|
||||
|
||||
context 'and terminer dossiers on each of the others groups' do
|
||||
let!(:archived_dossier_on_gi_2) { create(:dossier, :en_instruction, groupe_instructeur: gi_2, archived: true) }
|
||||
|
@ -357,22 +358,23 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:archived_dossiers)).to match_array([archived_dossier, archived_dossier_on_gi_2]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([archived_dossier, archived_dossier_on_gi_2]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an expirants dossier' do
|
||||
let(:statut) { 'expirant' }
|
||||
let!(:expiring_dossier_termine_deleted) { create(:dossier, :accepte, procedure: procedure, processed_at: 175.days.ago, hidden_by_administration_at: 2.days.ago) }
|
||||
let!(:expiring_dossier_termine) { create(:dossier, :accepte, procedure: procedure, processed_at: 175.days.ago) }
|
||||
let!(:expiring_dossier_en_construction) { create(:dossier, :en_construction, procedure: procedure, en_construction_at: 175.days.ago) }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(assigns(:expirant_dossiers)).to match_array([expiring_dossier_termine, expiring_dossier_en_construction]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([expiring_dossier_termine, expiring_dossier_en_construction]) }
|
||||
end
|
||||
|
||||
describe 'statut' do
|
||||
let!(:a_suivre__dossier) { Timecop.freeze(1.day.ago) { create(:dossier, :en_instruction, procedure: procedure) } }
|
||||
let!(:a_suivre_dossier) { Timecop.freeze(1.day.ago) { create(:dossier, :en_instruction, procedure: procedure) } }
|
||||
let!(:new_followed_dossier) { Timecop.freeze(2.days.ago) { create(:dossier, :en_instruction, procedure: procedure) } }
|
||||
let!(:termine_dossier) { Timecop.freeze(3.days.ago) { create(:dossier, :accepte, procedure: procedure) } }
|
||||
let!(:archived_dossier) { Timecop.freeze(4.days.ago) { create(:dossier, :en_instruction, procedure: procedure, archived: true) } }
|
||||
|
@ -385,7 +387,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
context 'when statut is empty' do
|
||||
let(:statut) { nil }
|
||||
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre__dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre_dossier]) }
|
||||
it { expect(assigns(:statut)).to eq('a-suivre') }
|
||||
end
|
||||
|
||||
|
@ -393,7 +395,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
let(:statut) { 'a-suivre' }
|
||||
|
||||
it { expect(assigns(:statut)).to eq('a-suivre') }
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre__dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre_dossier]) }
|
||||
end
|
||||
|
||||
context 'when statut is suivis' do
|
||||
|
@ -414,7 +416,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
let(:statut) { 'tous' }
|
||||
|
||||
it { expect(assigns(:statut)).to eq('tous') }
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre__dossier, new_followed_dossier, termine_dossier]) }
|
||||
it { expect(assigns(:dossiers)).to match_array([a_suivre_dossier, new_followed_dossier, termine_dossier]) }
|
||||
end
|
||||
|
||||
context 'when statut is archives' do
|
||||
|
@ -465,7 +467,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
let(:instructeur) { create(:instructeur) }
|
||||
let!(:procedure) { create(:procedure) }
|
||||
let!(:gi_0) { procedure.defaut_groupe_instructeur }
|
||||
let!(:gi_1) { GroupeInstructeur.create(label: 'gi_1', procedure: procedure, instructeurs: [instructeur]) }
|
||||
let!(:gi_1) { create(:groupe_instructeur, label: 'gi_1', procedure: procedure, instructeurs: [instructeur]) }
|
||||
|
||||
before { sign_in(instructeur.user) }
|
||||
|
||||
|
@ -494,7 +496,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
end
|
||||
|
||||
context 'when the export is ready' do
|
||||
let!(:export) { create(:export, groupe_instructeurs: [gi_1]) }
|
||||
let(:export) { create(:export, groupe_instructeurs: [gi_1]) }
|
||||
|
||||
before do
|
||||
export.file.attach(io: StringIO.new('export'), filename: 'file.csv')
|
||||
|
@ -507,7 +509,7 @@ describe Instructeurs::ProceduresController, type: :controller do
|
|||
end
|
||||
|
||||
context 'when another export is ready' do
|
||||
let!(:export) { create(:export, groupe_instructeurs: [gi_0, gi_1]) }
|
||||
let(:export) { create(:export, groupe_instructeurs: [gi_0, gi_1]) }
|
||||
|
||||
before do
|
||||
export.file.attach(io: StringIO.new('export'), filename: 'file.csv')
|
||||
|
|
|
@ -1190,30 +1190,6 @@ describe Dossier do
|
|||
after { Timecop.return }
|
||||
end
|
||||
|
||||
describe '#export_and_attachments_downloadable?' do
|
||||
let(:dossier) { create(:dossier, user: user) }
|
||||
|
||||
context "no attachments" do
|
||||
it {
|
||||
expect(dossier.export_and_attachments_downloadable?).to be true
|
||||
}
|
||||
end
|
||||
|
||||
context "with a small attachment" do
|
||||
it {
|
||||
expect(PiecesJustificativesService).to receive(:pieces_justificatives_total_size).and_return(4.megabytes)
|
||||
expect(dossier.export_and_attachments_downloadable?).to be true
|
||||
}
|
||||
end
|
||||
|
||||
context "with a too large attachment" do
|
||||
it {
|
||||
expect(PiecesJustificativesService).to receive(:pieces_justificatives_total_size).and_return(100.megabytes)
|
||||
expect(dossier.export_and_attachments_downloadable?).to be false
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe '#notify_draft_not_submitted' do
|
||||
let!(:user1) { create(:user) }
|
||||
let!(:user2) { create(:user) }
|
||||
|
@ -1744,4 +1720,29 @@ describe Dossier do
|
|||
expect(rebased_datetime_champ.rebased_at).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#processed_in_month' do
|
||||
include ActiveSupport::Testing::TimeHelpers
|
||||
|
||||
let(:dossier_accepte_at) { DateTime.new(2022, 3, 31, 12, 0) }
|
||||
before do
|
||||
travel_to(dossier_accepte_at) do
|
||||
dossier = create(:dossier, :accepte)
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a date' do
|
||||
let(:archive_date) { Date.new(2022, 3, 1) }
|
||||
it 'includes a dossier processed_at at last day of month' do
|
||||
expect(Dossier.processed_in_month(archive_date).count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a datetime' do
|
||||
let(:archive_date) { DateTime.new(2022, 3, 1, 12, 0) }
|
||||
it 'includes a dossier processed_at at last day of month' do
|
||||
expect(Dossier.processed_in_month(archive_date).count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -133,7 +133,7 @@ describe ProcedurePresentation do
|
|||
let(:sort) { { 'table' => table, 'column' => column, 'order' => order } }
|
||||
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to, sort: sort) }
|
||||
|
||||
subject { procedure_presentation.sorted_ids(procedure.dossiers, procedure.dossiers.count, instructeur) }
|
||||
subject { procedure_presentation.sorted_ids(procedure.dossiers, procedure.dossiers.count) }
|
||||
|
||||
context 'for notifications table' do
|
||||
let(:table) { 'notifications' }
|
||||
|
|
|
@ -1059,17 +1059,6 @@ describe Procedure do
|
|||
it { expect(Procedure.default_sort).to eq({ "table" => "self", "column" => "id", "order" => "desc" }) }
|
||||
end
|
||||
|
||||
describe "#export_filename" do
|
||||
before { Timecop.freeze(Time.zone.local(2018, 1, 2, 23, 11, 14)) }
|
||||
after { Timecop.return }
|
||||
|
||||
subject { procedure.export_filename(:csv) }
|
||||
|
||||
let(:procedure) { create(:procedure, :published) }
|
||||
|
||||
it { is_expected.to eq("dossiers_#{procedure.path}_2018-01-02_23-11.csv") }
|
||||
end
|
||||
|
||||
describe '#new_dossier' do
|
||||
let(:procedure) do
|
||||
create(:procedure,
|
||||
|
|
|
@ -15,23 +15,6 @@ describe PiecesJustificativesService do
|
|||
create(:dossier_operation_log, dossier: dossier, bill_signature: bill_signature)
|
||||
end
|
||||
|
||||
describe '.liste_pieces_justificatives' do
|
||||
subject { PiecesJustificativesService.liste_pieces_justificatives(dossier) }
|
||||
|
||||
it "doesn't return sensitive documents like titre_identite" do
|
||||
expect(champ_identite.piece_justificative_file).to be_attached
|
||||
expect(subject.any? { |piece| piece.name == 'piece_justificative_file' }).to be_falsy
|
||||
end
|
||||
|
||||
it "doesn't return export pdf of the dossier" do
|
||||
expect(subject.any? { |piece| piece.name == 'pdf_export_for_instructeur' }).to be_falsy
|
||||
end
|
||||
|
||||
it "doesn't return operation logs of the dossier" do
|
||||
expect(subject.any? { |piece| piece.name == 'serialized' }).to be_falsy
|
||||
end
|
||||
end
|
||||
|
||||
describe '.liste_documents' do
|
||||
subject { PiecesJustificativesService.liste_documents(dossier, false) }
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ describe ProcedureArchiveService do
|
|||
let(:year) { 2021 }
|
||||
|
||||
it 'collects files with success' do
|
||||
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://opengraph.githubassets.com/d0e7862b24d8026a3c03516d865b28151eb3859029c6c6c2e86605891fbdcd7a/socketry/async-io")
|
||||
allow_any_instance_of(ActiveStorage::Attachment).to receive(:url).and_return("https://opengraph.githubassets.com/d0e7862b24d8026a3c03516d865b28151eb3859029c6c6c2e86605891fbdcd7a/socketry/async-io")
|
||||
|
||||
VCR.use_cassette('archive/new_file_to_get_200') do
|
||||
service.make_and_upload_archive(archive, instructeur)
|
||||
|
@ -145,7 +145,7 @@ describe ProcedureArchiveService do
|
|||
let(:archive) { create(:archive, time_span_type: 'everything', status: 'pending', groupe_instructeurs: groupe_instructeurs) }
|
||||
|
||||
it 'collect files' do
|
||||
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://opengraph.githubassets.com/5e61989aecb78e369c93674f877d7bf4ecde378850114a9563cdf8b6a2472536/typhoeus/typhoeus/issues/110")
|
||||
allow_any_instance_of(ActiveStorage::Attachment).to receive(:url).and_return("https://opengraph.githubassets.com/5e61989aecb78e369c93674f877d7bf4ecde378850114a9563cdf8b6a2472536/typhoeus/typhoeus/issues/110")
|
||||
|
||||
VCR.use_cassette('archive/old_file_to_get_200') do
|
||||
service.make_and_upload_archive(archive, instructeur)
|
||||
|
|
Loading…
Reference in a new issue