commit
53be5f9f21
14 changed files with 339 additions and 0 deletions
BIN
app/assets/images/mailer/gestionnaire_mailer/logo.png
Executable file
BIN
app/assets/images/mailer/gestionnaire_mailer/logo.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
|
@ -8,6 +8,11 @@ class GestionnaireMailer < ApplicationMailer
|
|||
send_mail email, email_admin, "Vous avez été assigné à un nouvel administrateur sur la plateforme TPS"
|
||||
end
|
||||
|
||||
def last_week_overview(gestionnaire, overview)
|
||||
headers['X-mailjet-campaign'] = 'last_week_overview'
|
||||
send_mail gestionnaire.email, overview, 'Résumé de la semaine'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def vars_mailer email, args
|
||||
|
|
|
@ -92,6 +92,26 @@ class Gestionnaire < ActiveRecord::Base
|
|||
notifications.pluck(:dossier_id).uniq.count
|
||||
end
|
||||
|
||||
def last_week_overview
|
||||
start_date = DateTime.now.beginning_of_week
|
||||
|
||||
active_procedure_overviews = procedures
|
||||
.where(published: true)
|
||||
.all
|
||||
.map { |procedure| procedure.procedure_overview(start_date, dossiers_with_notifications_count_for_procedure(procedure)) }
|
||||
.select(&:had_some_activities?)
|
||||
|
||||
if active_procedure_overviews.count == 0 && notifications.count == 0
|
||||
nil
|
||||
else
|
||||
{
|
||||
start_date: start_date,
|
||||
procedure_overviews: active_procedure_overviews,
|
||||
notifications: notifications
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_couple_table_attr? table, column
|
||||
|
|
|
@ -141,4 +141,7 @@ class Procedure < ActiveRecord::Base
|
|||
}
|
||||
end
|
||||
|
||||
def procedure_overview(start_date, notifications_count)
|
||||
ProcedureOverview.new(self, start_date, notifications_count)
|
||||
end
|
||||
end
|
||||
|
|
82
app/models/procedure_overview.rb
Normal file
82
app/models/procedure_overview.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
class ProcedureOverview
|
||||
include Rails.application.routes.url_helpers
|
||||
attr_accessor :libelle, :notifications_count, :received_dossiers_count, :created_dossiers_count, :processed_dossiers_count, :date
|
||||
|
||||
def initialize(procedure, start_date, notifications_count)
|
||||
@libelle = procedure.libelle
|
||||
@procedure_url = backoffice_dossiers_procedure_path(procedure)
|
||||
@notifications_count = notifications_count
|
||||
|
||||
@received_dossiers_count = procedure.dossiers.where(state: :received).count
|
||||
@created_dossiers_count = procedure.dossiers
|
||||
.where(created_at: start_date..DateTime.now)
|
||||
.where.not(state: :draft)
|
||||
.count
|
||||
@processed_dossiers_count = procedure.dossiers.where(processed_at: start_date..DateTime.now).count
|
||||
end
|
||||
|
||||
def had_some_activities?
|
||||
[received_dossiers_count,
|
||||
created_dossiers_count,
|
||||
processed_dossiers_count,
|
||||
notifications_count].reduce(:+) > 0
|
||||
end
|
||||
|
||||
def to_html
|
||||
[libelle_description,
|
||||
dossiers_en_instruction_description,
|
||||
created_dossier_description,
|
||||
processed_dossier_description,
|
||||
notifications_description].compact.join('<br>')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def libelle_description
|
||||
"<a href='#{@procedure_url}'><strong>#{libelle}</strong></a>"
|
||||
end
|
||||
|
||||
def dossiers_en_instruction_description
|
||||
case received_dossiers_count
|
||||
when 0
|
||||
nil
|
||||
when 1
|
||||
"1 dossier est en cours d'instruction"
|
||||
else
|
||||
"#{received_dossiers_count} dossiers sont en cours d'instruction"
|
||||
end
|
||||
end
|
||||
|
||||
def created_dossier_description
|
||||
case created_dossiers_count
|
||||
when 0
|
||||
nil
|
||||
when 1
|
||||
'1 nouveau dossier a été déposé'
|
||||
else
|
||||
"#{created_dossiers_count} nouveaux dossiers ont été déposés"
|
||||
end
|
||||
end
|
||||
|
||||
def processed_dossier_description
|
||||
case processed_dossiers_count
|
||||
when 0
|
||||
nil
|
||||
when 1
|
||||
'1 dossier a été instruit'
|
||||
else
|
||||
"#{processed_dossiers_count} dossiers ont été instruits"
|
||||
end
|
||||
end
|
||||
|
||||
def notifications_description
|
||||
case notifications_count
|
||||
when 0
|
||||
nil
|
||||
when 1
|
||||
'1 notification en attente sur les dossiers que vous suivez'
|
||||
else
|
||||
"#{notifications_count} notifications en attente sur les dossiers que vous suivez"
|
||||
end
|
||||
end
|
||||
end
|
26
app/views/gestionnaire_mailer/last_week_overview.html.haml
Normal file
26
app/views/gestionnaire_mailer/last_week_overview.html.haml
Normal file
|
@ -0,0 +1,26 @@
|
|||
%table{ align: 'center', border: '0', cellpadding: '0', cellspacing: '0', height: '100%', style: 'background-color: #fafafa', width: '100%' }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ align: 'center', style: 'height: 100%; margin: 0; padding: 30px; width: 100%; border-top: 0', valign: 'top' }
|
||||
%table{ border: '0', cellpadding: '0', cellspacing: '0', style: 'border-collapse: collapse; border: 0; max-width: 600px!important;', width: '100%' }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: 'background: #ffffff none no-repeat center/cover; background-color: #ffffff; background-image: none; background-repeat: no-repeat; background-position: center; background-size: cover; border-top: 0; padding-top: 0;', valign: 'top' }
|
||||
%table{ border: '0', cellpadding: '0', cellspacing: '0', style: 'min-width: 100%; border-collapse: collapse', width: '100%' }
|
||||
%tr
|
||||
%td{ style: 'padding: 0 30px; mso-line-height-rule: exactly; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; ', valign: 'top' }
|
||||
%img{ align: 'middle', alt: 'Logo TPS', src: image_url('mailer/gestionnaire_mailer/logo.png'), style: 'max-width: 125px; padding: 30px 0; display: inline !important; vertical-align: bottom; border: 0; height: auto; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;' }
|
||||
%tr
|
||||
%td{ style: 'padding: 0 30px 30px; word-break: break-word; color: #333333; font-family: Helvetica; font-size: 16px; line-height: 150%; text-align: left; border-bottom: 2px solid #4393F3;', valign: 'top' }
|
||||
Bonjour, voici votre résumé de l'activité de la semaine du #{l(@args[:start_date], format: '%d %B')} au #{l(DateTime.now, format: '%d %B')}.
|
||||
%br
|
||||
%br
|
||||
|
||||
- @args[:procedure_overviews].each do |procedure_overview|
|
||||
= procedure_overview.to_html.html_safe
|
||||
%br
|
||||
%br
|
||||
Bonne journée,
|
||||
%br
|
||||
%br
|
||||
L'équipe Téléprocédures Simplifiées
|
13
app/workers/weekly_overview_worker.rb
Normal file
13
app/workers/weekly_overview_worker.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class WeeklyOverviewWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform(*args)
|
||||
# Feature flipped to avoid mails in staging due to unprocessed dossier
|
||||
if Features.weekly_overview
|
||||
Gestionnaire.all
|
||||
.map { |gestionnaire| [gestionnaire, gestionnaire.last_week_overview] }
|
||||
.reject { |_, overview| overview.nil? }
|
||||
.each { |gestionnaire, overview| GestionnaireMailer.last_week_overview(gestionnaire, overview).deliver_now }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -42,6 +42,7 @@ Rails.application.configure do
|
|||
# Action Mailer settings
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
||||
config.action_mailer.asset_host = 'http://localhost:3000'
|
||||
# Config for mailcatcher https://mailcatcher.me/
|
||||
config.action_mailer.smtp_settings = {
|
||||
:address => "localhost",
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
remote_storage: false
|
||||
weekly_overview: false
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
auto_archive_procedure:
|
||||
cron: "* * * * *"
|
||||
class: "AutoArchiveProcedureWorker"
|
||||
weekly_overview_worker:
|
||||
cron: "0 8 * * 0"
|
||||
class: "WeeklyOverviewWorker"
|
||||
|
|
6
spec/mailers/previews/gestionnaire_mailer_preview.rb
Normal file
6
spec/mailers/previews/gestionnaire_mailer_preview.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class GestionnaireMailerPreview < ActionMailer::Preview
|
||||
def last_week_overview
|
||||
gestionnaire = Gestionnaire.first
|
||||
GestionnaireMailer.last_week_overview(gestionnaire, gestionnaire.last_week_overview)
|
||||
end
|
||||
end
|
|
@ -347,4 +347,52 @@ describe Gestionnaire, type: :model do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'last_week_overview' do
|
||||
let!(:gestionnaire2) { create(:gestionnaire) }
|
||||
subject { gestionnaire2.last_week_overview }
|
||||
let(:friday) { DateTime.new(2017, 5, 12) }
|
||||
let(:monday) { DateTime.now.beginning_of_week }
|
||||
|
||||
before :each do
|
||||
Timecop.freeze(friday)
|
||||
end
|
||||
|
||||
context 'when no procedure published was active last week' do
|
||||
let!(:procedure) { create(:procedure, gestionnaires: [gestionnaire2], libelle: 'procedure', published: true) }
|
||||
context 'when the gestionnaire has no notifications' do
|
||||
it { is_expected.to eq(nil) }
|
||||
end
|
||||
|
||||
context 'when the gestionnaire has one notification' do
|
||||
before :each do
|
||||
expect(gestionnaire2).to receive(:notifications).twice.and_return([1])
|
||||
end
|
||||
|
||||
it { is_expected.to eq({ start_date: monday, procedure_overviews: [], notifications: [1] }) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a procedure published was active' do
|
||||
let!(:procedure) { create(:procedure, gestionnaires: [gestionnaire2], libelle: 'procedure', published: true) }
|
||||
let(:procedure_overview) { double('procedure_overview', 'had_some_activities?'.to_sym => true) }
|
||||
|
||||
before :each do
|
||||
expect_any_instance_of(Procedure).to receive(:procedure_overview).and_return(procedure_overview)
|
||||
end
|
||||
|
||||
it { expect(gestionnaire.last_week_overview[:procedure_overviews]).to match([procedure_overview]) }
|
||||
end
|
||||
|
||||
context 'when a procedure not published was active with no notifications' do
|
||||
let!(:procedure) { create(:procedure, gestionnaires: [gestionnaire2], libelle: 'procedure', published: false) }
|
||||
let(:procedure_overview) { double('procedure_overview', 'had_some_activities?'.to_sym => true) }
|
||||
|
||||
before :each do
|
||||
allow_any_instance_of(Procedure).to receive(:procedure_overview).and_return(procedure_overview)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(nil) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
87
spec/models/procedure_overview_spec.rb
Normal file
87
spec/models/procedure_overview_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ProcedureOverview, type: :model do
|
||||
let(:procedure) { create(:procedure, libelle: 'libelle') }
|
||||
let(:friday) { DateTime.new(2017, 5, 12) } # vendredi 12 mai 2017, de la semaine du 8 mai
|
||||
let(:monday) { DateTime.new(2017, 5, 8) }
|
||||
|
||||
before :each do
|
||||
Timecop.freeze(friday)
|
||||
end
|
||||
|
||||
let(:procedure_overview) { ProcedureOverview.new(procedure, monday, 0) }
|
||||
|
||||
describe 'received_dossiers_count' do
|
||||
let!(:received_dossier) do
|
||||
dossier = create(:dossier, procedure: procedure, state: :received, created_at: monday)
|
||||
end
|
||||
|
||||
it { expect(procedure_overview.received_dossiers_count).to eq(1) }
|
||||
end
|
||||
|
||||
describe 'created_dossiers_count' do
|
||||
let!(:created_dossier_during_the_week) do
|
||||
create(:dossier, procedure: procedure, created_at: monday, state: :received)
|
||||
end
|
||||
|
||||
let!(:created_dossier_during_the_week_but_in_draft) do
|
||||
create(:dossier, procedure: procedure, created_at: monday, state: :draft)
|
||||
end
|
||||
|
||||
let!(:created_dossier_before_the_week) do
|
||||
create(:dossier, procedure: procedure, created_at: (monday - 1.week), state: :received)
|
||||
end
|
||||
|
||||
it { expect(procedure_overview.created_dossiers_count).to eq(1) }
|
||||
end
|
||||
|
||||
describe 'processed_dossiers_count' do
|
||||
let!(:processed_dossier_during_the_week) do
|
||||
create(:dossier, procedure: procedure, created_at: monday, processed_at: monday)
|
||||
end
|
||||
|
||||
let!(:processed_dossier_before_the_week) do
|
||||
create(:dossier, procedure: procedure, created_at: (monday - 1.week), processed_at: (monday - 1.week))
|
||||
end
|
||||
|
||||
it { expect(procedure_overview.processed_dossiers_count).to eq(1) }
|
||||
end
|
||||
|
||||
describe 'to_html' do
|
||||
subject { procedure_overview.to_html }
|
||||
|
||||
context 'when the different count are equal to 0' do
|
||||
it { is_expected.to match(/^<a href='.+'><strong>libelle<\/strong><\/a>$/) }
|
||||
end
|
||||
|
||||
context 'when the different counts are equal to 1' do
|
||||
before :each do
|
||||
procedure_overview.notifications_count = 1
|
||||
procedure_overview.received_dossiers_count = 1
|
||||
procedure_overview.created_dossiers_count = 1
|
||||
procedure_overview.processed_dossiers_count = 1
|
||||
end
|
||||
|
||||
it { is_expected.to match(/^<a href='.+'><strong>libelle<\/strong><\/a>/) }
|
||||
it { is_expected.to include("1 dossier est en cours d'instruction") }
|
||||
it { is_expected.to include('1 nouveau dossier a été déposé') }
|
||||
it { is_expected.to include('1 dossier a été instruit') }
|
||||
it { is_expected.to include('1 notification en attente sur les dossiers que vous suivez') }
|
||||
end
|
||||
|
||||
context 'when the different counts are equal to 2' do
|
||||
before :each do
|
||||
procedure_overview.notifications_count = 2
|
||||
procedure_overview.received_dossiers_count = 3
|
||||
procedure_overview.created_dossiers_count = 4
|
||||
procedure_overview.processed_dossiers_count = 5
|
||||
end
|
||||
|
||||
it { is_expected.to match(/^<a href='.+'><strong>libelle<\/strong><\/a>/) }
|
||||
it { is_expected.to include("3 dossiers sont en cours d'instruction") }
|
||||
it { is_expected.to include('4 nouveaux dossiers ont été déposés') }
|
||||
it { is_expected.to include('5 dossiers ont été instruits') }
|
||||
it { is_expected.to include('2 notifications en attente sur les dossiers que vous suivez') }
|
||||
end
|
||||
end
|
||||
end
|
44
spec/workers/weekly_overview_worker_spec.rb
Normal file
44
spec/workers/weekly_overview_worker_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe WeeklyOverviewWorker, type: :worker do
|
||||
describe 'perform' do
|
||||
let!(:gestionnaire) { create(:gestionnaire) }
|
||||
let(:overview) { double('overview') }
|
||||
let(:mailer_double) { double('mailer', deliver_now: true) }
|
||||
|
||||
context 'if the feature is enabled' do
|
||||
before { allow(Features).to receive(:weekly_overview).and_return(true) }
|
||||
|
||||
context 'with one gestionnaire with one overview' do
|
||||
before :each do
|
||||
expect_any_instance_of(Gestionnaire).to receive(:last_week_overview).and_return(overview)
|
||||
allow(GestionnaireMailer).to receive(:last_week_overview).and_return(mailer_double)
|
||||
WeeklyOverviewWorker.new.perform
|
||||
end
|
||||
|
||||
it { expect(GestionnaireMailer).to have_received(:last_week_overview).with(gestionnaire, overview) }
|
||||
it { expect(mailer_double).to have_received(:deliver_now) }
|
||||
end
|
||||
|
||||
context 'with one gestionnaire with no overviews' do
|
||||
before :each do
|
||||
expect_any_instance_of(Gestionnaire).to receive(:last_week_overview).and_return(nil)
|
||||
allow(GestionnaireMailer).to receive(:last_week_overview)
|
||||
WeeklyOverviewWorker.new.perform
|
||||
end
|
||||
|
||||
it { expect(GestionnaireMailer).not_to have_received(:last_week_overview) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the feature is disabled' do
|
||||
before { allow(Features).to receive(:weekly_overview).and_return(false) }
|
||||
before :each do
|
||||
allow(Gestionnaire).to receive(:all)
|
||||
WeeklyOverviewWorker.new.perform
|
||||
end
|
||||
|
||||
it { expect(Gestionnaire).not_to receive(:all) }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue