Merge pull request #1396 from betagouv/mmagn-comments

Mmagn comments
This commit is contained in:
Mathieu Magnin 2018-02-07 10:25:49 +01:00 committed by GitHub
commit d644fabe2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 16 additions and 464 deletions

View file

@ -1,20 +1,4 @@
$(document).on('turbolinks:load', the_terms);
$(document).on('turbolinks:load', pannel_switch);
function pannel_switch() {
$('#switch-notifications').click(function () {
$('#procedure-list').addClass('hidden');
$('#notifications-list').removeClass('hidden');
$(this).addClass('active');
$('#switch-procedures').removeClass('active');
})
$('#switch-procedures').click(function () {
$('#notifications-list').addClass('hidden');
$('#procedure-list').removeClass('hidden');
$(this).addClass('active');
$('#switch-notifications').removeClass('active');
})
}
function the_terms() {
var the_terms = $("#dossier_autorisation_donnees");

View file

@ -29,7 +29,6 @@
// = require login
// = require main_container
// = require navbar
// = require notification_alert
// = require pieces_justificatives_fields
// = require pj_modal
// = require pref_list_menu

View file

@ -36,8 +36,7 @@ h5 span {
cursor: pointer;
}
#procedure-list,
#notifications-list {
#procedure-list {
margin-left: -10px;
margin-top: 20px;
@ -47,13 +46,11 @@ h5 span {
text-decoration: none;
}
.procedure-list-element.active,
.notification.active {
.procedure-list-element.active {
background-color: #668ABD;
}
.procedure-list-element,
.notification {
.procedure-list-element {
padding: 15px 40px 15px 20px;
cursor: pointer;
line-height: 1.8em;
@ -63,8 +60,7 @@ h5 span {
}
}
.procedure-list-element:hover,
.notification:hover {
.procedure-list-element:hover {
background-color: #668ABD;
cursor: pointer;
}

View file

@ -1,12 +0,0 @@
#notification-alert {
position: fixed;
top: 20px;
right: -250px;
z-index: 1000;
width: 250px;
height: 80px;
border: solid #000000 1px;
}

View file

@ -203,22 +203,18 @@ module NewGestionnaire
end
def mark_demande_as_read
dossier.notifications.demande.mark_as_read
current_gestionnaire.mark_tab_as_seen(dossier, :demande)
end
def mark_messagerie_as_read
dossier.notifications.messagerie.mark_as_read
current_gestionnaire.mark_tab_as_seen(dossier, :messagerie)
end
def mark_avis_as_read
dossier.notifications.avis.mark_as_read
current_gestionnaire.mark_tab_as_seen(dossier, :avis)
end
def mark_annotations_privees_as_read
dossier.notifications.annotations_privees.mark_as_read
current_gestionnaire.mark_tab_as_seen(dossier, :annotations_privees)
end
end

View file

@ -21,8 +21,6 @@ module NewGestionnaire
.group(:procedure_id)
.reorder(nil)
.count
@notifications_count_per_procedure = current_gestionnaire.notifications_count_per_procedure
end
def show
@ -41,7 +39,7 @@ module NewGestionnaire
@followed_dossiers = current_gestionnaire
.followed_dossiers
.includes(:user, :notifications)
.includes(:user)
.where(procedure: @procedure)
.en_cours

View file

@ -2,9 +2,9 @@ class PingController < ApplicationController
def index
Rails.logger.silence do
if (ActiveRecord::Base.connected?)
head :ok
head :ok, content_type: "application/json"
else
head :internal_server_error
head :internal_server_error, content_type: "application/json"
end
end
end

View file

@ -1,8 +0,0 @@
class NotificationDecorator < Draper::Decorator
delegate_all
def index_display
['champs', 'piece_justificative'].include?(type_notif) ? type = liste.join(" ") : type = liste.last
{ dossier: "Dossier nº #{dossier.id}", date: created_at.strftime('%d/%m %H:%M'), type: type }
end
end

View file

@ -9,10 +9,6 @@ class DossierFacades
@dossier.decorate
end
def last_notifications
@dossier.notifications.order("updated_at DESC").limit(5)
end
def champs
@dossier.ordered_champs
end

View file

@ -5,8 +5,6 @@ class Cerfa < ActiveRecord::Base
mount_uploader :content, CerfaUploader
validates :content, :file_size => { :maximum => 20.megabytes }
after_save :internal_notification, if: Proc.new { dossier.present? }
def empty?
content.blank?
end
@ -20,12 +18,4 @@ class Cerfa < ActiveRecord::Base
end
end
end
private
def internal_notification
if dossier.state != 'brouillon'
NotificationService.new('cerfa', self.dossier.id).notify
end
end
end

View file

@ -9,8 +9,6 @@ class Champ < ActiveRecord::Base
before_save :format_datetime, if: Proc.new { type_champ == 'datetime' }
before_save :multiple_select_to_string, if: Proc.new { type_champ == 'multiple_drop_down_list' }
after_save :internal_notification, if: Proc.new { dossier.present? }
scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) }
def mandatory?
@ -110,16 +108,6 @@ class Champ < ActiveRecord::Base
end
end
def internal_notification
if dossier.state != 'brouillon'
if type == 'ChampPublic'
NotificationService.new('champs', self.dossier.id, self.libelle).notify
else
NotificationService.new('annotations_privees', self.dossier.id, self.libelle).notify
end
end
end
def multiple_select_to_string
if value.present?
json = JSON.parse(value)

View file

@ -35,11 +35,11 @@ class Commentaire < ActiveRecord::Base
when I18n.t("dynamics.contact_email")
# The commentaire is a copy of an automated notification email
# we sent to a user, so do nothing
when dossier_user_email, *invited_users_emails
# A user or an inved user posted a commentaire,
# we need to notify the gestionnaires
# do nothing, the notification system will properly
notify_gestionnaires
else
# A gestionnaire posted a commentaire,
# we need to notify the user
@ -48,10 +48,6 @@ class Commentaire < ActiveRecord::Base
end
end
def notify_gestionnaires
NotificationService.new('commentaire', self.dossier.id).notify
end
def notify_user
NotificationMailer.new_answer(dossier).deliver_now!
end

View file

@ -29,7 +29,6 @@ class Dossier < ActiveRecord::Base
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy
has_many :follows
has_many :notifications, dependent: :destroy
has_many :avis, dependent: :destroy
belongs_to :procedure
@ -58,7 +57,6 @@ class Dossier < ActiveRecord::Base
scope :downloadable_sorted, -> { state_not_brouillon.includes(:entreprise, :etablissement, :champs, :champs_private).order(en_construction_at: 'asc') }
scope :en_cours, -> { not_archived.state_en_construction_ou_instruction }
scope :without_followers, -> { left_outer_joins(:follows).where(follows: { id: nil }) }
scope :with_unread_notifications, -> { where(notifications: { already_read: false }) }
scope :followed_by, -> (gestionnaire) { joins(:follows).where(follows: { gestionnaire: gestionnaire }) }
accepts_nested_attributes_for :individual
@ -78,29 +76,10 @@ class Dossier < ActiveRecord::Base
validates :user, presence: true
def unreaded_notifications
@unreaded_notif ||= notifications.where(already_read: false)
end
def first_unread_notification
unreaded_notifications.order("created_at ASC").first
end
def was_piece_justificative_uploaded_for_type_id?(type_id)
pieces_justificatives.where(type_de_piece_justificative_id: type_id).count > 0
end
def notifications_summary
unread_notifications = notifications.unread
{
demande: unread_notifications.select(&:demande?).present?,
avis: unread_notifications.select(&:avis?).present?,
messagerie: unread_notifications.select(&:messagerie?).present?,
annotations_privees: unread_notifications.select(&:annotations_privees?).present?
}
end
def retrieve_last_piece_justificative_by_type(type)
pieces_justificatives.where(type_de_piece_justificative_id: type).last
end

View file

@ -47,27 +47,6 @@ class Gestionnaire < ActiveRecord::Base
procedures.find_by(id: procedure_id).present?
end
def notifications
Notification.where(already_read: false, dossier_id: follows.pluck(:dossier_id)).order("updated_at DESC")
end
def dossiers_with_notifications_count_for_procedure(procedure)
followed_dossiers_id = followed_dossiers.where(procedure: procedure).pluck(:id)
Notification.unread.where(dossier_id: followed_dossiers_id).select(:dossier_id).distinct(:dossier_id).count
end
def notifications_count_per_procedure
followed_dossiers
.joins(:notifications)
.where(notifications: { already_read: false })
.group('procedure_id')
.count
end
def dossiers_with_notifications_count
notifications.pluck(:dossier_id).uniq.count
end
def last_week_overview
start_date = DateTime.now.beginning_of_week

View file

@ -1,41 +0,0 @@
class Notification < ActiveRecord::Base
enum type_notif: {
commentaire: 'commentaire',
cerfa: 'cerfa',
piece_justificative: 'piece_justificative',
champs: 'champs',
submitted: 'submitted',
avis: 'avis',
annotations_privees: 'annotations_privees'
}
DEMANDE = %w(cerfa piece_justificative champs submitted)
AVIS = %w(avis)
MESSAGERIE = %w(commentaire)
ANNOTATIONS_PRIVEES = %w(annotations_privees)
belongs_to :dossier
scope :unread, -> { where(already_read: false) }
scope :demande, -> { where(type_notif: DEMANDE) }
scope :avis, -> { where(type_notif: AVIS) }
scope :messagerie, -> { where(type_notif: MESSAGERIE) }
scope :annotations_privees, -> { where(type_notif: ANNOTATIONS_PRIVEES) }
scope :mark_as_read, -> { update_all(already_read: true) }
def demande?
Notification::DEMANDE.include?(type_notif)
end
def avis?
Notification::AVIS.include?(type_notif)
end
def messagerie?
Notification::MESSAGERIE.include?(type_notif)
end
def annotations_privees?
Notification::ANNOTATIONS_PRIVEES.include?(type_notif)
end
end

View file

@ -13,8 +13,6 @@ class PieceJustificative < ActiveRecord::Base
validates :content, :file_size => { :maximum => 20.megabytes }
validates :content, presence: true, allow_blank: false, allow_nil: false
after_save :internal_notification, if: Proc.new { dossier.present? }
scope :updated_since?, -> (date) { where('pieces_justificatives.updated_at > ?', date) }
def empty?
@ -55,12 +53,4 @@ class PieceJustificative < ActiveRecord::Base
image/jpeg
"
end
private
def internal_notification
if self.type_de_piece_justificative.present? || dossier.state != 'brouillon'
NotificationService.new('piece_justificative', self.dossier.id, self.libelle).notify
end
end
end

View file

@ -1,43 +0,0 @@
class NotificationService
def initialize type_notif, dossier_id, attribut_change = ''
@type_notif = type_notif
@dossier_id = dossier_id
notification.liste.push text_for_notif attribut_change
notification.liste = notification.liste.uniq
self
end
def notify
notification.save
end
def notification
@notification ||=
begin
Notification.find_by! dossier_id: @dossier_id, already_read: false, type_notif: @type_notif
rescue ActiveRecord::RecordNotFound
Notification.new dossier_id: @dossier_id, type_notif: @type_notif, liste: []
end
end
def text_for_notif attribut = ''
case @type_notif
when 'commentaire'
"#{notification.liste.size + 1} nouveau(x) commentaire(s) déposé(s)."
when 'cerfa'
"Un nouveau formulaire a été déposé."
when 'piece_justificative'
attribut
when 'champs'
attribut
when 'submitted'
"Le dossier nº #{@dossier_id} a été déposé."
when 'avis'
'Un nouvel avis a été rendu'
else
'Notification par défaut'
end
end
end

View file

@ -34,7 +34,7 @@ class TypesDeChampService
def self.order_champs(params, attributes)
# It's OK to use an unsafe hash here because the params will then go through
# require / permit methods in the method before this one
# require / permit methods in #create_update_procedure_params
tdcas = params[:procedure][attributes].to_unsafe_hash.to_a
.map { |_hash_index, tdca| tdca }

View file

@ -0,0 +1,5 @@
class DropNotifications < ActiveRecord::Migration[5.0]
def change
drop_table :notifications
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180111153308) do
ActiveRecord::Schema.define(version: 20180201163642) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -332,16 +332,6 @@ ActiveRecord::Schema.define(version: 20180111153308) do
t.index ["procedure_id"], name: "index_module_api_cartos_on_procedure_id", unique: true, using: :btree
end
create_table "notifications", force: :cascade do |t|
t.boolean "already_read", default: false
t.string "liste", array: true
t.string "type_notif"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "dossier_id"
t.index ["dossier_id"], name: "index_notifications_on_dossier_id", using: :btree
end
create_table "pieces_justificatives", force: :cascade do |t|
t.string "content"
t.integer "dossier_id"

View file

@ -280,38 +280,6 @@ describe NewGestionnaire::DossiersController, type: :controller do
end
end
describe '#show #messagerie #annotations_privees #avis' do
before do
dossier.notifications = %w(champs annotations_privees avis commentaire).map{ |type| Notification.create!(type_notif: type) }
get method, params: { procedure_id: procedure.id, dossier_id: dossier.id }
dossier.notifications.each(&:reload)
end
context '#show' do
let(:method) { :show }
it { expect(dossier.notifications.map(&:already_read)).to match([true, false, false, false]) }
it { expect(response).to have_http_status(:success) }
end
context '#annotations_privees' do
let(:method) { :annotations_privees }
it { expect(dossier.notifications.map(&:already_read)).to match([false, true, false, false]) }
it { expect(response).to have_http_status(:success) }
end
context '#avis' do
let(:method) { :avis }
it { expect(dossier.notifications.map(&:already_read)).to match([false, false, true, false]) }
it { expect(response).to have_http_status(:success) }
end
context '#messagerie' do
let(:method) { :messagerie }
it { expect(dossier.notifications.map(&:already_read)).to match([false, false, false, true]) }
it { expect(response).to have_http_status(:success) }
end
end
describe "#create_commentaire" do
let(:saved_commentaire) { dossier.commentaires.first }
let(:body) { "avant\napres" }

View file

@ -50,10 +50,6 @@ describe Users::CommentairesController, type: :controller do
subject
end
it 'Notification interne is create' do
expect { subject }.to change(Notification, :count).by (1)
end
end
context 'when document is upload whith a commentaire', vcr: { cassette_name: 'controllers_sers_commentaires_controller_upload_doc' } do

View file

@ -190,10 +190,6 @@ shared_examples 'description_controller_spec' do
context 'Quand la procédure accepte les CERFA' do
subject { post :update, params: { dossier_id: dossier_id, cerfa_pdf: cerfa_pdf } }
it 'Notification interne is create' do
expect { subject }.to change(Notification, :count).by (1)
end
context 'Sauvegarde du CERFA PDF', vcr: { cassette_name: 'controllers_users_description_controller_save_cerfa' } do
before do
post :update, params: { dossier_id: dossier_id, cerfa_pdf: cerfa_pdf }
@ -369,10 +365,6 @@ shared_examples 'description_controller_spec' do
sign_in guest
end
it 'Notification interne is create' do
expect { subject }.to change(Notification, :count).by (1)
end
context 'when PJ have no documents' do
it { expect(dossier.pieces_justificatives.size).to eq 0 }

View file

@ -1,12 +0,0 @@
FactoryBot.define do
factory :notification do
type_notif 'commentaire'
liste []
before(:create) do |notification, _evaluator|
if !notification.dossier
notification.dossier = create :dossier
end
end
end
end

View file

@ -4,7 +4,6 @@ RSpec.describe NotificationMailer, type: :mailer do
shared_examples_for "create a commentaire not notified" do
it do
expect { subject.deliver_now }.to change { Commentaire.count }.by(1)
expect { subject.deliver_now }.to_not change { Notification.count }
subject.deliver_now
commentaire = Commentaire.last
@ -19,7 +18,6 @@ RSpec.describe NotificationMailer, type: :mailer do
describe '.send_notification' do
let(:email_template) { instance_double('email_template', subject_for_dossier: 'subject', body_for_dossier: 'body') }
let(:attestation) { nil }
let(:notifications_count_before) { Notification.count }
subject { described_class.send_notification(dossier, email_template, attestation) }

View file

@ -17,30 +17,6 @@ describe Commentaire do
let(:dossier) { create(:dossier, procedure: procedure, user: user) }
let(:commentaire) { Commentaire.new(dossier: dossier, body: "Mon commentaire") }
context "with a commentaire created by a user" do
it "calls notify_gestionnaires" do
expect(commentaire).to receive(:notify_gestionnaires)
commentaire.email = user.email
commentaire.save
end
end
context "with a commentaire created by an invited user" do
let(:user_invite) { create(:user) }
before do
FactoryBot.create(:invite_user, email: "invite@tps.apientreprise.fr", dossier: dossier, user: user_invite)
end
it "calls notify_gestionnaires" do
expect(commentaire).to receive(:notify_gestionnaires)
commentaire.email = user_invite.email
commentaire.save
end
end
context "with a commentaire created by a gestionnaire" do
it "calls notify_user" do
expect(commentaire).to receive(:notify_user)

View file

@ -125,93 +125,6 @@ describe Gestionnaire, type: :model do
end
end
describe '#dossiers_with_notifications_count' do
subject { gestionnaire.dossiers_with_notifications_count }
context 'when there is no notifications' do
it { is_expected.to eq(0) }
end
context 'when there is one notification for one dossier' do
let(:notification){ create(:notification, already_read: false) }
let!(:follow){ create(:follow, dossier: notification.dossier, gestionnaire: gestionnaire) }
it { is_expected.to eq(1) }
end
context 'when there is one notification read' do
let(:notification){ create(:notification, already_read: true) }
let!(:follow){ create(:follow, dossier: notification.dossier, gestionnaire: gestionnaire) }
it { is_expected.to eq(0) }
end
context 'when there are many notifications for one dossier' do
let(:notification){ create(:notification, already_read: false) }
let(:notification2){ create(:notification, already_read: false, dossier: notification.dossier) }
let!(:follow){ create(:follow, dossier: notification.dossier, gestionnaire: gestionnaire) }
it { is_expected.to eq(1) }
end
context 'when there are many notifications for many dossiers' do
let(:notification){ create(:notification, already_read: false) }
let(:notification2){ create(:notification, already_read: false) }
let!(:follow){ create(:follow, dossier: notification.dossier, gestionnaire: gestionnaire) }
let!(:follow2){ create(:follow, dossier: notification2.dossier, gestionnaire: gestionnaire) }
it { is_expected.to eq(2) }
end
end
describe '#dossiers_with_notifications_count_for_procedure' do
subject { gestionnaire.dossiers_with_notifications_count_for_procedure(procedure) }
context 'without notifications' do
it { is_expected.to eq(0) }
end
context 'with a followed dossier' do
let!(:dossier){ create(:dossier, procedure: procedure, state: 'en_instruction') }
let!(:follow){ create(:follow, dossier: dossier, gestionnaire: gestionnaire) }
context 'with 1 notification' do
let!(:notification){ create(:notification, already_read: false, dossier: dossier) }
it { is_expected.to eq(1) }
end
context 'with 1 read notification' do
let!(:notification){ create(:notification, already_read: true, dossier: dossier) }
it { is_expected.to eq(0) }
end
context 'with 2 notifications' do
let!(:notification){ create(:notification, already_read: false, dossier: dossier) }
let!(:notification2){ create(:notification, already_read: false, dossier: dossier) }
it { is_expected.to eq(1) }
end
context 'with another dossier' do
let!(:dossier2){ create(:dossier, procedure: procedure, state: 'en_instruction') }
let!(:follow2){ create(:follow, dossier: dossier2, gestionnaire: gestionnaire) }
context 'and some notifications' do
let!(:notification){ create(:notification, already_read: false, dossier: dossier) }
let!(:notification2){ create(:notification, already_read: false, dossier: dossier) }
let!(:notification3){ create(:notification, already_read: false, dossier: dossier) }
let!(:notification4){ create(:notification, already_read: false, dossier: dossier2) }
let!(:notification5){ create(:notification, already_read: false, dossier: dossier2) }
it { is_expected.to eq(2) }
end
end
end
end
describe 'last_week_overview' do
let!(:gestionnaire2) { create(:gestionnaire) }
subject { gestionnaire2.last_week_overview }
@ -274,32 +187,6 @@ describe Gestionnaire, type: :model do
end
end
describe '#notifications_count_per_procedure' do
subject { gestionnaire.notifications_count_per_procedure }
let(:dossier_with_unread_notification) do
create(:dossier, notifications: [Notification.create(type_notif: 'champs', already_read: false)])
end
let(:dossier_with_no_unread_notification) do
create(:dossier, notifications: [Notification.create(type_notif: 'champs', already_read: true)])
end
before { gestionnaire.followed_dossiers << followed_dossier }
context 'when a followed dossier has unread notification' do
let(:followed_dossier) { dossier_with_unread_notification }
it { is_expected.to eq({ dossier_with_unread_notification.procedure.id => 1 }) }
end
context 'when a followed dossier has unread notification' do
let(:followed_dossier) { dossier_with_no_unread_notification }
it { is_expected.to eq({}) }
end
end
describe "procedure_presentation_for_procedure_id" do
let!(:procedure_assign_2) { create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2 }
let!(:pp) { ProcedurePresentation.create(assign_to: procedure_assign) }

View file

@ -1,11 +0,0 @@
require 'spec_helper'
describe Notification do
it { is_expected.to have_db_column(:already_read) }
it { is_expected.to have_db_column(:liste) }
it { is_expected.to have_db_column(:type_notif) }
it { is_expected.to have_db_column(:created_at) }
it { is_expected.to have_db_column(:updated_at) }
it { is_expected.to belong_to(:dossier) }
end

View file

@ -1,24 +0,0 @@
require 'spec_helper'
describe NotificationService do
describe '.notify' do
let(:dossier) { create :dossier }
let(:service) { described_class.new type_notif, dossier.id }
subject { service.notify }
context 'when is the first notification for dossier_id and type_notif and alread_read is false' do
let(:type_notif) { 'commentaire' }
it { expect { subject }.to change(Notification, :count).by (1) }
context 'when is not the first notification' do
before do
create :notification, dossier: dossier, type_notif: type_notif
end
it { expect { subject }.to change(Notification, :count).by (0) }
end
end
end
end