Move followed_dossiers_with_notifications to a Dossier scope
Instead of instructeur.followed_dossiers_with_notifications, we can now write instructeur.followed_dossiers.with_notifications. Yay composition!
This commit is contained in:
parent
780e157190
commit
03c950ea97
4 changed files with 51 additions and 26 deletions
|
@ -164,6 +164,31 @@ class Dossier < ApplicationRecord
|
||||||
scope :for_procedure, -> (procedure) { includes(:user, :groupe_instructeur).where(groupe_instructeurs: { procedure: procedure }) }
|
scope :for_procedure, -> (procedure) { includes(:user, :groupe_instructeur).where(groupe_instructeurs: { procedure: procedure }) }
|
||||||
scope :for_api_v2, -> { includes(procedure: [:administrateurs], etablissement: [], individual: []) }
|
scope :for_api_v2, -> { includes(procedure: [:administrateurs], etablissement: [], individual: []) }
|
||||||
|
|
||||||
|
scope :with_notifications, -> do
|
||||||
|
# This scope is meant to be composed, typically with Instructeur.followed_dossiers, which means that the :follows table is already INNER JOINed;
|
||||||
|
# it will fail otherwise
|
||||||
|
|
||||||
|
# Relations passed to #or must be “structurally compatible”, i.e. query the same tables.
|
||||||
|
joined_dossiers = left_outer_joins(:champs, :champs_private, :avis, :commentaires)
|
||||||
|
|
||||||
|
updated_demandes = joined_dossiers
|
||||||
|
.where('champs.updated_at > follows.demande_seen_at')
|
||||||
|
|
||||||
|
# We join `:champs` twice, the second time with `has_many :champs_privates`. ActiveRecord generates the SQL: 'LEFT OUTER JOIN "champs" "champs_privates_dossiers" ON …'. We can then use this `champs_privates_dossiers` alias to disambiguate the table in this WHERE clause.
|
||||||
|
updated_annotations = joined_dossiers
|
||||||
|
.where('champs_privates_dossiers.updated_at > follows.annotations_privees_seen_at')
|
||||||
|
|
||||||
|
updated_avis = joined_dossiers
|
||||||
|
.where('avis.updated_at > follows.avis_seen_at')
|
||||||
|
|
||||||
|
updated_messagerie = joined_dossiers
|
||||||
|
.where('commentaires.updated_at > follows.messagerie_seen_at')
|
||||||
|
.where.not(commentaires: { email: OLD_CONTACT_EMAIL })
|
||||||
|
.where.not(commentaires: { email: CONTACT_EMAIL })
|
||||||
|
|
||||||
|
updated_demandes.or(updated_annotations).or(updated_avis).or(updated_messagerie).distinct
|
||||||
|
end
|
||||||
|
|
||||||
accepts_nested_attributes_for :individual
|
accepts_nested_attributes_for :individual
|
||||||
|
|
||||||
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
||||||
|
|
|
@ -113,13 +113,15 @@ class Instructeur < ApplicationRecord
|
||||||
procedure
|
procedure
|
||||||
.defaut_groupe_instructeur.dossiers
|
.defaut_groupe_instructeur.dossiers
|
||||||
.send(scope) # :en_cours or :termine or :not_archived (or any other Dossier scope)
|
.send(scope) # :en_cours or :termine or :not_archived (or any other Dossier scope)
|
||||||
.merge(followed_dossiers_with_notifications)
|
.merge(followed_dossiers)
|
||||||
|
.with_notifications
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedures_with_notifications(scope)
|
def procedures_with_notifications(scope)
|
||||||
dossiers = Dossier
|
dossiers = Dossier
|
||||||
.send(scope) # :en_cours or :termine (or any other Dossier scope)
|
.send(scope) # :en_cours or :termine (or any other Dossier scope)
|
||||||
.merge(followed_dossiers_with_notifications)
|
.merge(followed_dossiers)
|
||||||
|
.with_notifications
|
||||||
|
|
||||||
Procedure
|
Procedure
|
||||||
.where(id: dossiers.joins(:groupe_instructeur)
|
.where(id: dossiers.joins(:groupe_instructeur)
|
||||||
|
@ -128,29 +130,6 @@ class Instructeur < ApplicationRecord
|
||||||
.distinct
|
.distinct
|
||||||
end
|
end
|
||||||
|
|
||||||
def followed_dossiers_with_notifications
|
|
||||||
# Relations passed to #or must be “structurally compatible”, i.e. query the same tables.
|
|
||||||
joined_dossiers = self.followed_dossiers
|
|
||||||
.left_outer_joins(:champs, :champs_private, :avis, :commentaires)
|
|
||||||
|
|
||||||
updated_demandes = joined_dossiers
|
|
||||||
.where('champs.updated_at > follows.demande_seen_at')
|
|
||||||
|
|
||||||
# We join `:champs` twice, the second time with `has_many :champs_privates`. ActiveRecord generates the SQL: 'LEFT OUTER JOIN "champs" "champs_privates_dossiers" ON …'. We can then use this `champs_privates_dossiers` alias to disambiguate the table in this WHERE clause.
|
|
||||||
updated_annotations = joined_dossiers
|
|
||||||
.where('champs_privates_dossiers.updated_at > follows.annotations_privees_seen_at')
|
|
||||||
|
|
||||||
updated_avis = joined_dossiers
|
|
||||||
.where('avis.updated_at > follows.avis_seen_at')
|
|
||||||
|
|
||||||
updated_messagerie = joined_dossiers
|
|
||||||
.where('commentaires.updated_at > follows.messagerie_seen_at')
|
|
||||||
.where.not(commentaires: { email: OLD_CONTACT_EMAIL })
|
|
||||||
.where.not(commentaires: { email: CONTACT_EMAIL })
|
|
||||||
|
|
||||||
updated_demandes.or(updated_annotations).or(updated_avis).or(updated_messagerie)
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_tab_as_seen(dossier, tab)
|
def mark_tab_as_seen(dossier, tab)
|
||||||
attributes = {}
|
attributes = {}
|
||||||
attributes["#{tab}_seen_at"] = Time.zone.now
|
attributes["#{tab}_seen_at"] = Time.zone.now
|
||||||
|
|
|
@ -80,7 +80,7 @@ class ProcedurePresentation < ApplicationRecord
|
||||||
|
|
||||||
case table
|
case table
|
||||||
when 'notifications'
|
when 'notifications'
|
||||||
dossiers_id_with_notification = dossiers.merge(instructeur.followed_dossiers_with_notifications).ids
|
dossiers_id_with_notification = dossiers.with_notifications.merge(instructeur.followed_dossiers).ids
|
||||||
if order == 'desc'
|
if order == 'desc'
|
||||||
return dossiers_id_with_notification +
|
return dossiers_id_with_notification +
|
||||||
(dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification)
|
(dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification)
|
||||||
|
|
|
@ -53,6 +53,27 @@ describe Dossier do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'with_notifications' do
|
||||||
|
let(:dossier) { create(:dossier) }
|
||||||
|
let(:instructeur) { create(:instructeur) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create(:follow, dossier: dossier, instructeur: instructeur, messagerie_seen_at: 2.hours.ago)
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { instructeur.followed_dossiers.with_notifications }
|
||||||
|
|
||||||
|
context('without changes') do
|
||||||
|
it { is_expected.to eq [] }
|
||||||
|
end
|
||||||
|
|
||||||
|
context('with changes') do
|
||||||
|
before { dossier.commentaires << create(:commentaire, email: 'test@exemple.fr') }
|
||||||
|
|
||||||
|
it { is_expected.to match([dossier]) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'methods' do
|
describe 'methods' do
|
||||||
let(:dossier) { create(:dossier, :with_entreprise, user: user) }
|
let(:dossier) { create(:dossier, :with_entreprise, user: user) }
|
||||||
let(:etablissement) { dossier.etablissement }
|
let(:etablissement) { dossier.etablissement }
|
||||||
|
|
Loading…
Reference in a new issue