Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ def initialize(patient_session, context:, programmes: [])
def can_register_attendance?
session_attendance =
SessionAttendance.new(
patient_session:,
session_date: SessionDate.new(value: Date.current)
patient:,
session_date: SessionDate.new(session:, value: Date.current)
)

policy(session_attendance).new?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ def update

def set_session_attendance
@session_attendance =
authorize @patient_session
.session_attendances
.includes(:patient, :session_date)
.find_or_initialize_by(session_date: @session_date)
authorize(
@patient
.session_attendances
.includes(:patient, session_date: { session: :programmes })
.find_or_initialize_by(session_date: @session_date)
)
end

def session_attendance_params
Expand Down
17 changes: 10 additions & 7 deletions app/lib/generate/vaccination_records.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ def create_vaccinations
vaccination_records = []

random_patient_sessions.each do |patient_session|
patient_session_id = patient_session.id
session_date_ids = patient_session.session.session_dates.pluck(:id)

unless SessionAttendance.exists?(
patient_session_id:,
session_date_id: session_date_ids
patient = patient_session.patient
session = patient_session.session

unless SessionAttendance.joins(:session_date).exists?(
patient:,
session_date: {
session:
}
)
session_attendances << FactoryBot.build(
:session_attendance,
:present,
patient_session:
patient:,
session:
)
end

Expand Down
1 change: 1 addition & 0 deletions app/lib/status_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def update_registration_statuses!
.where(patient_session_id: patient_sessions.select(:id))
.includes(
:session_attendances,
:session_date,
:vaccination_records,
patient_session: {
session: :programmes
Expand Down
4 changes: 2 additions & 2 deletions app/models/patient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Patient < ApplicationRecord
has_many :consent_notifications
has_many :consent_statuses
has_many :consents
has_many :gillick_assessments
has_many :notes
has_many :notify_log_entries
has_many :parent_relationships, -> { order(:created_at) }
Expand All @@ -73,17 +74,16 @@ class Patient < ApplicationRecord
has_many :pre_screenings
has_many :school_move_log_entries
has_many :school_moves
has_many :session_attendances
has_many :session_notifications
has_many :triage_statuses
has_many :triages
has_many :vaccination_records, -> { kept }
has_many :vaccination_statuses
has_many :patient_specific_directions

has_many :gillick_assessments
has_many :parents, through: :parent_relationships
has_many :patient_specific_directions
has_many :session_attendances, through: :patient_sessions
has_many :sessions, through: :patient_sessions
has_many :teams, -> { distinct }, through: :sessions

Expand Down
12 changes: 8 additions & 4 deletions app/models/patient_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class PatientSession < ApplicationRecord
belongs_to :patient
belongs_to :session

has_many :session_attendances, dependent: :destroy
has_one :registration_status

has_one :location, through: :session
Expand All @@ -67,6 +66,10 @@ class PatientSession < ApplicationRecord
-> { where(patient_id: it.patient_id) },
through: :session

has_many :session_attendances,
-> { where(patient_id: it.patient_id) },
through: :session

has_many :session_notifications,
-> { where(session_id: it.session_id) },
through: :patient
Expand Down Expand Up @@ -315,9 +318,10 @@ def programmes = session.programmes_for(patient:, academic_year:)

def todays_attendance
if (session_date = session.session_dates.today.first)
session_attendances.includes(:session_date).find_or_initialize_by(
session_date:
)
patient
.session_attendances
.includes(:patient, session_date: { session: :programmes })
.find_or_initialize_by(session_date:)
end
end

Expand Down
11 changes: 7 additions & 4 deletions app/models/patient_session/registration_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@ class PatientSession::RegistrationStatus < ApplicationRecord
belongs_to :patient_session

has_one :patient, through: :patient_session
has_one :session, through: :patient_session

has_many :vaccination_records,
-> { kept.order(performed_at: :desc) },
through: :patient

has_many :session_attendances,
-> { includes(:session_date) },
through: :patient_session
has_one :session_date, -> { today }, through: :session, source: :session_dates

has_many :session_attendances, through: :patient

enum :status,
{ unknown: 0, attending: 1, not_attending: 2, completed: 3 },
default: :unknown,
validate: true

def session_attendance = session_attendances.find(&:today?)
def session_attendance
session_attendances.find { it.session_date_id == session_date.id }
end

def assign_status
self.status = generator.status
Expand Down
1 change: 1 addition & 0 deletions app/models/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Session < ApplicationRecord
has_many :programmes, through: :session_programmes
has_many :gillick_assessments, through: :session_dates
has_many :patients, through: :patient_sessions
has_many :session_attendances, through: :session_dates
has_many :vaccines, through: :programmes

has_many :location_programme_year_groups,
Expand Down
26 changes: 13 additions & 13 deletions app/models/session_attendance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@
#
# Table name: session_attendances
#
# id :bigint not null, primary key
# attending :boolean not null
# created_at :datetime not null
# updated_at :datetime not null
# patient_session_id :bigint not null
# session_date_id :bigint not null
# id :bigint not null, primary key
# attending :boolean not null
# created_at :datetime not null
# updated_at :datetime not null
# patient_id :bigint not null
# session_date_id :bigint not null
#
# Indexes
#
# idx_on_patient_session_id_session_date_id_be8bd21ddf (patient_session_id,session_date_id) UNIQUE
# index_session_attendances_on_session_date_id (session_date_id)
# index_session_attendances_on_patient_id (patient_id)
# index_session_attendances_on_patient_id_and_session_date_id (patient_id,session_date_id) UNIQUE
# index_session_attendances_on_session_date_id (session_date_id)
#
# Foreign Keys
#
# fk_rails_... (patient_session_id => patient_sessions.id)
# fk_rails_... (patient_id => patients.id)
# fk_rails_... (session_date_id => session_dates.id)
#
class SessionAttendance < ApplicationRecord
audited associated_with: :patient_session
audited associated_with: :patient

belongs_to :patient_session
belongs_to :patient
belongs_to :session_date

has_one :session, through: :patient_session
has_one :patient, through: :patient_session
has_one :session, through: :session_date
has_one :location, through: :session

scope :today, -> { joins(:session_date).merge(SessionDate.today) }
Expand Down
21 changes: 10 additions & 11 deletions app/policies/session_attendance_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@ def update?

private

delegate :patient_session, :session_date, to: :record

def academic_year = patient_session.session.academic_year
delegate :patient, :session_date, to: :record
delegate :session, to: :session_date
delegate :academic_year, to: :session

def already_vaccinated?
patient_session.programmes.all? do |programme|
patient_session
.patient
.vaccination_status(programme:, academic_year:)
.vaccinated?
end
session
.programmes_for(patient:, academic_year:)
.all? do |programme|
patient.vaccination_status(programme:, academic_year:).vaccinated?
end
end

def was_seen_by_nurse?
VaccinationRecord.kept.exists?(
patient_id: patient_session.patient_id,
session_id: patient_session.session_id,
patient:,
session:,
performed_at: session_date.value.all_day
)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

class RemovePatientSessionFromSessionAttendances < ActiveRecord::Migration[8.0]
def up
change_table :session_attendances, bulk: true do |t|
t.references :patient, foreign_key: true
t.index %i[patient_id session_date_id], unique: true
end

SessionAttendance.find_each do |session_attendance|
patient_session =
PatientSession.find(session_attendance.patient_session_id)
patient_id = patient_session.patient_id
session_attendance.update_column(:patient_id, patient_id)
end

change_table :session_attendances, bulk: true do |t|
t.change_null :patient_id, false
t.remove_references :patient_session
end
end

def down
add_reference :session_attendances, :patient_session

SessionAttendance.find_each do |session_attendance|
session_id =
SessionDate.find(session_attendance.session_date_id).session_id
patient_session =
PatientSession.find_by!(
patient_id: session_attendance.patient_id,
session_id:
)
session_attendance.update_column(:patient_session_id, patient_session.id)
end

change_table :session_attendances, bulk: true do |t|
t.change_null :patient_session_id, false
t.remove_references :patient
end
end
end
7 changes: 4 additions & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,13 @@
end

create_table "session_attendances", force: :cascade do |t|
t.bigint "patient_session_id", null: false
t.bigint "session_date_id", null: false
t.boolean "attending", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["patient_session_id", "session_date_id"], name: "idx_on_patient_session_id_session_date_id_be8bd21ddf", unique: true
t.bigint "patient_id", null: false
t.index ["patient_id", "session_date_id"], name: "index_session_attendances_on_patient_id_and_session_date_id", unique: true
t.index ["patient_id"], name: "index_session_attendances_on_patient_id"
t.index ["session_date_id"], name: "index_session_attendances_on_session_date_id"
end

Expand Down Expand Up @@ -1148,7 +1149,7 @@
add_foreign_key "school_moves", "locations", column: "school_id"
add_foreign_key "school_moves", "patients"
add_foreign_key "school_moves", "teams"
add_foreign_key "session_attendances", "patient_sessions"
add_foreign_key "session_attendances", "patients"
add_foreign_key "session_attendances", "session_dates"
add_foreign_key "session_dates", "sessions"
add_foreign_key "session_notifications", "patients"
Expand Down
12 changes: 9 additions & 3 deletions spec/factories/patient_sessions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,22 @@
end

trait :in_attendance do
session_attendances do
[association(:session_attendance, :present, patient_session: instance)]
end
registration_status do
association(
:patient_session_registration_status,
:attending,
patient_session: instance
)
end

after(:create) do |patient_session|
create(
:session_attendance,
:present,
patient: patient_session.patient,
session: patient_session.session
)
end
end

trait :added_to_session
Expand Down
7 changes: 6 additions & 1 deletion spec/factories/patients.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@
)

if evaluator.in_attendance
create(:session_attendance, :present, patient_session:)
create(
:session_attendance,
:present,
patient:,
session: evaluator.session
)
create(
:patient_session_registration_status,
:attending,
Expand Down
25 changes: 14 additions & 11 deletions spec/factories/session_attendances.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,30 @@
#
# Table name: session_attendances
#
# id :bigint not null, primary key
# attending :boolean not null
# created_at :datetime not null
# updated_at :datetime not null
# patient_session_id :bigint not null
# session_date_id :bigint not null
# id :bigint not null, primary key
# attending :boolean not null
# created_at :datetime not null
# updated_at :datetime not null
# patient_id :bigint not null
# session_date_id :bigint not null
#
# Indexes
#
# idx_on_patient_session_id_session_date_id_be8bd21ddf (patient_session_id,session_date_id) UNIQUE
# index_session_attendances_on_session_date_id (session_date_id)
# index_session_attendances_on_patient_id (patient_id)
# index_session_attendances_on_patient_id_and_session_date_id (patient_id,session_date_id) UNIQUE
# index_session_attendances_on_session_date_id (session_date_id)
#
# Foreign Keys
#
# fk_rails_... (patient_session_id => patient_sessions.id)
# fk_rails_... (patient_id => patients.id)
# fk_rails_... (session_date_id => session_dates.id)
#
FactoryBot.define do
factory :session_attendance do
patient_session
session_date { patient_session.session.session_dates.first }
transient { session { association(:session) } }

patient
session_date { session.session_dates.first }

trait :present do
attending { true }
Expand Down
Loading