From beac289b79c52cb1959d70a02b7dcb9622abf6d2 Mon Sep 17 00:00:00 2001 From: John Henderson Date: Thu, 28 Aug 2025 17:44:28 +0100 Subject: [PATCH] Add PSD filters to PSDs tab page --- .../app_patient_search_form_component.rb | 16 +++++++ .../concerns/patient_search_form_concern.rb | 1 + app/forms/patient_search_form.rb | 15 ++++++ app/models/patient_session.rb | 12 +++++ .../patient_specific_directions/show.html.erb | 48 +++++++++++-------- spec/forms/patient_search_form_spec.rb | 46 ++++++++++++++++++ 6 files changed, 118 insertions(+), 20 deletions(-) diff --git a/app/components/app_patient_search_form_component.rb b/app/components/app_patient_search_form_component.rb index 0688c21555..5affb4f558 100644 --- a/app/components/app_patient_search_form_component.rb +++ b/app/components/app_patient_search_form_component.rb @@ -79,6 +79,19 @@ class AppPatientSearchFormComponent < ViewComponent::Base <% end %> <% end %> <% end %> + + <% if patient_specific_direction_statuses.any? %> + <%= f.govuk_radio_buttons_fieldset :patient_specific_direction_status, legend: { text: "PSD status", size: "s" } do %> + <%= f.govuk_radio_button :patient_specific_direction_status, "", checked: form.patient_specific_direction_status.blank?, label: { text: "Any" } %> + + <% patient_specific_direction_statuses.each do |status| %> + <%= f.govuk_radio_button :patient_specific_direction_status, + status, + checked: form.patient_specific_direction_status == status, + label: { text: t(status, scope: %i[status patient_specific_direction label]) } %> + <% end %> + <% end %> + <% end %> <% if vaccine_methods.any? %> <%= f.govuk_radio_buttons_fieldset :vaccine_method, legend: { text: "Vaccination method", size: "s" } do %> @@ -182,6 +195,7 @@ def initialize( register_statuses: [], triage_statuses: [], vaccination_statuses: [], + patient_specific_direction_statuses: [], vaccine_methods: [], year_groups: [], heading_level: 3, @@ -197,6 +211,7 @@ def initialize( @register_statuses = register_statuses @triage_statuses = triage_statuses @vaccination_statuses = vaccination_statuses + @patient_specific_direction_statuses = patient_specific_direction_statuses @vaccine_methods = vaccine_methods @year_groups = year_groups @heading_level = heading_level @@ -212,6 +227,7 @@ def initialize( :register_statuses, :triage_statuses, :vaccination_statuses, + :patient_specific_direction_statuses, :vaccine_methods, :year_groups, :heading_level, diff --git a/app/controllers/concerns/patient_search_form_concern.rb b/app/controllers/concerns/patient_search_form_concern.rb index 073bc33ef5..1c92036518 100644 --- a/app/controllers/concerns/patient_search_form_concern.rb +++ b/app/controllers/concerns/patient_search_form_concern.rb @@ -28,6 +28,7 @@ def patient_search_form_params :date_of_birth_year, :missing_nhs_number, :vaccination_status, + :patient_specific_direction_status, :q, :register_status, :triage_status, diff --git a/app/forms/patient_search_form.rb b/app/forms/patient_search_form.rb index 85393fd6e4..9a782d1243 100644 --- a/app/forms/patient_search_form.rb +++ b/app/forms/patient_search_form.rb @@ -12,6 +12,7 @@ class PatientSearchForm < SearchForm attribute :date_of_birth_year, :integer attribute :missing_nhs_number, :boolean attribute :vaccination_status, :string + attribute :patient_specific_direction_status, :string attribute :programme_types, array: true attribute :q, :string attribute :register_status, :string @@ -59,6 +60,7 @@ def apply(scope) scope = filter_register_status(scope) scope = filter_triage_status(scope) scope = filter_vaccine_method(scope) + scope = filter_patient_specific_direction_status(scope) scope.order_by_name end @@ -168,6 +170,19 @@ def filter_vaccination_statuses(scope) end end + def filter_patient_specific_direction_status(scope) + return scope if (status = patient_specific_direction_status&.to_sym).blank? + + case status + when :added + scope.has_patient_specific_direction(programme: programmes) + when :not_added + scope.without_patient_specific_direction(programme: programmes) + else + scope + end + end + def filter_register_status(scope) if (status = register_status&.to_sym).present? scope.has_registration_status(status) diff --git a/app/models/patient_session.rb b/app/models/patient_session.rb index 65dbee21df..0444ff71df 100644 --- a/app/models/patient_session.rb +++ b/app/models/patient_session.rb @@ -266,6 +266,18 @@ class PatientSession < ApplicationRecord ) end + scope :has_patient_specific_direction, + ->(programme:) do + joins(:session).where( + PatientSpecificDirection + .where("patient_id = patient_sessions.patient_id") + .where("academic_year = sessions.academic_year") + .where(programme:) + .arel + .exists + ) + end + scope :destroy_all_if_safe, -> do includes( diff --git a/app/views/sessions/patient_specific_directions/show.html.erb b/app/views/sessions/patient_specific_directions/show.html.erb index c73abcf084..788c9df2bb 100644 --- a/app/views/sessions/patient_specific_directions/show.html.erb +++ b/app/views/sessions/patient_specific_directions/show.html.erb @@ -8,29 +8,37 @@ <%= render "sessions/header" %> -<%= govuk_inset_text do %> - Information: -

- There are <%= @eligible_for_bulk_psd_count %> children with consent for the nasal flu vaccine - who do not require triage and do not yet have a PSD in place. -

- <% if current_user.is_nurse? %> - - <% end %> -<% end %> -
-
+
+ <%= render AppPatientSearchFormComponent.new( + @form, + url: session_patient_specific_directions_path(@session), + programmes: @session.programmes, + patient_specific_direction_statuses: %w[added not_added], + year_groups: @session.year_groups, + ) %> +
+ <%= govuk_inset_text do %> + Information: +

+ There are <%= @eligible_for_bulk_psd_count %> children with consent for the nasal flu vaccine + who do not require triage and do not yet have a PSD in place. +

+ <% if current_user.is_nurse? %> + + <% end %> + <% end %> + <%= render AppSessionNeedsReviewWarningComponent.new(session: @session) %> <%= render AppSearchResultsComponent.new(@pagy, label: "children", heading: "Review PSDs") do %> <% @patient_sessions.each do |patient_session| %> diff --git a/spec/forms/patient_search_form_spec.rb b/spec/forms/patient_search_form_spec.rb index 7ca085eb95..41110305bf 100644 --- a/spec/forms/patient_search_form_spec.rb +++ b/spec/forms/patient_search_form_spec.rb @@ -34,6 +34,7 @@ let(:register_status) { nil } let(:triage_status) { nil } let(:vaccine_method) { nil } + let(:patient_specific_direction_status) { nil } let(:year_groups) { %w[8 9 10 11] } let(:params) do @@ -46,6 +47,7 @@ date_of_birth_year:, missing_nhs_number:, vaccination_status:, + patient_specific_direction_status:, programme_types:, q:, register_status:, @@ -458,6 +460,50 @@ end end + context "filtering on patient specific direction status" do + let(:consent_statuses) { nil } + let(:date_of_birth_day) { nil } + let(:date_of_birth_month) { nil } + let(:date_of_birth_year) { nil } + let(:missing_nhs_number) { nil } + let(:vaccination_status) { nil } + let(:programme_types) { nil } + let(:q) { nil } + let(:register_status) { nil } + let(:triage_status) { nil } + let(:year_groups) { nil } + + let!(:patient_session_with_psd) do + create(:patient_session, session:).tap do |patient_session| + create( + :patient_specific_direction, + patient: patient_session.patient, + programme: programmes.first + ) + end + end + + let!(:patient_session_without_psd) { create(:patient_session, session:) } + + context "when status is 'added'" do + let(:patient_specific_direction_status) { "added" } + + it "finds the patient with the PSD" do + expect(form.apply(scope)).to contain_exactly(patient_session_with_psd) + end + end + + context "when status is 'not_added'" do + let(:patient_specific_direction_status) { "not_added" } + + it "finds the patient that has no PSD" do + expect(form.apply(scope)).to contain_exactly( + patient_session_without_psd + ) + end + end + end + context "filtering on vaccine method" do let(:consent_statuses) { nil } let(:date_of_birth_day) { nil }