diff --git a/app/controllers/experts/avis_controller.rb b/app/controllers/experts/avis_controller.rb index 35ff9c99d..108cc377f 100644 --- a/app/controllers/experts/avis_controller.rb +++ b/app/controllers/experts/avis_controller.rb @@ -60,9 +60,17 @@ module Experts end def update + updated_recently = @avis.updated_recently? if @avis.update(avis_params) flash.notice = 'Votre réponse est enregistrée.' @avis.dossier.update!(last_avis_updated_at: Time.zone.now) + if !updated_recently + @avis.dossier.followers_instructeurs + .with_instant_expert_avis_email_notifications_enabled + .each do |instructeur| + DossierMailer.notify_new_avis_to_instructeur(@avis, instructeur.email).deliver_later + end + end redirect_to instruction_expert_avis_path(@avis.procedure, @avis) else flash.now.alert = @avis.errors.full_messages diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 0fdfdfa58..8f26f35ff 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -261,7 +261,7 @@ module Instructeurs def assign_to_params params.require(:assign_to) - .permit(:instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled) + .permit(:instant_expert_avis_email_notifications_enabled, :instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled) end def assign_exports diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 645bb559e..36f0e56f3 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -46,6 +46,15 @@ class DossierMailer < ApplicationMailer end end + def notify_new_avis_to_instructeur(avis, instructeur_email) + I18n.with_locale(avis.dossier.user_locale) do + @avis = avis + @subject = default_i18n_subject(dossier_id: avis.dossier.id, libelle_demarche: avis.procedure.libelle) + + mail(to: instructeur_email, subject: @subject) + end + end + def notify_new_dossier_depose_to_instructeur(dossier, instructeur_email) I18n.with_locale(dossier.user_locale) do @dossier = dossier diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index d457f766e..8febd4b3c 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -2,16 +2,17 @@ # # Table name: assign_tos # -# id :integer not null, primary key -# daily_email_notifications_enabled :boolean default(FALSE), not null -# instant_email_dossier_notifications_enabled :boolean default(FALSE), not null -# instant_email_message_notifications_enabled :boolean default(FALSE), not null -# manager :boolean default(FALSE) -# weekly_email_notifications_enabled :boolean default(TRUE), not null -# created_at :datetime -# updated_at :datetime -# groupe_instructeur_id :bigint -# instructeur_id :integer +# id :integer not null, primary key +# daily_email_notifications_enabled :boolean default(FALSE), not null +# instant_email_dossier_notifications_enabled :boolean default(FALSE), not null +# instant_email_message_notifications_enabled :boolean default(FALSE), not null +# instant_expert_avis_email_notifications_enabled :boolean default(FALSE), not null +# manager :boolean default(FALSE) +# weekly_email_notifications_enabled :boolean default(TRUE), not null +# created_at :datetime +# updated_at :datetime +# groupe_instructeur_id :bigint +# instructeur_id :integer # class AssignTo < ApplicationRecord belongs_to :instructeur, optional: false diff --git a/app/models/avis.rb b/app/models/avis.rb index 183f52c73..4a49adb0e 100644 --- a/app/models/avis.rb +++ b/app/models/avis.rb @@ -74,6 +74,10 @@ class Avis < ApplicationRecord ] end + def updated_recently? + updated_at > 30.minutes.ago + end + def revoked? revoked_at.present? end diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index 70930a4c9..21ab826fb 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -41,6 +41,10 @@ class Instructeur < ApplicationRecord includes(:assign_to).where(assign_tos: { instant_email_dossier_notifications_enabled: true }) } + scope :with_instant_expert_avis_email_notifications_enabled, -> { + includes(:assign_to).where(assign_tos: { instant_expert_avis_email_notifications_enabled: true }) + } + default_scope { eager_load(:user) } def self.by_email(email) @@ -81,7 +85,7 @@ class Instructeur < ApplicationRecord end end - NOTIFICATION_SETTINGS = [:daily_email_notifications_enabled, :instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :weekly_email_notifications_enabled] + NOTIFICATION_SETTINGS = [:daily_email_notifications_enabled, :instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :weekly_email_notifications_enabled, :instant_expert_avis_email_notifications_enabled] def notification_settings(procedure_id) assign_to diff --git a/app/views/dossier_mailer/notify_new_avis_to_instructeur.html.haml b/app/views/dossier_mailer/notify_new_avis_to_instructeur.html.haml new file mode 100644 index 000000000..2c04917c1 --- /dev/null +++ b/app/views/dossier_mailer/notify_new_avis_to_instructeur.html.haml @@ -0,0 +1,9 @@ +- content_for(:title, "#{@subject}") + +%p= t(:hello, scope: [:views, :shared, :greetings]) + +%p + = t('.body', dossier_id: @avis.dossier.id, libelle_demarche: @avis.dossier.procedure.libelle) +%p= link_to("Voir le dossier n°#{@avis.dossier.id}", instructeur_dossier_url(@avis.procedure, @avis.dossier)) + += render partial: "layouts/mailers/signature" diff --git a/app/views/instructeurs/procedures/email_notifications.html.haml b/app/views/instructeurs/procedures/email_notifications.html.haml index eda53e02d..54f44534f 100644 --- a/app/views/instructeurs/procedures/email_notifications.html.haml +++ b/app/views/instructeurs/procedures/email_notifications.html.haml @@ -74,6 +74,20 @@ = form.radio_button :weekly_email_notifications_enabled, false = t('.utils.negative') + = form.label :email_notification, t('.avis_notifications.title') + %p.notice + = t('.avis_notifications.notice_1') + %p.notice + = t('.avis_notifications.notice_2') + + .radios + %label + = form.radio_button :instant_expert_avis_email_notifications_enabled, true + = t('.utils.positive') + %label + = form.radio_button :instant_expert_avis_email_notifications_enabled, false + = t('.utils.negative') + .send-wrapper = link_to t('.buttons.back_to_procedure'), instructeur_procedure_path(@procedure), class: 'button mr-1' = form.submit t('.buttons.save'), class: "button primary" diff --git a/config/locales/views/dossier_mailer/notify_new_avis_to_instructeur/fr.yml b/config/locales/views/dossier_mailer/notify_new_avis_to_instructeur/fr.yml new file mode 100644 index 000000000..df076042b --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_new_avis_to_instructeur/fr.yml @@ -0,0 +1,5 @@ +fr: + dossier_mailer: + notify_new_avis_to_instructeur: + subject: Nouvel avis déposé sur le dossier n°%{dossier_id} + body: Un nouvel a été déposé par un expert sur le dossier n° %{dossier_id} de la démarche %{libelle_demarche}. diff --git a/config/locales/views/instructeurs/procedures/email_notifications/fr.yml b/config/locales/views/instructeurs/procedures/email_notifications/fr.yml index e2b5b1277..6568b73de 100644 --- a/config/locales/views/instructeurs/procedures/email_notifications/fr.yml +++ b/config/locales/views/instructeurs/procedures/email_notifications/fr.yml @@ -23,6 +23,10 @@ fr: title: Recevoir un récapitulatif hebdomadaire notice_1: Cet email récapitule l’activité de la semaine sur l’ensemble de vos démarches. notice_2: Il est envoyé chaque semaine le lundi matin. + avis_notifications: + title: Recevoir une notification pour chaque avis rendu par un expert + notice_1: Cet email vous signale un nouvel avis posté par un expert que vous avez sollicité sur un dossier. + notice_2: Il est envoyé à chaque fois qu'un expert rend un avis. buttons: back_to_procedure: Revenir à la procédure save: Enregistrer diff --git a/db/migrate/20220830125703_add_avis_email_notification.rb b/db/migrate/20220830125703_add_avis_email_notification.rb new file mode 100644 index 000000000..9bf4e9a16 --- /dev/null +++ b/db/migrate/20220830125703_add_avis_email_notification.rb @@ -0,0 +1,5 @@ +class AddAvisEmailNotification < ActiveRecord::Migration[6.1] + def change + add_column :assign_tos, :instant_expert_avis_email_notifications_enabled, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 7157e7fe5..31a4c228b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_07_28_084804) do +ActiveRecord::Schema.define(version: 2022_08_30_125703) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -111,6 +111,7 @@ ActiveRecord::Schema.define(version: 2022_07_28_084804) do t.bigint "groupe_instructeur_id" t.boolean "instant_email_dossier_notifications_enabled", default: false, null: false t.boolean "instant_email_message_notifications_enabled", default: false, null: false + t.boolean "instant_expert_avis_email_notifications_enabled", default: false, null: false t.integer "instructeur_id" t.boolean "manager", default: false t.datetime "updated_at" diff --git a/spec/controllers/experts/avis_controller_spec.rb b/spec/controllers/experts/avis_controller_spec.rb index 655d21b63..8c492e4d0 100644 --- a/spec/controllers/experts/avis_controller_spec.rb +++ b/spec/controllers/experts/avis_controller_spec.rb @@ -4,10 +4,11 @@ describe Experts::AvisController, type: :controller do let(:now) { Time.zone.parse('01/02/2345') } let(:instructeur) { create(:instructeur) } + let!(:instructeur_with_instant_avis_notification) { create(:instructeur) } let(:another_instructeur) { create(:instructeur) } let(:claimant) { create(:expert) } let(:expert) { create(:expert) } - let(:procedure) { create(:procedure, :published, instructeurs: [instructeur, another_instructeur]) } + let(:procedure) { create(:procedure, :published, instructeurs: [instructeur, another_instructeur, instructeur_with_instant_avis_notification]) } let(:another_procedure) { create(:procedure, :published, instructeurs: [instructeur]) } let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: procedure) } @@ -155,6 +156,38 @@ describe Experts::AvisController, type: :controller do end end + context 'without attachment with an instructeur wants to be notified' do + before do + allow(DossierMailer).to receive(:notify_new_avis_to_instructeur).and_return(double(deliver_later: nil)) + AssignTo.find_by(instructeur: instructeur_with_instant_avis_notification).update!(instant_expert_avis_email_notifications_enabled: true) + Timecop.freeze(now) + instructeur_with_instant_avis_notification.follow(avis_without_answer.dossier) + patch :update, params: { id: avis_without_answer.id, procedure_id: procedure.id, avis: { answer: 'answer' } } + avis_without_answer.reload + end + after { Timecop.return } + + it 'The instructeur should be notified of the new avis' do + expect(DossierMailer).to have_received(:notify_new_avis_to_instructeur).once.with(avis_without_answer, instructeur_with_instant_avis_notification.email) + end + end + + context 'without attachment with an instructeur wants to be notified' do + before do + allow(DossierMailer).to receive(:notify_new_avis_to_instructeur).and_return(double(deliver_later: nil)) + AssignTo.find_by(instructeur: instructeur_with_instant_avis_notification).update!(instant_expert_avis_email_notifications_enabled: true) + Timecop.freeze(now) + instructeur_with_instant_avis_notification.follow(avis_without_answer.dossier) + patch :update, params: { id: avis_without_answer.id, procedure_id: procedure.id, avis: { answer: 'answer' } } + avis_without_answer.reload + end + after { Timecop.return } + + it 'The instructeur should be notified of the new avis' do + expect(DossierMailer).to have_received(:notify_new_avis_to_instructeur).once.with(avis_without_answer, instructeur_with_instant_avis_notification.email) + end + end + context 'with attachment' do include ActiveJob::TestHelper let(:file) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }