diff --git a/app/components/procedure/card/emails_component.rb b/app/components/procedure/card/emails_component.rb index 60d5dd31b..16a153efb 100644 --- a/app/components/procedure/card/emails_component.rb +++ b/app/components/procedure/card/emails_component.rb @@ -1,5 +1,5 @@ class Procedure::Card::EmailsComponent < ApplicationComponent - CUSTOMIZABLE_COUNT = 5 + CUSTOMIZABLE_COUNT = 6 def initialize(procedure:) @procedure = procedure @@ -31,7 +31,8 @@ class Procedure::Card::EmailsComponent < ApplicationComponent @procedure.received_mail, @procedure.closed_mail, @procedure.refused_mail, - @procedure.without_continuation_mail + @procedure.without_continuation_mail, + @procedure.re_instructed_mail ].map { |mail| mail&.updated_at }.compact.size end end diff --git a/app/components/procedure/publication_warning_component.rb b/app/components/procedure/publication_warning_component.rb index dc90de716..726d3f987 100644 --- a/app/components/procedure/publication_warning_component.rb +++ b/app/components/procedure/publication_warning_component.rb @@ -25,7 +25,7 @@ class Procedure::PublicationWarningComponent < ApplicationComponent champs_admin_procedure_path(@procedure) when :attestation_template edit_admin_procedure_attestation_template_path(@procedure) - when :initiated_mail, :received_mail, :closed_mail, :refused_mail, :without_continuation_mail + when :initiated_mail, :received_mail, :closed_mail, :refused_mail, :without_continuation_mail, :re_instructed_mail admin_procedure_mail_templates_path(@procedure) end end diff --git a/app/controllers/administrateurs/mail_templates_controller.rb b/app/controllers/administrateurs/mail_templates_controller.rb index 37716eec4..f7ec84444 100644 --- a/app/controllers/administrateurs/mail_templates_controller.rb +++ b/app/controllers/administrateurs/mail_templates_controller.rb @@ -58,7 +58,8 @@ module Administrateurs procedure.received_mail_template, procedure.closed_mail_template, procedure.refused_mail_template, - procedure.without_continuation_mail_template + procedure.without_continuation_mail_template, + procedure.re_instructed_mail_template ] end diff --git a/app/controllers/administrateurs/procedures_controller.rb b/app/controllers/administrateurs/procedures_controller.rb index af7ab2857..f1370199a 100644 --- a/app/controllers/administrateurs/procedures_controller.rb +++ b/app/controllers/administrateurs/procedures_controller.rb @@ -116,7 +116,8 @@ module Administrateurs received_mail: [], closed_mail: [], refused_mail: [], - without_continuation_mail: [] + without_continuation_mail: [], + re_instructed_mail: [] ) .find(params[:id]) diff --git a/app/dashboards/procedure_dashboard.rb b/app/dashboards/procedure_dashboard.rb index 1c71652fb..ae4b1661e 100644 --- a/app/dashboards/procedure_dashboard.rb +++ b/app/dashboards/procedure_dashboard.rb @@ -38,6 +38,7 @@ class ProcedureDashboard < Administrate::BaseDashboard closed_mail_template: MailTemplateField, refused_mail_template: MailTemplateField, without_continuation_mail_template: MailTemplateField, + re_instructed_mail_template: MailTemplateField, attestation_template: AttestationTemplateField, procedure_expires_when_termine_enabled: Field::Boolean, duree_conservation_dossiers_dans_ds: Field::Number, @@ -97,6 +98,7 @@ class ProcedureDashboard < Administrate::BaseDashboard :closed_mail_template, :refused_mail_template, :without_continuation_mail_template, + :re_instructed_mail_template, :attestation_template, :procedure_expires_when_termine_enabled, :duree_conservation_dossiers_dans_ds, diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index adad878a2..005d2340d 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -81,19 +81,6 @@ class DossierMailer < ApplicationMailer end end - def notify_revert_to_instruction(dossier) - I18n.with_locale(dossier.user_locale) do - @dossier = dossier - @service = dossier.procedure.service - @logo_url = procedure_logo_url(@dossier.procedure) - @subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle) - - mail(to: dossier.user_email_for(:notification), subject: @subject) do |format| - format.html { render layout: 'mailers/notifications_layout' } - end - end - end - def notify_brouillon_near_deletion(dossiers, to_email) I18n.with_locale(dossiers.first.user_locale) do @subject = default_i18n_subject(count: dossiers.size) diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 3b9e5a80f..6ebe4cec2 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -44,6 +44,10 @@ class NotificationMailer < ApplicationMailer with(dossier: dossier, state: Dossier.states.fetch(:sans_suite)).send_notification end + def self.send_repasser_en_instruction_notification(dossier) + with(dossier: dossier, state: Dossier.states.fetch(:en_instruction)).send_notification + end + def self.send_pending_correction(dossier) with(dossier: dossier).send_notification end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 178acd8e6..43ac679d0 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -876,7 +876,7 @@ class Dossier < ApplicationRecord end def mail_template_for_state - procedure.mail_template_for(state) + procedure.mail_template_for(self) end def after_passer_en_construction @@ -978,12 +978,14 @@ class Dossier < ApplicationRecord self.sva_svr_decision_on = nil self.motivation = nil self.justificatif_motivation.purge_later + self.re_instructed_at = Time.zone.now save! rebase_later + + MailTemplatePresenterService.create_commentaire_for_state(self) if !disable_notification - # pourquoi pas de commentaire automatique ici ? - DossierMailer.notify_revert_to_instruction(self).deliver_later + NotificationMailer.send_repasser_en_instruction_notification(self).deliver_later end log_dossier_operation(instructeur, :repasser_en_instruction) end diff --git a/app/models/mails/re_instructed_mail.rb b/app/models/mails/re_instructed_mail.rb new file mode 100644 index 000000000..0a7dc35e0 --- /dev/null +++ b/app/models/mails/re_instructed_mail.rb @@ -0,0 +1,27 @@ +# == Schema Information +# +# Table name: re_instructed_mails +# +# id :integer not null, primary key +# body :text +# subject :string +# created_at :datetime not null +# updated_at :datetime not null +# procedure_id :integer +# +module Mails + class ReInstructedMail < ApplicationRecord + include MailTemplateConcern + + belongs_to :procedure, optional: false + + validates :subject, tags: true + validates :body, tags: true + + SLUG = "re_instructed_mail" + DEFAULT_TEMPLATE_NAME = "notification_mailer/default_templates/re_instructed_mail" + DISPLAYED_NAME = I18n.t('activerecord.models.mail.re_instructed_mail.under_re_instruction') + DEFAULT_SUBJECT = I18n.t('activerecord.models.mail.re_instructed_mail.default_subject', dossier_number: '--numéro du dossier--', procedure_libelle: '--libellé démarche--') + DOSSIER_STATE = Dossier.states.fetch(:en_instruction) + end +end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 79b1bc2ed..0eba2e718 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -156,6 +156,7 @@ class Procedure < ApplicationRecord has_one :closed_mail, class_name: "Mails::ClosedMail", dependent: :destroy has_one :refused_mail, class_name: "Mails::RefusedMail", dependent: :destroy has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy + has_one :re_instructed_mail, class_name: "Mails::ReInstructedMail", dependent: :destroy belongs_to :defaut_groupe_instructeur, class_name: 'GroupeInstructeur', inverse_of: false, optional: true @@ -272,6 +273,7 @@ class Procedure < ApplicationRecord validates_associated :closed_mail, on: :publication validates_associated :refused_mail, on: :publication validates_associated :without_continuation_mail, on: :publication + validates_associated :re_instructed_mail, on: :publication validates_associated :attestation_template, on: :publication, if: -> { attestation_template&.activated? } FILE_MAX_SIZE = 20.megabytes @@ -506,6 +508,7 @@ class Procedure < ApplicationRecord procedure.closed_mail = closed_mail&.dup procedure.refused_mail = refused_mail&.dup procedure.without_continuation_mail = without_continuation_mail&.dup + procedure.re_instructed_mail = re_instructed_mail&.dup procedure.ask_birthday = false # see issue #4242 procedure.cloned_from_library = from_library @@ -582,12 +585,16 @@ class Procedure < ApplicationRecord without_continuation_mail || Mails::WithoutContinuationMail.default_for_procedure(self) end - def mail_template_for(state) - case state + def re_instructed_mail_template + re_instructed_mail || Mails::ReInstructedMail.default_for_procedure(self) + end + + def mail_template_for(dossier) + case dossier.state when Dossier.states.fetch(:en_construction) initiated_mail_template when Dossier.states.fetch(:en_instruction) - received_mail_template + dossier.re_instructed_at.present? ? re_instructed_mail_template : received_mail_template when Dossier.states.fetch(:accepte) closed_mail_template when Dossier.states.fetch(:refuse) diff --git a/app/views/dossier_mailer/notify_revert_to_instruction.html.haml b/app/views/dossier_mailer/notify_revert_to_instruction.html.haml deleted file mode 100644 index fad3671c0..000000000 --- a/app/views/dossier_mailer/notify_revert_to_instruction.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- content_for :procedure_logo do - = render 'layouts/mailers/logo', url: @logo_url - -%p= t(:hello, scope: [:views, :shared, :greetings]) - -%p - = t('.body_html', dossier_id: @dossier.id, libelle_demarche: @dossier.procedure.libelle) - = link_to dossier_url(@dossier), dossier_url(@dossier), target: '_blank', rel: 'noopener' -- if @dossier.procedure.service.present? - %p - = t('.contact') - = mail_to @dossier.procedure.service.email, @dossier.procedure.service.email - -= render 'layouts/mailers/signature' - -- content_for :footer do - = render 'layouts/mailers/service_footer', service: @service, dossier: @dossier diff --git a/app/views/notification_mailer/default_templates/re_instructed_mail.html.haml b/app/views/notification_mailer/default_templates/re_instructed_mail.html.haml new file mode 100644 index 000000000..7a00ae190 --- /dev/null +++ b/app/views/notification_mailer/default_templates/re_instructed_mail.html.haml @@ -0,0 +1,11 @@ +%p + Bonjour, + +%p + Votre dossier nº --numéro du dossier-- + va être réexaminé, la précédente décision sur ce dossier est caduque. + Vous pouvez retrouver le dossier que vous avez créé pour la démarche --libellé démarche-- à l’adresse suivante : --lien dossier-- + + Pour obtenir le détail de cette modification de la décision, vous pouvez contacter le service : --nom du service--. + += render partial: "notification_mailer/default_templates/signature" diff --git a/config/locales/models/mail/re_instructed_mail/en.yml b/config/locales/models/mail/re_instructed_mail/en.yml new file mode 100644 index 000000000..58814def9 --- /dev/null +++ b/config/locales/models/mail/re_instructed_mail/en.yml @@ -0,0 +1,7 @@ +en: + activerecord: + models: + mail: + re_instructed_mail: + default_subject: Your file nº %{dossier_number} will be examined (%{procedure_libelle}) + under_re_instruction: Acknowledgment of being under instruction diff --git a/config/locales/models/mail/re_instructed_mail/fr.yml b/config/locales/models/mail/re_instructed_mail/fr.yml new file mode 100644 index 000000000..7ae03f856 --- /dev/null +++ b/config/locales/models/mail/re_instructed_mail/fr.yml @@ -0,0 +1,7 @@ +fr: + activerecord: + models: + mail: + re_instructed_mail: + default_subject: Votre dossier nº %{dossier_number} est en train d'être réexaminé (%{procedure_libelle}) + under_re_instruction: Réexamen du dossier diff --git a/config/locales/views/dossier_mailer/notify_revert_to_instruction/en.yml b/config/locales/views/dossier_mailer/notify_revert_to_instruction/en.yml deleted file mode 100644 index 6f820beeb..000000000 --- a/config/locales/views/dossier_mailer/notify_revert_to_instruction/en.yml +++ /dev/null @@ -1,9 +0,0 @@ -en: - dossier_mailer: - notify_revert_to_instruction: - subject: Your file nº %{dossier_id} « %{libelle_demarche} » will be reexamined - body_html: | - Your file nº %{dossier_id} will be reexamined. All previous decisions are void. - To see the file created on procedure « %{libelle_demarche} », select the following link: - contact: | - In order to get more details about the decision to reexamin, please contact the following service: diff --git a/config/locales/views/dossier_mailer/notify_revert_to_instruction/fr.yml b/config/locales/views/dossier_mailer/notify_revert_to_instruction/fr.yml deleted file mode 100644 index 9fa0f014a..000000000 --- a/config/locales/views/dossier_mailer/notify_revert_to_instruction/fr.yml +++ /dev/null @@ -1,9 +0,0 @@ -fr: - dossier_mailer: - notify_revert_to_instruction: - subject: Votre dossier nº %{dossier_id} sur la démarche « %{libelle_demarche} » est en train d’être réexaminé - body_html: | - Votre dossier nº %{dossier_id} va être réexaminé, la précédente décision sur ce dossier est caduque. - Vous pouvez retrouver le dossier que vous avez créé pour la démarche « %{libelle_demarche} » à l’adresse suivante : - contact: | - Pour obtenir le détail de cette modification de la décision, vous pouvez contacter par email : diff --git a/db/migrate/20231107130640_add_re_instructed_at_to_dossiers.rb b/db/migrate/20231107130640_add_re_instructed_at_to_dossiers.rb new file mode 100644 index 000000000..a75e2446a --- /dev/null +++ b/db/migrate/20231107130640_add_re_instructed_at_to_dossiers.rb @@ -0,0 +1,5 @@ +class AddReInstructedAtToDossiers < ActiveRecord::Migration[7.0] + def change + add_column :dossiers, :re_instructed_at, :datetime + end +end diff --git a/db/migrate/20231107150217_create_re_instructed_mails.rb b/db/migrate/20231107150217_create_re_instructed_mails.rb new file mode 100644 index 000000000..d8992b6a0 --- /dev/null +++ b/db/migrate/20231107150217_create_re_instructed_mails.rb @@ -0,0 +1,12 @@ +class CreateReInstructedMails < ActiveRecord::Migration[7.0] + def change + create_table :re_instructed_mails do |t| + t.text :body + t.string :subject + t.integer :procedure_id, null: false + + t.timestamps + end + add_index :re_instructed_mails, :procedure_id + end +end diff --git a/db/schema.rb b/db/schema.rb index bd188e760..adcff1293 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[7.0].define(version: 2023_11_03_084116) do +ActiveRecord::Schema[7.0].define(version: 2023_11_07_150217) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -422,6 +422,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_11_03_084116) do t.boolean "prefilled" t.string "private_search_terms" t.datetime "processed_at", precision: 6 + t.datetime "re_instructed_at" t.bigint "revision_id" t.string "search_terms" t.string "state" @@ -878,12 +879,21 @@ ActiveRecord::Schema[7.0].define(version: 2023_11_03_084116) do t.index ["zone_id"], name: "index_procedures_zones_on_zone_id" end + create_table "re_instructed_mails", force: :cascade do |t| + t.text "body" + t.datetime "created_at", null: false + t.integer "procedure_id", null: false + t.string "subject" + t.datetime "updated_at", null: false + t.index ["procedure_id"], name: "index_re_instructed_mails_on_procedure_id" + end + create_table "received_mails", id: :serial, force: :cascade do |t| t.text "body" - t.datetime "created_at", precision: 6, null: false + t.datetime "created_at", precision: nil, null: false t.integer "procedure_id" t.string "subject" - t.datetime "updated_at", precision: 6, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["procedure_id"], name: "index_received_mails_on_procedure_id" end diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index c800b2083..449465f63 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -86,18 +86,6 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.body).to include(deleted_dossier.procedure.libelle) } end - describe '.notify_revert_to_instruction' do - let(:dossier) { create(:dossier, procedure: create(:simple_procedure)) } - - subject { described_class.notify_revert_to_instruction(dossier) } - - it { expect(subject.subject).to include('réexaminé') } - it { expect(subject.body).to include(dossier.procedure.libelle) } - it { expect(subject.body).to include(dossier_url(dossier)) } - - it_behaves_like 'a dossier notification' - end - describe '.notify_brouillon_near_deletion' do let(:dossier) { create(:dossier) } diff --git a/spec/mailers/previews/dossier_mailer_preview.rb b/spec/mailers/previews/dossier_mailer_preview.rb index 5b29ff27e..718d3f152 100644 --- a/spec/mailers/previews/dossier_mailer_preview.rb +++ b/spec/mailers/previews/dossier_mailer_preview.rb @@ -18,10 +18,6 @@ class DossierMailerPreview < ActionMailer::Preview DossierMailer.with(commentaire:).notify_pending_correction end - def notify_revert_to_instruction - DossierMailer.notify_revert_to_instruction(dossier) - end - def notify_brouillon_near_deletion DossierMailer.notify_brouillon_near_deletion([dossier], usager_email) end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 9836bcf10..a46a23ff1 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -1177,7 +1177,7 @@ describe Dossier, type: :model do it 'creates a commentaire in the messagerie with expected wording' do passer_en_instruction - email_template = dossier.procedure.mail_template_for(Dossier.states.fetch(:en_instruction)) + email_template = dossier.procedure.mail_template_for(dossier) commentaire = dossier.commentaires.last expect(commentaire.body).to include(email_template.subject_for_dossier(dossier), email_template.body_for_dossier(dossier)) @@ -1634,8 +1634,7 @@ describe Dossier, type: :model do before do Timecop.freeze - allow(DossierMailer).to receive(:notify_revert_to_instruction) - .and_return(double(deliver_later: true)) + allow(NotificationMailer).to receive(:send_repasser_en_instruction_notification).and_return(double(deliver_later: true)) dossier.repasser_en_instruction!(instructeur: instructeur) dossier.reload end @@ -1650,7 +1649,7 @@ describe Dossier, type: :model do it { expect(dossier.termine_close_to_expiration_notice_sent_at).to be_nil } it { expect(last_operation.operation).to eq('repasser_en_instruction') } it { expect(last_operation.data['author']['email']).to eq(instructeur.email) } - it { expect(DossierMailer).to have_received(:notify_revert_to_instruction).with(dossier) } + it { expect(NotificationMailer).to have_received(:send_repasser_en_instruction_notification).with(dossier) } after { Timecop.return } end diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 849841d5a..bc3724c9c 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -7,6 +7,7 @@ describe Procedure do it { expect(subject.closed_mail_template).to be_a(Mails::ClosedMail) } it { expect(subject.refused_mail_template).to be_a(Mails::RefusedMail) } it { expect(subject.without_continuation_mail_template).to be_a(Mails::WithoutContinuationMail) } + it { expect(subject.re_instructed_mail_template).to be_a(Mails::ReInstructedMail) } end describe 'compute_dossiers_count' do