Merge pull request #9270 from demarches-simplifiees/create-dossier-assignments

ETQ instructeur je vois les réaffectations d'un dossier
This commit is contained in:
Paul Chavard 2023-07-18 15:39:12 +00:00 committed by GitHub
commit 6d8a0506e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 228 additions and 30 deletions

View file

@ -743,6 +743,7 @@ Rails/CreateTableWithTimestamps:
- db/migrate/2017*.rb - db/migrate/2017*.rb
- db/migrate/2018*.rb - db/migrate/2018*.rb
- db/migrate/20200630140356_create_traitements.rb - db/migrate/20200630140356_create_traitements.rb
- db/migrate/20230630091637_create_dossier_assignments.rb
Rails/Date: Rails/Date:
Enabled: false Enabled: false

View file

@ -200,7 +200,7 @@ module Administrateurs
target_group = procedure.groupe_instructeurs.find(params[:target_group]) target_group = procedure.groupe_instructeurs.find(params[:target_group])
reaffecter_bulk_messages(target_group) reaffecter_bulk_messages(target_group)
groupe_instructeur.dossiers.find_each do |dossier| groupe_instructeur.dossiers.find_each do |dossier|
dossier.assign_to_groupe_instructeur(target_group, current_administrateur) dossier.assign_to_groupe_instructeur(target_group, DossierAssignment.modes.fetch(:manual), current_administrateur)
end end
flash[:notice] = "Les dossiers du groupe « #{groupe_instructeur.label} » ont été réaffectés au groupe « #{target_group.label} »." flash[:notice] = "Les dossiers du groupe « #{groupe_instructeur.label} » ont été réaffectés au groupe « #{target_group.label} »."
@ -210,7 +210,7 @@ module Administrateurs
def reaffecter_all_dossiers_to_defaut_groupe def reaffecter_all_dossiers_to_defaut_groupe
procedure.groupe_instructeurs_but_defaut.each do |gi| procedure.groupe_instructeurs_but_defaut.each do |gi|
gi.dossiers.find_each do |dossier| gi.dossiers.find_each do |dossier|
dossier.assign_to_groupe_instructeur(procedure.defaut_groupe_instructeur, current_administrateur) dossier.assign_to_groupe_instructeur(procedure.defaut_groupe_instructeur, DossierAssignment.modes.fetch(:manual), current_administrateur)
end end
end end
end end

View file

@ -91,6 +91,7 @@ module Instructeurs
@avis_emails = dossier.experts.map(&:email) @avis_emails = dossier.experts.map(&:email)
@invites_emails = dossier.invites.map(&:email) @invites_emails = dossier.invites.map(&:email)
@potential_recipients = dossier.groupe_instructeur.instructeurs.reject { |g| g == current_instructeur } @potential_recipients = dossier.groupe_instructeur.instructeurs.reject { |g| g == current_instructeur }
@manual_assignments = dossier.dossier_assignments.manual.includes(:groupe_instructeur, :previous_groupe_instructeur)
end end
def send_to_instructeurs def send_to_instructeurs
@ -362,9 +363,7 @@ module Instructeurs
.procedure .procedure
.groupe_instructeurs.find(params[:groupe_instructeur_id]) .groupe_instructeurs.find(params[:groupe_instructeur_id])
dossier.assign_to_groupe_instructeur(new_group) dossier.assign_to_groupe_instructeur(new_group, DossierAssignment.modes.fetch(:manual), current_instructeur)
dossier.update!(forced_groupe_instructeur: true)
flash.notice = t('instructeurs.dossiers.reaffectation', dossier_id: dossier.id, label: new_group.label) flash.notice = t('instructeurs.dossiers.reaffectation', dossier_id: dossier.id, label: new_group.label)
redirect_to instructeur_procedure_path(procedure) redirect_to instructeur_procedure_path(procedure)

View file

@ -542,8 +542,6 @@ module Users
errors += format_errors(errors: @dossier.errors) errors += format_errors(errors: @dossier.errors)
errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs) errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs)
RoutingEngine.compute(@dossier)
errors errors
end end

View file

@ -11,7 +11,7 @@ module Mutations
field :errors, [Types::ValidationErrorType], null: true field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, groupe_instructeur:) def resolve(dossier:, groupe_instructeur:)
dossier.assign_to_groupe_instructeur(groupe_instructeur) dossier.assign_to_groupe_instructeur(groupe_instructeur, DossierAssignment.modes.fetch(:manual), current_administrateur)
{ dossier: } { dossier: }
end end

View file

@ -69,7 +69,6 @@ module DossierCloneConcern
diff = make_diff(editing_fork) diff = make_diff(editing_fork)
apply_diff(diff) apply_diff(diff)
touch(:last_champ_updated_at) touch(:last_champ_updated_at)
assign_to_groupe_instructeur(editing_fork.groupe_instructeur)
end end
reload reload
update_search_terms_later update_search_terms_later

View file

@ -155,6 +155,8 @@ class Dossier < ApplicationRecord
has_one :traitement, -> { order(processed_at: :desc) }, inverse_of: false has_one :traitement, -> { order(processed_at: :desc) }, inverse_of: false
has_many :dossier_operation_logs, -> { order(:created_at) }, inverse_of: :dossier has_many :dossier_operation_logs, -> { order(:created_at) }, inverse_of: :dossier
has_many :dossier_assignments, -> { order(:assigned_at) }, inverse_of: :dossier, dependent: :destroy
has_one :dossier_assignment, -> { order(assigned_at: :desc) }, inverse_of: false
belongs_to :groupe_instructeur, optional: true belongs_to :groupe_instructeur, optional: true
belongs_to :revision, class_name: 'ProcedureRevision', optional: false belongs_to :revision, class_name: 'ProcedureRevision', optional: false
@ -474,7 +476,6 @@ class Dossier < ApplicationRecord
validates :user, presence: true, if: -> { deleted_user_email_never_send.nil? }, unless: -> { prefilled } validates :user, presence: true, if: -> { deleted_user_email_never_send.nil? }, unless: -> { prefilled }
validates :individual, presence: true, if: -> { revision.procedure.for_individual? } validates :individual, presence: true, if: -> { revision.procedure.for_individual? }
validates :groupe_instructeur, presence: true, if: -> { !brouillon? }
validates_associated :prefilled_champs_public, on: :prefilling validates_associated :prefilled_champs_public, on: :prefilling
@ -686,13 +687,17 @@ class Dossier < ApplicationRecord
procedure.discarded? || (brouillon? && !procedure.dossier_can_transition_to_en_construction?) procedure.discarded? || (brouillon? && !procedure.dossier_can_transition_to_en_construction?)
end end
def assign_to_groupe_instructeur(groupe_instructeur, author = nil) def assign_to_groupe_instructeur(groupe_instructeur, mode, author = nil)
return if groupe_instructeur.present? && groupe_instructeur.procedure != procedure return if groupe_instructeur.present? && groupe_instructeur.procedure != procedure
return if self.groupe_instructeur == groupe_instructeur return if self.groupe_instructeur == groupe_instructeur
previous_groupe_instructeur = self.groupe_instructeur
update!(groupe_instructeur:, groupe_instructeur_updated_at: Time.zone.now) update!(groupe_instructeur:, groupe_instructeur_updated_at: Time.zone.now)
update!(forced_groupe_instructeur: true) if mode == DossierAssignment.modes.fetch(:manual)
if !brouillon? if !brouillon?
create_assignment(mode, previous_groupe_instructeur, groupe_instructeur, author&.email)
unfollow_stale_instructeurs unfollow_stale_instructeurs
if author.present? if author.present?
log_dossier_operation(author, :changer_groupe_instructeur, self) log_dossier_operation(author, :changer_groupe_instructeur, self)
@ -900,6 +905,7 @@ class Dossier < ApplicationRecord
MailTemplatePresenterService.create_commentaire_for_state(self) MailTemplatePresenterService.create_commentaire_for_state(self)
NotificationMailer.send_en_construction_notification(self).deliver_later NotificationMailer.send_en_construction_notification(self).deliver_later
procedure.compute_dossiers_count procedure.compute_dossiers_count
RoutingEngine.compute(self)
end end
def after_passer_en_instruction(h) def after_passer_en_instruction(h)
@ -1310,6 +1316,19 @@ class Dossier < ApplicationRecord
(sva_svr_decision_on - Date.current).to_i (sva_svr_decision_on - Date.current).to_i
end end
def create_assignment(mode, previous_groupe_instructeur, groupe_instructeur, instructeur_email = nil)
DossierAssignment.create!(
dossier_id: self.id,
mode: mode,
previous_groupe_instructeur_id: previous_groupe_instructeur&.id,
groupe_instructeur_id: groupe_instructeur.id,
previous_groupe_instructeur_label: previous_groupe_instructeur&.label,
groupe_instructeur_label: groupe_instructeur.label,
assigned_at: Time.zone.now,
assigned_by: instructeur_email
)
end
private private
def create_missing_traitemets def create_missing_traitemets

View file

@ -0,0 +1,34 @@
# == Schema Information
#
# Table name: dossier_assignments
#
# id :bigint not null, primary key
# assigned_at :datetime not null
# assigned_by :string
# groupe_instructeur_label :string
# mode :string not null
# previous_groupe_instructeur_label :string
# dossier_id :bigint not null
# groupe_instructeur_id :bigint
# previous_groupe_instructeur_id :bigint
#
class DossierAssignment < ApplicationRecord
belongs_to :dossier
belongs_to :groupe_instructeur, optional: true, inverse_of: :assignments
belongs_to :previous_groupe_instructeur, class_name: 'GroupeInstructeur', optional: true, inverse_of: :previous_assignments
enum mode: {
auto: 'auto',
manual: 'manual'
}
scope :manual, -> { where(mode: :manual) }
def groupe_instructeur_label
@groupe_instructeur_label ||= groupe_instructeur&.label.presence || read_attribute(:groupe_instructeur_label)
end
def previous_groupe_instructeur_label
@previous_groupe_instructeur_label ||= previous_groupe_instructeur&.label.presence || read_attribute(:previous_groupe_instructeur_label)
end
end

View file

@ -19,6 +19,8 @@ class GroupeInstructeur < ApplicationRecord
has_many :dossiers has_many :dossiers
has_many :deleted_dossiers has_many :deleted_dossiers
has_many :batch_operations, through: :dossiers, source: :batch_operations has_many :batch_operations, through: :dossiers, source: :batch_operations
has_many :assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :groupe_instructeur
has_many :previous_assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :previous_groupe_instructeur
has_and_belongs_to_many :exports, dependent: :destroy has_and_belongs_to_many :exports, dependent: :destroy
has_and_belongs_to_many :bulk_messages, dependent: :destroy has_and_belongs_to_many :bulk_messages, dependent: :destroy

View file

@ -5,7 +5,9 @@ module RoutingEngine
matching_groupe = dossier.procedure.groupe_instructeurs.active.reject(&:invalid_rule?).find do |gi| matching_groupe = dossier.procedure.groupe_instructeurs.active.reject(&:invalid_rule?).find do |gi|
gi.routing_rule&.compute(dossier.champs) gi.routing_rule&.compute(dossier.champs)
end end
matching_groupe ||= dossier.procedure.defaut_groupe_instructeur matching_groupe ||= dossier.procedure.defaut_groupe_instructeur
dossier.assign_to_groupe_instructeur(matching_groupe)
dossier.assign_to_groupe_instructeur(matching_groupe, DossierAssignment.modes.fetch(:auto))
end end
end end

View file

@ -16,11 +16,11 @@
%th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count) %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count)
%tbody %tbody
- @groupes_instructeurs.each do |group| - @groupes_instructeurs.each do |group|
%tr .flex.justify-between.align-center.fr-mb-2w
%td= group.label %p.fr-mb-0= group.label
%td.actions= button_to 'Réaffecter les dossiers à ce groupe', = button_to 'Réaffecter les dossiers à ce groupe',
reaffecter_admin_procedure_groupe_instructeur_path(:target_group => group), reaffecter_admin_procedure_groupe_instructeur_path(:target_group => group),
{ class: 'button', { class: 'fr-btn fr-btn--secondary fr-btn--sm',
data: { confirm: "Êtes-vous sûr de vouloir réaffecter les dossiers du groupe « #{@groupe_instructeur.label} » vers le groupe  « #{group.label} » ?" } } data: { confirm: "Êtes-vous sûr de vouloir réaffecter les dossiers du groupe « #{@groupe_instructeur.label} » vers le groupe  « #{group.label} » ?" } }
= paginate @groupes_instructeurs, views_prefix: 'shared' = paginate @groupes_instructeurs, views_prefix: 'shared'

View file

@ -0,0 +1,16 @@
.tab-title Réaffectations
- if manual_assignments.any?
%ul.tab-list
- manual_assignments.each do |assignment|
%li
- assigned_at = l(assignment.assigned_at, format: '%d %B %Y à %R')
- assigned_by = assignment.assigned_by
- if assigned_by.present?
= "Le #{assigned_at}, #{assigned_by} a réaffecté ce dossier du groupe « #{assignment.previous_groupe_instructeur_label} » au groupe « #{assignment.groupe_instructeur_label} »"
- else
= "Le #{assigned_at}, ce dossier a été réaffecté du groupe « #{assignment.previous_groupe_instructeur_label} » au groupe « #{assignment.groupe_instructeur_label} »"
- elsif dossier.forced_groupe_instructeur
%p.tab-paragraph Ce dossier a été réaffecté au groupe « #{dossier.groupe_instructeur.label} »
- else
%p.tab-paragraph Ce dossier n'a pas été réaffecté

View file

@ -16,6 +16,7 @@
= render partial: 'instructeurs/dossiers/decisions_rendues_block', locals: { traitements: @dossier.traitements } = render partial: 'instructeurs/dossiers/decisions_rendues_block', locals: { traitements: @dossier.traitements }
= render partial: 'instructeurs/dossiers/reaffectations_block', locals: { manual_assignments: @manual_assignments, dossier: @dossier }
- if @dossier.archived? && @dossier.archived_at.present? - if @dossier.archived? && @dossier.archived_at.present?
= render partial: 'instructeurs/dossiers/archived_block', locals: @dossier.slice(:archived_by, :archived_at) = render partial: 'instructeurs/dossiers/archived_block', locals: @dossier.slice(:archived_by, :archived_at)

View file

@ -7,18 +7,18 @@
.card .card
.card-title Réaffectation du dossier nº #{@dossier.id} du groupe « #{@groupe_instructeur.label} » .card-title Réaffectation du dossier nº #{@dossier.id} du groupe « #{@groupe_instructeur.label} »
%p %p
Vous pouvez réaffecter le dossier nº #{@dossier.id} à l'un des groupes d'instructeurs suivants. Vous pouvez réaffecter le dossier nº #{@dossier.id} à lun des groupes dinstructeurs suivants.
%table.table.mt-2 %table.table.mt-2
%thead %thead
%tr %tr
%th{ colspan: 2 }= t("instructeurs.dossiers.existing_groupe", count: @groupes_instructeurs.total_count) %th{ colspan: 2 }= t("instructeurs.dossiers.existing_groupe", count: @groupes_instructeurs.total_count)
%tbody %tbody
- @groupes_instructeurs.each do |group| - @groupes_instructeurs.each do |group|
%tr .flex.justify-between.align-center.fr-mb-2w
%td= group.label %p.fr-mb-0= group.label
%td.actions= button_to 'Réaffecter le dossier à ce groupe', = button_to 'Réaffecter le dossier à ce groupe',
reaffecter_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, groupe_instructeur_id: group.id), reaffecter_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, groupe_instructeur_id: group.id),
{ class: 'button', { class: 'fr-btn fr-btn--secondary fr-btn--sm',
data: { confirm: "Êtes-vous sûr de vouloir réaffecter le dossier nº #{@dossier.id} du groupe « #{@groupe_instructeur.label} » vers le groupe  « #{group.label} » ?" } } data: { confirm: "Êtes-vous sûr de vouloir réaffecter le dossier nº #{@dossier.id} du groupe « #{@groupe_instructeur.label} » vers le groupe  « #{group.label} » ?" } }
= paginate @groupes_instructeurs, views_prefix: 'shared' = paginate @groupes_instructeurs, views_prefix: 'shared'

View file

@ -0,0 +1,14 @@
class CreateDossierAssignments < ActiveRecord::Migration[7.0]
def change
create_table :dossier_assignments do |t|
t.references :dossier, foreign_key: true, null: false
t.string :mode, null: false
t.bigint :groupe_instructeur_id
t.bigint :previous_groupe_instructeur_id
t.string :groupe_instructeur_label
t.string :previous_groupe_instructeur_label
t.string :assigned_by
t.timestamp :assigned_at, null: false
end
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_07_18_113720) do ActiveRecord::Schema[7.0].define(version: 2023_07_18_113820) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto" enable_extension "pgcrypto"
enable_extension "plpgsql" enable_extension "plpgsql"
@ -307,6 +307,18 @@ ActiveRecord::Schema[7.0].define(version: 2023_07_18_113720) do
t.index ["procedure_id"], name: "index_deleted_dossiers_on_procedure_id" t.index ["procedure_id"], name: "index_deleted_dossiers_on_procedure_id"
end end
create_table "dossier_assignments", force: :cascade do |t|
t.datetime "assigned_at", precision: nil, null: false
t.string "assigned_by"
t.bigint "dossier_id", null: false
t.bigint "groupe_instructeur_id"
t.string "groupe_instructeur_label"
t.string "mode", null: false
t.bigint "previous_groupe_instructeur_id"
t.string "previous_groupe_instructeur_label"
t.index ["dossier_id"], name: "index_dossier_assignments_on_dossier_id"
end
create_table "dossier_batch_operations", force: :cascade do |t| create_table "dossier_batch_operations", force: :cascade do |t|
t.bigint "batch_operation_id", null: false t.bigint "batch_operation_id", null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
@ -1030,6 +1042,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_07_18_113720) do
add_foreign_key "commentaires", "dossiers" add_foreign_key "commentaires", "dossiers"
add_foreign_key "commentaires", "experts" add_foreign_key "commentaires", "experts"
add_foreign_key "commentaires", "instructeurs" add_foreign_key "commentaires", "instructeurs"
add_foreign_key "dossier_assignments", "dossiers"
add_foreign_key "dossier_batch_operations", "batch_operations" add_foreign_key "dossier_batch_operations", "batch_operations"
add_foreign_key "dossier_batch_operations", "dossiers" add_foreign_key "dossier_batch_operations", "dossiers"
add_foreign_key "dossier_corrections", "commentaires" add_foreign_key "dossier_corrections", "commentaires"

View file

@ -208,6 +208,9 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) } it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) }
it { expect(gi_1_2.dossiers.last.id).to be(dossier12.id) } it { expect(gi_1_2.dossiers.last.id).to be(dossier12.id) }
it { expect(dossier12.groupe_instructeur.id).to be(gi_1_2.id) } it { expect(dossier12.groupe_instructeur.id).to be(gi_1_2.id) }
it { expect(dossier12.dossier_assignment.dossier_id).to be(dossier12.id) }
it { expect(dossier12.dossier_assignment.groupe_instructeur_id).to be(gi_1_2.id) }
it { expect(dossier12.dossier_assignment.assigned_by).to eq(admin.email) }
it { expect(bulk_message.groupe_instructeurs).to contain_exactly(gi_1_2, gi_1_3) } it { expect(bulk_message.groupe_instructeurs).to contain_exactly(gi_1_2, gi_1_3) }
end end
@ -231,6 +234,30 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
end end
end end
describe '#destroy_all_groups_but_defaut' do
let!(:dossierA) { create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1_2) }
let!(:dossierB) { create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1_2) }
before do
post :destroy_all_groups_but_defaut,
params: {
procedure_id: procedure.id
}
dossierA.reload
dossierB.reload
end
it do
expect(dossierA.groupe_instructeur.id).to be(procedure.defaut_groupe_instructeur.id)
expect(dossierB.groupe_instructeur.id).to be(procedure.defaut_groupe_instructeur.id)
expect(dossierA.dossier_assignment.dossier_id).to be(dossierA.id)
expect(dossierB.dossier_assignment.dossier_id).to be(dossierB.id)
expect(dossierA.dossier_assignment.groupe_instructeur_id).to be(procedure.defaut_groupe_instructeur.id)
expect(dossierB.dossier_assignment.groupe_instructeur_id).to be(procedure.defaut_groupe_instructeur.id)
expect(dossierA.dossier_assignment.assigned_by).to eq(admin.email)
expect(dossierB.dossier_assignment.assigned_by).to eq(admin.email)
end
end
describe '#update' do describe '#update' do
let(:new_name) { 'nouveau nom du groupe' } let(:new_name) { 'nouveau nom du groupe' }
let!(:procedure_non_routee) { create(:procedure, :published, :for_individual, administrateurs: [admin]) } let!(:procedure_non_routee) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }

View file

@ -1179,16 +1179,21 @@ describe Instructeurs::DossiersController, type: :controller do
it do it do
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
expect(response.body).to include("Vous pouvez réaffecter le dossier nº #{dossier.id} à l'un des groupes d'instructeurs suivants.") expect(response.body).to include("Vous pouvez réaffecter le dossier nº #{dossier.id} à lun des groupes dinstructeurs suivants.")
expect(response.body).to include('2 groupes existent') expect(response.body).to include('2 groupes existent')
end end
end end
describe '#reaffecter' do describe '#reaffecter' do
let!(:gi_1) { procedure.groupe_instructeurs.first }
let!(:gi_2) { GroupeInstructeur.create(label: 'deuxième groupe', procedure: procedure) } let!(:gi_2) { GroupeInstructeur.create(label: 'deuxième groupe', procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure, groupe_instructeur: procedure.groupe_instructeurs.first) } let!(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1) }
let!(:new_instructeur) { create(:instructeur) }
before do before do
gi_1.instructeurs << new_instructeur
new_instructeur.followed_dossiers << dossier
post :reaffecter, post :reaffecter,
params: { params: {
procedure_id: procedure.id, procedure_id: procedure.id,
@ -1200,8 +1205,39 @@ describe Instructeurs::DossiersController, type: :controller do
it do it do
expect(dossier.reload.groupe_instructeur.id).to eq(gi_2.id) expect(dossier.reload.groupe_instructeur.id).to eq(gi_2.id)
expect(dossier.forced_groupe_instructeur).to be_truthy expect(dossier.forced_groupe_instructeur).to be_truthy
expect(dossier.followers_instructeurs).to eq []
expect(dossier.dossier_assignment.previous_groupe_instructeur_id).to eq(gi_1.id)
expect(dossier.dossier_assignment.previous_groupe_instructeur_label).to eq(gi_1.label)
expect(dossier.dossier_assignment.groupe_instructeur_id).to eq(gi_2.id)
expect(dossier.dossier_assignment.groupe_instructeur_label).to eq(gi_2.label)
expect(dossier.dossier_assignment.mode).to eq('manual')
expect(dossier.dossier_assignment.assigned_by).to eq(instructeur.email)
expect(response).to redirect_to(instructeur_procedure_path(procedure)) expect(response).to redirect_to(instructeur_procedure_path(procedure))
expect(flash.notice).to eq("Le dossier nº #{dossier.id} a été réaffecté au groupe dinstructeurs « deuxième groupe ».") expect(flash.notice).to eq("Le dossier nº #{dossier.id} a été réaffecté au groupe dinstructeurs « deuxième groupe ».")
end end
end end
describe '#personnes_impliquees' do
let!(:gi_1) { procedure.groupe_instructeurs.first }
let!(:gi_2) { GroupeInstructeur.create(label: 'deuxième groupe', procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1) }
let!(:new_instructeur) { create(:instructeur) }
before do
gi_1.instructeurs << new_instructeur
gi_2.instructeurs << instructeur
new_instructeur.followed_dossiers << dossier
dossier.assign_to_groupe_instructeur(gi_2, DossierAssignment.modes.fetch(:manual), new_instructeur)
get :personnes_impliquees,
params: {
procedure_id: procedure.id,
dossier_id: dossier.id
}
end
it do
expect(response.body).to include('a réaffecté ce dossier du groupe « défaut » au groupe « deuxième groupe »')
end
end
end end

View file

@ -221,7 +221,7 @@ RSpec.describe DossierCloneConcern do
context 'with updated groupe instructeur' do context 'with updated groupe instructeur' do
before { before {
dossier.update!(groupe_instructeur: create(:groupe_instructeur)) dossier.update!(groupe_instructeur: create(:groupe_instructeur))
forked_dossier.assign_to_groupe_instructeur(dossier.procedure.defaut_groupe_instructeur) forked_dossier.assign_to_groupe_instructeur(dossier.procedure.defaut_groupe_instructeur, DossierAssignment.modes.fetch(:manual))
} }
it { is_expected.to eq(added: [], updated: [], removed: []) } it { is_expected.to eq(added: [], updated: [], removed: []) }

View file

@ -0,0 +1,37 @@
require 'rails_helper'
RSpec.describe DossierAssignment, type: :model do
include Logic
before { Flipper.enable(:routing_rules, procedure) }
context 'Assignment from routing engine' do
let(:procedure) do
create(:procedure,
types_de_champ_public: [{ type: :drop_down_list, libelle: 'Votre ville', options: ['Paris', 'Lyon', 'Marseille'] }]).tap do |p|
p.groupe_instructeurs.create(label: 'a second group')
p.groupe_instructeurs.create(label: 'a third group')
end
end
let(:drop_down_tdc) { procedure.draft_revision.types_de_champ.first }
let(:dossier) { create(:dossier, :en_construction, procedure:).tap { _1.update(groupe_instructeur_id: nil) } }
before do
RoutingEngine.compute(dossier)
dossier.reload
end
it 'creates a dossier assignment with right attributes' do
expect(dossier.dossier_assignments.count).to eq 1
expect(dossier.dossier_assignment.mode).to eq 'auto'
expect(dossier.dossier_assignment.dossier_id).to eq dossier.id
expect(dossier.dossier_assignment.groupe_instructeur_id).to eq dossier.groupe_instructeur.id
expect(dossier.dossier_assignment.groupe_instructeur_label).to eq dossier.groupe_instructeur.label
expect(dossier.dossier_assignment.previous_groupe_instructeur_id).to be nil
expect(dossier.dossier_assignment.previous_groupe_instructeur_label).to be nil
expect(dossier.dossier_assignment.assigned_by).to be nil
end
end
end

View file

@ -578,12 +578,12 @@ describe Dossier, type: :model do
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
it "can change groupe instructeur" do it "can change groupe instructeur" do
dossier.assign_to_groupe_instructeur(new_groupe_instructeur_new_procedure) dossier.assign_to_groupe_instructeur(new_groupe_instructeur_new_procedure, DossierAssignment.modes.fetch(:auto))
expect(dossier.groupe_instructeur).not_to eq(new_groupe_instructeur_new_procedure) expect(dossier.groupe_instructeur).not_to eq(new_groupe_instructeur_new_procedure)
end end
it "can not change groupe instructeur if new groupe is from another procedure" do it "can not change groupe instructeur if new groupe is from another procedure" do
dossier.assign_to_groupe_instructeur(new_groupe_instructeur) dossier.assign_to_groupe_instructeur(new_groupe_instructeur, DossierAssignment.modes.fetch(:auto))
expect(dossier.groupe_instructeur).to eq(new_groupe_instructeur) expect(dossier.groupe_instructeur).to eq(new_groupe_instructeur)
end end
end end
@ -603,7 +603,7 @@ describe Dossier, type: :model do
it "unfollows stale instructeurs when groupe instructeur change" do it "unfollows stale instructeurs when groupe instructeur change" do
instructeur.follow(dossier) instructeur.follow(dossier)
instructeur2.follow(dossier) instructeur2.follow(dossier)
dossier.reload.assign_to_groupe_instructeur(new_groupe_instructeur, procedure.administrateurs.first) dossier.reload.assign_to_groupe_instructeur(new_groupe_instructeur, DossierAssignment.modes.fetch(:auto), procedure.administrateurs.first)
expect(dossier.reload.followers_instructeurs).not_to include(instructeur) expect(dossier.reload.followers_instructeurs).not_to include(instructeur)
expect(dossier.reload.followers_instructeurs).to include(instructeur2) expect(dossier.reload.followers_instructeurs).to include(instructeur2)

View file

@ -209,7 +209,7 @@ describe Instructeur, type: :model do
context 'when there is a modification on groupe instructeur' do context 'when there is a modification on groupe instructeur' do
let(:groupe_instructeur) { create(:groupe_instructeur, instructeurs: [instructeur], procedure: dossier.procedure) } let(:groupe_instructeur) { create(:groupe_instructeur, instructeurs: [instructeur], procedure: dossier.procedure) }
before { dossier.assign_to_groupe_instructeur(groupe_instructeur) } before { dossier.assign_to_groupe_instructeur(groupe_instructeur, DossierAssignment.modes.fetch(:auto)) }
it { is_expected.to match({ demande: true, annotations_privees: false, avis: false, messagerie: false }) } it { is_expected.to match({ demande: true, annotations_privees: false, avis: false, messagerie: false }) }
end end