diff --git a/Gemfile b/Gemfile
index d629ba148..a03b04aab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,7 +5,7 @@ gem 'actiontext', git: 'https://github.com/kobaltz/actiontext.git', branch: 'arc
gem 'active_link_to' # Automatically set a class on active links
gem 'active_model_serializers'
gem 'active_storage_validations'
-gem 'activestorage-openstack'
+gem 'activestorage-openstack', git: 'https://github.com/tchak/activestorage-openstack.git', branch: 'fix-activestorage-filename-wrap'
gem 'administrate'
gem 'after_party'
gem 'anchored'
diff --git a/Gemfile.lock b/Gemfile.lock
index 460ed512d..292ab7bf7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -15,30 +15,41 @@ GIT
open4 (~> 1.3.4)
rake
+GIT
+ remote: https://github.com/tchak/activestorage-openstack.git
+ revision: 907582f14d785fb965baebe9524c0162b1bd57c9
+ branch: fix-activestorage-filename-wrap
+ specs:
+ activestorage-openstack (1.3.0)
+ fog-openstack (~> 1.0)
+ marcel
+ mime-types
+ rails (>= 5.2.2)
+
GEM
remote: https://rubygems.org/
specs:
aasm (5.0.1)
concurrent-ruby (~> 1.0)
- actioncable (5.2.3)
- actionpack (= 5.2.3)
+ actioncable (5.2.4.1)
+ actionpack (= 5.2.4.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailer (5.2.3)
- actionpack (= 5.2.3)
- actionview (= 5.2.3)
- activejob (= 5.2.3)
+ actionmailer (5.2.4.1)
+ actionpack (= 5.2.4.1)
+ actionview (= 5.2.4.1)
+ activejob (= 5.2.4.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (5.2.3)
- actionview (= 5.2.3)
- activesupport (= 5.2.3)
- rack (~> 2.0)
+ actionpack (5.2.4.1)
+ actionview (= 5.2.4.1)
+ activesupport (= 5.2.4.1)
+ rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (5.2.3)
- activesupport (= 5.2.3)
+ actionview (5.2.4.1)
+ activesupport (= 5.2.4.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@@ -46,32 +57,27 @@ GEM
active_link_to (1.0.5)
actionpack
addressable
- active_model_serializers (0.10.8)
- actionpack (>= 4.1, < 6)
- activemodel (>= 4.1, < 6)
+ active_model_serializers (0.10.10)
+ actionpack (>= 4.1, < 6.1)
+ activemodel (>= 4.1, < 6.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_storage_validations (0.8.7)
rails (>= 5.2.0)
- activejob (5.2.3)
- activesupport (= 5.2.3)
+ activejob (5.2.4.1)
+ activesupport (= 5.2.4.1)
globalid (>= 0.3.6)
- activemodel (5.2.3)
- activesupport (= 5.2.3)
- activerecord (5.2.3)
- activemodel (= 5.2.3)
- activesupport (= 5.2.3)
+ activemodel (5.2.4.1)
+ activesupport (= 5.2.4.1)
+ activerecord (5.2.4.1)
+ activemodel (= 5.2.4.1)
+ activesupport (= 5.2.4.1)
arel (>= 9.0)
- activestorage (5.2.3)
- actionpack (= 5.2.3)
- activerecord (= 5.2.3)
+ activestorage (5.2.4.1)
+ actionpack (= 5.2.4.1)
+ activerecord (= 5.2.4.1)
marcel (~> 0.3.1)
- activestorage-openstack (1.2.0)
- fog-openstack (~> 1.0)
- marcel
- mime-types
- rails (>= 5.2.2)
- activesupport (5.2.3)
+ activesupport (5.2.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -205,7 +211,7 @@ GEM
ethon (0.11.0)
ffi (>= 1.3.0)
eventmachine (1.2.7)
- excon (0.71.0)
+ excon (0.72.0)
execjs (2.7.0)
factory_bot (4.11.1)
activesupport (>= 3.0.0)
@@ -221,9 +227,9 @@ GEM
flipper (~> 0.17.2)
rack (>= 1.4, < 3)
rack-protection (>= 1.5.3, < 2.1.0)
- fog-core (2.1.2)
+ fog-core (2.2.0)
builder
- excon (~> 0.58)
+ excon (~> 0.71)
formatador (~> 0.2)
mime-types
fog-json (1.2.0)
@@ -239,8 +245,9 @@ GEM
geocoder (1.6.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
- gon (6.2.1)
- actionpack (>= 3.0)
+ gon (6.3.2)
+ actionpack (>= 3.0.20)
+ i18n (>= 0.7)
multi_json
request_store (>= 1.0)
graphiql-rails (1.7.0)
@@ -322,25 +329,25 @@ GEM
activesupport (>= 4.2)
aes_key_wrap
bindata
- jsonapi-renderer (0.2.0)
+ jsonapi-renderer (0.2.2)
jwt (2.1.0)
- kaminari (1.1.1)
+ kaminari (1.2.0)
activesupport (>= 4.1.0)
- kaminari-actionview (= 1.1.1)
- kaminari-activerecord (= 1.1.1)
- kaminari-core (= 1.1.1)
- kaminari-actionview (1.1.1)
+ kaminari-actionview (= 1.2.0)
+ kaminari-activerecord (= 1.2.0)
+ kaminari-core (= 1.2.0)
+ kaminari-actionview (1.2.0)
actionview
- kaminari-core (= 1.1.1)
- kaminari-activerecord (1.1.1)
+ kaminari-core (= 1.2.0)
+ kaminari-activerecord (1.2.0)
activerecord
- kaminari-core (= 1.1.1)
- kaminari-core (1.1.1)
+ kaminari-core (= 1.2.0)
+ kaminari-core (1.2.0)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.7.0)
launchy (~> 2.2)
- letter_opener_web (1.3.4)
+ letter_opener_web (1.4.0)
actionmailer (>= 3.2)
letter_opener (~> 1.0)
railties (>= 3.2)
@@ -367,10 +374,10 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
- mime-types (3.3)
+ mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.1009)
- mimemagic (0.3.3)
+ mimemagic (0.3.4)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
@@ -450,7 +457,7 @@ GEM
pry-byebug (3.6.0)
byebug (~> 10.0)
pry (~> 0.10)
- public_suffix (4.0.1)
+ public_suffix (4.0.3)
puma (3.12.2)
pundit (2.0.1)
activesupport (>= 3.0.0)
@@ -471,18 +478,18 @@ GEM
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
- rails (5.2.3)
- actioncable (= 5.2.3)
- actionmailer (= 5.2.3)
- actionpack (= 5.2.3)
- actionview (= 5.2.3)
- activejob (= 5.2.3)
- activemodel (= 5.2.3)
- activerecord (= 5.2.3)
- activestorage (= 5.2.3)
- activesupport (= 5.2.3)
+ rails (5.2.4.1)
+ actioncable (= 5.2.4.1)
+ actionmailer (= 5.2.4.1)
+ actionpack (= 5.2.4.1)
+ actionview (= 5.2.4.1)
+ activejob (= 5.2.4.1)
+ activemodel (= 5.2.4.1)
+ activerecord (= 5.2.4.1)
+ activestorage (= 5.2.4.1)
+ activesupport (= 5.2.4.1)
bundler (>= 1.3.0)
- railties (= 5.2.3)
+ railties (= 5.2.4.1)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
@@ -496,9 +503,9 @@ GEM
rails-i18n (5.1.2)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
- railties (5.2.3)
- actionpack (= 5.2.3)
- activesupport (= 5.2.3)
+ railties (5.2.4.1)
+ actionpack (= 5.2.4.1)
+ activesupport (= 5.2.4.1)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
@@ -515,7 +522,7 @@ GEM
railties (>= 3.2)
tilt
regexp_parser (1.6.0)
- request_store (1.4.1)
+ request_store (1.5.0)
rack (>= 1.4)
responders (3.0.0)
actionpack (>= 5.0)
@@ -716,7 +723,7 @@ DEPENDENCIES
active_link_to
active_model_serializers
active_storage_validations
- activestorage-openstack
+ activestorage-openstack!
administrate
after_party
anchored
diff --git a/app/controllers/admin/attestation_templates_controller.rb b/app/controllers/admin/attestation_templates_controller.rb
index d1eff3ba5..4306de5a9 100644
--- a/app/controllers/admin/attestation_templates_controller.rb
+++ b/app/controllers/admin/attestation_templates_controller.rb
@@ -48,7 +48,7 @@ class Admin::AttestationTemplatesController < AdminController
render 'admin/attestation_templates/show', formats: [:pdf]
else
- flash.alert = attestation_template.errors.full_messages.join('
')
+ flash.alert = attestation.errors.full_messages.join('
')
end
end
diff --git a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
index cf024df3d..8732b2bb1 100644
--- a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
+++ b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
@@ -70,7 +70,11 @@ module NewAdministrateur
def reaffecter
target_group = procedure.groupe_instructeurs.find(params[:target_group])
- groupe_instructeur.dossiers.update_all(groupe_instructeur_id: target_group.id)
+
+ groupe_instructeur.dossiers.find_each do |dossier|
+ dossier.assign_to_groupe_instructeur(target_group, current_administrateur)
+ end
+
flash[:notice] = "Les dossiers du groupe « #{groupe_instructeur.label} » ont été réaffectés au groupe « #{target_group.label} »."
redirect_to procedure_groupe_instructeurs_path(procedure)
end
diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb
index fac36c1c7..e66aaf44b 100644
--- a/app/controllers/users/dossiers_controller.rb
+++ b/app/controllers/users/dossiers_controller.rb
@@ -297,14 +297,13 @@ module Users
end
# FIXME: require(:dossier) when all the champs are united
- def champs_and_groupe_instructeurs_params
- params.permit(dossier: [
- :groupe_instructeur_id,
+ def champs_params
+ params.permit(dossier: {
champs_attributes: [
:id, :value, :primary_value, :secondary_value, :piece_justificative_file, value: [],
champs_attributes: [:id, :_destroy, :value, :primary_value, :secondary_value, :piece_justificative_file, value: []]
]
- ])
+ })
end
def dossier
@@ -315,11 +314,20 @@ module Users
Dossier.with_champs.find(params[:id])
end
+ def change_groupe_instructeur?
+ params[:dossier][:groupe_instructeur_id].present? && @dossier.groupe_instructeur_id != params[:dossier][:groupe_instructeur_id].to_i
+ end
+
def update_dossier_and_compute_errors
errors = []
- if champs_and_groupe_instructeurs_params[:dossier] && !@dossier.update(champs_and_groupe_instructeurs_params[:dossier])
- errors += @dossier.errors.full_messages
+ if champs_params[:dossier]
+ if !@dossier.update(champs_params[:dossier])
+ errors += @dossier.errors.full_messages
+ elsif change_groupe_instructeur?
+ groupe_instructeur = @dossier.procedure.groupe_instructeurs.find(params[:dossier][:groupe_instructeur_id])
+ @dossier.assign_to_groupe_instructeur(groupe_instructeur)
+ end
end
if !save_draft?
diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql
index 9e1661174..15cdb6803 100644
--- a/app/graphql/schema.graphql
+++ b/app/graphql/schema.graphql
@@ -385,6 +385,7 @@ type Dossier {
"""
dateTraitement: ISO8601DateTime
demandeur: Demandeur!
+ groupeInstructeur: GroupeInstructeur!
id: ID!
instructeurs: [Profile!]!
messages: [Message!]!
diff --git a/app/graphql/types/dossier_type.rb b/app/graphql/types/dossier_type.rb
index 5cfe64b81..77026ef92 100644
--- a/app/graphql/types/dossier_type.rb
+++ b/app/graphql/types/dossier_type.rb
@@ -35,6 +35,8 @@ module Types
field :messages, [Types::MessageType], null: false
field :avis, [Types::AvisType], null: false
+ field :groupe_instructeur, Types::GroupeInstructeurType, null: false
+
def state
object.state
end
@@ -47,6 +49,10 @@ module Types
Loaders::Association.for(object.class, :followers_instructeurs).load(object)
end
+ def groupe_instructeur
+ Loaders::Record.for(GroupeInstructeur).load(object.groupe_instructeur_id)
+ end
+
def messages
Loaders::Association.for(object.class, commentaires: [:instructeur, :user]).load(object)
end
diff --git a/app/models/dossier.rb b/app/models/dossier.rb
index 9c25ec40f..ebee64ca8 100644
--- a/app/models/dossier.rb
+++ b/app/models/dossier.rb
@@ -213,7 +213,6 @@ class Dossier < ApplicationRecord
before_save :build_default_champs, if: Proc.new { groupe_instructeur_id_was.nil? }
before_save :update_search_terms
- after_save :unfollow_stale_instructeurs
after_save :send_dossier_received
after_save :send_web_hook
after_create :send_draft_notification_email
@@ -300,6 +299,22 @@ class Dossier < ApplicationRecord
instruction_commencee? && retention_end_date <= Time.zone.now
end
+ def assign_to_groupe_instructeur(groupe_instructeur, author = nil)
+ if groupe_instructeur.procedure == procedure && groupe_instructeur != self.groupe_instructeur
+ if update(groupe_instructeur: groupe_instructeur)
+ unfollow_stale_instructeurs
+
+ if author.present?
+ log_dossier_operation(author, :changer_groupe_instructeur, self)
+ end
+
+ true
+ end
+ else
+ false
+ end
+ end
+
def text_summary
if brouillon?
parts = [
@@ -647,14 +662,11 @@ class Dossier < ApplicationRecord
end
def unfollow_stale_instructeurs
- if saved_change_to_groupe_instructeur_id? && saved_change_to_groupe_instructeur_id[0].present?
- followers_instructeurs.each do |instructeur|
- if instructeur.groupe_instructeurs.exclude?(groupe_instructeur)
- instructeur.unfollow(self)
- DossierMailer.notify_groupe_instructeur_changed(instructeur, self).deliver_later
- end
+ followers_instructeurs.each do |instructeur|
+ if instructeur.groupe_instructeurs.exclude?(groupe_instructeur)
+ instructeur.unfollow(self)
+ DossierMailer.notify_groupe_instructeur_changed(instructeur, self).deliver_later
end
- log_dossier_operation(user, :changer_groupe_instructeur, self)
end
end
diff --git a/spec/controllers/api/v2/graphql_controller_spec.rb b/spec/controllers/api/v2/graphql_controller_spec.rb
index eaab82e2f..feab5a789 100644
--- a/spec/controllers/api/v2/graphql_controller_spec.rb
+++ b/spec/controllers/api/v2/graphql_controller_spec.rb
@@ -201,6 +201,10 @@ describe API::V2::GraphqlController do
id
email
}
+ groupeInstructeur {
+ id
+ label
+ }
messages {
email
body
@@ -255,6 +259,10 @@ describe API::V2::GraphqlController do
email: instructeur.email
}
],
+ groupeInstructeur: {
+ id: dossier.groupe_instructeur.to_typed_id,
+ label: dossier.groupe_instructeur.label
+ },
demandeur: {
id: dossier.individual.to_typed_id,
nom: dossier.individual.nom,
diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb
index dbdc9ac69..f1cad93d2 100644
--- a/spec/models/dossier_spec.rb
+++ b/spec/models/dossier_spec.rb
@@ -398,12 +398,29 @@ describe Dossier do
it { is_expected.to match([dossier3, dossier4, dossier2]) }
end
+ describe "#assign_to_groupe_instructeur" do
+ let(:procedure) { create(:procedure) }
+ let(:new_groupe_instructeur_new_procedure) { create(:groupe_instructeur) }
+ let(:new_groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
+ let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
+
+ it "can change groupe instructeur" do
+ expect(dossier.assign_to_groupe_instructeur(new_groupe_instructeur_new_procedure)).to be_falsey
+ expect(dossier.groupe_instructeur).not_to eq(new_groupe_instructeur_new_procedure)
+ end
+
+ it "can not change groupe instructeur if new groupe is from another procedure" do
+ expect(dossier.assign_to_groupe_instructeur(new_groupe_instructeur)).to be_truthy
+ expect(dossier.groupe_instructeur).to eq(new_groupe_instructeur)
+ end
+ end
+
describe "#unfollow_stale_instructeurs" do
let(:procedure) { create(:procedure) }
let(:instructeur) { create(:instructeur) }
- let(:new_groupe_instructeur) { create(:groupe_instructeur) }
+ let(:new_groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
let(:instructeur2) { create(:instructeur, groupe_instructeurs: [procedure.defaut_groupe_instructeur, new_groupe_instructeur]) }
- let(:dossier) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction)) }
+ let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:last_operation) { DossierOperationLog.last }
before do
@@ -413,7 +430,7 @@ describe Dossier do
it "unfollows stale instructeurs when groupe instructeur change" do
instructeur.follow(dossier)
instructeur2.follow(dossier)
- dossier.reload.update(groupe_instructeur: new_groupe_instructeur)
+ dossier.reload.assign_to_groupe_instructeur(new_groupe_instructeur, procedure.administrateurs.first)
expect(dossier.reload.followers_instructeurs).not_to include(instructeur)
expect(dossier.reload.followers_instructeurs).to include(instructeur2)
diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb
index ce6a06349..d3985de74 100644
--- a/spec/models/procedure_presentation_spec.rb
+++ b/spec/models/procedure_presentation_spec.rb
@@ -215,7 +215,10 @@ describe ProcedurePresentation do
let!(:follow1) { create(:follow, dossier: dossier, instructeur: create(:instructeur, email: 'user1@host')) }
let!(:follow2) { create(:follow, dossier: dossier, instructeur: create(:instructeur, email: 'user2@host')) }
- it { is_expected.to eq('user1@host, user2@host') }
+ it "return emails of followers instructeurs" do
+ emails_to_display = procedure_presentation.displayed_field_values(dossier).first.split(', ').sort
+ expect(emails_to_display).to eq ["user1@host", "user2@host"]
+ end
end
context 'for type_de_champ table' do