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
2 changes: 1 addition & 1 deletion app/components/app_outcome_banner_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def rows
end

def vaccination_record
@vaccination_record ||= patient.programme_outcome.all[programme].last
@vaccination_record ||= patient.latest_vaccination_records(programme:).last
end

def triage
Expand Down
2 changes: 1 addition & 1 deletion app/components/app_patient_page_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
<% end %>
<% end %>

<% patient.programme_outcome.all[programme].each do |vaccination_record| %>
<% patient.latest_vaccination_records(programme:).each do |vaccination_record| %>
<%= render AppCardComponent.new do |c| %>
<% c.with_heading { "Vaccination details" } %>
<%= render AppVaccinationRecordSummaryComponent.new(vaccination_record, current_user:) %>
Expand Down
2 changes: 1 addition & 1 deletion app/components/app_patient_search_result_card_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def call
private

def programme_outcome_tag
status = @patient.programme_outcome.status[@programme]
status = @patient.vaccination_status(programme: @programme).status
render AppProgrammeStatusTagsComponent.new(
{ @programme => status },
outcome: :programme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def action_required
tag.ul(class: "nhsuk-list nhsuk-list--bullet") do
safe_join(
patient_session.programmes.map do |programme|
status = patient_session.patient.next_activity.status[programme]
status = patient_session.next_activity(programme:)
tag.li("#{I18n.t(status, scope: :activity)} for #{programme.name}")
end
)
Expand Down
5 changes: 4 additions & 1 deletion app/components/app_simple_status_banner_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ def who_refused
def nurse
(
patient.triages.includes(:performed_by).where(programme:) +
patient.programme_outcome.all[programme]
patient
.vaccination_records
.includes(:performed_by_user)
.where(programme:)
).max_by(&:updated_at)&.performed_by&.full_name
end

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/draft_vaccination_records_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ def handle_confirm

@vaccination_record.save!

StatusUpdater.call(patient: @patient)

send_vaccination_confirmation(@vaccination_record) if should_notify_parents

@vaccination_record.triage_patient_as_do_not_vaccinate!
Expand Down
14 changes: 3 additions & 11 deletions app/controllers/programmes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,14 @@ def sessions
end

def patients
@statuses = Patient::ProgrammeOutcome::STATUSES

scope =
policy_scope(Patient).in_programmes([@programme]).preload(
:triages,
:vaccination_records,
consents: :parent
policy_scope(Patient).includes(:vaccination_statuses).in_programmes(
[@programme]
)

patients = @form.apply(scope, programme: @programme)

if patients.is_a?(Array)
@pagy, @patients = pagy_array(patients)
else
@pagy, @patients = pagy(patients)
end
@pagy, @patients = pagy(patients)
end

def consent_form
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/triages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ def set_patient
@patient =
@session
.patients
.includes(:consents, :school, parent_relationships: :parent)
.includes(
:consents,
:school,
:vaccination_records,
parent_relationships: :parent
)
.find_by(id: params[:patient_id])
end

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/vaccination_records_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def destroy
send_vaccination_deletion(@vaccination_record)
end

StatusUpdater.call(patient: @vaccination_record.patient)

redirect_to @return_to, flash: { success: "Vaccination record deleted" }
end

Expand Down
2 changes: 1 addition & 1 deletion app/forms/search_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def apply(scope, programme: nil)
end

if (status = programme_status&.to_sym).present?
scope = scope.select { it.programme_outcome.status[programme] == status }
scope = scope.has_vaccination_status(status, programme:)
end

if (status = session_status&.to_sym).present?
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/concerns/send_clinic_invitations_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def should_send_notification?(patient_session:, programmes:, session_date:)

all_vaccinated =
eligible_programmes.all? do |programme|
patient.programme_outcome.vaccinated?(programme)
patient.vaccination_status(programme:).vaccinated?
end

return false if all_vaccinated
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/school_consent_reminders_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def should_send_notification?(patient_session:, programmes:)
has_consent_or_vaccinated =
programmes.all? do |programme|
patient.consents.any? { it.programme_id == programme.id } ||
patient.programme_outcome.all[programme].any?
patient.vaccination_records.any? { it.programme_id == programme.id }
end

return false if has_consent_or_vaccinated
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/school_consent_requests_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def should_send_notification?(patient:, programmes:)
has_consent_or_vaccinated =
programmes.all? do |programme|
patient.consents.any? { it.programme_id == programme.id } ||
patient.programme_outcome.all[programme].any?
patient.vaccination_records.any? { it.programme_id == programme.id }
end

return false if has_consent_or_vaccinated
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/school_session_reminders_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def should_send_notification?(patient_session:)

all_vaccinated =
programmes.all? do |programme|
patient.programme_outcome.vaccinated?(programme)
patient.vaccination_status(programme:).vaccinated?
end

return false if all_vaccinated
Expand Down
2 changes: 1 addition & 1 deletion app/lib/reports/offline_session_exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def rows(patient_session:)
}
}

vaccination_records = patient.programme_outcome.all[programme]
vaccination_records = patient.vaccination_records

if vaccination_records.any?
vaccination_records.map do |vaccination_record|
Expand Down
24 changes: 24 additions & 0 deletions app/lib/status_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def initialize(patient: nil, session: nil)
def call
update_consent_statuses!
update_triage_statuses!
update_vaccination_statuses!
end

def self.call(...) = new(...).call
Expand Down Expand Up @@ -69,6 +70,29 @@ def update_triage_statuses!
end
end

def update_vaccination_statuses!
Patient::VaccinationStatus.import!(
%i[patient_id programme_id],
patient_statuses_to_import,
on_duplicate_key_ignore: true
)

Patient::VaccinationStatus
.where(patient: patient_sessions.select(:patient_id))
.includes(:patient, :programme, :consents, :triages, :vaccination_records)
.find_in_batches(batch_size: 10_000) do |batch|
batch.each(&:assign_status)

Patient::VaccinationStatus.import!(
batch.select(&:changed?),
on_duplicate_key_update: {
conflict_target: [:id],
columns: %i[status]
}
)
end
end

def patient_statuses_to_import
@patient_statuses_to_import ||=
patient_sessions
Expand Down
16 changes: 7 additions & 9 deletions app/lib/vaccinated_criteria.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# frozen_string_literal: true

class VaccinatedCriteria
def initialize(programme, patient:, vaccination_records:)
def initialize(programme:, patient:, vaccination_records:)
@programme = programme
@patient = patient
@vaccination_records = vaccination_records
end

def call
if vaccination_records.any? { it.programme_id != programme.id }
raise "Vaccination records provided for different programme."
end
vaccination_records_for_programme =
vaccination_records.select { it.programme_id == programme.id }

return true if vaccination_records.any?(&:already_had?)
return true if vaccination_records_for_programme.any?(&:already_had?)

administered_records = vaccination_records.select(&:administered?)
administered_records =
vaccination_records_for_programme.select(&:administered?)

if programme.menacwy?
administered_records.any? { patient.age(now: it.performed_at) >= 10 }
Expand All @@ -30,9 +30,7 @@ def call
end
end

def self.call(*args, **kwargs)
new(*args, **kwargs).call
end
def self.call(...) = new(...).call

private_class_method :new

Expand Down
6 changes: 3 additions & 3 deletions app/models/concerns/patient_session_status_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def self.available_statuses
def status(programme:)
@status_by_programme ||= {}

@status_by_programme[
programme
] ||= if patient.programme_outcome.vaccinated?(programme)
@status_by_programme[programme] ||= if patient.vaccination_status(
programme:
).vaccinated?
"vaccinated"
elsif patient.triage_status(programme:).delay_vaccination?
"delay_vaccination"
Expand Down
2 changes: 1 addition & 1 deletion app/models/immunisation_import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ def count_column(vaccination_record)
end

def postprocess_rows!
# Nothing to do.
StatusUpdater.call(patient: patients)
end
end
28 changes: 19 additions & 9 deletions app/models/patient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Patient < ApplicationRecord
has_many :triage_statuses
has_many :triages, -> { order(:created_at) }
has_many :vaccination_records, -> { kept.order(:performed_at) }
has_many :vaccination_statuses

has_many :parents, through: :parent_relationships
has_many :gillick_assessments,
Expand Down Expand Up @@ -158,6 +159,17 @@ class Patient < ApplicationRecord

scope :search_by_nhs_number, ->(nhs_number) { where(nhs_number:) }

scope :has_vaccination_status,
->(status, programme:) do
where(
Patient::VaccinationStatus
.where("patient_id = patients.id")
.where(status:, programme:)
.arel
.exists
)
end

validates :given_name, :family_name, :date_of_birth, presence: true

validates :birth_academic_year, comparison: { greater_than_or_equal_to: 1990 }
Expand Down Expand Up @@ -264,14 +276,6 @@ def year_group_changed?
birth_academic_year_changed?
end

def programme_outcome
@programme_outcome ||= Patient::ProgrammeOutcome.new(self)
end

def next_activity
@next_activity ||= Patient::NextActivity.new(self)
end

def consent_status(programme:)
# Use `find` to allow for preloading.
consent_statuses.find { it.programme_id == programme.id } ||
Expand All @@ -295,14 +299,20 @@ def latest_triage(programme:)
.max_by(&:created_at)
end

def vaccination_status(programme:)
# Use `find` to allow for preloading.
vaccination_statuses.find { it.programme_id == programme.id } ||
vaccination_statuses.build(programme:)
end

def latest_vaccination_records(programme:)
vaccination_records
.select { it.programme_id == programme.id }
.reject(&:discarded?)
end

def consent_given_and_safe_to_vaccinate?(programme:)
return false if programme_outcome.vaccinated?(programme)
return false if vaccination_status(programme:).vaccinated?

consent_status(programme:).given? &&
(
Expand Down
44 changes: 0 additions & 44 deletions app/models/patient/next_activity.rb

This file was deleted.

Loading
Loading