diff --git a/README.md b/README.md index 4056df8e1..e398c5f45 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ En local, un utilisateur de test est créé automatiquement, avec les identifian OperationsSignatureJob.set(cron: "0 6 * * *").perform_later ExpiredDossiersDeletionJob.set(cron: "0 7 * * *").perform_later PurgeStaleExportsJob.set(cron: "*/5 * * * *").perform_later + NotifyDraftNotSubmittedJob.set(cron: "0 7 * * *").perform_later ### Voir les emails envoyés en local diff --git a/app/jobs/notify_draft_not_submitted_job.rb b/app/jobs/notify_draft_not_submitted_job.rb new file mode 100644 index 000000000..82958c538 --- /dev/null +++ b/app/jobs/notify_draft_not_submitted_job.rb @@ -0,0 +1,7 @@ +class NotifyDraftNotSubmittedJob < ApplicationJob + queue_as :cron + + def perform(*args) + Dossier.notify_draft_not_submitted + end +end diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index b3fcd9a94..6bc61df26 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -104,4 +104,11 @@ class DossierMailer < ApplicationMailer mail(from: NO_REPLY_EMAIL, to: instructeur.email, subject: @subject) end + + def notify_brouillon_not_submitted(dossier) + @subject = "Attention : votre dossier n'est pas déposé." + @dossier = dossier + + mail(to: dossier.user.email, subject: @subject) + end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index ab93d3ec2..c72486994 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -22,6 +22,8 @@ class Dossier < ApplicationRecord TAILLE_MAX_ZIP = 50.megabytes + REMAINING_DAYS_BEFORE_CLOSING = 2 + has_one :etablissement, dependent: :destroy has_one :individual, validate: false, dependent: :destroy has_one :attestation, dependent: :destroy @@ -186,6 +188,19 @@ class Dossier < ApplicationRecord scope :without_brouillon_expiration_notice_sent, -> { where(brouillon_close_to_expiration_notice_sent_at: nil) } scope :without_en_construction_expiration_notice_sent, -> { where(en_construction_close_to_expiration_notice_sent_at: nil) } + scope :brouillon_near_procedure_closing_date, -> do + # select users who have submitted dossier for the given 'procedures.id' + users_who_submitted = + state_not_brouillon + .joins(:groupe_instructeur) + .where("groupe_instructeurs.procedure_id = procedures.id") + .select(:user_id) + # select dossier in brouillon where procedure closes in two days and for which the user has not submitted a Dossier + brouillon.joins(:procedure) + .where("procedures.auto_archive_on = (now() + INTERVAL '#{REMAINING_DAYS_BEFORE_CLOSING} days')::date") + .where.not(user: users_who_submitted) + end + scope :for_procedure, -> (procedure) { includes(:user, :groupe_instructeur).where(groupe_instructeurs: { procedure: procedure }) } scope :for_api_v2, -> { includes(procedure: [:administrateurs], etablissement: [], individual: []) } @@ -690,4 +705,12 @@ class Dossier < ApplicationRecord end end end + + def self.notify_draft_not_submitted + brouillon_near_procedure_closing_date + .includes(:user) + .find_each do |dossier| + DossierMailer.notify_brouillon_not_submitted(dossier).deliver_later + end + end end diff --git a/app/views/dossier_mailer/notify_brouillon_not_submitted.html.haml b/app/views/dossier_mailer/notify_brouillon_not_submitted.html.haml new file mode 100644 index 000000000..fe4e33910 --- /dev/null +++ b/app/views/dossier_mailer/notify_brouillon_not_submitted.html.haml @@ -0,0 +1,24 @@ +- content_for(:title, "#{@subject}") + +%p + Bonjour, + +%p + Le dossier n°#{@dossier.id} pour la démarche «  + %strong + #{@dossier.procedure.libelle} +  » est commencé mais n'est pas encore déposé. +%p + Si vous souhaitez que ce dossier soit pris en compte, il vous faut le déposer avant le + #{l(@dossier.procedure.auto_archive_on - 1.day, format: '%-d %B %Y')} à 23h59, date de cloture de la démarche. +%p + Pour cela, affichez le dossier avec le bouton ci-dessous, vérifiez votre dossier puis + cliquez sur le bouton + %strong + 'Déposer le dossier' +%p + Si vous ne souhaitez plus déposer le dossier, vous n'avez rien à faire. + += round_button('Afficher votre dossier', dossier_url(@dossier), :primary) + += render partial: "layouts/mailers/signature" diff --git a/spec/mailers/previews/dossier_mailer_preview.rb b/spec/mailers/previews/dossier_mailer_preview.rb index 55c1fd562..c959003fd 100644 --- a/spec/mailers/previews/dossier_mailer_preview.rb +++ b/spec/mailers/previews/dossier_mailer_preview.rb @@ -53,6 +53,10 @@ class DossierMailerPreview < ActionMailer::Preview DossierMailer.notify_automatic_deletion_to_administration([deleted_dossier, deleted_dossier], administration_email) end + def notify_brouillon_not_submitted + DossierMailer.notify_brouillon_not_submitted(draft) + end + private def usager_email @@ -76,7 +80,7 @@ class DossierMailerPreview < ActionMailer::Preview end def procedure - Procedure.new(id: 1234, libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', service: service, logo: Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png')) + Procedure.new(id: 1234, libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', service: service, logo: Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png'), auto_archive_on: Time.zone.today + Dossier::REMAINING_DAYS_BEFORE_CLOSING.days) end def service diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 98d56fca9..e36469e75 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -1152,6 +1152,33 @@ describe Dossier do it { expect(Dossier.for_procedure(procedure_2)).to contain_exactly(dossier_2_1) } end + describe '#notify_draft_not_submitted' do + let!(:user1) { create(:user) } + let!(:user2) { create(:user) } + let!(:procedure_near_closing) { create(:procedure, auto_archive_on: Time.zone.today + Dossier::REMAINING_DAYS_BEFORE_CLOSING.days) } + let!(:procedure_closed_later) { create(:procedure, auto_archive_on: Time.zone.today + Dossier::REMAINING_DAYS_BEFORE_CLOSING.days + 1.day) } + let!(:procedure_closed_before) { create(:procedure, auto_archive_on: Time.zone.today + Dossier::REMAINING_DAYS_BEFORE_CLOSING.days - 1.day) } + + # user 1 has three draft dossiers where one is for procedure that closes in two days ==> should trigger one mail + let!(:draft_near_closing) { create(:dossier, user: user1, procedure: procedure_near_closing) } + let!(:draft_before) { create(:dossier, user: user1, procedure: procedure_closed_before) } + let!(:draft_later) { create(:dossier, user: user1, procedure: procedure_closed_later) } + + # user 2 submitted a draft and en_construction dossier for the same procedure ==> should not trigger the mail + let!(:draft_near_closing_2) { create(:dossier, :en_construction, user: user2, procedure: procedure_near_closing) } + let!(:submitted_near_closing_2) { create(:dossier, user: user2, procedure: procedure_near_closing) } + + before do + allow(DossierMailer).to receive(:notify_brouillon_not_submitted).and_return(double(deliver_later: nil)) + Dossier.notify_draft_not_submitted + end + + it 'notifies draft is not submitted' do + expect(DossierMailer).to have_received(:notify_brouillon_not_submitted).once + expect(DossierMailer).to have_received(:notify_brouillon_not_submitted).with(draft_near_closing) + end + end + describe '#geo_position' do let(:lat) { "46.538192" } let(:lon) { "2.428462" }