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_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
|
||||
|
||||
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
||||
|
|
|
@ -113,13 +113,15 @@ class Instructeur < ApplicationRecord
|
|||
procedure
|
||||
.defaut_groupe_instructeur.dossiers
|
||||
.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
|
||||
|
||||
def procedures_with_notifications(scope)
|
||||
dossiers = Dossier
|
||||
.send(scope) # :en_cours or :termine (or any other Dossier scope)
|
||||
.merge(followed_dossiers_with_notifications)
|
||||
.merge(followed_dossiers)
|
||||
.with_notifications
|
||||
|
||||
Procedure
|
||||
.where(id: dossiers.joins(:groupe_instructeur)
|
||||
|
@ -128,29 +130,6 @@ class Instructeur < ApplicationRecord
|
|||
.distinct
|
||||
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)
|
||||
attributes = {}
|
||||
attributes["#{tab}_seen_at"] = Time.zone.now
|
||||
|
|
|
@ -80,7 +80,7 @@ class ProcedurePresentation < ApplicationRecord
|
|||
|
||||
case table
|
||||
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'
|
||||
return dossiers_id_with_notification +
|
||||
(dossiers.order('dossiers.updated_at desc').ids - dossiers_id_with_notification)
|
||||
|
|
|
@ -53,6 +53,27 @@ describe Dossier do
|
|||
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
|
||||
let(:dossier) { create(:dossier, :with_entreprise, user: user) }
|
||||
let(:etablissement) { dossier.etablissement }
|
||||
|
|
Loading…
Reference in a new issue